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
...@@ -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,
Constants::C_CPPEDITOR);
}
bool CPPEditor::openEditorAt(Symbol *s)
{ {
const QString fileName = QString::fromUtf8(s->fileName(), s->fileNameLength()); const QString fileName = QString::fromUtf8(symbol->fileName(),
unsigned line = s->line(); symbol->fileNameLength());
unsigned column = s->column(); unsigned line = symbol->line();
unsigned column = symbol->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;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment