Skip to content

Commit afff065

Browse files
authored
Open the class under the cursor (#13432)
#8854 Added a context menu item Open Class. Ctrl+click to open the class
1 parent d44ecbc commit afff065

File tree

6 files changed

+133
-1
lines changed

6 files changed

+133
-1
lines changed

OMEdit/OMEditLIB/Editors/BaseEditor.cpp

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,7 @@ PlainTextEdit::PlainTextEdit(BaseEditor *pBaseEditor)
664664
: QPlainTextEdit(pBaseEditor), mpBaseEditor(pBaseEditor)
665665
{
666666
setObjectName("BaseEditor");
667+
setMouseTracking(true);
667668
QTextDocument *pTextDocument = document();
668669
pTextDocument->setDocumentMargin(2);
669670
BaseEditorDocumentLayout *pModelicaTextDocumentLayout = new BaseEditorDocumentLayout(pTextDocument);
@@ -1375,7 +1376,6 @@ void PlainTextEdit::toggleBlockVisible(const QTextBlock &block)
13751376
pBaseEditorDocumentLayout->emitDocumentSizeChanged();
13761377
}
13771378

1378-
13791379
/*!
13801380
* \brief BaseEditor::updateLineNumberAreaWidth
13811381
* Updates the width of LineNumberArea.
@@ -2053,6 +2053,38 @@ void PlainTextEdit::wheelEvent(QWheelEvent *event)
20532053
QPlainTextEdit::wheelEvent(event);
20542054
}
20552055

2056+
/*!
2057+
* \brief PlainTextEdit::mousePressEvent
2058+
* Reimplementation of QPlainTextEdit::mousePressEvent
2059+
* \param event
2060+
*/
2061+
void PlainTextEdit::mousePressEvent(QMouseEvent *event)
2062+
{
2063+
bool controlModifier = event->modifiers().testFlag(Qt::ControlModifier);
2064+
if (controlModifier) {
2065+
mpBaseEditor->symbolAtPosition(event->pos());
2066+
viewport()->unsetCursor();
2067+
}
2068+
QPlainTextEdit::mousePressEvent(event);
2069+
}
2070+
2071+
/*!
2072+
* \brief PlainTextEdit::mouseMoveEvent
2073+
* Reimplementation of QPlainTextEdit::mouseMoveEvent
2074+
* \param event
2075+
*/
2076+
void PlainTextEdit::mouseMoveEvent(QMouseEvent *event)
2077+
{
2078+
bool controlModifier = event->modifiers().testFlag(Qt::ControlModifier);
2079+
if (controlModifier) {
2080+
viewport()->setCursor(Qt::PointingHandCursor);
2081+
} else {
2082+
viewport()->unsetCursor();
2083+
}
2084+
2085+
QPlainTextEdit::mouseMoveEvent(event);
2086+
}
2087+
20562088
/*!
20572089
* \class BaseEditor
20582090
* Base class for all editors.
@@ -2074,6 +2106,7 @@ BaseEditor::BaseEditor(QWidget *pParent)
20742106

20752107
/*!
20762108
* \brief BaseEditor::wordUnderCursor
2109+
* Returns the word under cursor.
20772110
*/
20782111
QString BaseEditor::wordUnderCursor()
20792112
{
@@ -2082,6 +2115,19 @@ QString BaseEditor::wordUnderCursor()
20822115
return cursor.selectedText();
20832116
}
20842117

2118+
/*!
2119+
* \brief BaseEditor::symbolAtPosition
2120+
* Navigates to the symbol at position.\n
2121+
* The default implementation does nothing.\n
2122+
* Reimplement in the child class to navigate to the correct symbol based on the language.
2123+
* \param pos
2124+
*/
2125+
void BaseEditor::symbolAtPosition(const QPoint &pos)
2126+
{
2127+
Q_UNUSED(pos);
2128+
// Do nothing. Reimplement in the child class.
2129+
}
2130+
20852131
bool BaseEditor::isModelicaModelInPackageOneFile()
20862132
{
20872133
return (mpModelWidget && mpModelWidget->getLibraryTreeItem() &&
@@ -2161,6 +2207,10 @@ void BaseEditor::createActions()
21612207
connect(mpZoomOutAction, SIGNAL(triggered()), mpPlainTextEdit, SLOT(zoomOut()));
21622208
mpPlainTextEdit->addAction(mpZoomOutAction);
21632209
}
2210+
// open class action
2211+
mpOpenClassAction = new QAction(Helper::openClass, this);
2212+
mpOpenClassAction->setStatusTip(Helper::openClassTip);
2213+
connect(mpOpenClassAction, SIGNAL(triggered()), SLOT(openClass()));
21642214
// toggle comment action
21652215
mpToggleCommentSelectionAction = new QAction(tr("Toggle Comment Selection"), this);
21662216
mpToggleCommentSelectionAction->setShortcut(QKeySequence("Ctrl+k"));
@@ -2325,6 +2375,17 @@ void BaseEditor::showGotoLineNumberDialog()
23252375
pGotoLineWidget->exec();
23262376
}
23272377

2378+
/*!
2379+
* \brief BaseEditor::openClass
2380+
* Slot activated when open class is seleteted from context menu.
2381+
*/
2382+
void BaseEditor::openClass()
2383+
{
2384+
if (mContextMenuStartPositionValid) {
2385+
symbolAtPosition(mContextMenuStartPosition);
2386+
}
2387+
}
2388+
23282389
/*!
23292390
* \brief BaseEditor::toggleCommentSelection
23302391
* Slot activated when toggle comment selection is seleteted from context menu or ctrl+k is pressed.

OMEdit/OMEditLIB/Editors/BaseEditor.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,8 @@ public slots:
314314
virtual void focusOutEvent(QFocusEvent *event) override;
315315
void paintEvent(QPaintEvent *e) override;
316316
void wheelEvent(QWheelEvent *event) override;
317+
virtual void mousePressEvent(QMouseEvent *event) override;
318+
virtual void mouseMoveEvent(QMouseEvent *event) override;
317319
};
318320

319321
class BaseEditor : public QWidget
@@ -332,6 +334,7 @@ class BaseEditor : public QWidget
332334
void setForceSetPlainText(bool forceSetPlainText) {mForceSetPlainText = forceSetPlainText;}
333335
virtual void popUpCompleter () = 0;
334336
virtual QString wordUnderCursor();
337+
virtual void symbolAtPosition(const QPoint &pos);
335338
bool isModelicaModelInPackageOneFile();
336339
private:
337340
void initialize();
@@ -349,11 +352,14 @@ class BaseEditor : public QWidget
349352
QAction *mpResetZoomAction;
350353
QAction *mpZoomInAction;
351354
QAction *mpZoomOutAction;
355+
QAction *mpOpenClassAction;
352356
QAction *mpToggleCommentSelectionAction;
353357
QAction *mpFoldAllAction;
354358
QAction *mpUnFoldAllAction;
355359
DocumentMarker *mpDocumentMarker = nullptr;
356360
bool mForceSetPlainText;
361+
QPoint mContextMenuStartPosition;
362+
bool mContextMenuStartPositionValid = false;
357363

358364
QMenu* createStandardContextMenu();
359365
void contentsChanged();
@@ -364,6 +370,7 @@ public slots:
364370
void showFindReplaceWidget();
365371
void clearFindReplaceTexts();
366372
void showGotoLineNumberDialog();
373+
void openClass();
367374
virtual void toggleCommentSelection();
368375
};
369376

OMEdit/OMEditLIB/Editors/ModelicaEditor.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,40 @@ QString ModelicaEditor::wordUnderCursor()
185185
return mpPlainTextEdit->document()->toPlainText().mid(begin, end - begin);
186186
}
187187

188+
/*!
189+
* \brief ModelicaEditor::symbolAtPosition
190+
* Navigate to the Modelica class at position.
191+
* \param pos
192+
*/
193+
void ModelicaEditor::symbolAtPosition(const QPoint &pos)
194+
{
195+
if (mpModelWidget) {
196+
QTextCursor cursor = mpPlainTextEdit->cursorForPosition(pos);
197+
cursor.select(QTextCursor::WordUnderCursor);
198+
199+
int mid = cursor.position();
200+
int end = mid;
201+
202+
while (end < cursor.block().length()) {
203+
QChar ch = mpPlainTextEdit->document()->characterAt(end);
204+
if (!(ch.isLetterOrNumber() || ch == '.' || ch == '_'))
205+
break;
206+
end++;
207+
}
208+
209+
int begin = mid - 1;
210+
while (begin >= 0) {
211+
QChar ch = mpPlainTextEdit->document()->characterAt(begin);
212+
if (!(ch.isLetterOrNumber() || ch == '.' || ch == '_'))
213+
break;
214+
begin--;
215+
}
216+
begin++;
217+
218+
mpModelWidget->navigateToClass(mpPlainTextEdit->document()->toPlainText().mid(begin, end - begin));
219+
}
220+
}
221+
188222
/*!
189223
* \brief Returns the substring from the last occurrence of `word` to the cursor position
190224
* \param word Starting word of the substring
@@ -510,11 +544,16 @@ void ModelicaEditor::showContextMenu(QPoint point)
510544
{
511545
QMenu *pMenu = BaseEditor::createStandardContextMenu();
512546
pMenu->addSeparator();
547+
pMenu->addAction(mpOpenClassAction);
548+
pMenu->addSeparator();
513549
pMenu->addAction(mpToggleCommentSelectionAction);
514550
pMenu->addSeparator();
515551
pMenu->addAction(mpFoldAllAction);
516552
pMenu->addAction(mpUnFoldAllAction);
553+
mContextMenuStartPosition = point;
554+
mContextMenuStartPositionValid = true;
517555
pMenu->exec(mapToGlobal(point));
556+
mContextMenuStartPositionValid = false;
518557
delete pMenu;
519558
}
520559

OMEdit/OMEditLIB/Editors/ModelicaEditor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class ModelicaEditor : public BaseEditor
5959
bool isTextChanged() {return mTextChanged;}
6060
virtual void popUpCompleter() override;
6161
virtual QString wordUnderCursor() override;
62+
virtual void symbolAtPosition(const QPoint &pos) override;
6263
QString stringAfterWord(const QString &word);
6364
static LibraryTreeItem *deepResolve(LibraryTreeItem *pItem, QStringList nameComponents);
6465
QList<LibraryTreeItem *> getCandidateContexts(QStringList nameComponents);

OMEdit/OMEditLIB/Modeling/ModelWidgetContainer.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6809,6 +6809,29 @@ void ModelWidget::selectDeselectElement(const QString &name, bool selected)
68096809
}
68106810
}
68116811

6812+
/*!
6813+
* \brief ModelWidget::navigateToClass
6814+
* Lookup the class and open it.
6815+
* \param className
6816+
*/
6817+
void ModelWidget::navigateToClass(const QString &className)
6818+
{
6819+
LibraryWidget *pLibraryWidget = MainWindow::instance()->getLibraryWidget();
6820+
LibraryTreeItem *pLibraryTreeItem = nullptr;
6821+
// first see if we find any relative class
6822+
const QString parentClassName = StringHandler::removeLastWordAfterDot(mpLibraryTreeItem->getNameStructure());
6823+
pLibraryTreeItem = pLibraryWidget->getLibraryTreeModel()->findLibraryTreeItem(parentClassName % "." % className);
6824+
if (pLibraryTreeItem) {
6825+
pLibraryWidget->getLibraryTreeModel()->showModelWidget(pLibraryTreeItem);
6826+
} else {
6827+
// relative class not found.
6828+
pLibraryTreeItem = pLibraryWidget->getLibraryTreeModel()->findLibraryTreeItem(className);
6829+
if (pLibraryTreeItem) {
6830+
pLibraryWidget->getLibraryTreeModel()->showModelWidget(pLibraryTreeItem);
6831+
}
6832+
}
6833+
}
6834+
68126835
/*!
68136836
* \brief ModelWidget::createUndoStack
68146837
* Creates the undo stack.

OMEdit/OMEditLIB/Modeling/ModelWidgetContainer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,7 @@ class ModelWidget : public QWidget
602602
ModelInfo createModelInfo() const;
603603
void showElement(ModelInstance::Model *pModelInstance, bool addToList);
604604
void selectDeselectElement(const QString &name, bool selected);
605+
void navigateToClass(const QString &className);
605606
private:
606607
ModelWidgetContainer *mpModelWidgetContainer;
607608
ModelInstance::Model *mpModelInstance;

0 commit comments

Comments
 (0)