From 2ccfc4abf5b3d29870f3f19457950d43f16759d5 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Tue, 14 Sep 2021 19:17:34 +0200 Subject: [PATCH] Introduce QMessageBox that asks the user to save a changed TraceFile The TraceAnalyzer now asks the user to save the changed TraceFile (eg. modified comments, etc.) when closing the tab. --- .../presentation/tracenavigator.cpp | 13 +++ .../presentation/tracenavigator.h | 5 ++ DRAMSys/traceAnalyzer/traceanalyzer.cpp | 53 ++++++++---- DRAMSys/traceAnalyzer/traceanalyzer.h | 3 + DRAMSys/traceAnalyzer/tracefiletab.cpp | 82 +++++++++++++------ DRAMSys/traceAnalyzer/tracefiletab.h | 8 +- 6 files changed, 121 insertions(+), 43 deletions(-) diff --git a/DRAMSys/traceAnalyzer/presentation/tracenavigator.cpp b/DRAMSys/traceAnalyzer/presentation/tracenavigator.cpp index 47ef74cf..f5ab5a0b 100644 --- a/DRAMSys/traceAnalyzer/presentation/tracenavigator.cpp +++ b/DRAMSys/traceAnalyzer/presentation/tracenavigator.cpp @@ -54,6 +54,9 @@ TraceNavigator::TraceNavigator(QString path, CommentModel *commentModel, QObject navigateToTime(commentModel->getTimeFromIndex(index)); }); + QObject::connect(commentModel, &CommentModel::dataChanged, this, &TraceNavigator::traceFileModified); + QObject::connect(commentModel, &CommentModel::rowsRemoved, this, &TraceNavigator::traceFileModified); + tracePlotLineCache = std::make_shared(getTracePlotLines(), GeneralTraceInfo().numberOfRanks, GeneralTraceInfo().groupsPerRank, GeneralTraceInfo().banksPerGroup); @@ -317,3 +320,13 @@ const CommentModel *TraceNavigator::getCommentModel() const { return commentModel; } + +bool TraceNavigator::existChangesToCommit() const +{ + return changesToCommitExist; +} + +void TraceNavigator::traceFileModified() +{ + changesToCommitExist = true; +} diff --git a/DRAMSys/traceAnalyzer/presentation/tracenavigator.h b/DRAMSys/traceAnalyzer/presentation/tracenavigator.h index d72e1f52..f8a89bf1 100644 --- a/DRAMSys/traceAnalyzer/presentation/tracenavigator.h +++ b/DRAMSys/traceAnalyzer/presentation/tracenavigator.h @@ -118,10 +118,15 @@ public: const CommentModel *getCommentModel() const; + bool existChangesToCommit() const; + Q_SIGNALS: void currentTraceTimeChanged(); void selectedTransactionsChanged(); +public Q_SLOTS: + void traceFileModified(); + private: TraceDB traceFile; diff --git a/DRAMSys/traceAnalyzer/traceanalyzer.cpp b/DRAMSys/traceAnalyzer/traceanalyzer.cpp index 02103ce7..0a3454fb 100644 --- a/DRAMSys/traceAnalyzer/traceanalyzer.cpp +++ b/DRAMSys/traceAnalyzer/traceanalyzer.cpp @@ -37,12 +37,13 @@ */ #include "traceanalyzer.h" -#include "ui_traceanalyzer.h" +#include "QMessageBox" #include "tracefiletab.h" +#include "ui_traceanalyzer.h" +#include +#include #include #include -#include -#include "QMessageBox" #include void TraceAnalyzer::setUpStatusBar() @@ -137,15 +138,21 @@ void TraceAnalyzer::on_traceFileTabs_tabCloseRequested(int index) { TraceFileTab *traceFileTab = static_cast (ui->traceFileTabs->widget(index)); - openedTraceFiles.remove(traceFileTab->getPathToTraceFile()); - ui->traceFileTabs->removeTab(index); - delete traceFileTab; + + if (traceFileTab->close()) + { + openedTraceFiles.remove(traceFileTab->getPathToTraceFile()); + ui->traceFileTabs->removeTab(index); + delete traceFileTab; + } } void TraceAnalyzer::on_actionClose_all_triggered() { - while (ui->traceFileTabs->count()) - on_traceFileTabs_tabCloseRequested(0); + for (unsigned int i = ui->traceFileTabs->count(); i--;) + { + on_traceFileTabs_tabCloseRequested(i); + } // All files closed. Disable actions except for "Open". ui->actionReload_all->setEnabled(false); @@ -163,23 +170,24 @@ void TraceAnalyzer::on_actionReload_all_triggered() TraceFileTab *traceFileTab; // Remove all tabs - int tabIndex = 0; - while (ui->traceFileTabs->count() != 0) { + for (unsigned int i = ui->traceFileTabs->count(); i--;) + { traceFileTab = static_cast(ui->traceFileTabs->widget(0)); - std::cout << "Closing tab #" << tabIndex << " \"" << - traceFileTab->getPathToTraceFile().toStdString() << "\"" << std::endl; + std::cout << "Closing tab #" << i << " \"" << traceFileTab->getPathToTraceFile().toStdString() << "\"" + << std::endl; + + if (!traceFileTab->close()) + return; ui->traceFileTabs->removeTab(0); delete traceFileTab; - - tabIndex++; } QList list = openedTraceFiles.toList(); qSort(list); // Recreate all tabs - tabIndex = 0; + int tabIndex = 0; for (auto path : list) { std::cout << "Reopening tab# " << tabIndex << " \"" << path.toStdString() << "\"" << std::endl; @@ -231,3 +239,18 @@ void TraceAnalyzer::on_actionMetrics_triggered() evaluationTool.activateWindow(); evaluationTool.showAndEvaluateMetrics(openedTraceFiles.toList()); } + +void TraceAnalyzer::closeEvent(QCloseEvent *event) +{ + for (unsigned int i = 0; i < ui->traceFileTabs->count(); i++) + { + QWidget *tab = ui->traceFileTabs->widget(i); + if (!tab->close()) + { + event->ignore(); + return; + } + } + + event->accept(); +} diff --git a/DRAMSys/traceAnalyzer/traceanalyzer.h b/DRAMSys/traceAnalyzer/traceanalyzer.h index f28ae7e2..cfcf9e58 100644 --- a/DRAMSys/traceAnalyzer/traceanalyzer.h +++ b/DRAMSys/traceAnalyzer/traceanalyzer.h @@ -67,6 +67,9 @@ public: void setUpStatusBar(); void setUpGui(); +protected: + void closeEvent(QCloseEvent *event) override; + private: void openTracefile(const QString &path); QLabel *statusLabel; diff --git a/DRAMSys/traceAnalyzer/tracefiletab.cpp b/DRAMSys/traceAnalyzer/tracefiletab.cpp index 324a1a2a..db6d3f62 100644 --- a/DRAMSys/traceAnalyzer/tracefiletab.cpp +++ b/DRAMSys/traceAnalyzer/tracefiletab.cpp @@ -37,38 +37,37 @@ */ #include "tracefiletab.h" -#include "ui_tracefiletab.h" -#include "queryeditor.h" #include "QFileInfo" -#include "qmessagebox.h" +#include "businessObjects/commentmodel.h" +#include "businessObjects/configmodels.h" #include "businessObjects/pythoncaller.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include "qwt_plot_histogram.h" -#include "qwt_plot_curve.h" -#include "qwt_plot_layout.h" -#include "qwt_scale_draw.h" -#include "qwt_scale_widget.h" +#include "presentation/traceselector.h" +#include "qmessagebox.h" +#include "queryeditor.h" #include "qwt_legend.h" +#include "qwt_plot_curve.h" +#include "qwt_plot_histogram.h" +#include "qwt_plot_layout.h" #include "qwt_plot_magnifier.h" #include "qwt_plot_panner.h" -#include "presentation/traceselector.h" -#include "businessObjects/configmodels.h" -#include "businessObjects/commentmodel.h" +#include "qwt_scale_draw.h" +#include "qwt_scale_widget.h" +#include "ui_tracefiletab.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include - -TraceFileTab::TraceFileTab(QWidget *parent, const QString &path) : - QWidget(parent), ui(new Ui::TraceFileTab), navigator(new TraceNavigator(path, this)), - mcConfigModel(new McConfigModel(navigator->TraceFile(), this)), - memSpecModel(new MemSpecModel(navigator->TraceFile(), this)), - commentModel(new CommentModel(this)), savingChangesToDB(false) +TraceFileTab::TraceFileTab(QWidget *parent, const QString &path) + : QWidget(parent), ui(new Ui::TraceFileTab), commentModel(new CommentModel(this)), + navigator(new TraceNavigator(path, commentModel, this)), + mcConfigModel(new McConfigModel(navigator->TraceFile(), this)), + memSpecModel(new MemSpecModel(navigator->TraceFile(), this)), savingChangesToDB(false) { ui->setupUi(this); this->path = path; @@ -199,6 +198,37 @@ void TraceFileTab::tracefileChanged() navigator->refreshData(); } +void TraceFileTab::closeEvent(QCloseEvent *event) +{ + if (navigator->existChangesToCommit()) + { + QMessageBox saveDialog; + saveDialog.setWindowTitle(QFileInfo(path).baseName()); + saveDialog.setText("The trace file has been modified."); + saveDialog.setInformativeText("Do you want to save your changes?
Unsaved changes will be lost."); + saveDialog.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); + saveDialog.setDefaultButton(QMessageBox::Save); + saveDialog.setIcon(QMessageBox::Warning); + int returnCode = saveDialog.exec(); + + switch (returnCode) + { + case QMessageBox::Cancel: + event->ignore(); + break; + case QMessageBox::Discard: + event->accept(); + break; + case QMessageBox::Save: + commitChangesToDB(); + event->accept(); + break; + }; + } + else + event->accept(); +} + class ItemDelegate: public QItemDelegate { public: diff --git a/DRAMSys/traceAnalyzer/tracefiletab.h b/DRAMSys/traceAnalyzer/tracefiletab.h index 58329853..1962088d 100644 --- a/DRAMSys/traceAnalyzer/tracefiletab.h +++ b/DRAMSys/traceAnalyzer/tracefiletab.h @@ -73,15 +73,19 @@ public: void commitChangesToDB(void); void exportAsVCD(); +protected: + void closeEvent(QCloseEvent *event) override; + private: QString path; Ui::TraceFileTab *ui; - TraceNavigator *navigator; QFileSystemWatcher *fileWatcher; + CommentModel *commentModel; + TraceNavigator *navigator; + QAbstractItemModel *mcConfigModel; QAbstractItemModel *memSpecModel; - CommentModel *commentModel; void setUpQueryEditor(QString path); bool savingChangesToDB;