From f24f78c0cc86761028713a615a9ba7364d810825 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 13 Jan 2022 20:31:35 +0300 Subject: [PATCH] Use click handler property instead of dynamic cast. --- .../SourceFiles/core/click_handler_types.h | 2 + .../data/data_file_click_handler.cpp | 5 + .../admin_log/history_admin_log_inner.cpp | 60 +++++----- .../history/history_inner_widget.cpp | 16 ++- .../view/history_view_context_menu.cpp | 22 ++-- .../info/media/info_media_list_widget.cpp | 107 ++++++++++-------- 6 files changed, 122 insertions(+), 90 deletions(-) diff --git a/Telegram/SourceFiles/core/click_handler_types.h b/Telegram/SourceFiles/core/click_handler_types.h index 55b99eea1..dc39ec65c 100644 --- a/Telegram/SourceFiles/core/click_handler_types.h +++ b/Telegram/SourceFiles/core/click_handler_types.h @@ -10,6 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/basic_click_handlers.h" constexpr auto kPeerLinkPeerIdProperty = 0x01; +constexpr auto kPhotoLinkMediaIdProperty = 0x02; +constexpr auto kDocumentLinkMediaIdProperty = 0x03; namespace Main { class Session; diff --git a/Telegram/SourceFiles/data/data_file_click_handler.cpp b/Telegram/SourceFiles/data/data_file_click_handler.cpp index ae82e775f..4bd22b0d2 100644 --- a/Telegram/SourceFiles/data/data_file_click_handler.cpp +++ b/Telegram/SourceFiles/data/data_file_click_handler.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "data/data_file_click_handler.h" +#include "core/click_handler_types.h" #include "core/file_utilities.h" #include "data/data_document.h" #include "data/data_photo.h" @@ -44,6 +45,9 @@ DocumentClickHandler::DocumentClickHandler( FullMsgId context) : FileClickHandler(context) , _document(document) { + setProperty( + kDocumentLinkMediaIdProperty, + QVariant(qulonglong(_document->id))); } DocumentOpenClickHandler::DocumentOpenClickHandler( @@ -146,6 +150,7 @@ PhotoClickHandler::PhotoClickHandler( : FileClickHandler(context) , _photo(photo) , _peer(peer) { + setProperty(kPhotoLinkMediaIdProperty, QVariant(qulonglong(_photo->id))); } not_null PhotoClickHandler::photo() const { diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp index edfb960c3..ab9c2e1a7 100644 --- a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp +++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp @@ -1169,11 +1169,21 @@ void InnerWidget::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { auto view = App::hoveredItem() ? App::hoveredItem() : App::hoveredLinkItem(); - auto lnkPhoto = dynamic_cast(link.get()); - auto lnkDocument = dynamic_cast(link.get()); - auto lnkIsVideo = lnkDocument ? lnkDocument->document()->isVideoFile() : false; - auto lnkIsVoice = lnkDocument ? lnkDocument->document()->isVoiceMessage() : false; - auto lnkIsAudio = lnkDocument ? lnkDocument->document()->isAudioFile() : false; + const auto lnkPhotoId = PhotoId(link + ? link->property(kPhotoLinkMediaIdProperty).toULongLong() + : 0); + const auto lnkDocumentId = DocumentId(link + ? link->property(kDocumentLinkMediaIdProperty).toULongLong() + : 0); + const auto lnkPhoto = lnkPhotoId + ? session().data().photo(lnkPhotoId).get() + : nullptr; + const auto lnkDocument = lnkDocumentId + ? session().data().document(lnkDocumentId).get() + : nullptr; + auto lnkIsVideo = lnkDocument ? lnkDocument->isVideoFile() : false; + auto lnkIsVoice = lnkDocument ? lnkDocument->isVoiceMessage() : false; + auto lnkIsAudio = lnkDocument ? lnkDocument->isAudioFile() : false; const auto fromId = PeerId(link ? link->property(kPeerLinkPeerIdProperty).toULongLong() : 0); @@ -1184,21 +1194,20 @@ void InnerWidget::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { }, &st::menuIconCopy); } if (lnkPhoto) { - const auto photo = lnkPhoto->photo(); - const auto media = photo->activeMediaView(); - if (!photo->isNull() && media && media->loaded()) { + const auto media = lnkPhoto->activeMediaView(); + if (!lnkPhoto->isNull() && media && media->loaded()) { _menu->addAction(tr::lng_context_save_image(tr::now), App::LambdaDelayed(st::defaultDropdownMenu.menu.ripple.hideDuration, this, [=] { - savePhotoToFile(photo); + savePhotoToFile(lnkPhoto); }), &st::menuIconSaveImage); _menu->addAction(tr::lng_context_copy_image(tr::now), [=] { - copyContextImage(photo); + copyContextImage(lnkPhoto); }, &st::menuIconCopy); } - if (photo->hasAttachedStickers()) { + if (lnkPhoto->hasAttachedStickers()) { const auto controller = _controller; auto callback = [=] { auto &attached = session().api().attachedStickers(); - attached.requestAttachedStickerSets(controller, photo); + attached.requestAttachedStickerSets(controller, lnkPhoto); }; _menu->addAction( tr::lng_context_attached_stickers(tr::now), @@ -1206,22 +1215,21 @@ void InnerWidget::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { &st::menuIconStickers); } } else { - auto document = lnkDocument->document(); - if (document->loading()) { + if (lnkDocument->loading()) { _menu->addAction(tr::lng_context_cancel_download(tr::now), [=] { - cancelContextDownload(document); + cancelContextDownload(lnkDocument); }, &st::menuIconCancel); } else { const auto itemId = view ? view->data()->fullId() : FullMsgId(); - if (const auto item = document->session().data().message(itemId)) { + if (const auto item = session().data().message(itemId)) { const auto notAutoplayedGif = [&] { - return document->isGifv() + return lnkDocument->isGifv() && !Data::AutoDownload::ShouldAutoPlay( - document->session().settings().autoDownload(), + session().settings().autoDownload(), item->history()->peer, - document); + lnkDocument); }(); if (notAutoplayedGif) { _menu->addAction(tr::lng_context_open_gif(tr::now), [=] { @@ -1229,19 +1237,19 @@ void InnerWidget::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { }, &st::menuIconShowInChat); } } - if (!document->filepath(true).isEmpty()) { + if (!lnkDocument->filepath(true).isEmpty()) { _menu->addAction(Platform::IsMac() ? tr::lng_context_show_in_finder(tr::now) : tr::lng_context_show_in_folder(tr::now), [=] { - showContextInFolder(document); + showContextInFolder(lnkDocument); }, &st::menuIconShowInFolder); } - _menu->addAction(lnkIsVideo ? tr::lng_context_save_video(tr::now) : (lnkIsVoice ? tr::lng_context_save_audio(tr::now) : (lnkIsAudio ? tr::lng_context_save_audio_file(tr::now) : tr::lng_context_save_file(tr::now))), App::LambdaDelayed(st::defaultDropdownMenu.menu.ripple.hideDuration, this, [this, document] { - saveDocumentToFile(document); + _menu->addAction(lnkIsVideo ? tr::lng_context_save_video(tr::now) : (lnkIsVoice ? tr::lng_context_save_audio(tr::now) : (lnkIsAudio ? tr::lng_context_save_audio_file(tr::now) : tr::lng_context_save_file(tr::now))), App::LambdaDelayed(st::defaultDropdownMenu.menu.ripple.hideDuration, this, [this, lnkDocument] { + saveDocumentToFile(lnkDocument); }), &st::menuIconDownload); - if (document->hasAttachedStickers()) { + if (lnkDocument->hasAttachedStickers()) { const auto controller = _controller; - auto callback = [=, doc = document] { + auto callback = [=] { auto &attached = session().api().attachedStickers(); - attached.requestAttachedStickerSets(controller, doc); + attached.requestAttachedStickerSets(controller, lnkDocument); }; _menu->addAction( tr::lng_context_attached_stickers(tr::now), diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index 37b3109b3..757038433 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -2045,9 +2045,13 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { }; const auto link = ClickHandler::getActive(); - auto lnkPhoto = dynamic_cast(link.get()); - auto lnkDocument = dynamic_cast(link.get()); - if (lnkPhoto || lnkDocument) { + const auto lnkPhotoId = PhotoId(link + ? link->property(kPhotoLinkMediaIdProperty).toULongLong() + : 0); + const auto lnkDocumentId = DocumentId(link + ? link->property(kDocumentLinkMediaIdProperty).toULongLong() + : 0); + if (lnkPhotoId || lnkDocumentId) { const auto item = _dragStateItem; const auto itemId = item ? item->fullId() : FullMsgId(); if (isUponSelected > 0 && !hasCopyRestrictionForSelected()) { @@ -2059,10 +2063,10 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { &st::menuIconCopy); } addItemActions(item, item); - if (lnkPhoto) { - addPhotoActions(lnkPhoto->photo(), item); + if (lnkPhotoId) { + addPhotoActions(session->data().photo(lnkPhotoId), item); } else { - addDocumentActions(lnkDocument->document(), item); + addDocumentActions(session->data().document(lnkDocumentId), item); } if (item && item->hasDirectLink() && isUponSelected != 2 && isUponSelected != -2) { _menu->addAction(item->history()->peer->isMegagroup() ? tr::lng_context_copy_message_link(tr::now) : tr::lng_context_copy_post_link(tr::now), [=] { diff --git a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp index 9ba02bf5a..cd7608c0d 100644 --- a/Telegram/SourceFiles/history/view/history_view_context_menu.cpp +++ b/Telegram/SourceFiles/history/view/history_view_context_menu.cpp @@ -45,6 +45,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_file_origin.h" #include "data/data_scheduled_messages.h" #include "core/file_utilities.h" +#include "core/click_handler_types.h" #include "base/platform/base_platform_info.h" #include "window/window_peer_menu.h" #include "window/window_controller.h" @@ -921,12 +922,17 @@ base::unique_qptr FillContextMenu( const auto view = request.view; const auto item = request.item; const auto itemId = item ? item->fullId() : FullMsgId(); - const auto rawLink = link.get(); - const auto linkPhoto = dynamic_cast(rawLink); - const auto linkDocument = dynamic_cast(rawLink); - const auto photo = linkPhoto ? linkPhoto->photo().get() : nullptr; - const auto document = linkDocument - ? linkDocument->document().get() + const auto lnkPhotoId = PhotoId(link + ? link->property(kPhotoLinkMediaIdProperty).toULongLong() + : 0); + const auto lnkDocumentId = DocumentId(link + ? link->property(kDocumentLinkMediaIdProperty).toULongLong() + : 0); + const auto photo = lnkPhotoId + ? list->session().data().photo(lnkPhotoId).get() + : nullptr; + const auto document = lnkDocumentId + ? list->session().data().document(lnkDocumentId).get() : nullptr; const auto poll = item ? (item->media() ? item->media()->poll() : nullptr) @@ -951,9 +957,9 @@ base::unique_qptr FillContextMenu( } AddTopMessageActions(result, request, list); - if (linkPhoto) { + if (photo) { AddPhotoActions(result, photo, item, list); - } else if (linkDocument) { + } else if (document) { AddDocumentActions(result, document, item, list); } else if (poll) { AddPollActions(result, poll, item, list->elementContext()); diff --git a/Telegram/SourceFiles/info/media/info_media_list_widget.cpp b/Telegram/SourceFiles/info/media/info_media_list_widget.cpp index 6fef80a03..eb6e37095 100644 --- a/Telegram/SourceFiles/info/media/info_media_list_widget.cpp +++ b/Telegram/SourceFiles/info/media/info_media_list_widget.cpp @@ -1593,68 +1593,75 @@ void ListWidget::showContextMenu( }, &st::menuIconShowInChat); - auto photoLink = dynamic_cast(link.get()); - auto fileLink = dynamic_cast(link.get()); - if (photoLink || fileLink) { + const auto lnkPhotoId = PhotoId(link + ? link->property(kPhotoLinkMediaIdProperty).toULongLong() + : 0); + const auto lnkDocumentId = DocumentId(link + ? link->property(kDocumentLinkMediaIdProperty).toULongLong() + : 0); + const auto lnkPhoto = lnkPhotoId + ? session().data().photo(lnkPhotoId).get() + : nullptr; + const auto lnkDocument = lnkDocumentId + ? session().data().document(lnkDocumentId).get() + : nullptr; + if (lnkPhoto || lnkDocument) { auto [isVideo, isVoice, isAudio] = [&] { - if (fileLink) { - auto document = fileLink->document(); + if (lnkDocument) { return std::make_tuple( - document->isVideoFile(), - document->isVoiceMessage(), - document->isAudioFile() + lnkDocument->isVideoFile(), + lnkDocument->isVoiceMessage(), + lnkDocument->isAudioFile() ); } return std::make_tuple(false, false, false); }(); - if (photoLink) { + if (lnkPhoto) { } else { - if (auto document = fileLink->document()) { - if (document->loading()) { - _contextMenu->addAction( - tr::lng_context_cancel_download(tr::now), - [document] { - document->cancel(); - }, - &st::menuIconCancel); - } else { - auto filepath = document->filepath(true); - if (!filepath.isEmpty()) { - auto handler = App::LambdaDelayed( - st::defaultDropdownMenu.menu.ripple.hideDuration, - this, - [filepath] { - File::ShowInFolder(filepath); - }); - _contextMenu->addAction( - (Platform::IsMac() - ? tr::lng_context_show_in_finder(tr::now) - : tr::lng_context_show_in_folder(tr::now)), - std::move(handler), - &st::menuIconShowInFolder); - } + if (lnkDocument->loading()) { + _contextMenu->addAction( + tr::lng_context_cancel_download(tr::now), + [lnkDocument] { + lnkDocument->cancel(); + }, + &st::menuIconCancel); + } else { + auto filepath = lnkDocument->filepath(true); + if (!filepath.isEmpty()) { auto handler = App::LambdaDelayed( st::defaultDropdownMenu.menu.ripple.hideDuration, this, - [=] { - DocumentSaveClickHandler::Save( - itemFullId, - document, - DocumentSaveClickHandler::Mode::ToNewFile); + [filepath] { + File::ShowInFolder(filepath); }); - if (_peer->allowsForwarding() && !item->forbidsForward()) { - _contextMenu->addAction( - (isVideo - ? tr::lng_context_save_video(tr::now) - : isVoice - ? tr::lng_context_save_audio(tr::now) - : isAudio - ? tr::lng_context_save_audio_file(tr::now) - : tr::lng_context_save_file(tr::now)), - std::move(handler), - &st::menuIconDownload); - } + _contextMenu->addAction( + (Platform::IsMac() + ? tr::lng_context_show_in_finder(tr::now) + : tr::lng_context_show_in_folder(tr::now)), + std::move(handler), + &st::menuIconShowInFolder); + } + auto handler = App::LambdaDelayed( + st::defaultDropdownMenu.menu.ripple.hideDuration, + this, + [=] { + DocumentSaveClickHandler::Save( + itemFullId, + lnkDocument, + DocumentSaveClickHandler::Mode::ToNewFile); + }); + if (_peer->allowsForwarding() && !item->forbidsForward()) { + _contextMenu->addAction( + (isVideo + ? tr::lng_context_save_video(tr::now) + : isVoice + ? tr::lng_context_save_audio(tr::now) + : isAudio + ? tr::lng_context_save_audio_file(tr::now) + : tr::lng_context_save_file(tr::now)), + std::move(handler), + &st::menuIconDownload); } } }