From 7b7a2ad63083717ce92cfc6d2d871034d6dc43c3 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Thu, 24 Jan 2019 06:39:20 +0100 Subject: [PATCH] TextEditor: Use callback in refactoring markers Allows to trigger actions without adding specific handling into the editor. Change-Id: Ia63d65d3feca37bcefca1b6322ade039027a92d8 Reviewed-by: Eike Ziller --- .../clangcodemodel/clangdiagnosticmanager.cpp | 11 +++++- src/plugins/cppeditor/cppeditorwidget.cpp | 38 ++----------------- src/plugins/cppeditor/cppeditorwidget.h | 4 -- .../cppeditor/cppfunctiondecldeflink.cpp | 23 +++++------ .../cppeditor/cppfunctiondecldeflink.h | 4 -- src/plugins/cpptools/cpptoolsconstants.h | 1 + src/plugins/qmljseditor/qmljseditor.cpp | 33 +++++----------- src/plugins/qmljseditor/qmljseditor.h | 1 - .../qmljseditor/qmljseditorconstants.h | 2 + src/plugins/texteditor/refactoroverlay.cpp | 8 ++++ src/plugins/texteditor/refactoroverlay.h | 12 +++++- src/plugins/texteditor/texteditor.cpp | 3 +- src/plugins/texteditor/texteditor.h | 2 - 13 files changed, 56 insertions(+), 86 deletions(-) diff --git a/src/plugins/clangcodemodel/clangdiagnosticmanager.cpp b/src/plugins/clangcodemodel/clangdiagnosticmanager.cpp index 91914699e66..72049242dc5 100644 --- a/src/plugins/clangcodemodel/clangdiagnosticmanager.cpp +++ b/src/plugins/clangcodemodel/clangdiagnosticmanager.cpp @@ -38,6 +38,7 @@ #include #include +#include #include #include @@ -268,7 +269,15 @@ TextEditor::RefactorMarker createFixItAvailableMarker(QTextDocument *textDocumen TextEditor::RefactorMarker marker; marker.tooltip = tooltipForFixItAvailableMarker(); marker.cursor = cursorAtLastPositionOfLine(textDocument, lineNumber); - marker.data = QLatin1String(CppTools::Constants::CPP_CLANG_FIXIT_AVAILABLE_MARKER_ID); + marker.callback = [marker](TextEditor::TextEditorWidget *editor) { + int line, column; + if (Utils::Text::convertPosition(marker.cursor.document(), + marker.cursor.position(), &line, &column)) { + editor->setTextCursor(marker.cursor); + editor->invokeAssist(TextEditor::QuickFix); + } + }; + marker.type = CppTools::Constants::CPP_CLANG_FIXIT_AVAILABLE_MARKER_ID; return marker; } diff --git a/src/plugins/cppeditor/cppeditorwidget.cpp b/src/plugins/cppeditor/cppeditorwidget.cpp index 7bec7b9fe70..286ef4cdf91 100644 --- a/src/plugins/cppeditor/cppeditorwidget.cpp +++ b/src/plugins/cppeditor/cppeditorwidget.cpp @@ -324,13 +324,14 @@ void CppEditorWidget::onCppDocumentUpdated() void CppEditorWidget::onCodeWarningsUpdated(unsigned revision, const QList selections, - const TextEditor::RefactorMarkers &refactorMarkers) + const RefactorMarkers &refactorMarkers) { if (revision != documentRevision()) return; setExtraSelections(TextEditorWidget::CodeWarningsSelection, selections); - setRefactorMarkers(refactorMarkersWithoutClangMarkers() + refactorMarkers); + setRefactorMarkers(refactorMarkers + RefactorMarker::filterOutType( + this->refactorMarkers(), CppTools::Constants::CPP_CLANG_FIXIT_AVAILABLE_MARKER_ID)); } void CppEditorWidget::onIfdefedOutBlocksUpdated(unsigned revision, @@ -753,26 +754,6 @@ unsigned CppEditorWidget::documentRevision() const return document()->revision(); } -static bool isClangFixItAvailableMarker(const RefactorMarker &marker) -{ - return marker.data.toString() - == QLatin1String(CppTools::Constants::CPP_CLANG_FIXIT_AVAILABLE_MARKER_ID); -} - -RefactorMarkers CppEditorWidget::refactorMarkersWithoutClangMarkers() const -{ - RefactorMarkers clearedRefactorMarkers; - - foreach (const RefactorMarker &marker, refactorMarkers()) { - if (isClangFixItAvailableMarker(marker)) - continue; - - clearedRefactorMarkers.append(marker); - } - - return clearedRefactorMarkers; -} - CppTools::FollowSymbolInterface &CppEditorWidget::followSymbolInterface() const { return d->m_modelManager->followSymbolInterface(); @@ -1026,19 +1007,6 @@ QSharedPointer CppEditorWidget::declDefLink() const return d->m_declDefLink; } -void CppEditorWidget::onRefactorMarkerClicked(const RefactorMarker &marker) -{ - if (marker.data.canConvert()) { - applyDeclDefLinkChanges(true); - } else if (isClangFixItAvailableMarker(marker)) { - int line, column; - if (Utils::Text::convertPosition(document(), marker.cursor.position(), &line, &column)) { - setTextCursor(marker.cursor); - invokeAssist(TextEditor::QuickFix); - } - } -} - void CppEditorWidget::updateFunctionDeclDefLink() { const int pos = textCursor().selectionStart(); diff --git a/src/plugins/cppeditor/cppeditorwidget.h b/src/plugins/cppeditor/cppeditorwidget.h index f141ee22485..57fd9d0fd65 100644 --- a/src/plugins/cppeditor/cppeditorwidget.h +++ b/src/plugins/cppeditor/cppeditorwidget.h @@ -105,8 +105,6 @@ protected: bool resolveTarget = true, bool inNextSplit = false) override; - void onRefactorMarkerClicked(const TextEditor::RefactorMarker &marker) override; - void slotCodeStyleSettingsChanged(const QVariant &) override; private: @@ -138,8 +136,6 @@ private: QMenu *createRefactorMenu(QWidget *parent) const; - TextEditor::RefactorMarkers refactorMarkersWithoutClangMarkers() const; - CppTools::FollowSymbolInterface &followSymbolInterface() const; CppTools::ProjectPart *projectPart() const; diff --git a/src/plugins/cppeditor/cppfunctiondecldeflink.cpp b/src/plugins/cppeditor/cppfunctiondecldeflink.cpp index 86bdf2a0cf7..a1af83596f8 100644 --- a/src/plugins/cppeditor/cppfunctiondecldeflink.cpp +++ b/src/plugins/cppeditor/cppfunctiondecldeflink.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -300,21 +301,12 @@ void FunctionDeclDefLink::apply(CppEditorWidget *editor, bool jumpToMatch) } } -static QList removeDeclDefLinkMarkers(const QList &markers) -{ - QList result; - foreach (const RefactorMarker &marker, markers) { - if (!marker.data.canConvert()) - result += marker; - } - return result; -} - void FunctionDeclDefLink::hideMarker(CppEditorWidget *editor) { if (!hasMarker) return; - editor->setRefactorMarkers(removeDeclDefLinkMarkers(editor->refactorMarkers())); + editor->setRefactorMarkers(RefactorMarker::filterOutType( + editor->refactorMarkers(), CppTools::Constants::CPP_FUNCTION_DECL_DEF_LINK_MARKER_ID)); hasMarker = false; } @@ -323,7 +315,8 @@ void FunctionDeclDefLink::showMarker(CppEditorWidget *editor) if (hasMarker) return; - QList markers = removeDeclDefLinkMarkers(editor->refactorMarkers()); + QList markers = RefactorMarker::filterOutType( + editor->refactorMarkers(), CppTools::Constants::CPP_FUNCTION_DECL_DEF_LINK_MARKER_ID); RefactorMarker marker; // show the marker at the end of the linked area, with a special case @@ -348,7 +341,11 @@ void FunctionDeclDefLink::showMarker(CppEditorWidget *editor) message = ProxyAction::stringWithAppendedShortcut(message, quickfixCommand->keySequence()); marker.tooltip = message; - marker.data = QVariant::fromValue(Marker()); + marker.type = CppTools::Constants::CPP_FUNCTION_DECL_DEF_LINK_MARKER_ID; + marker.callback = [](TextEditor::TextEditorWidget *widget) { + if (auto cppEditor = qobject_cast(widget)) + cppEditor->applyDeclDefLinkChanges(true); + }; markers += marker; editor->setRefactorMarkers(markers); diff --git a/src/plugins/cppeditor/cppfunctiondecldeflink.h b/src/plugins/cppeditor/cppfunctiondecldeflink.h index 0698521bcdd..4d6437965db 100644 --- a/src/plugins/cppeditor/cppfunctiondecldeflink.h +++ b/src/plugins/cppeditor/cppfunctiondecldeflink.h @@ -70,8 +70,6 @@ class FunctionDeclDefLink Q_DISABLE_COPY(FunctionDeclDefLink) FunctionDeclDefLink() = default; public: - class Marker {}; - bool isValid() const; bool isMarkerVisible() const; @@ -113,5 +111,3 @@ private: } // namespace Internal } // namespace CppEditor - -Q_DECLARE_METATYPE(CppEditor::Internal::FunctionDeclDefLink::Marker) diff --git a/src/plugins/cpptools/cpptoolsconstants.h b/src/plugins/cpptools/cpptoolsconstants.h index 07c6c64e7d0..2e1aebfd432 100644 --- a/src/plugins/cpptools/cpptoolsconstants.h +++ b/src/plugins/cpptools/cpptoolsconstants.h @@ -71,6 +71,7 @@ const char CPP_DIAGNOSTIC_CONFIG_SETTINGS_NAME[] = QT_TRANSLATE_NOOP("CppTools", const char CPP_SETTINGS_CATEGORY[] = "I.C++"; const char CPP_CLANG_FIXIT_AVAILABLE_MARKER_ID[] = "ClangFixItAvailableMarker"; +const char CPP_FUNCTION_DECL_DEF_LINK_MARKER_ID[] = "FunctionDeclDefLinkMarker"; const char CPP_SETTINGS_ID[] = "Cpp"; const char CPP_SETTINGS_NAME[] = QT_TRANSLATE_NOOP("CppTools", "C++"); diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp index ee3f30b2fe3..458cb55b6ef 100644 --- a/src/plugins/qmljseditor/qmljseditor.cpp +++ b/src/plugins/qmljseditor/qmljseditor.cpp @@ -269,23 +269,10 @@ void QmlJSEditorWidget::updateOutlineIndexNow() } // namespace Internal } // namespace QmlJSEditor -class QtQuickToolbarMarker {}; -Q_DECLARE_METATYPE(QtQuickToolbarMarker) namespace QmlJSEditor { namespace Internal { -template -static QList removeMarkersOfType(const QList &markers) -{ - QList result; - foreach (const RefactorMarker &marker, markers) { - if (!marker.data.canConvert()) - result += marker; - } - return result; -} - void QmlJSEditorWidget::updateContextPane() { const SemanticInfo info = m_qmlJsEditorDocument->semanticInfo(); @@ -299,7 +286,8 @@ void QmlJSEditorWidget::updateContextPane() if (m_contextPane->isAvailable(this, info.document, newNode) && !m_contextPane->widget()->isVisible()) { - QList markers = removeMarkersOfType(refactorMarkers()); + QList markers = RefactorMarker::filterOutType( + refactorMarkers(), Constants::QT_QUICK_TOOLBAR_MARKER_ID); if (UiObjectMember *m = newNode->uiObjectMemberCast()) { const int start = qualifiedTypeNameId(m)->identifierToken.begin(); for (UiQualifiedId *q = qualifiedTypeNameId(m); q; q = q->next) { @@ -311,7 +299,10 @@ void QmlJSEditorWidget::updateContextPane() tc.setPosition(end); marker.cursor = tc; marker.tooltip = tr("Show Qt Quick ToolBar"); - marker.data = QVariant::fromValue(QtQuickToolbarMarker()); + marker.type = Constants::QT_QUICK_TOOLBAR_MARKER_ID; + marker.callback = [this](TextEditorWidget *) { + showContextPane(); + }; markers.append(marker); } } @@ -319,7 +310,8 @@ void QmlJSEditorWidget::updateContextPane() } setRefactorMarkers(markers); } else if (oldNode != newNode) { - setRefactorMarkers(removeMarkersOfType(refactorMarkers())); + setRefactorMarkers(RefactorMarker::filterOutType( + refactorMarkers(), Constants::QT_QUICK_TOOLBAR_MARKER_ID)); } m_oldCursorPosition = position(); @@ -820,7 +812,8 @@ void QmlJSEditorWidget::showContextPane() &scopeChain, newNode, false, true); m_oldCursorPosition = position(); - setRefactorMarkers(removeMarkersOfType(refactorMarkers())); + setRefactorMarkers(RefactorMarker::filterOutType( + refactorMarkers(), Constants::QT_QUICK_TOOLBAR_MARKER_ID)); } } @@ -939,12 +932,6 @@ void QmlJSEditorWidget::semanticInfoUpdated(const SemanticInfo &semanticInfo) updateUses(); } -void QmlJSEditorWidget::onRefactorMarkerClicked(const RefactorMarker &marker) -{ - if (marker.data.canConvert()) - showContextPane(); -} - QModelIndex QmlJSEditorWidget::indexForPosition(unsigned cursorPosition, const QModelIndex &rootIndex) const { QModelIndex lastIndex = rootIndex; diff --git a/src/plugins/qmljseditor/qmljseditor.h b/src/plugins/qmljseditor/qmljseditor.h index 251ab2a8177..7b6b6c096b2 100644 --- a/src/plugins/qmljseditor/qmljseditor.h +++ b/src/plugins/qmljseditor/qmljseditor.h @@ -108,7 +108,6 @@ protected: bool resolveTarget = true, bool inNextSplit = false) override; QString foldReplacementText(const QTextBlock &block) const override; - void onRefactorMarkerClicked(const TextEditor::RefactorMarker &marker) override; private: void setSelectedElements(); diff --git a/src/plugins/qmljseditor/qmljseditorconstants.h b/src/plugins/qmljseditor/qmljseditorconstants.h index ac13c9add5a..61624bf1ff2 100644 --- a/src/plugins/qmljseditor/qmljseditorconstants.h +++ b/src/plugins/qmljseditor/qmljseditorconstants.h @@ -60,5 +60,7 @@ const char QML_UI_FILE_WARNING[] = "QmlJSEditor.QmlUiFileWarning"; const char AUTO_FORMAT_ON_SAVE[] = "QmlJSEditor.AutoFormatOnSave"; const char AUTO_FORMAT_ONLY_CURRENT_PROJECT[] = "QmlJSEditor.AutoFormatOnlyCurrentProject"; +const char QT_QUICK_TOOLBAR_MARKER_ID[] = "QtQuickToolbarMarkerId"; + } // namespace Constants } // namespace QmlJSEditor diff --git a/src/plugins/texteditor/refactoroverlay.cpp b/src/plugins/texteditor/refactoroverlay.cpp index a07229b840e..65ef1dae0ab 100644 --- a/src/plugins/texteditor/refactoroverlay.cpp +++ b/src/plugins/texteditor/refactoroverlay.cpp @@ -27,6 +27,7 @@ #include "textdocumentlayout.h" #include "texteditor.h" +#include #include #include @@ -92,4 +93,11 @@ void RefactorOverlay::paintMarker(const RefactorMarker& marker, QPainter *painte m_maxWidth = qMax(m_maxWidth, x + actualIconSize.width() - int(offset.x())); } +RefactorMarkers RefactorMarker::filterOutType(const RefactorMarkers &markers, const Core::Id &type) +{ + return Utils::filtered(markers, [type](const RefactorMarker &marker) { + return marker.type != type; + }); +} + } // namespace TextEditor diff --git a/src/plugins/texteditor/refactoroverlay.h b/src/plugins/texteditor/refactoroverlay.h index 2e9a7dcdd76..e6ed0655b62 100644 --- a/src/plugins/texteditor/refactoroverlay.h +++ b/src/plugins/texteditor/refactoroverlay.h @@ -27,22 +27,30 @@ #include "texteditor_global.h" +#include + #include #include namespace TextEditor { class TextEditorWidget; -struct TEXTEDITOR_EXPORT RefactorMarker { +struct TEXTEDITOR_EXPORT RefactorMarker; +using RefactorMarkers = QList; + +struct TEXTEDITOR_EXPORT RefactorMarker { inline bool isValid() const { return !cursor.isNull(); } QTextCursor cursor; QString tooltip; QIcon icon; mutable QRect rect; // used to cache last drawing positin in document coordinates + std::function callback; + Core::Id type; QVariant data; + + static RefactorMarkers filterOutType(const RefactorMarkers &markers, const Core::Id &type); }; -using RefactorMarkers = QList; class TEXTEDITOR_EXPORT RefactorOverlay : public QObject { diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index d7ceb831445..96cf099c5e3 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -5601,7 +5601,8 @@ void TextEditorWidget::mousePressEvent(QMouseEvent *e) RefactorMarker refactorMarker = d->m_refactorOverlay->markerAt(e->pos()); if (refactorMarker.isValid()) { - onRefactorMarkerClicked(refactorMarker); + if (refactorMarker.callback) + refactorMarker.callback(this); } else { d->requestUpdateLink(e, true); diff --git a/src/plugins/texteditor/texteditor.h b/src/plugins/texteditor/texteditor.h index 8ea2606bd22..f1d1b193535 100644 --- a/src/plugins/texteditor/texteditor.h +++ b/src/plugins/texteditor/texteditor.h @@ -524,8 +524,6 @@ protected: virtual void triggerPendingUpdates(); virtual void applyFontSettings(); - virtual void onRefactorMarkerClicked(const RefactorMarker &) {} - void showDefaultContextMenu(QContextMenuEvent *e, Core::Id menuContextId); virtual void finalizeInitialization() {} virtual void finalizeInitializationAfterDuplication(TextEditorWidget *) {}