diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index ffa8862aab455f3de5a0a6003aefce944989a6c9..8176f838026182241995be4a3e8893fb226b0ac3 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -648,6 +648,9 @@ void BaseTextEditor::slotSelectionChanged() d->m_blockSelectionExtraX = 0; if (!d->m_selectBlockAnchor.isNull() && !textCursor().hasSelection()) d->m_selectBlockAnchor = QTextCursor(); + + // Clear any link which might be showing when the selection changes + clearLink(); } void BaseTextEditor::gotoBlockStart() @@ -1470,7 +1473,7 @@ BaseTextEditorPrivate::BaseTextEditorPrivate() m_requestMarkEnabled(true), m_lineSeparatorsAllowed(false), m_visibleWrapColumn(0), - m_showingLink(false), + m_linkPressed(false), m_editable(0), m_actionHack(0), m_inBlockSelectionMode(false), @@ -2864,35 +2867,11 @@ void BaseTextEditorPrivate::clearVisibleCollapsedBlock() } } - void BaseTextEditor::mouseMoveEvent(QMouseEvent *e) { d->m_lastEventWasBlockSelectionEvent = (e->modifiers() & Qt::AltModifier); - bool linkFound = false; - - if (d->m_mouseNavigationEnabled && e->modifiers() & Qt::ControlModifier) { - // Link emulation behaviour for 'go to definition' - const QTextCursor cursor = cursorForPosition(e->pos()); - - // Check that the mouse was actually on the text somewhere - bool onText = cursorRect(cursor).right() >= e->x(); - if (!onText) { - QTextCursor nextPos = cursor; - nextPos.movePosition(QTextCursor::Right); - onText = cursorRect(nextPos).right() >= e->x(); - } - - const Link link = findLinkAt(cursor, false); - - if (onText && link.isValid()) { - showLink(link); - linkFound = true; - } - } - - if (!linkFound) - clearLink(); + updateLink(e); if (e->buttons() == Qt::NoButton) { const QTextBlock collapsedBlock = collapsedBlockAt(e->pos()); @@ -2936,16 +2915,23 @@ void BaseTextEditor::mousePressEvent(QMouseEvent *e) toggleBlockVisible(collapsedBlock); viewport()->setCursor(Qt::IBeamCursor); } + + updateLink(e); + + if (d->m_currentLink.isValid()) + d->m_linkPressed = true; } QPlainTextEdit::mousePressEvent(e); } void BaseTextEditor::mouseReleaseEvent(QMouseEvent *e) { - if (d->m_mouseNavigationEnabled && e->modifiers() & Qt::ControlModifier + if (d->m_mouseNavigationEnabled + && d->m_linkPressed + && e->modifiers() & Qt::ControlModifier && !(e->modifiers() & Qt::ShiftModifier) - && e->button() == Qt::LeftButton) { - + && e->button() == Qt::LeftButton + ) { const QTextCursor cursor = cursorForPosition(e->pos()); if (openLink(findLinkAt(cursor))) { clearLink(); @@ -3461,8 +3447,39 @@ bool BaseTextEditor::openLink(const Link &link) return openEditorAt(link.fileName, link.line, link.column); } +void BaseTextEditor::updateLink(QMouseEvent *e) +{ + bool linkFound = false; + + if (d->m_mouseNavigationEnabled && e->modifiers() & Qt::ControlModifier) { + // Link emulation behaviour for 'go to definition' + const QTextCursor cursor = cursorForPosition(e->pos()); + + // Check that the mouse was actually on the text somewhere + bool onText = cursorRect(cursor).right() >= e->x(); + if (!onText) { + QTextCursor nextPos = cursor; + nextPos.movePosition(QTextCursor::Right); + onText = cursorRect(nextPos).right() >= e->x(); + } + + const Link link = findLinkAt(cursor, false); + + if (onText && link.isValid()) { + showLink(link); + linkFound = true; + } + } + + if (!linkFound) + clearLink(); +} + void BaseTextEditor::showLink(const Link &link) { + if (d->m_currentLink == link) + return; + QTextEdit::ExtraSelection sel; sel.cursor = textCursor(); sel.cursor.setPosition(link.pos); @@ -3471,25 +3488,26 @@ void BaseTextEditor::showLink(const Link &link) sel.format.setFontUnderline(true); setExtraSelections(OtherSelection, QList<QTextEdit::ExtraSelection>() << sel); viewport()->setCursor(Qt::PointingHandCursor); - d->m_showingLink = true; + d->m_currentLink = link; + d->m_linkPressed = false; } void BaseTextEditor::clearLink() { - if (!d->m_showingLink) + if (!d->m_currentLink.isValid()) return; setExtraSelections(OtherSelection, QList<QTextEdit::ExtraSelection>()); viewport()->setCursor(Qt::IBeamCursor); - d->m_showingLink = false; + d->m_currentLink = Link(); + d->m_linkPressed = false; } void BaseTextEditorPrivate::updateMarksBlock(const QTextBlock &block) { if (const TextBlockUserData *userData = TextEditDocumentLayout::testUserData(block)) - foreach (ITextMark *mrk, userData->marks()) { + foreach (ITextMark *mrk, userData->marks()) mrk->updateBlock(block); - } } void BaseTextEditorPrivate::updateMarksLineNumber() diff --git a/src/plugins/texteditor/basetexteditor.h b/src/plugins/texteditor/basetexteditor.h index 69b74fad1e0214c7add6c19cb1775cb590af1023..fbd1e977e720a08a75124a57875d1055b236c818 100644 --- a/src/plugins/texteditor/basetexteditor.h +++ b/src/plugins/texteditor/basetexteditor.h @@ -538,6 +538,9 @@ protected: bool isValid() const { return !(pos == -1 || length == -1); } + bool operator==(const Link &other) const + { return pos == other.pos && length == other.length; } + int pos; // Link position int length; // Link length @@ -593,6 +596,7 @@ private: QTextBlock collapsedBlockAt(const QPoint &pos, QRect *box = 0) const; + void updateLink(QMouseEvent *e); void showLink(const Link &); void clearLink(); diff --git a/src/plugins/texteditor/basetexteditor_p.h b/src/plugins/texteditor/basetexteditor_p.h index 0ef9a1272c2dd633eb4fc27a35fab9f87b799b5c..a1829e70f8179999cafb2199ea4dd3499c8c1120 100644 --- a/src/plugins/texteditor/basetexteditor_p.h +++ b/src/plugins/texteditor/basetexteditor_p.h @@ -204,7 +204,8 @@ public: int m_visibleWrapColumn; QTextCharFormat m_linkFormat; - bool m_showingLink; + BaseTextEditor::Link m_currentLink; + bool m_linkPressed; QTextCharFormat m_ifdefedOutFormat;