/* This file is part of Telegram Desktop, the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once #include "ui/image/image.h" namespace Images { class ImageSource : public Source { public: ImageSource(QImage &&data, const QByteArray &format); void load( Data::FileOrigin origin, bool loadFirst, bool prior) override; void loadEvenCancelled( Data::FileOrigin origin, bool loadFirst, bool prior) override; QImage takeLoaded() override; void unload() override; void automaticLoad( Data::FileOrigin origin, const HistoryItem *item) override; void automaticLoadSettingsChanged() override; bool loading() override; bool displayLoading() override; void cancel() override; float64 progress() override; int loadOffset() override; const StorageImageLocation &location() override; void refreshFileReference(const QByteArray &data) override; std::optional cacheKey() override; void setDelayedStorageLocation( const StorageImageLocation &location) override; void performDelayedLoad(Data::FileOrigin origin) override; bool isDelayedStorageImage() const override; void setImageBytes(const QByteArray &bytes) override; int width() override; int height() override; int bytesSize() override; void setInformation(int size, int width, int height) override; QByteArray bytesForCache() override; private: QImage _data; QByteArray _format; QByteArray _bytes; int _width = 0; int _height = 0; }; class LocalFileSource : public Source { public: explicit LocalFileSource( const QString &path, const QByteArray &content = QByteArray(), const QByteArray &format = QByteArray(), QImage &&data = QImage()); void load( Data::FileOrigin origin, bool loadFirst, bool prior) override; void loadEvenCancelled( Data::FileOrigin origin, bool loadFirst, bool prior) override; QImage takeLoaded() override; void unload() override; void automaticLoad( Data::FileOrigin origin, const HistoryItem *item) override; void automaticLoadSettingsChanged() override; bool loading() override; bool displayLoading() override; void cancel() override; float64 progress() override; int loadOffset() override; const StorageImageLocation &location() override; void refreshFileReference(const QByteArray &data) override; std::optional cacheKey() override; void setDelayedStorageLocation( const StorageImageLocation &location) override; void performDelayedLoad(Data::FileOrigin origin) override; bool isDelayedStorageImage() const override; void setImageBytes(const QByteArray &bytes) override; int width() override; int height() override; int bytesSize() override; void setInformation(int size, int width, int height) override; QByteArray bytesForCache() override; private: void ensureDimensionsKnown(); QString _path; QByteArray _bytes; QByteArray _format; QImage _data; int _width = 0; int _height = 0; }; class RemoteSource : public Source { public: void load( Data::FileOrigin origin, bool loadFirst, bool prior) override; void loadEvenCancelled( Data::FileOrigin origin, bool loadFirst, bool prior) override; QImage takeLoaded() override; void unload() override; void automaticLoad( Data::FileOrigin origin, const HistoryItem *item) override; void automaticLoadSettingsChanged() override; bool loading() override; bool displayLoading() override; void cancel() override; float64 progress() override; int loadOffset() override; const StorageImageLocation &location() override; void refreshFileReference(const QByteArray &data) override; void setDelayedStorageLocation( const StorageImageLocation &location) override; void performDelayedLoad(Data::FileOrigin origin) override; bool isDelayedStorageImage() const override; void setImageBytes(const QByteArray &bytes) override; QByteArray bytesForCache() override; ~RemoteSource(); protected: // If after loading the image we need to shrink it to fit into a // specific size, you can return this size here. virtual QSize shrinkBox() const = 0; virtual FileLoader *createLoader( Data::FileOrigin origin, LoadFromCloudSetting fromCloud, bool autoLoading) = 0; void loadLocal(); private: bool loaderValid() const; bool cancelled() const; void destroyLoader(FileLoader *newValue = nullptr); FileLoader *_loader = nullptr; }; class StorageSource : public RemoteSource { public: StorageSource( const StorageImageLocation &location, int size); const StorageImageLocation &location() override; std::optional cacheKey() override; void refreshFileReference(const QByteArray &data) override; int width() override; int height() override; int bytesSize() override; void setInformation(int size, int width, int height) override; protected: QSize shrinkBox() const override; FileLoader *createLoader( Data::FileOrigin origin, LoadFromCloudSetting fromCloud, bool autoLoading) override; StorageImageLocation _location; int _size = 0; }; class WebCachedSource : public RemoteSource { public: WebCachedSource(const WebFileLocation &location, QSize box, int size = 0); WebCachedSource( const WebFileLocation &location, int width, int height, int size = 0); std::optional cacheKey() override; int width() override; int height() override; int bytesSize() override; void setInformation(int size, int width, int height) override; protected: QSize shrinkBox() const override; FileLoader *createLoader( Data::FileOrigin origin, LoadFromCloudSetting fromCloud, bool autoLoading) override; WebFileLocation _location; QSize _box; int _width = 0; int _height = 0; int _size = 0; }; class GeoPointSource : public RemoteSource { public: GeoPointSource(const GeoPointLocation &location); std::optional cacheKey() override; int width() override; int height() override; int bytesSize() override; void setInformation(int size, int width, int height) override; protected: QSize shrinkBox() const override; FileLoader *createLoader( Data::FileOrigin origin, LoadFromCloudSetting fromCloud, bool autoLoading) override; GeoPointLocation _location; int _size = 0; }; class DelayedStorageSource : public StorageSource { public: DelayedStorageSource(); DelayedStorageSource(int width, int height); void load( Data::FileOrigin origin, bool loadFirst, bool prior) override; void loadEvenCancelled( Data::FileOrigin origin, bool loadFirst, bool prior) override; void setDelayedStorageLocation( const StorageImageLocation &location) override; bool isDelayedStorageImage() const override; void performDelayedLoad(Data::FileOrigin origin) override; void automaticLoad( Data::FileOrigin origin, const HistoryItem *item) override; // auto load photo void automaticLoadSettingsChanged() override; bool loading() override { return _location.isNull() ? _loadRequested : StorageSource::loading(); } bool displayLoading() override; void cancel() override; private: bool _loadRequested = false; bool _loadCancelled = false; bool _loadFromCloud = false; }; class WebUrlSource : public RemoteSource { public: // If !box.isEmpty() then resize the image to fit in this box. explicit WebUrlSource(const QString &url, QSize box = QSize()); WebUrlSource(const QString &url, int width, int height); std::optional cacheKey() override; int width() override; int height() override; int bytesSize() override; void setInformation(int size, int width, int height) override; protected: QSize shrinkBox() const override; FileLoader *createLoader( Data::FileOrigin origin, LoadFromCloudSetting fromCloud, bool autoLoading) override; private: QString _url; QSize _box; int _size = 0; int _width = 0; int _height = 0; }; } // namespace Images