diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index f0186c340f561dc1c1284e8852b4cb259e36af61..6e0a511db7d23de7956439fb4ba77b01251e9140 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 96ee05af9532cd8460113b18c80edba697fb0b74..bd30f3031f9dd72a1fd172e7ff0202d44e43894a 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 6574d416310a5e2691c92f9c4be52a7be3ba3928..322039c0cbd036c34e365cf16730f82dcfa47eaa 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 638f2faba225d217c36cb8a45841b3475e712cc3..d33fa9d7d4c2fdef660fb8967638787d50f2ec17 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();