diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index 5b363e291dbe598b7c47b07a81c2225449672dc7..1976195c91f36156e1d43b05f206d15ae75f989f 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -370,7 +370,7 @@ void CPPEditor::jumpToMethod(int) if (! symbol) return; - openEditorAt(symbol); + openCppEditorAt(locationForSymbol(symbol)); } void CPPEditor::updateMethodBoxIndex() @@ -579,50 +579,51 @@ void CPPEditor::switchDeclarationDefinition() declaration = symbols.first(); if (declaration) - openEditorAt(declaration); + openCppEditorAt(locationForSymbol(declaration)); } else if (lastSymbol->type()->isFunctionType()) { if (Symbol *def = findDefinition(lastSymbol)) - openEditorAt(def); + openCppEditorAt(locationForSymbol(def)); } } -void CPPEditor::jumpToDefinition() +CPPEditor::Location CPPEditor::findDestinationFor(const QTextCursor &cursor) { + Location dest; + if (!m_modelManager) - return; + return dest; const Snapshot snapshot = m_modelManager->snapshot(); - - // Find the last symbol up to the cursor position int line = 0, column = 0; - convertPosition(position(), &line, &column); + convertPosition(cursor.position(), &line, &column); Document::Ptr doc = snapshot.value(file()->fileName()); if (!doc) - return; + return dest; - QTextCursor tc = textCursor(); - unsigned lineno = tc.blockNumber() + 1; + // Handle include directives + const unsigned lineno = cursor.blockNumber() + 1; foreach (const Document::Include &incl, doc->includes()) { if (incl.line() == lineno) { - if (openCppEditorAt(incl.fileName(), 0, 0)) - return; // done - break; + dest.fileName = incl.fileName(); + return dest; } } + // Find the last symbol up to the cursor position Symbol *lastSymbol = doc->findSymbolAt(line, column); if (!lastSymbol) - return; + return dest; // Get the expression under the cursor - const int endOfName = endOfNameUnderCursor(); + const int endOfName = endOfNameAtPosition(cursor.position()); + QTextCursor tc = cursor; tc.setPosition(endOfName); ExpressionUnderCursor expressionUnderCursor; const QString expression = expressionUnderCursor(tc); // Evaluate the type of the expression TypeOfExpression typeOfExpression; - typeOfExpression.setSnapshot(m_modelManager->snapshot()); + typeOfExpression.setSnapshot(snapshot); QList<TypeOfExpression::Result> resolvedSymbols = typeOfExpression(expression, doc, lastSymbol); @@ -633,10 +634,7 @@ void CPPEditor::jumpToDefinition() if (!lastSymbol->isFunction()) def = findDefinition(symbol); - if (def) - openEditorAt(def); - else - openEditorAt(symbol); + return locationForSymbol(def ? def : symbol); // This would jump to the type of a name #if 0 @@ -649,15 +647,23 @@ void CPPEditor::jumpToDefinition() #endif } } else { + // Handle macro uses foreach (const Document::MacroUse use, doc->macroUses()) { if (use.contains(endOfName - 1)) { const Macro ¯o = use.macro(); - const QString fileName = QString::fromUtf8(macro.fileName()); - if (openCppEditorAt(fileName, macro.line(), 0)) - return; // done + dest.fileName = QString::fromUtf8(macro.fileName()); + dest.line = macro.line(); + return dest; } } } + + return dest; +} + +void CPPEditor::jumpToDefinition() +{ + openCppEditorAt(findDestinationFor(textCursor())); } Symbol *CPPEditor::findDefinition(Symbol *symbol) @@ -777,6 +783,55 @@ void CPPEditor::contextMenuEvent(QContextMenuEvent *e) delete menu; } +void CPPEditor::mouseMoveEvent(QMouseEvent *e) +{ + bool hasDestination = false; + Qt::CursorShape cursorShape; + + if (e->modifiers() & Qt::ControlModifier) { + // Link emulation behaviour for 'go to definition' + const QTextCursor cursor = cursorForPosition(e->pos()); + const Location loc = findDestinationFor(cursor); + + if (!loc.fileName.isEmpty()) { + QTextEdit::ExtraSelection sel; + sel.cursor = cursor; + sel.cursor.select(QTextCursor::WordUnderCursor); + sel.format.setFontUnderline(true); + sel.format.setForeground(Qt::blue); + setExtraSelections(OtherSelection, QList<QTextEdit::ExtraSelection>() << sel); + hasDestination = true; + cursorShape = Qt::PointingHandCursor; + } + } + + if (!hasDestination) { + setExtraSelections(OtherSelection, QList<QTextEdit::ExtraSelection>()); + cursorShape = Qt::IBeamCursor; + } + + TextEditor::BaseTextEditor::mouseMoveEvent(e); + + viewport()->setCursor(cursorShape); +} + +void CPPEditor::mouseReleaseEvent(QMouseEvent *e) +{ + if (e->modifiers() & Qt::ControlModifier && !(e->modifiers() & Qt::ShiftModifier) + && e->button() == Qt::LeftButton) { + + const QTextCursor cursor = cursorForPosition(e->pos()); + if (openCppEditorAt(findDestinationFor(cursor))) { + setExtraSelections(OtherSelection, QList<QTextEdit::ExtraSelection>()); + viewport()->setCursor(Qt::IBeamCursor); + e->accept(); + return; + } + } + + TextEditor::BaseTextEditor::mouseReleaseEvent(e); +} + QList<int> CPPEditorEditable::context() const { return m_context; @@ -946,9 +1001,11 @@ void CPPEditor::unCommentSelection() cursor.endEditBlock(); } -int CPPEditor::endOfNameUnderCursor() +int CPPEditor::endOfNameAtPosition(int pos) { - int pos = position(); + if (pos == -1) + pos = position(); + QChar chr = characterAt(pos); // Skip to the start of a name @@ -958,32 +1015,37 @@ int CPPEditor::endOfNameUnderCursor() return pos; } -TextEditor::ITextEditor *CPPEditor::openCppEditorAt(const QString &fileName, - int line, int column) +CPPEditor::Location CPPEditor::locationForSymbol(CPlusPlus::Symbol *symbol) { - return TextEditor::BaseTextEditor::openEditorAt(fileName, line, column, - Constants::C_CPPEDITOR); -} - -bool CPPEditor::openEditorAt(Symbol *s) -{ - const QString fileName = QString::fromUtf8(s->fileName(), s->fileNameLength()); - unsigned line = s->line(); - unsigned column = s->column(); + const QString fileName = QString::fromUtf8(symbol->fileName(), + symbol->fileNameLength()); + unsigned line = symbol->line(); + unsigned column = symbol->column(); if (column) --column; - if (s->isGenerated()) + if (symbol->isGenerated()) column = 0; - if (baseTextDocument()->fileName() == fileName) { + return Location(fileName, line, column); +} + +bool CPPEditor::openCppEditorAt(const Location &loc) +{ + if (loc.fileName.isEmpty()) + return false; + + if (baseTextDocument()->fileName() == loc.fileName) { Core::EditorManager *editorManager = Core::EditorManager::instance(); editorManager->addCurrentPositionToNavigationHistory(); - gotoLine(line, column); + gotoLine(loc.line, loc.column); setFocus(); return true; } - return openCppEditorAt(fileName, line, column); + return TextEditor::BaseTextEditor::openEditorAt(loc.fileName, + loc.line, + loc.column, + Constants::C_CPPEDITOR); } diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h index 7a91faebf3c02a1de19eadd16ae27cf8807b527b..c54b33a0cb083e39c731d16717da06749fcf5bb6 100644 --- a/src/plugins/cppeditor/cppeditor.h +++ b/src/plugins/cppeditor/cppeditor.h @@ -97,6 +97,9 @@ public slots: protected: void contextMenuEvent(QContextMenuEvent *e); + void mouseMoveEvent(QMouseEvent *e); + void mouseReleaseEvent(QMouseEvent *e); + TextEditor::BaseTextEditorEditable *createEditableInterface(); // Rertuns true if key triggers anindent. @@ -122,9 +125,26 @@ private: void createToolBar(CPPEditorEditable *editable); - int endOfNameUnderCursor(); - - bool openEditorAt(CPlusPlus::Symbol *symbol); + int endOfNameAtPosition(int pos); + + struct Location + { + Location(const QString &fileName = QString(), + int line = 0, + int column = 0) + : fileName(fileName) + , line(line) + , column(column) + {} + + QString fileName; + int line; + int column; + }; + + Location findDestinationFor(const QTextCursor &); + static Location locationForSymbol(CPlusPlus::Symbol *symbol); + bool openCppEditorAt(const Location &); CppTools::CppModelManagerInterface *m_modelManager; diff --git a/src/plugins/vcsbase/vcsbaseeditor.cpp b/src/plugins/vcsbase/vcsbaseeditor.cpp index d185efa9b0a5eb495ba4161d92922263b5b63a94..3675999266e9d1b2e03891bdee26153f855d8dd0 100644 --- a/src/plugins/vcsbase/vcsbaseeditor.cpp +++ b/src/plugins/vcsbase/vcsbaseeditor.cpp @@ -335,7 +335,6 @@ void VCSBaseEditor::mouseMoveEvent(QMouseEvent *e) sel.cursor = cursor; sel.cursor.select(QTextCursor::WordUnderCursor); sel.format.setFontUnderline(true); - change = changeUnderCursor(cursor); sel.format.setProperty(QTextFormat::UserProperty, change); setExtraSelections(OtherSelection, QList<QTextEdit::ExtraSelection>() << sel); overrideCursor = true;