Skip to content
Snippets Groups Projects
Commit c08405fe authored by Thorbjørn Lindeijer's avatar Thorbjørn Lindeijer
Browse files

Turn code into links when holding Ctrl

Allows navigating the code using the mouse when pressing Ctrl. Suggested
a few times and also seen in other IDEs.
parent 8344cc68
No related branches found
No related tags found
No related merge requests found
...@@ -370,7 +370,7 @@ void CPPEditor::jumpToMethod(int) ...@@ -370,7 +370,7 @@ void CPPEditor::jumpToMethod(int)
if (! symbol) if (! symbol)
return; return;
openEditorAt(symbol); openCppEditorAt(locationForSymbol(symbol));
} }
void CPPEditor::updateMethodBoxIndex() void CPPEditor::updateMethodBoxIndex()
...@@ -579,50 +579,51 @@ void CPPEditor::switchDeclarationDefinition() ...@@ -579,50 +579,51 @@ void CPPEditor::switchDeclarationDefinition()
declaration = symbols.first(); declaration = symbols.first();
if (declaration) if (declaration)
openEditorAt(declaration); openCppEditorAt(locationForSymbol(declaration));
} else if (lastSymbol->type()->isFunctionType()) { } else if (lastSymbol->type()->isFunctionType()) {
if (Symbol *def = findDefinition(lastSymbol)) 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) if (!m_modelManager)
return; return dest;
const Snapshot snapshot = m_modelManager->snapshot(); const Snapshot snapshot = m_modelManager->snapshot();
// Find the last symbol up to the cursor position
int line = 0, column = 0; int line = 0, column = 0;
convertPosition(position(), &line, &column); convertPosition(cursor.position(), &line, &column);
Document::Ptr doc = snapshot.value(file()->fileName()); Document::Ptr doc = snapshot.value(file()->fileName());
if (!doc) if (!doc)
return; return dest;
QTextCursor tc = textCursor(); // Handle include directives
unsigned lineno = tc.blockNumber() + 1; const unsigned lineno = cursor.blockNumber() + 1;
foreach (const Document::Include &incl, doc->includes()) { foreach (const Document::Include &incl, doc->includes()) {
if (incl.line() == lineno) { if (incl.line() == lineno) {
if (openCppEditorAt(incl.fileName(), 0, 0)) dest.fileName = incl.fileName();
return; // done return dest;
break;
} }
} }
// Find the last symbol up to the cursor position
Symbol *lastSymbol = doc->findSymbolAt(line, column); Symbol *lastSymbol = doc->findSymbolAt(line, column);
if (!lastSymbol) if (!lastSymbol)
return; return dest;
// Get the expression under the cursor // Get the expression under the cursor
const int endOfName = endOfNameUnderCursor(); const int endOfName = endOfNameAtPosition(cursor.position());
QTextCursor tc = cursor;
tc.setPosition(endOfName); tc.setPosition(endOfName);
ExpressionUnderCursor expressionUnderCursor; ExpressionUnderCursor expressionUnderCursor;
const QString expression = expressionUnderCursor(tc); const QString expression = expressionUnderCursor(tc);
// Evaluate the type of the expression // Evaluate the type of the expression
TypeOfExpression typeOfExpression; TypeOfExpression typeOfExpression;
typeOfExpression.setSnapshot(m_modelManager->snapshot()); typeOfExpression.setSnapshot(snapshot);
QList<TypeOfExpression::Result> resolvedSymbols = QList<TypeOfExpression::Result> resolvedSymbols =
typeOfExpression(expression, doc, lastSymbol); typeOfExpression(expression, doc, lastSymbol);
...@@ -633,10 +634,7 @@ void CPPEditor::jumpToDefinition() ...@@ -633,10 +634,7 @@ void CPPEditor::jumpToDefinition()
if (!lastSymbol->isFunction()) if (!lastSymbol->isFunction())
def = findDefinition(symbol); def = findDefinition(symbol);
if (def) return locationForSymbol(def ? def : symbol);
openEditorAt(def);
else
openEditorAt(symbol);
// This would jump to the type of a name // This would jump to the type of a name
#if 0 #if 0
...@@ -649,15 +647,23 @@ void CPPEditor::jumpToDefinition() ...@@ -649,15 +647,23 @@ void CPPEditor::jumpToDefinition()
#endif #endif
} }
} else { } else {
// Handle macro uses
foreach (const Document::MacroUse use, doc->macroUses()) { foreach (const Document::MacroUse use, doc->macroUses()) {
if (use.contains(endOfName - 1)) { if (use.contains(endOfName - 1)) {
const Macro &macro = use.macro(); const Macro &macro = use.macro();
const QString fileName = QString::fromUtf8(macro.fileName()); dest.fileName = QString::fromUtf8(macro.fileName());
if (openCppEditorAt(fileName, macro.line(), 0)) dest.line = macro.line();
return; // done return dest;
} }
} }
} }
return dest;
}
void CPPEditor::jumpToDefinition()
{
openCppEditorAt(findDestinationFor(textCursor()));
} }
Symbol *CPPEditor::findDefinition(Symbol *symbol) Symbol *CPPEditor::findDefinition(Symbol *symbol)
...@@ -777,6 +783,55 @@ void CPPEditor::contextMenuEvent(QContextMenuEvent *e) ...@@ -777,6 +783,55 @@ void CPPEditor::contextMenuEvent(QContextMenuEvent *e)
delete menu; 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 QList<int> CPPEditorEditable::context() const
{ {
return m_context; return m_context;
...@@ -946,9 +1001,11 @@ void CPPEditor::unCommentSelection() ...@@ -946,9 +1001,11 @@ void CPPEditor::unCommentSelection()
cursor.endEditBlock(); cursor.endEditBlock();
} }
int CPPEditor::endOfNameUnderCursor() int CPPEditor::endOfNameAtPosition(int pos)
{ {
int pos = position(); if (pos == -1)
pos = position();
QChar chr = characterAt(pos); QChar chr = characterAt(pos);
// Skip to the start of a name // Skip to the start of a name
...@@ -958,32 +1015,37 @@ int CPPEditor::endOfNameUnderCursor() ...@@ -958,32 +1015,37 @@ int CPPEditor::endOfNameUnderCursor()
return pos; return pos;
} }
TextEditor::ITextEditor *CPPEditor::openCppEditorAt(const QString &fileName, CPPEditor::Location CPPEditor::locationForSymbol(CPlusPlus::Symbol *symbol)
int line, int column)
{ {
return TextEditor::BaseTextEditor::openEditorAt(fileName, line, column, const QString fileName = QString::fromUtf8(symbol->fileName(),
Constants::C_CPPEDITOR); symbol->fileNameLength());
} unsigned line = symbol->line();
unsigned column = symbol->column();
bool CPPEditor::openEditorAt(Symbol *s)
{
const QString fileName = QString::fromUtf8(s->fileName(), s->fileNameLength());
unsigned line = s->line();
unsigned column = s->column();
if (column) if (column)
--column; --column;
if (s->isGenerated()) if (symbol->isGenerated())
column = 0; 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(); Core::EditorManager *editorManager = Core::EditorManager::instance();
editorManager->addCurrentPositionToNavigationHistory(); editorManager->addCurrentPositionToNavigationHistory();
gotoLine(line, column); gotoLine(loc.line, loc.column);
setFocus(); setFocus();
return true; return true;
} }
return openCppEditorAt(fileName, line, column); return TextEditor::BaseTextEditor::openEditorAt(loc.fileName,
loc.line,
loc.column,
Constants::C_CPPEDITOR);
} }
...@@ -97,6 +97,9 @@ public slots: ...@@ -97,6 +97,9 @@ public slots:
protected: protected:
void contextMenuEvent(QContextMenuEvent *e); void contextMenuEvent(QContextMenuEvent *e);
void mouseMoveEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);
TextEditor::BaseTextEditorEditable *createEditableInterface(); TextEditor::BaseTextEditorEditable *createEditableInterface();
// Rertuns true if key triggers anindent. // Rertuns true if key triggers anindent.
...@@ -122,9 +125,26 @@ private: ...@@ -122,9 +125,26 @@ private:
void createToolBar(CPPEditorEditable *editable); void createToolBar(CPPEditorEditable *editable);
int endOfNameUnderCursor(); int endOfNameAtPosition(int pos);
bool openEditorAt(CPlusPlus::Symbol *symbol); 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; CppTools::CppModelManagerInterface *m_modelManager;
......
...@@ -335,7 +335,6 @@ void VCSBaseEditor::mouseMoveEvent(QMouseEvent *e) ...@@ -335,7 +335,6 @@ void VCSBaseEditor::mouseMoveEvent(QMouseEvent *e)
sel.cursor = cursor; sel.cursor = cursor;
sel.cursor.select(QTextCursor::WordUnderCursor); sel.cursor.select(QTextCursor::WordUnderCursor);
sel.format.setFontUnderline(true); sel.format.setFontUnderline(true);
change = changeUnderCursor(cursor);
sel.format.setProperty(QTextFormat::UserProperty, change); sel.format.setProperty(QTextFormat::UserProperty, change);
setExtraSelections(OtherSelection, QList<QTextEdit::ExtraSelection>() << sel); setExtraSelections(OtherSelection, QList<QTextEdit::ExtraSelection>() << sel);
overrideCursor = true; overrideCursor = true;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment