diff --git a/RedPandaIDE/RedPandaIDE.pro b/RedPandaIDE/RedPandaIDE.pro index 0dea66be..05cb6ca8 100644 --- a/RedPandaIDE/RedPandaIDE.pro +++ b/RedPandaIDE/RedPandaIDE.pro @@ -135,7 +135,8 @@ SOURCES += \ widgets/qconsole.cpp \ widgets/qpatchedcombobox.cpp \ widgets/searchdialog.cpp \ - widgets/searchresultview.cpp + widgets/searchresultview.cpp \ + widgets/signalmessagedialog.cpp HEADERS += \ ConvertUTF.h \ @@ -260,7 +261,8 @@ HEADERS += \ widgets/qconsole.h \ widgets/qpatchedcombobox.h \ widgets/searchdialog.h \ - widgets/searchresultview.h + widgets/searchresultview.h \ + widgets/signalmessagedialog.h FORMS += \ settingsdialog/compilerautolinkwidget.ui \ @@ -305,7 +307,8 @@ FORMS += \ widgets/filepropertiesdialog.ui \ widgets/newprojectdialog.ui \ widgets/ojproblempropertywidget.ui \ - widgets/searchdialog.ui + widgets/searchdialog.ui \ + widgets/signalmessagedialog.ui TRANSLATIONS += \ RedPandaIDE_zh_CN.ts diff --git a/RedPandaIDE/debugger.cpp b/RedPandaIDE/debugger.cpp index bff1edae..5387307b 100644 --- a/RedPandaIDE/debugger.cpp +++ b/RedPandaIDE/debugger.cpp @@ -15,6 +15,7 @@ #include #include #include +#include "widgets/signalmessagedialog.h" Debugger::Debugger(QObject *parent) : QObject(parent) { @@ -77,6 +78,10 @@ bool Debugger::start() &Debugger::updateEval); connect(mReader, &DebugReader::disassemblyUpdate,this, &Debugger::updateDisassembly); + connect(mReader, &DebugReader::registerNamesUpdated, this, + &Debugger::updateRegisterNames); + connect(mReader, &DebugReader::registerValuesUpdated, this, + &Debugger::updateRegisterValues); connect(mReader, &DebugReader::inferiorContinued,pMainWindow, &MainWindow::removeActiveBreakpoints); connect(mReader, &DebugReader::inferiorStopped,pMainWindow, @@ -133,6 +138,16 @@ void Debugger::clearUpReader() } } +void Debugger::updateRegisterNames(const QStringList ®isterNames) +{ + mRegisterModel->updateNames(registerNames); +} + +void Debugger::updateRegisterValues(const QHash &values) +{ + mRegisterModel->updateValues(values); +} + RegisterModel *Debugger::registerModel() const { return mRegisterModel; @@ -489,31 +504,16 @@ void Debugger::syncFinishedParsing() return; } - // Some part of the CPU form has been updated - if (pMainWindow->cpuDialog()!=nullptr && !mReader->signalReceived()) { -// if (mReader->doregistersready) { -// mRegisterModel->update(mReader->mRegisters); -// mReader->mRegisters.clear(); -// mReader->doregistersready = false; -// } - -// if (mReader->dodisassemblerready) { -// pMainWindow->cpuDialog()->setDisassembly(mReader->mDisassembly); -// mReader->mDisassembly.clear(); -// mReader->dodisassemblerready = false; -// } - } - -// if (mReader->updateExecution()) { -// if (mReader->currentCmd() && mReader->currentCmd()->source == DebugCommandSource::Console) { -// pMainWindow->setActiveBreakpoint(mReader->breakPointFile(), mReader->breakPointLine(),false); -// } else { -// pMainWindow->setActiveBreakpoint(mReader->breakPointFile(), mReader->breakPointLine()); -// } -// refreshWatchVars(); // update variable information -// } - if (mReader->signalReceived()) { + SignalMessageDialog dialog(pMainWindow); + dialog.setMessage( + tr("Signal \"%1\" Received: ").arg(mReader->signalName()) + + "
" + + mReader->signalMeaning()); + int result = dialog.exec(); + if (result == QDialog::Accepted && dialog.openCPUInfo()) { + pMainWindow->showCPUInfoDialog(); + } //SignalDialog := CreateMessageDialog(fSignal, mtError, [mbOk]); //SignalCheck := TCheckBox.Create(SignalDialog); @@ -595,7 +595,6 @@ DebugReader::DebugReader(Debugger* debugger, QObject *parent) : QThread(parent), { mDebugger = debugger; mProcess = nullptr; - mUseUTF8 = false; mCmdRunning = false; mInvalidateAllVars = false; } @@ -744,6 +743,12 @@ void DebugReader::processResult(const QByteArray &result) case GDBMIResultType::Memory: handleMemory(multiValues["memory"].array()); return; + case GDBMIResultType::RegisterNames: + handleRegisterNames(multiValues["register-names"].array()); + return; + case GDBMIResultType::RegisterValues: + handleRegisterValue(multiValues["register-values"].array()); + return; } } @@ -794,6 +799,8 @@ void DebugReader::processExecAsyncRecord(const QByteArray &line) } if (reason == "signal-received") { mSignalReceived = true; + mSignalName = multiValues["signal-name"].value(); + mSignalMeaning = multiValues["signal-meaning"].value(); } runInferiorStoppedHook(); if (mCurrentCmd && mCurrentCmd->source == DebugCommandSource::Console) @@ -1284,6 +1291,33 @@ void DebugReader::handleMemory(const QList &rows) emit memoryUpdated(memory); } +void DebugReader::handleRegisterNames(const QList &names) +{ + QStringList nameList; + foreach (const GDBMIResultParser::ParseValue& nameValue, names) { + nameList.append(nameValue.value()); + } + emit registerNamesUpdated(nameList); +} + +void DebugReader::handleRegisterValue(const QList &values) +{ + QHash result; + foreach (const GDBMIResultParser::ParseValue& val, values) { + GDBMIResultParser::ParseObject obj = val.object(); + int number = obj["number"].intValue(); + QString value = obj["value"].value(); + bool ok; + long long intVal; + intVal = value.toLongLong(&ok,10); + if (ok) { + value = QString("0x%1").arg(intVal,0,16); + } + result.insert(number,value); + } + emit registerValuesUpdated(result); +} + QByteArray DebugReader::removeToken(const QByteArray &line) { int p=0; @@ -1299,6 +1333,16 @@ QByteArray DebugReader::removeToken(const QByteArray &line) return line; } +const QString &DebugReader::signalMeaning() const +{ + return mSignalMeaning; +} + +const QString &DebugReader::signalName() const +{ + return mSignalName; +} + bool DebugReader::inferiorRunning() const { return mInferiorRunning; @@ -2042,32 +2086,27 @@ RegisterModel::RegisterModel(QObject *parent):QAbstractTableModel(parent) int RegisterModel::rowCount(const QModelIndex &) const { - return mRegisters.count(); + return mRegisterNames.count(); } int RegisterModel::columnCount(const QModelIndex &) const { - return 3; + return 2; } QVariant RegisterModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); - if (index.row()<0 || index.row() >= static_cast(mRegisters.size())) - return QVariant(); - PRegister reg = mRegisters[index.row()]; - if (!reg) + if (index.row()<0 || index.row() >= static_cast(mRegisterNames.size())) return QVariant(); switch (role) { case Qt::DisplayRole: switch (index.column()) { case 0: - return reg->name; + return mRegisterNames[index.row()]; case 1: - return reg->hexValue; - case 2: - return reg->decValue; + return mRegisterValues.value(index.row(),""); default: return QVariant(); } @@ -2083,26 +2122,31 @@ QVariant RegisterModel::headerData(int section, Qt::Orientation orientation, int case 0: return tr("Register"); case 1: - return tr("Value(Hex)"); - case 2: - return tr("Value(Dec)"); + return tr("Value"); } } return QVariant(); } -void RegisterModel::update(const QList ®s) +void RegisterModel::updateNames(const QStringList ®Names) { beginResetModel(); - mRegisters.clear(); - mRegisters.append(regs); + mRegisterNames = regNames; endResetModel(); } +void RegisterModel::updateValues(const QHash registerValues) +{ + mRegisterValues= registerValues; + emit dataChanged(createIndex(0,1), + createIndex(mRegisterNames.count()-1,1)); +} + void RegisterModel::clear() { beginResetModel(); - mRegisters.clear(); + mRegisterNames.clear(); + mRegisterValues.clear(); endResetModel(); } diff --git a/RedPandaIDE/debugger.h b/RedPandaIDE/debugger.h index abbe6ef9..40ec39c2 100644 --- a/RedPandaIDE/debugger.h +++ b/RedPandaIDE/debugger.h @@ -60,14 +60,6 @@ struct Trace { using PTrace = std::shared_ptr; -struct Register { - QString name; - QString hexValue; - QString decValue; -}; - -using PRegister = std::shared_ptr; - class RegisterModel: public QAbstractTableModel { Q_OBJECT public: @@ -76,10 +68,12 @@ public: int columnCount(const QModelIndex &parent) const override; QVariant data(const QModelIndex &index, int role) const override; QVariant headerData(int section, Qt::Orientation orientation, int role) const override; - void update(const QList& regs); + void updateNames(const QStringList& regNames); + void updateValues(const QHash registerValues); void clear(); private: - QList mRegisters; + QStringList mRegisterNames; + QHash mRegisterValues; }; class BreakpointModel: public QAbstractTableModel { @@ -246,6 +240,8 @@ private slots: void updateDisassembly(const QString& file, const QString& func,const QStringList& value); void onChangeDebugConsoleLastline(const QString& text); void clearUpReader(); + void updateRegisterNames(const QStringList& registerNames); + void updateRegisterValues(const QHash& values); private: bool mExecuting; @@ -310,6 +306,10 @@ public: bool inferiorRunning() const; + const QString &signalName() const; + + const QString &signalMeaning() const; + signals: void parseStarted(); void invalidateAllVars(); @@ -327,6 +327,8 @@ signals: void evalUpdated(const QString& value); void memoryUpdated(const QStringList& memoryValues); void disassemblyUpdate(const QString& filename, const QString& funcName, const QStringList& result); + void registerNamesUpdated(const QStringList& registerNames); + void registerValuesUpdated(const QHash& values); private: void clearCmdQueue(); @@ -341,6 +343,8 @@ private: void handleLocalVariables(const QList & variables); void handleEvaluation(const QString& value); void handleMemory(const QList & rows); + void handleRegisterNames(const QList & names); + void handleRegisterValue(const QList & values); void processConsoleOutput(const QByteArray& line); void processResult(const QByteArray& result); void processExecAsyncRecord(const QByteArray& line); @@ -360,15 +364,12 @@ private: //fOnInvalidateAllVars: TInvalidateAllVarsEvent; bool mCmdRunning; PDebugCommand mCurrentCmd; - QList mRegisters; - QStringList mDisassembly; - QProcess* mProcess; //fWatchView: TTreeView; - QString mSignal; - bool mUseUTF8; + QString mSignalName; + QString mSignalMeaning; // QList mInferiorStoppedHookCommands; diff --git a/RedPandaIDE/gdbmiresultparser.cpp b/RedPandaIDE/gdbmiresultparser.cpp index 0ebc5157..961da48a 100644 --- a/RedPandaIDE/gdbmiresultparser.cpp +++ b/RedPandaIDE/gdbmiresultparser.cpp @@ -16,6 +16,8 @@ GDBMIResultParser::GDBMIResultParser() // mResultTypes.insert("register-names",GDBMIResultType::RegisterNames); // mResultTypes.insert("register-values",GDBMIResultType::RegisterValues); mResultTypes.insert("-data-read-memory",GDBMIResultType::Memory); + mResultTypes.insert("-data-list-register-names",GDBMIResultType::RegisterNames); + mResultTypes.insert("-data-list-register-values",GDBMIResultType::RegisterValues); } bool GDBMIResultParser::parse(const QByteArray &record, const QString& command, GDBMIResultType &type, ParseObject& multiValues) diff --git a/RedPandaIDE/main.cpp b/RedPandaIDE/main.cpp index c3709e8a..64d8fd45 100644 --- a/RedPandaIDE/main.cpp +++ b/RedPandaIDE/main.cpp @@ -103,6 +103,7 @@ int main(int argc, char *argv[]) qRegisterMetaType("PCompileIssue"); qRegisterMetaType("PCompileIssue&"); qRegisterMetaType>("QVector"); + qRegisterMetaType>("QHash"); initParser(); diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp index 51bc48d8..69090b43 100644 --- a/RedPandaIDE/mainwindow.cpp +++ b/RedPandaIDE/mainwindow.cpp @@ -1432,6 +1432,7 @@ void MainWindow::debug() mDebugger->sendAllBreakpointsToDebugger(); // Run the debugger + mDebugger->sendCommand("-data-list-register-names",""); mDebugger->sendCommand("-gdb-set", "width 0"); // don't wrap output, very annoying mDebugger->sendCommand("-gdb-set", "new-console on"); mDebugger->sendCommand("-gdb-set", "confirm off"); @@ -1474,6 +1475,15 @@ void MainWindow::showSearchPanel(bool showReplace) ui->tabMessages->setCurrentWidget(ui->tabSearch); } +void MainWindow::showCPUInfoDialog() +{ + if (mCPUDialog==nullptr) { + mCPUDialog = new CPUDialog(this); + connect(mCPUDialog, &CPUDialog::closed, this, &MainWindow::cleanUpCPUDialog); + } + mCPUDialog->show(); +} + void MainWindow::openCloseBottomPanel(bool open) { // if Assigned(fReportToolWindow) then @@ -4048,11 +4058,7 @@ void MainWindow::on_actionAdd_Watch_triggered() void MainWindow::on_actionView_CPU_Window_triggered() { - if (mCPUDialog==nullptr) { - mCPUDialog = new CPUDialog(this); - connect(mCPUDialog, &CPUDialog::closed, this, &MainWindow::cleanUpCPUDialog); - } - mCPUDialog->show(); + showCPUInfoDialog(); } void MainWindow::on_actionExit_triggered() diff --git a/RedPandaIDE/mainwindow.h b/RedPandaIDE/mainwindow.h index 39550f94..8e647ca4 100644 --- a/RedPandaIDE/mainwindow.h +++ b/RedPandaIDE/mainwindow.h @@ -95,6 +95,7 @@ public: void runExecutable(RunType runType = RunType::Normal); void debug(); void showSearchPanel(bool showReplace = false); + void showCPUInfoDialog(); void applySettings(); void applyUISettings(); diff --git a/RedPandaIDE/widgets/cpudialog.cpp b/RedPandaIDE/widgets/cpudialog.cpp index 03b81b6b..8494e430 100644 --- a/RedPandaIDE/widgets/cpudialog.cpp +++ b/RedPandaIDE/widgets/cpudialog.cpp @@ -57,7 +57,7 @@ void CPUDialog::updateInfo() if (pMainWindow->debugger()->executing()) { // Load the registers.. sendSyntaxCommand(); - //pMainWindow->debugger()->sendCommand("info", "registers"); + pMainWindow->debugger()->sendCommand("-data-list-register-values", "N"); if (ui->chkBlendMode->isChecked()) pMainWindow->debugger()->sendCommand("disas", "/s"); else @@ -78,7 +78,7 @@ void CPUDialog::setDisassembly(const QString& file, const QString& funcName,cons ui->txtCode->lines()->add(line); } if (activeLine!=-1) - ui->txtCode->setCaretXY(BufferCoord{1,activeLine}); + ui->txtCode->setCaretXYCentered(true,BufferCoord{1,activeLine}); } void CPUDialog::sendSyntaxCommand() diff --git a/RedPandaIDE/widgets/signalmessagedialog.cpp b/RedPandaIDE/widgets/signalmessagedialog.cpp new file mode 100644 index 00000000..b44e5730 --- /dev/null +++ b/RedPandaIDE/widgets/signalmessagedialog.cpp @@ -0,0 +1,24 @@ +#include "signalmessagedialog.h" +#include "ui_signalmessagedialog.h" + +SignalMessageDialog::SignalMessageDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::SignalMessageDialog) +{ + ui->setupUi(this); +} + +SignalMessageDialog::~SignalMessageDialog() +{ + delete ui; +} + +void SignalMessageDialog::setMessage(const QString &message) +{ + ui->lblMessage->setText(message); +} + +bool SignalMessageDialog::openCPUInfo() +{ + return ui->chkOpenCPUInfo->isChecked(); +} diff --git a/RedPandaIDE/widgets/signalmessagedialog.h b/RedPandaIDE/widgets/signalmessagedialog.h new file mode 100644 index 00000000..f7781fcf --- /dev/null +++ b/RedPandaIDE/widgets/signalmessagedialog.h @@ -0,0 +1,24 @@ +#ifndef SIGNALMESSAGEDIALOG_H +#define SIGNALMESSAGEDIALOG_H + +#include + +namespace Ui { +class SignalMessageDialog; +} + +class SignalMessageDialog : public QDialog +{ + Q_OBJECT + +public: + explicit SignalMessageDialog(QWidget *parent = nullptr); + ~SignalMessageDialog(); + void setMessage(const QString& message); + bool openCPUInfo(); + +private: + Ui::SignalMessageDialog *ui; +}; + +#endif // SIGNALMESSAGEDIALOG_H diff --git a/RedPandaIDE/widgets/signalmessagedialog.ui b/RedPandaIDE/widgets/signalmessagedialog.ui new file mode 100644 index 00000000..4c6deff6 --- /dev/null +++ b/RedPandaIDE/widgets/signalmessagedialog.ui @@ -0,0 +1,90 @@ + + + SignalMessageDialog + + + + 0 + 0 + 400 + 240 + + + + Signal Received + + + + + + + 0 + 0 + + + + TextLabel + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + Open CPU Info Dialog + + + true + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + SignalMessageDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + SignalMessageDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + +