diff --git a/RedPandaIDE/debugger.cpp b/RedPandaIDE/debugger.cpp index a02e6708..c712b141 100644 --- a/RedPandaIDE/debugger.cpp +++ b/RedPandaIDE/debugger.cpp @@ -3,10 +3,12 @@ #include "mainwindow.h" #include "editor.h" #include "settings.h" +#include "cpudialog.h" #include #include #include +#include Debugger::Debugger(QObject *parent) : QObject(parent) { @@ -36,6 +38,7 @@ void Debugger::start() mReader = new DebugReader(this); mReader->setDebuggerPath(debuggerPath); connect(mReader, &QThread::finished,this,&Debugger::stop); + connect(mReader, &DebugReader::parseFinished,this,&Debugger::syncFinishedParsing,Qt::BlockingQueuedConnection); mReader->start(); @@ -79,23 +82,23 @@ void Debugger::stop() pMainWindow->updateAppTitle(); - MainForm.OnBacktraceReady; + mBacktraceModel->clear(); - Application.HintHidePause := 2500; +// Application.HintHidePause := 2500; - WatchView.Items.BeginUpdate; - try - //Clear all watch values - for I := 0 to WatchVarList.Count - 1 do begin - WatchVar := PWatchVar(WatchVarList.Items[I]); - WatchVar^.Node.Text := WatchVar^.Name + ' = '+Lang[ID_MSG_EXECUTE_TO_EVALUATE]; +// WatchView.Items.BeginUpdate; +// try +// //Clear all watch values +// for I := 0 to WatchVarList.Count - 1 do begin +// WatchVar := PWatchVar(WatchVarList.Items[I]); +// WatchVar^.Node.Text := WatchVar^.Name + ' = '+Lang[ID_MSG_EXECUTE_TO_EVALUATE]; - // Delete now invalid children - WatchVar^.Node.DeleteChildren; - end; - finally - WatchView.Items.EndUpdate; - end; +// // Delete now invalid children +// WatchVar^.Node.DeleteChildren; +// end; +// finally +// WatchView.Items.EndUpdate; +// end; } } @@ -221,7 +224,7 @@ void Debugger::sendBreakpointCommand(PBreakpoint breakpoint) void Debugger::sendClearBreakpointCommand(int index) { - sendClearBreakpointCommand(mBreakpointModel->breakpoints()[breakpoint]); + sendClearBreakpointCommand(mBreakpointModel->breakpoints()[index]); } void Debugger::sendClearBreakpointCommand(PBreakpoint breakpoint) @@ -237,6 +240,133 @@ void Debugger::sendClearBreakpointCommand(PBreakpoint breakpoint) } } +void Debugger::syncFinishedParsing() +{ + bool spawnedcpuform = false; + + // GDB determined that the source code is more recent than the executable. Ask the user if he wants to rebuild. + if (mReader->doreceivedsfwarning) { + if (QMessageBox::question(pMainWindow, + tr("Compile"), + tr("Source file is more recent than executable.")+"

" + tr("Recompile?"), + QMessageBox::Yes | QMessageBox::No, + QMessageBox::Yes + ) == QMessageBox::Yes) { + stop(); + pMainWindow->compile(); + return; + } + } + + // The program to debug has stopped. Stop the debugger + if (mReader->doprocessexited) { + stop(); + return; + } + + // An evaluation variable has been processed. Forward the results + if (mReader->doevalready) { + emit evalReady(mReader->mEvalValue); + } + + // show command output + if (pSettings->debugger().showCommandLog() || + (mReader->mCurrentCmd && mReader->mCurrentCmd->showInConsole)) { + if (pSettings->debugger().showAnnotations()) { + QString strOutput = mReader->mOutput; + strOutput.replace(QChar(26),'>'); + pMainWindow->addDebugOutput(strOutput); + pMainWindow->addDebugOutput(""); + pMainWindow->addDebugOutput(""); + } else { + QStringList strList = TextToLines(mReader->mOutput); + QStringList outStrList; + bool addToLastLine=false; + for (int i=0;i0) { + outStrList[outStrList.size()-1]+=strOutput; + } else { + outStrList.append(strOutput); + } + addToLastLine = false; + } + } + for (const QString& line:outStrList) { + pMainWindow->addDebugOutput(line); + } + } + } + + // Some part of the CPU form has been updated + if (pMainWindow->CPUDialog()->isVisible() && !mReader->doreceivedsignal) { +// if (mReader->doregistersready) +// CPUForm.OnRegistersReady; + +// if (mReader->dodisassemblerready) +// CPUForm.OnAssemblerReady; + } + +//if dobacktraceready then +// MainForm.OnBacktraceReady; + + + if (mReader->doupdateexecution) { + if (mReader->mCurrentCmd && mReader->mCurrentCmd == DebugCommandSource::Console) { + pMainWindow->setActiveBreakpoint(mReader->mBreakPointFile, mReader->mBreakPointLine,false); + } else { + pMainWindow->setActiveBreakpoint(mReader->mBreakPointFile, mReader->mBreakPointLine); + } + refreshWatchVars(); // update variable information + } + + if (mReader->doreceivedsignal) { +//SignalDialog := CreateMessageDialog(fSignal, mtError, [mbOk]); +//SignalCheck := TCheckBox.Create(SignalDialog); + +//// Display it on top of everything +//SignalDialog.FormStyle := fsStayOnTop; + +//SignalDialog.Height := 150; + +//with SignalCheck do begin +// Parent := SignalDialog; +// Caption := 'Show CPU window'; +// Top := Parent.ClientHeight - 22; +// Left := 8; +// Width := Parent.ClientWidth - 16; +// Checked := devData.ShowCPUSignal; +//end; + +//MessageBeep(MB_ICONERROR); +//if SignalDialog.ShowModal = ID_OK then begin +// devData.ShowCPUSignal := SignalCheck.Checked; +// if SignalCheck.Checked and not Assigned(CPUForm) then begin +// MainForm.ViewCPUItemClick(nil); +// spawnedcpuform := true; +// end; +//end; + +//SignalDialog.Free; + + } + + + // CPU form updates itself when spawned, don't update twice! + if ((mReader->doupdatecpuwindow && !spawnedcpuform) && (pMainWindow->CPUDialog()->isVisible())) { + sendCommand("disas", ""); + sendCommand("info registers", ""); + } +} + +bool Debugger::executing() const +{ + return mExecuting; +} + DebugReader::DebugReader(Debugger* debugger, QObject *parent) : QThread(parent) { mDebugger = debugger; diff --git a/RedPandaIDE/debugger.h b/RedPandaIDE/debugger.h index a17d0df0..f4eeed9c 100644 --- a/RedPandaIDE/debugger.h +++ b/RedPandaIDE/debugger.h @@ -146,16 +146,20 @@ public: BacktraceModel* backtraceModel(); BreakpointModel* breakpointModel(); + bool executing() const; + public slots: void stop(); signals: + void evalReady(QString value); private: void sendBreakpointCommand(int index); void sendBreakpointCommand(PBreakpoint breakpoint); void sendClearBreakpointCommand(int index); void sendClearBreakpointCommand(PBreakpoint breakpoint); - +private slots: + void syncFinishedParsing(); private: bool mExecuting; bool mCommandChanged; @@ -253,7 +257,7 @@ private: bool doreceivedsfwarning; bool mStop; - + friend class Debugger; // QThread interface protected: void run() override; diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp index dced5466..717c0534 100644 --- a/RedPandaIDE/mainwindow.cpp +++ b/RedPandaIDE/mainwindow.cpp @@ -6,6 +6,8 @@ #include "settings.h" #include "qsynedit/Constants.h" #include "debugger.h" +#include "cpudialog.h" + #include #include @@ -82,6 +84,8 @@ MainWindow::MainWindow(QWidget *parent) ui->actionEncode_in_ANSI->setCheckable(true); ui->actionEncode_in_UTF_8->setCheckable(true); + mCPUDialog = new CPUDialog(this); + updateEditorActions(); applySettings(); @@ -217,48 +221,66 @@ void MainWindow::removeActiveBreakpoints() void MainWindow::updateAppTitle() { -appName := Lang[ID_DEVCPP]; -e := fEditorList.GetEditor; -if Assigned(e) and not e.InProject then begin - if e.Text.Modified then - str := e.FileName + ' [*]' - else - str := e.FileName; - if fDebugger.Executing then begin - Caption := Format('%s - [Debugging] - %s %s', [str, appName, DEVCPP_VERSION]); - Application.Title := Format('%s - [Debugging] - %s', [ExtractFileName(e.FileName), appName]); - end else if devExecutor.Running then begin - Caption := Format('%s - [Executing] - %s %s', [str, appName, DEVCPP_VERSION]); - Application.Title := Format('%s - [Executing] - %s', [ExtractFileName(e.FileName), appName]); - end else if fCompiler.Compiling then begin - Caption := Format('%s - [Compiling] - %s %s', [str, appName, DEVCPP_VERSION]); - Application.Title := Format('%s - [Compiling] - %s', [ExtractFileName(e.FileName), appName]); - end else begin - Caption := Format('%s - %s %s', [str, appName, DEVCPP_VERSION]); - Application.Title := Format('%s - %s', [ExtractFileName(e.FileName), appName]); - end; -end else if Assigned(fProject) then begin - if fDebugger.Executing then begin - Caption := Format('%s - [%s] - [Debugging] - %s %s', - [fProject.Name, ExtractFilename(fProject.Filename), appName, DEVCPP_VERSION]); - Application.Title := Format('%s - [Debugging] - %s', [fProject.Name, appName]); - end else if devExecutor.Running then begin - Caption := Format('%s - [%s] - [Executing] - %s %s', - [fProject.Name, ExtractFilename(fProject.Filename), appName, DEVCPP_VERSION]); - Application.Title := Format('%s - [Executing] - %s', [fProject.Name, appName]); - end else if fCompiler.Compiling then begin - Caption := Format('%s - [%s] - [Compiling] - %s %s', - [fProject.Name, ExtractFilename(fProject.Filename), appName, DEVCPP_VERSION]); - Application.Title := Format('%s - [Compiling] - %s', [fProject.Name, appName]); - end else begin - Caption := Format('%s - [%s] - %s %s', - [fProject.Name, ExtractFilename(fProject.Filename), appName, DEVCPP_VERSION]); - Application.Title := Format('%s - %s', [fProject.Name, appName]); - end; -end else begin - Caption := Format('%s %s', [appName, DEVCPP_VERSION]); - Application.Title := Format('%s', [DEVCPP]); -end; + QString appName("Red Panda Dev-C++"); + Editor *e = mEditorList->getEditor(); + QString str; + QCoreApplication *app = QApplication::instance(); + if (e && !e->inProject()) { + if (e->modified()) + str = e->filename() + " [*]"; + else + str = e->filename(); + if (mDebugger->executing()) { + setWindowTitle(QString("%s - [%s] - %s %s").arg(str).arg(appName) + .arg(tr("Debugging")).arg(DEVCPP_VERSION)); + app->setApplicationName(QString("%s - [%s] - %s").arg(str).arg(appName) + .arg(tr("Debugging"))); + } else if (mCompilerManager->running()) { + setWindowTitle(QString("%s - [%s] - %s %s").arg(str).arg(appName) + .arg(tr("Running")).arg(DEVCPP_VERSION)); + app->setApplicationName(QString("%s - [%s] - %s").arg(str).arg(appName) + .arg(tr("Running"))); + } else if (mCompilerManager->compiling()) { + setWindowTitle(QString("%s - [%s] - %s %s").arg(str).arg(appName) + .arg(tr("Compiling")).arg(DEVCPP_VERSION)); + app->setApplicationName(QString("%s - [%s] - %s").arg(str).arg(appName) + .arg(tr("Compiling"))); + } else { + this->setWindowTitle(QString("%s - %s %s").arg(str).arg(appName).arg(DEVCPP_VERSION)); + app->setApplicationName(QString("%s - %s").arg(str).arg(appName)); + } + } +// else if Assigned(fProject) then begin +// if fDebugger.Executing then begin +// Caption := Format('%s - [%s] - [Debugging] - %s %s', +// [fProject.Name, ExtractFilename(fProject.Filename), appName, DEVCPP_VERSION]); +// Application.Title := Format('%s - [Debugging] - %s', [fProject.Name, appName]); +// end else if devExecutor.Running then begin +// Caption := Format('%s - [%s] - [Executing] - %s %s', +// [fProject.Name, ExtractFilename(fProject.Filename), appName, DEVCPP_VERSION]); +// Application.Title := Format('%s - [Executing] - %s', [fProject.Name, appName]); +// end else if fCompiler.Compiling then begin +// Caption := Format('%s - [%s] - [Compiling] - %s %s', +// [fProject.Name, ExtractFilename(fProject.Filename), appName, DEVCPP_VERSION]); +// Application.Title := Format('%s - [Compiling] - %s', [fProject.Name, appName]); +// end else begin +// Caption := Format('%s - [%s] - %s %s', +// [fProject.Name, ExtractFilename(fProject.Filename), appName, DEVCPP_VERSION]); +// Application.Title := Format('%s - %s', [fProject.Name, appName]); +// end; + else { + setWindowTitle(QString("%s %s").arg(appName).arg(DEVCPP_VERSION)); + app->setApplicationName(QString("%s").arg(appName)); + } +} + +void MainWindow::addDebugOutput(const QString &text) +{ + if (text.isEmpty()) { + ui->debugConsole->addLine(""); + } else { + ui->debugConsole->addText(text); + } } void MainWindow::updateStatusbarForLineCol() @@ -762,6 +784,11 @@ void MainWindow::prepareDebugger() mDebugger->deleteWatchVars(false); } +CPUDialog *MainWindow::CPUDialog() const +{ + return mCPUDialog; +} + void MainWindow::on_actionNew_triggered() { diff --git a/RedPandaIDE/mainwindow.h b/RedPandaIDE/mainwindow.h index 4d09ce55..88defeb7 100644 --- a/RedPandaIDE/mainwindow.h +++ b/RedPandaIDE/mainwindow.h @@ -19,6 +19,7 @@ class QComboBox; class CompilerManager; class Editor; class Debugger; +class CPUDialog; class MainWindow : public QMainWindow { @@ -60,6 +61,9 @@ public: void removeActiveBreakpoints(); void updateAppTitle(); + void addDebugOutput(const QString& text); + + CPUDialog *CPUDialog() const; protected: void openFiles(const QStringList& files); @@ -159,6 +163,7 @@ private: QComboBox* mCompilerSet; CompilerManager* mCompilerManager; Debugger* mDebugger; + CPUDialog* mCPUDialog; bool mMessageControlChanged; bool mTabMessagesTogglingState; diff --git a/RedPandaIDE/settings.cpp b/RedPandaIDE/settings.cpp index 556951da..da4eb0a2 100644 --- a/RedPandaIDE/settings.cpp +++ b/RedPandaIDE/settings.cpp @@ -97,6 +97,11 @@ QString Settings::filename() const return mFilename; } +Debugger Settings::debugger() const +{ + return mDebugger; +} + Settings::Dirs::Dirs(Settings *settings): _Base(settings, SETTING_DIRS) { @@ -2223,7 +2228,6 @@ void Settings::Executor::setMinimizeOnRun(bool minimizeOnRun) void Settings::Executor::doSave() { - //Appearence saveValue("pause_console", mPauseConsole); saveValue("minimize_on_run", mMinimizeOnRun); } @@ -2240,8 +2244,44 @@ void Settings::Executor::setPauseConsole(bool pauseConsole) void Settings::Executor::doLoad() { - //Appearence mPauseConsole = boolValue("pause_console",true); mMinimizeOnRun = boolValue("minimize_on_run",false); } + +Settings::Debugger::Debugger(Settings *settings):_Base(settings, SETTING_DEBUGGER) +{ + +} + +bool Settings::Debugger::showCommandLog() const +{ + return mShowCommandLog; +} + +void Settings::Debugger::setShowCommandLog(bool showCommandLog) +{ + mShowCommandLog = showCommandLog; +} + +bool Settings::Debugger::showAnnotations() const +{ + return mShowAnnotations; +} + +void Settings::Debugger::setShowAnnotations(bool showAnnotations) +{ + mShowAnnotations = showAnnotations; +} + +void Settings::Debugger::doSave() +{ + saveValue("show_command_log", mShowCommandLog); + saveValue("show_annotations", mShowAnnotations); +} + +void Settings::Debugger::doLoad() +{ + mShowCommandLog = boolValue("show_command_log",true); + mShowAnnotations = boolValue("show_annotations",false); +} diff --git a/RedPandaIDE/settings.h b/RedPandaIDE/settings.h index 1da8f5f6..36f44e46 100644 --- a/RedPandaIDE/settings.h +++ b/RedPandaIDE/settings.h @@ -16,6 +16,7 @@ #define SETTING_EDITOR "Editor" #define SETTING_ENVIRONMENT "Environment" #define SETTING_EXECUTOR "Executor" +#define SETTING_DEBUGGER "Debugger" #define SETTING_COMPILTER_SETS "CompilerSets" #define SETTING_COMPILTER_SETS_DEFAULT_INDEX "defaultIndex" #define SETTING_COMPILTER_SETS_COUNT "count" @@ -388,6 +389,25 @@ public: void doLoad() override; }; + class Debugger: public _Base { + public: + explicit Debugger(Settings* settings); + bool showCommandLog() const; + void setShowCommandLog(bool showCommandLog); + + bool showAnnotations() const; + void setShowAnnotations(bool showAnnotations); + + private: + bool mShowCommandLog; + bool mShowAnnotations; + + // _Base interface + protected: + void doSave() override; + void doLoad() override; + }; + class CompilerSet { public: @@ -566,6 +586,8 @@ public: Executor& executor(); QString filename() const; + Debugger& debugger() const; + private: QString mFilename; QSettings mSettings; @@ -574,6 +596,7 @@ private: Environment mEnvironment; CompilerSets mCompilerSets; Executor mExecutor; + Debugger mDebugger; }; diff --git a/RedPandaIDE/systemconsts.h b/RedPandaIDE/systemconsts.h index 39e70917..f23a65bb 100644 --- a/RedPandaIDE/systemconsts.h +++ b/RedPandaIDE/systemconsts.h @@ -30,6 +30,8 @@ #error "Only support windows and linux now!" #endif +#define DEVCPP_VERSION "0.01" + class SystemConsts { public: diff --git a/RedPandaIDE/widgets/qconsole.cpp b/RedPandaIDE/widgets/qconsole.cpp index 3c3630bb..0c712c25 100644 --- a/RedPandaIDE/widgets/qconsole.cpp +++ b/RedPandaIDE/widgets/qconsole.cpp @@ -11,6 +11,7 @@ #include #include #include +#include "../utils.h" QConsole::QConsole(QWidget *parent): QAbstractScrollArea(parent), @@ -143,6 +144,14 @@ void QConsole::addLine(const QString &line) mContents.addLine(line); } +void QConsole::addText(const QString &text) +{ + QStringList lst = TextToLines(text); + for (const QString& line:lst) { + addLine(line); + } +} + void QConsole::removeLastLine() { mCurrentEditableLine = ""; diff --git a/RedPandaIDE/widgets/qconsole.h b/RedPandaIDE/widgets/qconsole.h index 54b50a65..767e7801 100644 --- a/RedPandaIDE/widgets/qconsole.h +++ b/RedPandaIDE/widgets/qconsole.h @@ -110,6 +110,7 @@ public: void invalidateRect(const QRect& rect); void addLine(const QString& line); + void addText(const QString& text); void removeLastLine(); void changeLastLine(const QString& line); QString getLastLine();