From 8088ca2c43b4926f0c7ac37a37a2d9072e366c76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= <thorbjorn.lindeijer@nokia.com> Date: Wed, 25 Mar 2009 11:38:54 +0100 Subject: [PATCH] Stop fighting over which mouse cursor to show on text editor The BaseTextEditor was unconditionally setting the mouse cursor on each mouse move event, after which the CPPEditor would set it as well when the mouse was above a link. This caused some mouse cursor flickering, so now the cursor is only set when it's supposed to change. Also fixed an issue where the link wasn't removed when leaving the text editor with the mouse while Ctrl was pressed. --- src/plugins/cppeditor/cppeditor.cpp | 66 +++++++++++++---------- src/plugins/cppeditor/cppeditor.h | 5 ++ src/plugins/texteditor/basetexteditor.cpp | 19 +++++-- src/plugins/texteditor/basetexteditor_p.h | 1 + 4 files changed, 58 insertions(+), 33 deletions(-) diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index f0186c340f5..6e0a511db7d 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -183,13 +183,13 @@ CPPEditorEditable::CPPEditorEditable(CPPEditor *editor) CPPEditor::CPPEditor(QWidget *parent) : TextEditor::BaseTextEditor(parent) + , m_showingLink(false) { setParenthesesMatchingEnabled(true); setMarksVisible(true); setCodeFoldingSupported(true); setCodeFoldingVisible(true); baseTextDocument()->setSyntaxHighlighter(new CppHighlighter); -// new QShortcut(QKeySequence("Ctrl+Alt+M"), this, SLOT(foo()), 0, Qt::WidgetShortcut); #ifdef WITH_TOKEN_MOVE_POSITION new QShortcut(QKeySequence::MoveToPreviousWord, this, SLOT(moveToPreviousToken()), @@ -808,8 +808,7 @@ void CPPEditor::contextMenuEvent(QContextMenuEvent *e) void CPPEditor::mouseMoveEvent(QMouseEvent *e) { - bool hasDestination = false; - Qt::CursorShape cursorShape; + bool linkFound = false; if (e->modifiers() & Qt::ControlModifier) { // Link emulation behaviour for 'go to definition' @@ -826,30 +825,15 @@ void CPPEditor::mouseMoveEvent(QMouseEvent *e) const Link link = findLinkAt(cursor, false); if (onText && !link.fileName.isEmpty()) { - QTextEdit::ExtraSelection sel; - sel.cursor = cursor; - if (link.pos >= 0) { - sel.cursor.setPosition(link.pos); - sel.cursor.setPosition(link.pos + link.length, QTextCursor::KeepAnchor); - } else { - sel.cursor.select(QTextCursor::WordUnderCursor); - } - sel.format = m_linkFormat; - sel.format.setFontUnderline(true); - setExtraSelections(OtherSelection, QList<QTextEdit::ExtraSelection>() << sel); - hasDestination = true; - cursorShape = Qt::PointingHandCursor; + showLink(link); + linkFound = true; } } - if (!hasDestination) { - setExtraSelections(OtherSelection, QList<QTextEdit::ExtraSelection>()); - cursorShape = Qt::IBeamCursor; - } + if (!linkFound) + clearLink(); TextEditor::BaseTextEditor::mouseMoveEvent(e); - - viewport()->setCursor(cursorShape); } void CPPEditor::mouseReleaseEvent(QMouseEvent *e) @@ -859,8 +843,7 @@ void CPPEditor::mouseReleaseEvent(QMouseEvent *e) const QTextCursor cursor = cursorForPosition(e->pos()); if (openCppEditorAt(findLinkAt(cursor))) { - setExtraSelections(OtherSelection, QList<QTextEdit::ExtraSelection>()); - viewport()->setCursor(Qt::IBeamCursor); + clearLink(); e->accept(); return; } @@ -869,17 +852,44 @@ void CPPEditor::mouseReleaseEvent(QMouseEvent *e) TextEditor::BaseTextEditor::mouseReleaseEvent(e); } +void CPPEditor::leaveEvent(QEvent *e) +{ + clearLink(); + TextEditor::BaseTextEditor::leaveEvent(e); +} + void CPPEditor::keyReleaseEvent(QKeyEvent *e) { // Clear link emulation when Ctrl is released - if (e->key() == Qt::Key_Control) { - setExtraSelections(OtherSelection, QList<QTextEdit::ExtraSelection>()); - viewport()->setCursor(Qt::IBeamCursor); - } + if (e->key() == Qt::Key_Control) + clearLink(); TextEditor::BaseTextEditor::keyReleaseEvent(e); } +void CPPEditor::showLink(const Link &link) +{ + QTextEdit::ExtraSelection sel; + sel.cursor = textCursor(); + sel.cursor.setPosition(link.pos); + sel.cursor.setPosition(link.pos + link.length, QTextCursor::KeepAnchor); + sel.format = m_linkFormat; + sel.format.setFontUnderline(true); + setExtraSelections(OtherSelection, QList<QTextEdit::ExtraSelection>() << sel); + viewport()->setCursor(Qt::PointingHandCursor); + m_showingLink = true; +} + +void CPPEditor::clearLink() +{ + if (!m_showingLink) + return; + + setExtraSelections(OtherSelection, QList<QTextEdit::ExtraSelection>()); + viewport()->setCursor(Qt::IBeamCursor); + m_showingLink = false; +} + QList<int> CPPEditorEditable::context() const { return m_context; diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h index 96ee05af953..bd30f3031f9 100644 --- a/src/plugins/cppeditor/cppeditor.h +++ b/src/plugins/cppeditor/cppeditor.h @@ -99,6 +99,7 @@ protected: void contextMenuEvent(QContextMenuEvent *); void mouseMoveEvent(QMouseEvent *); void mouseReleaseEvent(QMouseEvent *); + void leaveEvent(QEvent *); void keyReleaseEvent(QKeyEvent *); TextEditor::BaseTextEditorEditable *createEditableInterface(); @@ -148,6 +149,10 @@ private: int column; // Target column }; + void showLink(const Link &); + void clearLink(); + bool m_showingLink; + Link findLinkAt(const QTextCursor &, bool lookupDefinition = true); static Link linkToSymbol(CPlusPlus::Symbol *symbol); bool openCppEditorAt(const Link &); diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index 6574d416310..322039c0cbd 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -1255,6 +1255,7 @@ BaseTextEditorPrivate::BaseTextEditorPrivate() m_document(new BaseTextDocument()), m_parenthesesMatchingEnabled(false), m_extraArea(0), + m_mouseOnCollapsedMarker(false), m_marksVisible(false), m_codeFoldingVisible(false), m_codeFoldingSupported(false), @@ -2421,22 +2422,30 @@ void BaseTextEditorPrivate::clearVisibleCollapsedBlock() void BaseTextEditor::mouseMoveEvent(QMouseEvent *e) { d->m_lastEventWasBlockSelectionEvent = (e->modifiers() & Qt::AltModifier); - if (e->buttons() == 0) { - QTextBlock collapsedBlock = collapsedBlockAt(e->pos()); - int blockNumber = collapsedBlock.next().blockNumber(); + if (e->buttons() == Qt::NoButton) { + const QTextBlock collapsedBlock = collapsedBlockAt(e->pos()); + const int blockNumber = collapsedBlock.next().blockNumber(); if (blockNumber < 0) { d->clearVisibleCollapsedBlock(); } else if (blockNumber != d->visibleCollapsedBlockNumber) { d->suggestedVisibleCollapsedBlockNumber = blockNumber; d->collapsedBlockTimer.start(40, this); } - viewport()->setCursor(collapsedBlock.isValid() ? Qt::PointingHandCursor : Qt::IBeamCursor); + + // Update the mouse cursor + if (collapsedBlock.isValid() && !d->m_mouseOnCollapsedMarker) { + d->m_mouseOnCollapsedMarker = true; + viewport()->setCursor(Qt::PointingHandCursor); + } else if (!collapsedBlock.isValid() && d->m_mouseOnCollapsedMarker) { + d->m_mouseOnCollapsedMarker = false; + viewport()->setCursor(Qt::IBeamCursor); + } } else { QPlainTextEdit::mouseMoveEvent(e); } if (d->m_lastEventWasBlockSelectionEvent && d->m_inBlockSelectionMode) { if (textCursor().atBlockEnd()) { - d->m_blockSelectionExtraX = qMax(0, e->pos().x() - cursorRect().center().x()) / fontMetrics().width(QLatin1Char('x')); + d->m_blockSelectionExtraX = qMax(0, e->pos().x() - cursorRect().center().x()) / fontMetrics().averageCharWidth(); } else { d->m_blockSelectionExtraX = 0; } diff --git a/src/plugins/texteditor/basetexteditor_p.h b/src/plugins/texteditor/basetexteditor_p.h index 638f2faba22..d33fa9d7d4c 100644 --- a/src/plugins/texteditor/basetexteditor_p.h +++ b/src/plugins/texteditor/basetexteditor_p.h @@ -175,6 +175,7 @@ public: int visibleCollapsedBlockNumber; int suggestedVisibleCollapsedBlockNumber; void clearVisibleCollapsedBlock(); + bool m_mouseOnCollapsedMarker; QBasicTimer autoScrollTimer; void updateMarksLineNumber(); -- GitLab