TextEditor: Use callback in refactoring markers

Allows to trigger actions without adding specific handling into the
editor.

Change-Id: Ia63d65d3feca37bcefca1b6322ade039027a92d8
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
David Schulz
2019-01-24 06:39:20 +01:00
parent a420374976
commit 7b7a2ad630
13 changed files with 56 additions and 86 deletions

View File

@@ -38,6 +38,7 @@
#include <texteditor/fontsettings.h>
#include <texteditor/textdocument.h>
#include <texteditor/texteditor.h>
#include <texteditor/texteditorsettings.h>
#include <utils/textutils.h>
@@ -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;
}

View File

@@ -324,13 +324,14 @@ void CppEditorWidget::onCppDocumentUpdated()
void CppEditorWidget::onCodeWarningsUpdated(unsigned revision,
const QList<QTextEdit::ExtraSelection> 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<FunctionDeclDefLink> CppEditorWidget::declDefLink() const
return d->m_declDefLink;
}
void CppEditorWidget::onRefactorMarkerClicked(const RefactorMarker &marker)
{
if (marker.data.canConvert<FunctionDeclDefLink::Marker>()) {
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();

View File

@@ -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;

View File

@@ -32,6 +32,7 @@
#include <coreplugin/actionmanager/command.h>
#include <cpptools/cppcodestylesettings.h>
#include <cpptools/cpplocalsymbols.h>
#include <cpptools/cpptoolsconstants.h>
#include <cpptools/symbolfinder.h>
#include <texteditor/refactoroverlay.h>
#include <texteditor/texteditorconstants.h>
@@ -300,21 +301,12 @@ void FunctionDeclDefLink::apply(CppEditorWidget *editor, bool jumpToMatch)
}
}
static QList<RefactorMarker> removeDeclDefLinkMarkers(const QList<RefactorMarker> &markers)
{
QList<RefactorMarker> result;
foreach (const RefactorMarker &marker, markers) {
if (!marker.data.canConvert<FunctionDeclDefLink::Marker>())
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<RefactorMarker> markers = removeDeclDefLinkMarkers(editor->refactorMarkers());
QList<RefactorMarker> 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<CppEditorWidget *>(widget))
cppEditor->applyDeclDefLinkChanges(true);
};
markers += marker;
editor->setRefactorMarkers(markers);

View File

@@ -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)

View File

@@ -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++");

View File

@@ -269,23 +269,10 @@ void QmlJSEditorWidget::updateOutlineIndexNow()
} // namespace Internal
} // namespace QmlJSEditor
class QtQuickToolbarMarker {};
Q_DECLARE_METATYPE(QtQuickToolbarMarker)
namespace QmlJSEditor {
namespace Internal {
template <class T>
static QList<RefactorMarker> removeMarkersOfType(const QList<RefactorMarker> &markers)
{
QList<RefactorMarker> result;
foreach (const RefactorMarker &marker, markers) {
if (!marker.data.canConvert<T>())
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<RefactorMarker> markers = removeMarkersOfType<QtQuickToolbarMarker>(refactorMarkers());
QList<RefactorMarker> 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<QtQuickToolbarMarker>(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<QtQuickToolbarMarker>(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<QtQuickToolbarMarker>())
showContextPane();
}
QModelIndex QmlJSEditorWidget::indexForPosition(unsigned cursorPosition, const QModelIndex &rootIndex) const
{
QModelIndex lastIndex = rootIndex;

View File

@@ -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();

View File

@@ -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

View File

@@ -27,6 +27,7 @@
#include "textdocumentlayout.h"
#include "texteditor.h"
#include <utils/algorithm.h>
#include <utils/utilsicons.h>
#include <QPainter>
@@ -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

View File

@@ -27,22 +27,30 @@
#include "texteditor_global.h"
#include <coreplugin/id.h>
#include <QTextCursor>
#include <QIcon>
namespace TextEditor {
class TextEditorWidget;
struct TEXTEDITOR_EXPORT RefactorMarker {
struct TEXTEDITOR_EXPORT RefactorMarker;
using RefactorMarkers = QList<RefactorMarker>;
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<void(TextEditor::TextEditorWidget *)> callback;
Core::Id type;
QVariant data;
static RefactorMarkers filterOutType(const RefactorMarkers &markers, const Core::Id &type);
};
using RefactorMarkers = QList<RefactorMarker>;
class TEXTEDITOR_EXPORT RefactorOverlay : public QObject
{

View File

@@ -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);

View File

@@ -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 *) {}