diff --git a/ui/widgets/labels.cpp b/ui/widgets/labels.cpp index 3225978..7d44cae 100644 --- a/ui/widgets/labels.cpp +++ b/ui/widgets/labels.cpp @@ -403,6 +403,10 @@ void FlatLabel::overrideLinkClickHandler(Fn handler) { }); } +void FlatLabel::setContextMenuHook(Fn hook) { + _contextMenuHook = std::move(hook); +} + void FlatLabel::mouseMoveEvent(QMouseEvent *e) { _lastMousePos = e->globalPos(); dragActionUpdate(); @@ -579,7 +583,7 @@ void FlatLabel::keyPressEvent(QKeyEvent *e) { } void FlatLabel::contextMenuEvent(QContextMenuEvent *e) { - if (!_selectable && !_text.hasLinks()) { + if (!_contextMenuHook && !_selectable && !_text.hasLinks()) { return; } @@ -661,42 +665,27 @@ void FlatLabel::showContextMenu(QContextMenuEvent *e, ContextMenuReason reason) } else { _lastMousePos = QCursor::pos(); } - auto state = dragActionUpdate(); - + const auto state = dragActionUpdate(); const auto hasSelection = _selectable && !_selection.empty(); const auto uponSelection = _selectable && ((reason == ContextMenuReason::FromTouch && hasSelection) || (state.uponSymbol && (state.symbol >= _selection.from) && (state.symbol < _selection.to))); - const auto fullSelection = _selectable - && _text.isFullSelection(_selection); _contextMenu = base::make_unique_q(this, _stMenu); + const auto request = ContextMenuRequest{ + .menu = _contextMenu.get(), + .link = ClickHandler::getActive(), + .hasSelection = hasSelection, + .uponSelection = uponSelection, + .fullSelection = _selectable && _text.isFullSelection(_selection), + }; - if (fullSelection && !_contextCopyText.isEmpty()) { - _contextMenu->addAction( - _contextCopyText, - [=] { copyContextText(); }); - } else if (uponSelection && !fullSelection) { - _contextMenu->addAction( - Integration::Instance().phraseContextCopySelected(), - [=] { copySelectedText(); }); - } else if (_selectable && !hasSelection && !_contextCopyText.isEmpty()) { - _contextMenu->addAction( - _contextCopyText, - [=] { copyContextText(); }); - } - - if (const auto link = ClickHandler::getActive()) { - const auto actionText = link->copyToClipboardContextItemText(); - if (!actionText.isEmpty()) { - _contextMenu->addAction( - actionText, - [text = link->copyToClipboardText()] { - QGuiApplication::clipboard()->setText(text); - }); - } + if (_contextMenuHook) { + _contextMenuHook(request); + } else { + fillContextMenu(request); } if (_contextMenu->empty()) { @@ -707,6 +696,35 @@ void FlatLabel::showContextMenu(QContextMenuEvent *e, ContextMenuReason reason) } } +void FlatLabel::fillContextMenu(ContextMenuRequest request) { + if (request.fullSelection && !_contextCopyText.isEmpty()) { + request.menu->addAction( + _contextCopyText, + [=] { copyContextText(); }); + } else if (request.uponSelection && !request.fullSelection) { + request.menu->addAction( + Integration::Instance().phraseContextCopySelected(), + [=] { copySelectedText(); }); + } else if (_selectable + && !request.hasSelection + && !_contextCopyText.isEmpty()) { + request.menu->addAction( + _contextCopyText, + [=] { copyContextText(); }); + } + + if (request.link) { + const auto label = request.link->copyToClipboardContextItemText(); + if (!label.isEmpty()) { + request.menu->addAction( + label, + [text = request.link->copyToClipboardText()] { + QGuiApplication::clipboard()->setText(text); + }); + } + } +} + void FlatLabel::copySelectedText() { const auto selection = _selection.empty() ? (_contextMenu ? _savedSelection : _selection) : _selection; if (!selection.empty()) { diff --git a/ui/widgets/labels.h b/ui/widgets/labels.h index b7ab34d..62402d1 100644 --- a/ui/widgets/labels.h +++ b/ui/widgets/labels.h @@ -142,6 +142,15 @@ public: void overrideLinkClickHandler(Fn handler); void overrideLinkClickHandler(Fn handler); + struct ContextMenuRequest { + not_null menu; + ClickHandlerPtr link; + bool hasSelection = false; + bool uponSelection = false; + bool fullSelection = false; + }; + void setContextMenuHook(Fn hook); + // ClickHandlerHost interface void clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) override; void clickHandlerPressedChanged(const ClickHandlerPtr &action, bool pressed) override; @@ -201,6 +210,7 @@ private: FromTouch, }; void showContextMenu(QContextMenuEvent *e, ContextMenuReason reason); + void fillContextMenu(ContextMenuRequest request); Text::String _text; const style::FlatLabel &_st; @@ -237,6 +247,7 @@ private: base::Timer _trippleClickTimer; base::unique_qptr _contextMenu; + Fn _contextMenuHook; QString _contextCopyText; ClickHandlerFilter _clickHandlerFilter;