/* 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 */ #include "iv/editor/iv_editor_clipboard.h" #include "base/random.h" #include #include namespace Iv::Editor { namespace { struct ClipboardStorage { uint64 sessionId = base::RandomValue(); uint64 serial = 0; QPointer mimeData; std::optional data; }; [[nodiscard]] ClipboardStorage &Storage() { static auto storage = ClipboardStorage(); return storage; } [[nodiscard]] bool MarkerMatches(const QMimeData *mimeData) { return mimeData && mimeData->hasFormat(ClipboardMimeType()) && (mimeData->data(ClipboardMimeType()) == "1"); } [[nodiscard]] bool OriginMatches( const ClipboardOrigin &origin, const ClipboardStorage &storage) { return (origin.sessionId == storage.sessionId) && (origin.serial == storage.serial) && (origin.serial != 0); } [[nodiscard]] bool StoredDataMatches( const ClipboardData &data, const ClipboardStorage &storage) { return std::visit([&](const auto &payload) { return OriginMatches(payload.origin, storage); }, data); } [[nodiscard]] ClipboardData StampClipboardData(ClipboardData data) { auto &storage = Storage(); const auto serial = ++storage.serial; return std::visit([&](auto payload) -> ClipboardData { payload.origin.sessionId = storage.sessionId; payload.origin.serial = serial; return ClipboardData(std::move(payload)); }, std::move(data)); } } // namespace QString ClipboardMimeType() { return u"application/x-td-iv-editor"_q; } std::unique_ptr MimeDataFromClipboardData(ClipboardData data) { auto &storage = Storage(); storage.data = StampClipboardData(std::move(data)); auto result = std::make_unique(); result->setData(ClipboardMimeType(), "1"); storage.mimeData = result.get(); return result; } std::optional ClipboardDataFromMimeData( const QMimeData *mimeData) { const auto &storage = Storage(); if (!MarkerMatches(mimeData) || !storage.data || !storage.mimeData || (storage.mimeData.data() != mimeData) || !StoredDataMatches(*storage.data, storage)) { return std::nullopt; } return storage.data; } } // namespace Iv::Editor