From 25070cc4914a5ef0b60a48038479d915ef2e4de2 Mon Sep 17 00:00:00 2001 From: "royqh1979@gmail.com" Date: Sat, 2 Oct 2021 17:01:08 +0800 Subject: [PATCH] - implement: context menu for debug console - fix: errors in debug console - fix: speed up the parsing process of debugger --- NEWS.md | 3 + RedPandaIDE/debugger.cpp | 2 +- RedPandaIDE/mainwindow.cpp | 67 ++++++++++++++++++++- RedPandaIDE/mainwindow.h | 8 +++ RedPandaIDE/platform.cpp | 4 +- RedPandaIDE/widgets/codecompletionpopup.cpp | 6 +- RedPandaIDE/widgets/qconsole.cpp | 65 ++++++++++++++++++++ RedPandaIDE/widgets/qconsole.h | 5 ++ 8 files changed, 155 insertions(+), 5 deletions(-) diff --git a/NEWS.md b/NEWS.md index 1607f932..36623e43 100644 --- a/NEWS.md +++ b/NEWS.md @@ -21,6 +21,9 @@ Version 0.3.0 - enhancement: use up/down key to navigate function parameter tooltip - enhancement: press esc to close function parameter tooltip - enhancement: code suggestion for unicode identifiers + - implement: context menu for debug console + - fix: errors in debug console + - fix: speed up the parsing process of debugger Version 0.2.1 - fix: crash when load last opens diff --git a/RedPandaIDE/debugger.cpp b/RedPandaIDE/debugger.cpp index be138e8f..a0b76c13 100644 --- a/RedPandaIDE/debugger.cpp +++ b/RedPandaIDE/debugger.cpp @@ -1665,7 +1665,7 @@ void DebugReader::run() } else if (!mCmdRunning && readed.isEmpty()){ runNextCmd(); } else if (readed.isEmpty()){ - msleep(100); + msleep(1); } } if (errorOccurred) { diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp index 79364b42..d891d09f 100644 --- a/RedPandaIDE/mainwindow.cpp +++ b/RedPandaIDE/mainwindow.cpp @@ -1338,6 +1338,9 @@ void MainWindow::prepareDebugger() // Clear logs ui->debugConsole->clear(); + if (!pSettings->debugger().showCommandLog()) { + ui->debugConsole->addLine("(gdb) "); + } ui->txtEvalOutput->clear(); // Restore when no watch vars are shown @@ -1539,6 +1542,51 @@ void MainWindow::buildContextMenus() connect(ui->watchView,&QWidget::customContextMenuRequested, this, &MainWindow::onWatchViewContextMenu); + //context menu signal for the watch view + ui->debugConsole->setContextMenuPolicy(Qt::CustomContextMenu); + connect(ui->debugConsole,&QWidget::customContextMenuRequested, + this, &MainWindow::onDebugConsoleContextMenu); + mDebugConsole_ShowCommandLog = createActionFor( + tr("Show debug logs in the debug console"), + ui->debugConsole); + mDebugConsole_ShowCommandLog->setCheckable(true); + connect(mDebugConsole_ShowCommandLog, &QAction::toggled, + [this]() { + pSettings->debugger().setShowCommandLog(mDebugConsole_ShowCommandLog->isChecked()); + pSettings->debugger().save(); + }); + mDebugConsole_Copy=createActionFor( + tr("Copy"), + ui->debugConsole, + QKeySequence("Ctrl+C")); + connect(mDebugConsole_Copy, &QAction::triggered, + [this]() { + ui->debugConsole->copy(); + }); + mDebugConsole_Paste=createActionFor( + tr("Paste"), + ui->debugConsole, + QKeySequence("Ctrl+V")); + connect(mDebugConsole_Paste, &QAction::triggered, + [this]() { + ui->debugConsole->paste(); + }); + mDebugConsole_SelectAll=createActionFor( + tr("Select All"), + ui->debugConsole, + QKeySequence("Ctrl+A")); + connect(mDebugConsole_SelectAll, &QAction::triggered, + [this]() { + ui->debugConsole->selectAll(); + }); + mDebugConsole_Clear=createActionFor( + tr("Clear"), + ui->debugConsole); + connect(mDebugConsole_Clear, &QAction::triggered, + [this]() { + ui->debugConsole->clear(); + }); + //context menu signal for Editor's tabbar ui->EditorTabsLeft->tabBar()->setContextMenuPolicy(Qt::CustomContextMenu); connect(ui->EditorTabsLeft->tabBar(),&QWidget::customContextMenuRequested, @@ -2051,6 +2099,23 @@ void MainWindow::onClassBrowserContextMenu(const QPoint &pos) menu.exec(ui->projectView->mapToGlobal(pos)); } +void MainWindow::onDebugConsoleContextMenu(const QPoint &pos) +{ + QMenu menu(this); + + bool oldBlock = mDebugConsole_ShowCommandLog->blockSignals(true); + mDebugConsole_ShowCommandLog->setChecked(pSettings->debugger().showCommandLog()); + mDebugConsole_ShowCommandLog->blockSignals(oldBlock); + + menu.addAction(mDebugConsole_Copy); + menu.addAction(mDebugConsole_Paste); + menu.addAction(mDebugConsole_SelectAll); + menu.addAction(mDebugConsole_Clear); + menu.addSeparator(); + menu.addAction(mDebugConsole_ShowCommandLog); + menu.exec(ui->debugConsole->mapToGlobal(pos)); +} + void MainWindow::onEditorContextMenu(const QPoint &pos) { Editor * editor = mEditorList->getEditor(); @@ -2655,7 +2720,7 @@ void MainWindow::cleanUpCPUDialog() void MainWindow::onDebugCommandInput(const QString &command) { if (mDebugger->executing()) { - mDebugger->sendCommand(command,""); + mDebugger->sendCommand(command,"",true,true); } } diff --git a/RedPandaIDE/mainwindow.h b/RedPandaIDE/mainwindow.h index 5beb8526..aa91a176 100644 --- a/RedPandaIDE/mainwindow.h +++ b/RedPandaIDE/mainwindow.h @@ -175,6 +175,7 @@ private slots: void onBreakpointsViewContextMenu(const QPoint& pos); void onProjectViewContextMenu(const QPoint& pos); void onClassBrowserContextMenu(const QPoint& pos); + void onDebugConsoleContextMenu(const QPoint& pos); void on_actionNew_triggered(); @@ -432,6 +433,13 @@ private: QAction * mClassBrowser_goto_definition; QWidget * mClassBrowserToolbar; + //action for debug console + QAction * mDebugConsole_ShowCommandLog; + QAction * mDebugConsole_Clear; + QAction * mDebugConsole_Copy; + QAction * mDebugConsole_Paste; + QAction * mDebugConsole_SelectAll; + // QWidget interface protected: void closeEvent(QCloseEvent *event) override; diff --git a/RedPandaIDE/platform.cpp b/RedPandaIDE/platform.cpp index 2b642b7a..f951ce21 100644 --- a/RedPandaIDE/platform.cpp +++ b/RedPandaIDE/platform.cpp @@ -2,9 +2,9 @@ #include #include #include - -#ifdef Q_OS_WIN #include +#ifdef Q_OS_WIN + #include #endif diff --git a/RedPandaIDE/widgets/codecompletionpopup.cpp b/RedPandaIDE/widgets/codecompletionpopup.cpp index 11b87766..803fc79a 100644 --- a/RedPandaIDE/widgets/codecompletionpopup.cpp +++ b/RedPandaIDE/widgets/codecompletionpopup.cpp @@ -569,7 +569,11 @@ void CodeCompletionPopup::getCompletionFor(const QString &fileName, const QStrin } PStatement parentTypeStatement; PStatement statement = mParser->findStatementOf( - fileName, scopeName,mCurrentStatement,parentTypeStatement); + fileName, + scopeName, + mCurrentStatement, + parentTypeStatement); + if (!statement) return; // find the most inner scope statement that has a name (not a block) diff --git a/RedPandaIDE/widgets/qconsole.cpp b/RedPandaIDE/widgets/qconsole.cpp index e3233701..116a6a31 100644 --- a/RedPandaIDE/widgets/qconsole.cpp +++ b/RedPandaIDE/widgets/qconsole.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include "../utils.h" QConsole::QConsole(QWidget *parent): @@ -180,6 +181,63 @@ void QConsole::clear() mSelectionBegin = {0,0}; mSelectionEnd = {0,0}; mCaretChar = 0; + updateScrollbars(); +} + +void QConsole::copy() +{ + if (!this->hasSelection()) + return; + QString s = selText(); + QClipboard* clipboard=QGuiApplication::clipboard(); + clipboard->clear(); + clipboard->setText(s); +} + +void QConsole::paste() +{ + if (mReadonly) + return; + QClipboard* clipboard=QGuiApplication::clipboard(); + textInputed(clipboard->text()); +} + +void QConsole::selectAll() +{ + if (mContents.lines()>0) { + mSelectionBegin = {1,1}; + mSelectionEnd = { mContents.getLastLine().length()+1,mContents.lines()}; + } +} + +QString QConsole::selText() +{ + if (!hasSelection()) + return ""; + int ColFrom = selectionBegin().ch; + int First = selectionBegin().line; + int ColTo = selectionEnd().ch; + int Last = selectionEnd().line; + if (First == Last) { + QString s = mContents.getLine(First); + if (First == mContents.lines()) { + s += this->mCommand; + } + return s.mid(ColFrom, ColTo - ColFrom); + + } else { + QString result = mContents.getLine(First).mid(ColFrom); + result+= lineBreak(); + for (int i = First + 1; i<=Last - 1; i++) { + result += mContents.getLine(i); + result+= lineBreak(); + } + QString s = mContents.getLine(Last); + if (Last == mContents.lines()) + s+= this->mCommand; + result += s.leftRef(ColTo); + return result; + } } void QConsole::recalcCharExtent() { @@ -645,6 +703,7 @@ void QConsole::paintEvent(QPaintEvent *event) //Get the invalidated rect. QRect rcClip = event->rect(); QRect rcCaret= getCaretRect(); + if (rcCaret == rcClip) { // only update caret painter.drawImage(rcCaret,*mContentImage,rcCaret); @@ -656,6 +715,7 @@ void QConsole::paintEvent(QPaintEvent *event) nL2 = std::min(std::max(mTopRow + (rcClip.bottom() + mRowHeight - 1) / mRowHeight, 1), maxScrollHeight() + mRowsInWindow - 1); QPainter cachePainter(mContentImage.get()); cachePainter.setFont(font()); + painter.fillRect(rcClip,mBackground); paintRows(cachePainter,nL1,nL2); painter.drawImage(rcClip,*mContentImage,rcClip); } @@ -841,6 +901,11 @@ RowColumn QConsole::pixelsToNearestRowColumn(int x, int y) }; } +QString QConsole::lineBreak() +{ + return "\r\n"; +} + void QConsole::fontChanged() { diff --git a/RedPandaIDE/widgets/qconsole.h b/RedPandaIDE/widgets/qconsole.h index 767e7801..ee037f93 100644 --- a/RedPandaIDE/widgets/qconsole.h +++ b/RedPandaIDE/widgets/qconsole.h @@ -115,6 +115,10 @@ public: void changeLastLine(const QString& line); QString getLastLine(); void clear(); + void copy(); + void paste(); + void selectAll(); + QString selText(); signals: void commandInput(const QString& command); @@ -180,6 +184,7 @@ private: bool hasSelection(); int computeScrollY(int Y); RowColumn pixelsToNearestRowColumn(int x,int y); + QString lineBreak(); private slots: