mirror of
https://github.com/epasveer/seer.git
synced 2026-08-29 08:34:42 +08:00
Add feature: Mouse navigation
This commit is contained in:
@@ -902,6 +902,8 @@ void SeerEditorManagerWidget::handleOpenFileWithDetails (const QString& file, co
|
||||
}
|
||||
}
|
||||
|
||||
handleAddToMouseNavigation({file, fullname, cursorRow, 1, editorWidget->sourceArea()->firstDisplayLine()});
|
||||
|
||||
// Ask for the breakpoint list to be resent, in case this file has breakpoints.
|
||||
emit refreshBreakpointsList();
|
||||
|
||||
@@ -1035,6 +1037,7 @@ SeerEditorWidgetSource* SeerEditorManagerWidget::createEditorWidgetTab (const QS
|
||||
QObject::connect(editorWidget->sourceArea(), &SeerEditorWidgetSourceArea::addMatrixVisualizer, this, &SeerEditorManagerWidget::handleAddMatrixVisualizer);
|
||||
QObject::connect(editorWidget->sourceArea(), &SeerEditorWidgetSourceArea::addStructVisualizer, this, &SeerEditorManagerWidget::handleAddStructVisualizer);
|
||||
QObject::connect(editorWidget, &SeerEditorWidgetSource::addAlternateDirectory, this, &SeerEditorManagerWidget::handleAddAlternateDirectory);
|
||||
QObject::connect(editorWidget->sourceArea(), &SeerEditorWidgetSourceArea::addToMouseNavigation, this, &SeerEditorManagerWidget::handleAddToMouseNavigation);
|
||||
|
||||
// Send the Editor widget the command to load the file. ??? Do better than this.
|
||||
editorWidget->sourceArea()->handleText(text);
|
||||
@@ -1097,6 +1100,7 @@ SeerEditorWidgetSource* SeerEditorManagerWidget::createEditorWidgetTab (const QS
|
||||
QObject::connect(editorWidget->sourceArea(), &SeerEditorWidgetSourceArea::addMatrixVisualizer, this, &SeerEditorManagerWidget::handleAddMatrixVisualizer);
|
||||
QObject::connect(editorWidget->sourceArea(), &SeerEditorWidgetSourceArea::addStructVisualizer, this, &SeerEditorManagerWidget::handleAddStructVisualizer);
|
||||
QObject::connect(editorWidget, &SeerEditorWidgetSource::addAlternateDirectory, this, &SeerEditorManagerWidget::handleAddAlternateDirectory);
|
||||
QObject::connect(editorWidget->sourceArea(), &SeerEditorWidgetSourceArea::addToMouseNavigation, this, &SeerEditorManagerWidget::handleAddToMouseNavigation);
|
||||
|
||||
// Load the file.
|
||||
editorWidget->sourceArea()->open(fullname, QFileInfo(file).fileName());
|
||||
@@ -1475,10 +1479,116 @@ void SeerEditorManagerWidget::handleSessionTerminated () {
|
||||
}
|
||||
}
|
||||
|
||||
// Clear the stack of recently closed files whenever a new gdb session starts
|
||||
// Clear the stack of recently closed files backward/forward list whenever a new gdb session starts
|
||||
void SeerEditorManagerWidget::handleGdbStateChanged()
|
||||
{
|
||||
while (!_stackClosedFiles.empty()) {
|
||||
_stackClosedFiles.pop();
|
||||
}
|
||||
_listForwardFiles.clear();
|
||||
_forwardFilesIndex = -1;
|
||||
}
|
||||
/***********************************************************************************************************************
|
||||
* Function for handling mouse navigation
|
||||
**********************************************************************************************************************/
|
||||
void SeerEditorManagerWidget::handleAddToMouseNavigation(const SeerEditorWidgetSourceArea::SeerCurrentFile& currentFile)
|
||||
{
|
||||
// Record this file in the forward list.
|
||||
if (currentFile.file != "")
|
||||
{
|
||||
// Check if the last added file is the same as currentFile
|
||||
if (!_listForwardFiles.empty())
|
||||
{
|
||||
const SeerEditorWidgetSourceArea::SeerCurrentFile& lastFile = _listForwardFiles[_listForwardFiles.size() -1];
|
||||
if (currentFile == lastFile)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// if _forwardFilesIndex is at the end of the list, just append
|
||||
if (_forwardFilesIndex >= _listForwardFiles.size() - 1)
|
||||
{
|
||||
_listForwardFiles.append(currentFile);
|
||||
_forwardFilesIndex ++;
|
||||
}
|
||||
else // else remove all entries after _forwardFilesIndex and then append
|
||||
{
|
||||
int removeCount = _listForwardFiles.size() - 1 - _forwardFilesIndex;
|
||||
if ((currentFile == _listForwardFiles[_listForwardFiles.size() -1]) || (currentFile == _listForwardFiles[0])
|
||||
|| (currentFile == _listForwardFiles[_listForwardFiles.size() - 1 - removeCount]) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (int i=0; i < removeCount; i++)
|
||||
{
|
||||
_listForwardFiles.removeLast();
|
||||
}
|
||||
_listForwardFiles.append(currentFile);
|
||||
_forwardFilesIndex = _listForwardFiles.size() -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SeerEditorManagerWidget::handleOpenForwardBackward(const SeerEditorWidgetSourceArea::SeerCurrentFile& fileInfo) {
|
||||
// Get the EditorWidget for the file. Create one if needed.
|
||||
SeerEditorWidgetSource* editorWidget = editorWidgetTab(fileInfo.fullname);
|
||||
|
||||
if (editorWidget == 0) {
|
||||
editorWidget = createEditorWidgetTab(fileInfo.fullname, fileInfo.file);
|
||||
}
|
||||
|
||||
// Can still be null, if the file is ignored.
|
||||
if (editorWidget == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Push this tab to the top only if the current one in not the "Assembly" tab.
|
||||
QString tabtext = "";
|
||||
|
||||
if (tabWidget->currentIndex() >= 0) {
|
||||
tabtext = tabWidget->tabText(tabWidget->currentIndex());
|
||||
}
|
||||
|
||||
if (keepAssemblyTabOnTop() && tabtext == "Assembly") {
|
||||
// Do nothing. The "Assembly" tab is already on top.
|
||||
}else{
|
||||
tabWidget->setCurrentWidget(editorWidget);
|
||||
}
|
||||
|
||||
if (fileInfo.firstDisplayLine > 0) { // scroll to the previous first display line
|
||||
QScrollBar *scrollBar = editorWidget->sourceArea()->verticalScrollBar();
|
||||
int step = scrollBar->singleStep();
|
||||
scrollBar->setValue(fileInfo.firstDisplayLine * step - 1);
|
||||
|
||||
// Set cursor position
|
||||
QTextBlock block = editorWidget->sourceArea()->document()->findBlockByLineNumber(fileInfo.cursorRow-1);
|
||||
QTextCursor cursor = editorWidget->sourceArea()->textCursor();
|
||||
cursor.setPosition(block.position() + fileInfo.cursorCol - 1);
|
||||
editorWidget->sourceArea()->setTextCursor(cursor);
|
||||
}
|
||||
}
|
||||
// Handle mouse press events for navigation
|
||||
void SeerEditorManagerWidget::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
// Back button (XButton1) clicked
|
||||
if (event->button() == Qt::XButton1) {
|
||||
if (_forwardFilesIndex - 1 < 0)
|
||||
return;
|
||||
--_forwardFilesIndex;
|
||||
const SeerEditorWidgetSourceArea::SeerCurrentFile &info = _listForwardFiles.at(_forwardFilesIndex);
|
||||
handleOpenForwardBackward(info);
|
||||
}
|
||||
// Forward button (XButton2) clicked
|
||||
else if (event->button() == Qt::XButton2) {
|
||||
if (_forwardFilesIndex + 1 > _listForwardFiles.size() - 1)
|
||||
return;
|
||||
++ _forwardFilesIndex;
|
||||
const SeerEditorWidgetSourceArea::SeerCurrentFile &info = _listForwardFiles.at(_forwardFilesIndex);
|
||||
handleOpenForwardBackward(info);
|
||||
}
|
||||
else
|
||||
{
|
||||
QWidget::mousePressEvent(event);
|
||||
}
|
||||
}
|
||||
@@ -103,6 +103,10 @@ class SeerEditorManagerWidget : public QWidget, protected Ui::SeerEditorManagerW
|
||||
void handleAssemblyConfigChanged ();
|
||||
void handleSessionTerminated ();
|
||||
void handleGdbStateChanged ();
|
||||
void handleAddToMouseNavigation (const SeerEditorWidgetSourceArea::SeerCurrentFile& currentFile);
|
||||
|
||||
protected:
|
||||
void mousePressEvent (QMouseEvent *event) override;
|
||||
|
||||
private slots:
|
||||
void handleFileOpenToolButtonClicked ();
|
||||
@@ -144,6 +148,7 @@ class SeerEditorManagerWidget : public QWidget, protected Ui::SeerEditorManagerW
|
||||
SeerEditorWidgetAssembly* createAssemblyWidgetTab ();
|
||||
void deleteAssemblyWidgetTab ();
|
||||
void handleOpenFileWithDetails (const QString& file, const QString& fullname, int cursorRow, int cursorCol, int firstDisplayLine);
|
||||
void handleOpenForwardBackward (const SeerEditorWidgetSourceArea::SeerCurrentFile& fileInfo);
|
||||
|
||||
SeerEditorManagerEntries _entries;
|
||||
SeerHighlighterSettings _editorHighlighterSettings;
|
||||
@@ -167,5 +172,8 @@ class SeerEditorManagerWidget : public QWidget, protected Ui::SeerEditorManagerW
|
||||
|
||||
// list of recently closed files (Ctrl + Shift + T)
|
||||
QStack<SeerEditorWidgetSourceArea::SeerCurrentFile> _stackClosedFiles;
|
||||
// list of cursor positions for mouse navigation (back/forward)
|
||||
QList<SeerEditorWidgetSourceArea::SeerCurrentFile> _listForwardFiles;
|
||||
int _forwardFilesIndex = -1;
|
||||
};
|
||||
|
||||
|
||||
@@ -140,6 +140,7 @@ class SeerEditorWidgetSourceArea : public SeerPlainTextEdit {
|
||||
void showAlternateBar (bool flag);
|
||||
void showReloadBar (bool flag);
|
||||
void highlighterSettingsChanged ();
|
||||
void addToMouseNavigation (const SeerCurrentFile& currentFile);
|
||||
|
||||
public slots:
|
||||
void handleText (const QString& text);
|
||||
@@ -154,6 +155,7 @@ class SeerEditorWidgetSourceArea : public SeerPlainTextEdit {
|
||||
bool event (QEvent* event);
|
||||
void showExpressionTooltip ();
|
||||
void hideExpressionTooltip ();
|
||||
void mousePressEvent (QMouseEvent *event) override;
|
||||
|
||||
private slots:
|
||||
void refreshExtraSelections ();
|
||||
@@ -163,6 +165,7 @@ class SeerEditorWidgetSourceArea : public SeerPlainTextEdit {
|
||||
void updateBreakPointArea (const QRect& rect, int dy);
|
||||
|
||||
private:
|
||||
void handleCursorPositionChanged ();
|
||||
QString _fullname;
|
||||
QString _file;
|
||||
QString _alternateDirectory;
|
||||
@@ -194,6 +197,8 @@ class SeerEditorWidgetSourceArea : public SeerPlainTextEdit {
|
||||
|
||||
int _sourceTabSize;
|
||||
QString _externalEditorCommand;
|
||||
|
||||
int _ignoreThumbMouseEvent = 0;
|
||||
};
|
||||
|
||||
class SeerEditorWidgetSourceLineNumberArea : public QWidget {
|
||||
|
||||
@@ -69,6 +69,9 @@ SeerEditorWidgetSourceArea::SeerEditorWidgetSourceArea(QWidget* parent) : SeerPl
|
||||
QObject::connect(this, &SeerEditorWidgetSourceArea::updateRequest, this, &SeerEditorWidgetSourceArea::updateBreakPointArea);
|
||||
QObject::connect(this, &SeerEditorWidgetSourceArea::highlighterSettingsChanged, this, &SeerEditorWidgetSourceArea::handleHighlighterSettingsChanged);
|
||||
|
||||
// Connect cursor position changed signal.
|
||||
QObject::connect(this, &QPlainTextEdit::cursorPositionChanged, this, &SeerEditorWidgetSourceArea::handleCursorPositionChanged);
|
||||
|
||||
setCurrentLine(0);
|
||||
|
||||
updateMarginAreasWidth(0);
|
||||
@@ -2025,3 +2028,43 @@ void SeerEditorWidgetSourceBreakPointArea::mouseReleaseEvent (QMouseEvent* event
|
||||
QWidget::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************
|
||||
* Functions for mouse navigation feature *
|
||||
**********************************************************************************************************************/
|
||||
void SeerEditorWidgetSourceArea::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::XButton1 || event->button() == Qt::XButton2) {
|
||||
// Avoid the default back/forward action
|
||||
_ignoreThumbMouseEvent ++;
|
||||
SeerCurrentFile firstInfo = readCurrentPosition();
|
||||
// _ignoreThumbMouseEvent will incremented in mousePressEvent when thumb mouse button is pressed but it may not be decremented
|
||||
// if user just click the thumb mouse button without moving the cursor. So here we check if the position is the same as last time,
|
||||
// which means cursor didn't move, then we reset _ignoreThumbMouseEvent to 0 to avoid blocking future events.
|
||||
QTimer::singleShot(30, this, [this, firstInfo]() { // let's give 30 ms for cursor to move to new position
|
||||
SeerCurrentFile secondInfo = readCurrentPosition();
|
||||
if (firstInfo == secondInfo) { // cursor didn't move
|
||||
_ignoreThumbMouseEvent = 0; // reset to 0
|
||||
}
|
||||
} );
|
||||
}
|
||||
QPlainTextEdit::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void SeerEditorWidgetSourceArea::handleCursorPositionChanged()
|
||||
{
|
||||
// Emit signal to SeerEditorManagerWidget.cpp and save position
|
||||
// Read current position, deploy a timer
|
||||
SeerCurrentFile firstInfo = readCurrentPosition();
|
||||
if (_ignoreThumbMouseEvent > 0)
|
||||
{
|
||||
_ignoreThumbMouseEvent --;
|
||||
return;
|
||||
}
|
||||
|
||||
QTimer::singleShot(2000, this, [this, firstInfo]() {
|
||||
SeerCurrentFile secondInfo = readCurrentPosition();
|
||||
if (firstInfo == secondInfo) {
|
||||
emit addToMouseNavigation(firstInfo);
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user