work save

This commit is contained in:
royqh1979 2021-07-26 11:47:54 +08:00
parent e269e7c747
commit 8c7cb8dd65
9 changed files with 302 additions and 61 deletions

View File

@ -3,10 +3,12 @@
#include "mainwindow.h" #include "mainwindow.h"
#include "editor.h" #include "editor.h"
#include "settings.h" #include "settings.h"
#include "cpudialog.h"
#include <QFile> #include <QFile>
#include <QFileInfo> #include <QFileInfo>
#include <QMessageBox> #include <QMessageBox>
#include <QMessageBox>
Debugger::Debugger(QObject *parent) : QObject(parent) Debugger::Debugger(QObject *parent) : QObject(parent)
{ {
@ -36,6 +38,7 @@ void Debugger::start()
mReader = new DebugReader(this); mReader = new DebugReader(this);
mReader->setDebuggerPath(debuggerPath); mReader->setDebuggerPath(debuggerPath);
connect(mReader, &QThread::finished,this,&Debugger::stop); connect(mReader, &QThread::finished,this,&Debugger::stop);
connect(mReader, &DebugReader::parseFinished,this,&Debugger::syncFinishedParsing,Qt::BlockingQueuedConnection);
mReader->start(); mReader->start();
@ -79,23 +82,23 @@ void Debugger::stop()
pMainWindow->updateAppTitle(); pMainWindow->updateAppTitle();
MainForm.OnBacktraceReady; mBacktraceModel->clear();
Application.HintHidePause := 2500; // Application.HintHidePause := 2500;
WatchView.Items.BeginUpdate; // WatchView.Items.BeginUpdate;
try // try
//Clear all watch values // //Clear all watch values
for I := 0 to WatchVarList.Count - 1 do begin // for I := 0 to WatchVarList.Count - 1 do begin
WatchVar := PWatchVar(WatchVarList.Items[I]); // WatchVar := PWatchVar(WatchVarList.Items[I]);
WatchVar^.Node.Text := WatchVar^.Name + ' = '+Lang[ID_MSG_EXECUTE_TO_EVALUATE]; // WatchVar^.Node.Text := WatchVar^.Name + ' = '+Lang[ID_MSG_EXECUTE_TO_EVALUATE];
// Delete now invalid children // // Delete now invalid children
WatchVar^.Node.DeleteChildren; // WatchVar^.Node.DeleteChildren;
end; // end;
finally // finally
WatchView.Items.EndUpdate; // WatchView.Items.EndUpdate;
end; // end;
} }
} }
@ -221,7 +224,7 @@ void Debugger::sendBreakpointCommand(PBreakpoint breakpoint)
void Debugger::sendClearBreakpointCommand(int index) void Debugger::sendClearBreakpointCommand(int index)
{ {
sendClearBreakpointCommand(mBreakpointModel->breakpoints()[breakpoint]); sendClearBreakpointCommand(mBreakpointModel->breakpoints()[index]);
} }
void Debugger::sendClearBreakpointCommand(PBreakpoint breakpoint) 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.")+"<BR /><BR />" + 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;i<strList.size();i++) {
QString strOutput=strList[i];
if (strOutput.startsWith("\032\032")) {
addToLastLine = true;
} else {
if (addToLastLine && outStrList.size()>0) {
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) DebugReader::DebugReader(Debugger* debugger, QObject *parent) : QThread(parent)
{ {
mDebugger = debugger; mDebugger = debugger;

View File

@ -146,16 +146,20 @@ public:
BacktraceModel* backtraceModel(); BacktraceModel* backtraceModel();
BreakpointModel* breakpointModel(); BreakpointModel* breakpointModel();
bool executing() const;
public slots: public slots:
void stop(); void stop();
signals: signals:
void evalReady(QString value);
private: private:
void sendBreakpointCommand(int index); void sendBreakpointCommand(int index);
void sendBreakpointCommand(PBreakpoint breakpoint); void sendBreakpointCommand(PBreakpoint breakpoint);
void sendClearBreakpointCommand(int index); void sendClearBreakpointCommand(int index);
void sendClearBreakpointCommand(PBreakpoint breakpoint); void sendClearBreakpointCommand(PBreakpoint breakpoint);
private slots:
void syncFinishedParsing();
private: private:
bool mExecuting; bool mExecuting;
bool mCommandChanged; bool mCommandChanged;
@ -253,7 +257,7 @@ private:
bool doreceivedsfwarning; bool doreceivedsfwarning;
bool mStop; bool mStop;
friend class Debugger;
// QThread interface // QThread interface
protected: protected:
void run() override; void run() override;

View File

@ -6,6 +6,8 @@
#include "settings.h" #include "settings.h"
#include "qsynedit/Constants.h" #include "qsynedit/Constants.h"
#include "debugger.h" #include "debugger.h"
#include "cpudialog.h"
#include <QCloseEvent> #include <QCloseEvent>
#include <QComboBox> #include <QComboBox>
@ -82,6 +84,8 @@ MainWindow::MainWindow(QWidget *parent)
ui->actionEncode_in_ANSI->setCheckable(true); ui->actionEncode_in_ANSI->setCheckable(true);
ui->actionEncode_in_UTF_8->setCheckable(true); ui->actionEncode_in_UTF_8->setCheckable(true);
mCPUDialog = new CPUDialog(this);
updateEditorActions(); updateEditorActions();
applySettings(); applySettings();
@ -217,48 +221,66 @@ void MainWindow::removeActiveBreakpoints()
void MainWindow::updateAppTitle() void MainWindow::updateAppTitle()
{ {
appName := Lang[ID_DEVCPP]; QString appName("Red Panda Dev-C++");
e := fEditorList.GetEditor; Editor *e = mEditorList->getEditor();
if Assigned(e) and not e.InProject then begin QString str;
if e.Text.Modified then QCoreApplication *app = QApplication::instance();
str := e.FileName + ' [*]' if (e && !e->inProject()) {
else if (e->modified())
str := e.FileName; str = e->filename() + " [*]";
if fDebugger.Executing then begin else
Caption := Format('%s - [Debugging] - %s %s', [str, appName, DEVCPP_VERSION]); str = e->filename();
Application.Title := Format('%s - [Debugging] - %s', [ExtractFileName(e.FileName), appName]); if (mDebugger->executing()) {
end else if devExecutor.Running then begin setWindowTitle(QString("%s - [%s] - %s %s").arg(str).arg(appName)
Caption := Format('%s - [Executing] - %s %s', [str, appName, DEVCPP_VERSION]); .arg(tr("Debugging")).arg(DEVCPP_VERSION));
Application.Title := Format('%s - [Executing] - %s', [ExtractFileName(e.FileName), appName]); app->setApplicationName(QString("%s - [%s] - %s").arg(str).arg(appName)
end else if fCompiler.Compiling then begin .arg(tr("Debugging")));
Caption := Format('%s - [Compiling] - %s %s', [str, appName, DEVCPP_VERSION]); } else if (mCompilerManager->running()) {
Application.Title := Format('%s - [Compiling] - %s', [ExtractFileName(e.FileName), appName]); setWindowTitle(QString("%s - [%s] - %s %s").arg(str).arg(appName)
end else begin .arg(tr("Running")).arg(DEVCPP_VERSION));
Caption := Format('%s - %s %s', [str, appName, DEVCPP_VERSION]); app->setApplicationName(QString("%s - [%s] - %s").arg(str).arg(appName)
Application.Title := Format('%s - %s', [ExtractFileName(e.FileName), appName]); .arg(tr("Running")));
end; } else if (mCompilerManager->compiling()) {
end else if Assigned(fProject) then begin setWindowTitle(QString("%s - [%s] - %s %s").arg(str).arg(appName)
if fDebugger.Executing then begin .arg(tr("Compiling")).arg(DEVCPP_VERSION));
Caption := Format('%s - [%s] - [Debugging] - %s %s', app->setApplicationName(QString("%s - [%s] - %s").arg(str).arg(appName)
[fProject.Name, ExtractFilename(fProject.Filename), appName, DEVCPP_VERSION]); .arg(tr("Compiling")));
Application.Title := Format('%s - [Debugging] - %s', [fProject.Name, appName]); } else {
end else if devExecutor.Running then begin this->setWindowTitle(QString("%s - %s %s").arg(str).arg(appName).arg(DEVCPP_VERSION));
Caption := Format('%s - [%s] - [Executing] - %s %s', app->setApplicationName(QString("%s - %s").arg(str).arg(appName));
[fProject.Name, ExtractFilename(fProject.Filename), appName, DEVCPP_VERSION]); }
Application.Title := Format('%s - [Executing] - %s', [fProject.Name, appName]); }
end else if fCompiler.Compiling then begin // else if Assigned(fProject) then begin
Caption := Format('%s - [%s] - [Compiling] - %s %s', // if fDebugger.Executing then begin
[fProject.Name, ExtractFilename(fProject.Filename), appName, DEVCPP_VERSION]); // Caption := Format('%s - [%s] - [Debugging] - %s %s',
Application.Title := Format('%s - [Compiling] - %s', [fProject.Name, appName]); // [fProject.Name, ExtractFilename(fProject.Filename), appName, DEVCPP_VERSION]);
end else begin // Application.Title := Format('%s - [Debugging] - %s', [fProject.Name, appName]);
Caption := Format('%s - [%s] - %s %s', // end else if devExecutor.Running then begin
[fProject.Name, ExtractFilename(fProject.Filename), appName, DEVCPP_VERSION]); // Caption := Format('%s - [%s] - [Executing] - %s %s',
Application.Title := Format('%s - %s', [fProject.Name, appName]); // [fProject.Name, ExtractFilename(fProject.Filename), appName, DEVCPP_VERSION]);
end; // Application.Title := Format('%s - [Executing] - %s', [fProject.Name, appName]);
end else begin // end else if fCompiler.Compiling then begin
Caption := Format('%s %s', [appName, DEVCPP_VERSION]); // Caption := Format('%s - [%s] - [Compiling] - %s %s',
Application.Title := Format('%s', [DEVCPP]); // [fProject.Name, ExtractFilename(fProject.Filename), appName, DEVCPP_VERSION]);
end; // 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() void MainWindow::updateStatusbarForLineCol()
@ -762,6 +784,11 @@ void MainWindow::prepareDebugger()
mDebugger->deleteWatchVars(false); mDebugger->deleteWatchVars(false);
} }
CPUDialog *MainWindow::CPUDialog() const
{
return mCPUDialog;
}
void MainWindow::on_actionNew_triggered() void MainWindow::on_actionNew_triggered()
{ {

View File

@ -19,6 +19,7 @@ class QComboBox;
class CompilerManager; class CompilerManager;
class Editor; class Editor;
class Debugger; class Debugger;
class CPUDialog;
class MainWindow : public QMainWindow class MainWindow : public QMainWindow
{ {
@ -60,6 +61,9 @@ public:
void removeActiveBreakpoints(); void removeActiveBreakpoints();
void updateAppTitle(); void updateAppTitle();
void addDebugOutput(const QString& text);
CPUDialog *CPUDialog() const;
protected: protected:
void openFiles(const QStringList& files); void openFiles(const QStringList& files);
@ -159,6 +163,7 @@ private:
QComboBox* mCompilerSet; QComboBox* mCompilerSet;
CompilerManager* mCompilerManager; CompilerManager* mCompilerManager;
Debugger* mDebugger; Debugger* mDebugger;
CPUDialog* mCPUDialog;
bool mMessageControlChanged; bool mMessageControlChanged;
bool mTabMessagesTogglingState; bool mTabMessagesTogglingState;

View File

@ -97,6 +97,11 @@ QString Settings::filename() const
return mFilename; return mFilename;
} }
Debugger Settings::debugger() const
{
return mDebugger;
}
Settings::Dirs::Dirs(Settings *settings): Settings::Dirs::Dirs(Settings *settings):
_Base(settings, SETTING_DIRS) _Base(settings, SETTING_DIRS)
{ {
@ -2223,7 +2228,6 @@ void Settings::Executor::setMinimizeOnRun(bool minimizeOnRun)
void Settings::Executor::doSave() void Settings::Executor::doSave()
{ {
//Appearence
saveValue("pause_console", mPauseConsole); saveValue("pause_console", mPauseConsole);
saveValue("minimize_on_run", mMinimizeOnRun); saveValue("minimize_on_run", mMinimizeOnRun);
} }
@ -2240,8 +2244,44 @@ void Settings::Executor::setPauseConsole(bool pauseConsole)
void Settings::Executor::doLoad() void Settings::Executor::doLoad()
{ {
//Appearence
mPauseConsole = boolValue("pause_console",true); mPauseConsole = boolValue("pause_console",true);
mMinimizeOnRun = boolValue("minimize_on_run",false); 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);
}

View File

@ -16,6 +16,7 @@
#define SETTING_EDITOR "Editor" #define SETTING_EDITOR "Editor"
#define SETTING_ENVIRONMENT "Environment" #define SETTING_ENVIRONMENT "Environment"
#define SETTING_EXECUTOR "Executor" #define SETTING_EXECUTOR "Executor"
#define SETTING_DEBUGGER "Debugger"
#define SETTING_COMPILTER_SETS "CompilerSets" #define SETTING_COMPILTER_SETS "CompilerSets"
#define SETTING_COMPILTER_SETS_DEFAULT_INDEX "defaultIndex" #define SETTING_COMPILTER_SETS_DEFAULT_INDEX "defaultIndex"
#define SETTING_COMPILTER_SETS_COUNT "count" #define SETTING_COMPILTER_SETS_COUNT "count"
@ -388,6 +389,25 @@ public:
void doLoad() override; 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 { class CompilerSet {
public: public:
@ -566,6 +586,8 @@ public:
Executor& executor(); Executor& executor();
QString filename() const; QString filename() const;
Debugger& debugger() const;
private: private:
QString mFilename; QString mFilename;
QSettings mSettings; QSettings mSettings;
@ -574,6 +596,7 @@ private:
Environment mEnvironment; Environment mEnvironment;
CompilerSets mCompilerSets; CompilerSets mCompilerSets;
Executor mExecutor; Executor mExecutor;
Debugger mDebugger;
}; };

View File

@ -30,6 +30,8 @@
#error "Only support windows and linux now!" #error "Only support windows and linux now!"
#endif #endif
#define DEVCPP_VERSION "0.01"
class SystemConsts class SystemConsts
{ {
public: public:

View File

@ -11,6 +11,7 @@
#include <QDebug> #include <QDebug>
#include <QTimer> #include <QTimer>
#include <QApplication> #include <QApplication>
#include "../utils.h"
QConsole::QConsole(QWidget *parent): QConsole::QConsole(QWidget *parent):
QAbstractScrollArea(parent), QAbstractScrollArea(parent),
@ -143,6 +144,14 @@ void QConsole::addLine(const QString &line)
mContents.addLine(line); mContents.addLine(line);
} }
void QConsole::addText(const QString &text)
{
QStringList lst = TextToLines(text);
for (const QString& line:lst) {
addLine(line);
}
}
void QConsole::removeLastLine() void QConsole::removeLastLine()
{ {
mCurrentEditableLine = ""; mCurrentEditableLine = "";

View File

@ -110,6 +110,7 @@ public:
void invalidateRect(const QRect& rect); void invalidateRect(const QRect& rect);
void addLine(const QString& line); void addLine(const QString& line);
void addText(const QString& text);
void removeLastLine(); void removeLastLine();
void changeLastLine(const QString& line); void changeLastLine(const QString& line);
QString getLastLine(); QString getLastLine();