data_document.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #pragma once
  8. #include "base/flags.h"
  9. #include "base/binary_guard.h"
  10. #include "data/data_types.h"
  11. #include "data/data_cloud_file.h"
  12. #include "core/file_location.h"
  13. class HistoryItem;
  14. class PhotoData;
  15. enum class ChatRestriction;
  16. class mtpFileLoader;
  17. namespace Images {
  18. class Source;
  19. } // namespace Images
  20. namespace Core {
  21. enum class NameType : uchar;
  22. } // namespace Core
  23. namespace Storage {
  24. namespace Cache {
  25. struct Key;
  26. } // namespace Cache
  27. } // namespace Storage
  28. namespace Media {
  29. struct VideoQuality;
  30. } // namespace Media
  31. namespace Media::Streaming {
  32. class Loader;
  33. } // namespace Media::Streaming
  34. namespace Data {
  35. class Session;
  36. class DocumentMedia;
  37. class ReplyPreview;
  38. enum class StickersType : uchar;
  39. } // namespace Data
  40. namespace Main {
  41. class Session;
  42. } // namespace Main
  43. inline uint64 mediaMix32To64(int32 a, int32 b) {
  44. return (uint64(*reinterpret_cast<uint32*>(&a)) << 32)
  45. | uint64(*reinterpret_cast<uint32*>(&b));
  46. }
  47. // version field removed from document.
  48. inline MediaKey mediaKey(LocationType type, int32 dc, const uint64 &id) {
  49. return MediaKey(mediaMix32To64(type, dc), id);
  50. }
  51. struct DocumentAdditionalData {
  52. virtual ~DocumentAdditionalData() = default;
  53. };
  54. enum class StickerType : uchar {
  55. Webp,
  56. Tgs,
  57. Webm,
  58. };
  59. struct StickerData : public DocumentAdditionalData {
  60. [[nodiscard]] Data::FileOrigin setOrigin() const;
  61. [[nodiscard]] bool isStatic() const;
  62. [[nodiscard]] bool isLottie() const;
  63. [[nodiscard]] bool isAnimated() const;
  64. [[nodiscard]] bool isWebm() const;
  65. QString alt;
  66. StickerSetIdentifier set;
  67. StickerType type = StickerType::Webp;
  68. Data::StickersType setType = Data::StickersType();
  69. };
  70. struct SongData : public DocumentAdditionalData {
  71. QString title, performer;
  72. };
  73. struct VoiceData : public DocumentAdditionalData {
  74. ~VoiceData();
  75. VoiceWaveform waveform;
  76. char wavemax = 0;
  77. };
  78. struct VideoData : public DocumentAdditionalData {
  79. QString codec;
  80. std::vector<not_null<DocumentData*>> qualities;
  81. };
  82. using RoundData = VoiceData;
  83. namespace Serialize {
  84. class Document;
  85. } // namespace Serialize;
  86. class DocumentData final {
  87. public:
  88. DocumentData(not_null<Data::Session*> owner, DocumentId id);
  89. ~DocumentData();
  90. [[nodiscard]] Data::Session &owner() const;
  91. [[nodiscard]] Main::Session &session() const;
  92. void setattributes(
  93. const QVector<MTPDocumentAttribute> &attributes);
  94. void setVideoQualities(const QVector<MTPDocument> &list);
  95. void automaticLoadSettingsChanged();
  96. void setVideoQualities(std::vector<not_null<DocumentData*>> qualities);
  97. [[nodiscard]] int resolveVideoQuality() const;
  98. [[nodiscard]] auto resolveQualities(HistoryItem *context) const
  99. -> const std::vector<not_null<DocumentData*>> &;
  100. [[nodiscard]] not_null<DocumentData*> chooseQuality(
  101. HistoryItem *context,
  102. Media::VideoQuality request);
  103. [[nodiscard]] bool loading() const;
  104. [[nodiscard]] QString loadingFilePath() const;
  105. [[nodiscard]] bool displayLoading() const;
  106. void save(
  107. Data::FileOrigin origin,
  108. const QString &toFile,
  109. LoadFromCloudSetting fromCloud = LoadFromCloudOrLocal,
  110. bool autoLoading = false);
  111. void cancel();
  112. [[nodiscard]] bool cancelled() const;
  113. void resetCancelled();
  114. [[nodiscard]] float64 progress() const;
  115. [[nodiscard]] int64 loadOffset() const;
  116. [[nodiscard]] bool uploading() const;
  117. [[nodiscard]] bool loadedInMediaCache() const;
  118. void setLoadedInMediaCache(bool loaded);
  119. [[nodiscard]] ChatRestriction requiredSendRight() const;
  120. void setWaitingForAlbum();
  121. [[nodiscard]] bool waitingForAlbum() const;
  122. [[nodiscard]] const Core::FileLocation &location(
  123. bool check = false) const;
  124. void setLocation(const Core::FileLocation &loc);
  125. bool saveFromData();
  126. bool saveFromDataSilent();
  127. [[nodiscard]] QString filepath(bool check = false) const;
  128. void forceToCache(bool force);
  129. [[nodiscard]] bool saveToCache() const;
  130. [[nodiscard]] Image *getReplyPreview(
  131. Data::FileOrigin origin,
  132. not_null<PeerData*> context,
  133. bool spoiler);
  134. [[nodiscard]] Image *getReplyPreview(not_null<HistoryItem*> item);
  135. [[nodiscard]] bool replyPreviewLoaded(bool spoiler) const;
  136. [[nodiscard]] StickerData *sticker() const;
  137. [[nodiscard]] Data::FileOrigin stickerSetOrigin() const;
  138. [[nodiscard]] Data::FileOrigin stickerOrGifOrigin() const;
  139. [[nodiscard]] bool isStickerSetInstalled() const;
  140. [[nodiscard]] SongData *song();
  141. [[nodiscard]] const SongData *song() const;
  142. [[nodiscard]] VoiceData *voice();
  143. [[nodiscard]] const VoiceData *voice() const;
  144. [[nodiscard]] RoundData *round();
  145. [[nodiscard]] const RoundData *round() const;
  146. [[nodiscard]] VideoData *video();
  147. [[nodiscard]] const VideoData *video() const;
  148. void forceIsStreamedAnimation();
  149. [[nodiscard]] bool isVoiceMessage() const;
  150. [[nodiscard]] bool isVideoMessage() const;
  151. [[nodiscard]] bool isSong() const;
  152. [[nodiscard]] bool isSongWithCover() const;
  153. [[nodiscard]] bool isAudioFile() const;
  154. [[nodiscard]] bool isVideoFile() const;
  155. [[nodiscard]] bool isSilentVideo() const;
  156. [[nodiscard]] bool isAnimation() const;
  157. [[nodiscard]] bool isGifv() const;
  158. [[nodiscard]] bool isTheme() const;
  159. [[nodiscard]] bool isSharedMediaMusic() const;
  160. [[nodiscard]] crl::time duration() const;
  161. [[nodiscard]] bool hasDuration() const;
  162. [[nodiscard]] bool isImage() const;
  163. void recountIsImage();
  164. [[nodiscard]] bool supportsStreaming() const;
  165. void setNotSupportsStreaming();
  166. void setDataAndCache(const QByteArray &data);
  167. bool checkWallPaperProperties();
  168. [[nodiscard]] bool isWallPaper() const;
  169. [[nodiscard]] bool isPatternWallPaper() const;
  170. [[nodiscard]] bool isPatternWallPaperPNG() const;
  171. [[nodiscard]] bool isPatternWallPaperSVG() const;
  172. [[nodiscard]] bool isPremiumSticker() const;
  173. [[nodiscard]] bool isPremiumEmoji() const;
  174. [[nodiscard]] bool emojiUsesTextColor() const;
  175. void overrideEmojiUsesTextColor(bool value);
  176. [[nodiscard]] bool hasThumbnail() const;
  177. [[nodiscard]] bool thumbnailLoading() const;
  178. [[nodiscard]] bool thumbnailFailed() const;
  179. void loadThumbnail(Data::FileOrigin origin);
  180. [[nodiscard]] const ImageLocation &thumbnailLocation() const;
  181. [[nodiscard]] int thumbnailByteSize() const;
  182. [[nodiscard]] bool hasVideoThumbnail() const;
  183. [[nodiscard]] bool videoThumbnailLoading() const;
  184. [[nodiscard]] bool videoThumbnailFailed() const;
  185. void loadVideoThumbnail(Data::FileOrigin origin);
  186. [[nodiscard]] const ImageLocation &videoThumbnailLocation() const;
  187. [[nodiscard]] int videoThumbnailByteSize() const;
  188. void updateThumbnails(
  189. const InlineImageLocation &inlineThumbnail,
  190. const ImageWithLocation &thumbnail,
  191. const ImageWithLocation &videoThumbnail,
  192. bool isPremiumSticker);
  193. [[nodiscard]] QByteArray inlineThumbnailBytes() const {
  194. return _inlineThumbnailBytes;
  195. }
  196. [[nodiscard]] bool inlineThumbnailIsPath() const {
  197. return (_flags & Flag::InlineThumbnailIsPath);
  198. }
  199. void clearInlineThumbnailBytes() {
  200. _inlineThumbnailBytes = QByteArray();
  201. }
  202. [[nodiscard]] Storage::Cache::Key goodThumbnailCacheKey() const;
  203. [[nodiscard]] bool goodThumbnailChecked() const;
  204. [[nodiscard]] bool goodThumbnailGenerating() const;
  205. [[nodiscard]] bool goodThumbnailNoData() const;
  206. void setGoodThumbnailGenerating();
  207. void setGoodThumbnailDataReady();
  208. void setGoodThumbnailChecked(bool hasData);
  209. [[nodiscard]] std::shared_ptr<Data::DocumentMedia> createMediaView();
  210. [[nodiscard]] auto activeMediaView() const
  211. -> std::shared_ptr<Data::DocumentMedia>;
  212. void setGoodThumbnailPhoto(not_null<PhotoData*> photo);
  213. [[nodiscard]] PhotoData *goodThumbnailPhoto() const;
  214. [[nodiscard]] Storage::Cache::Key bigFileBaseCacheKey() const;
  215. void setStoryMedia(bool value);
  216. [[nodiscard]] bool storyMedia() const;
  217. void setRemoteLocation(
  218. int32 dc,
  219. uint64 access,
  220. const QByteArray &fileReference);
  221. void setContentUrl(const QString &url);
  222. void setWebLocation(const WebFileLocation &location);
  223. [[nodiscard]] bool hasRemoteLocation() const;
  224. [[nodiscard]] bool hasWebLocation() const;
  225. [[nodiscard]] bool isNull() const;
  226. [[nodiscard]] MTPInputDocument mtpInput() const;
  227. [[nodiscard]] QByteArray fileReference() const;
  228. void refreshFileReference(const QByteArray &value);
  229. // When we have some client-side generated document
  230. // (for example for displaying an external inline bot result)
  231. // and it has downloaded data, we can collect that data from it
  232. // to (this) received from the server "same" document.
  233. void collectLocalData(not_null<DocumentData*> local);
  234. [[nodiscard]] QString filename() const;
  235. [[nodiscard]] Core::NameType nameType() const;
  236. [[nodiscard]] QString mimeString() const;
  237. [[nodiscard]] bool hasMimeType(const QString &mime) const;
  238. void setMimeString(const QString &mime);
  239. [[nodiscard]] bool hasAttachedStickers() const;
  240. [[nodiscard]] MediaKey mediaKey() const;
  241. [[nodiscard]] Storage::Cache::Key cacheKey() const;
  242. [[nodiscard]] uint8 cacheTag() const;
  243. [[nodiscard]] bool canBeStreamed(HistoryItem *item) const;
  244. [[nodiscard]] auto createStreamingLoader(
  245. Data::FileOrigin origin,
  246. bool forceRemoteLoader) const
  247. -> std::unique_ptr<Media::Streaming::Loader>;
  248. [[nodiscard]] bool useStreamingLoader() const;
  249. void setInappPlaybackFailed();
  250. [[nodiscard]] bool inappPlaybackFailed() const;
  251. [[nodiscard]] int videoPreloadPrefix() const;
  252. [[nodiscard]] StorageFileLocation videoPreloadLocation() const;
  253. DocumentId id = 0;
  254. int64 size = 0;
  255. QSize dimensions;
  256. int32 date = 0;
  257. DocumentType type = FileDocument;
  258. FileStatus status = FileReady;
  259. std::unique_ptr<Data::UploadState> uploadingData;
  260. private:
  261. enum class Flag : ushort {
  262. StreamingMaybeYes = 0x0001,
  263. StreamingMaybeNo = 0x0002,
  264. StreamingPlaybackFailed = 0x0004,
  265. ImageType = 0x0008,
  266. DownloadCancelled = 0x0010,
  267. LoadedInMediaCache = 0x0020,
  268. HasAttachedStickers = 0x0040,
  269. InlineThumbnailIsPath = 0x0080,
  270. ForceToCache = 0x0100,
  271. PremiumSticker = 0x0200,
  272. PossibleCoverThumbnail = 0x0400,
  273. UseTextColor = 0x0800,
  274. StoryDocument = 0x1000,
  275. SilentVideo = 0x2000,
  276. };
  277. using Flags = base::flags<Flag>;
  278. friend constexpr bool is_flag_type(Flag) { return true; };
  279. enum class GoodThumbnailFlag : uchar {
  280. Checked = 0x01,
  281. Generating = 0x02,
  282. NoData = 0x03,
  283. Mask = 0x03,
  284. DataReady = 0x04,
  285. };
  286. using GoodThumbnailState = base::flags<GoodThumbnailFlag>;
  287. friend constexpr bool is_flag_type(GoodThumbnailFlag) { return true; };
  288. static constexpr Flags kStreamingSupportedMask = Flags()
  289. | Flag::StreamingMaybeYes
  290. | Flag::StreamingMaybeNo;
  291. static constexpr Flags kStreamingSupportedUnknown = Flags()
  292. | Flag::StreamingMaybeYes
  293. | Flag::StreamingMaybeNo;
  294. static constexpr Flags kStreamingSupportedMaybeYes = Flags()
  295. | Flag::StreamingMaybeYes;
  296. static constexpr Flags kStreamingSupportedMaybeNo = Flags()
  297. | Flag::StreamingMaybeNo;
  298. static constexpr Flags kStreamingSupportedNo = Flags();
  299. friend class Serialize::Document;
  300. [[nodiscard]] LocationType locationType() const;
  301. void validateLottieSticker();
  302. void setMaybeSupportsStreaming(bool supports);
  303. void setLoadedInMediaCacheLocation();
  304. void setFileName(const QString &remoteFileName);
  305. bool enforceNameType(Core::NameType nameType);
  306. void finishLoad();
  307. void handleLoaderUpdates();
  308. void destroyLoader();
  309. bool saveFromDataChecked();
  310. void refreshPossibleCoverThumbnail();
  311. const not_null<Data::Session*> _owner;
  312. int _videoPreloadPrefix = 0;
  313. // Two types of location: from MTProto by dc+access or from web by url
  314. int32 _dc = 0;
  315. uint64 _access = 0;
  316. QByteArray _fileReference;
  317. QString _url;
  318. QString _filename;
  319. QString _mimeString;
  320. WebFileLocation _urlLocation;
  321. QByteArray _inlineThumbnailBytes;
  322. Data::CloudFile _thumbnail;
  323. Data::CloudFile _videoThumbnail;
  324. std::unique_ptr<Data::ReplyPreview> _replyPreview;
  325. std::weak_ptr<Data::DocumentMedia> _media;
  326. PhotoData *_goodThumbnailPhoto = nullptr;
  327. crl::time _duration = -1;
  328. Core::FileLocation _location;
  329. std::unique_ptr<DocumentAdditionalData> _additional;
  330. mutable Flags _flags = kStreamingSupportedUnknown;
  331. GoodThumbnailState _goodThumbnailState = GoodThumbnailState();
  332. Core::NameType _nameType = Core::NameType();
  333. std::unique_ptr<FileLoader> _loader;
  334. };
  335. [[nodiscard]] PhotoData *LookupVideoCover(
  336. not_null<DocumentData*> document,
  337. HistoryItem *item);
  338. VoiceWaveform documentWaveformDecode(const QByteArray &encoded5bit);
  339. QByteArray documentWaveformEncode5bit(const VoiceWaveform &waveform);
  340. QString FileNameForSave(
  341. not_null<Main::Session*> session,
  342. const QString &title,
  343. const QString &filter,
  344. const QString &prefix,
  345. QString name,
  346. bool savingAs,
  347. const QDir &dir = QDir());
  348. QString DocumentFileNameForSave(
  349. not_null<const DocumentData*> data,
  350. bool forceSavingAs = false,
  351. const QString &already = QString(),
  352. const QDir &dir = QDir());