diff --git a/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.cpp b/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.cpp index 930f0e87..95c0a4cd 100644 --- a/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.cpp +++ b/DRAMSys/traceAnalyzer/presentation/tracedrawingproperties.cpp @@ -103,6 +103,9 @@ void TraceDrawingProperties::updateTracePlotLines(QTreeWidget *treeWidget) void TraceDrawingProperties::addRankGroup(unsigned int rank) { + if (rank >= numberOfRanks) + return; + std::shared_ptr firstRankLine; for (unsigned int group = groupsPerRank; group--;) diff --git a/DRAMSys/traceAnalyzer/presentation/traceplot.cpp b/DRAMSys/traceAnalyzer/presentation/traceplot.cpp index ac3c18cc..03f96539 100644 --- a/DRAMSys/traceAnalyzer/presentation/traceplot.cpp +++ b/DRAMSys/traceAnalyzer/presentation/traceplot.cpp @@ -416,6 +416,11 @@ void TracePlot::zoomOut(traceTime zoomCenter) (GetCurrentTimespan().Middle() - zoomCenter) / zoomFactor)); } +traceTime TracePlot::ZoomLevel() const +{ + return zoomLevel; +} + void TracePlot::setZoomLevel(traceTime newZoomLevel) { zoomLevel = newZoomLevel; diff --git a/DRAMSys/traceAnalyzer/presentation/traceplot.h b/DRAMSys/traceAnalyzer/presentation/traceplot.h index bea93693..5fff9b23 100644 --- a/DRAMSys/traceAnalyzer/presentation/traceplot.h +++ b/DRAMSys/traceAnalyzer/presentation/traceplot.h @@ -74,17 +74,13 @@ public: TracePlot(QWidget *parent = NULL); void init(TraceNavigator *navigator, QScrollBar *scrollBar, CommentModel *commentModel); Timespan GetCurrentTimespan(); - traceTime ZoomLevel() const - { - return zoomLevel; - } - void setUpActions(); - - void setUpContextMenu(); + traceTime ZoomLevel() const; + void setZoomLevel(traceTime newZoomLevel); CustomLabelScaleDraw *getCustomLabelScaleDraw() const; const TraceDrawingProperties &getDrawingProperties() const; + public Q_SLOTS: void currentTraceTimeChanged(); void selectedTransactionsChanged(); @@ -98,7 +94,6 @@ Q_SIGNALS: void tracePlotZoomChanged(); void tracePlotLinesChanged(); void colorGroupingChanged(ColorGrouping colorgrouping); - // void editComment private Q_SLOTS: void on_executeQuery(); @@ -139,6 +134,9 @@ private: void setUpAxis(); void setUpZoom(); void setUpQueryEditor(); + void setUpActions(); + void setUpContextMenu(); + void connectNavigatorQ_SIGNALS(); void getAndDrawComments(); @@ -156,7 +154,6 @@ private: constexpr static double zoomFactor = 0.8; void zoomIn(traceTime zoomCenter); void zoomOut(traceTime zoomCenter); - void setZoomLevel(traceTime newZoomLevel); void exitZoomMode(); void enterZoomMode(); diff --git a/DRAMSys/traceAnalyzer/presentation/tracescroller.cpp b/DRAMSys/traceAnalyzer/presentation/tracescroller.cpp index 70737a8b..564df655 100644 --- a/DRAMSys/traceAnalyzer/presentation/tracescroller.cpp +++ b/DRAMSys/traceAnalyzer/presentation/tracescroller.cpp @@ -174,7 +174,6 @@ void TraceScroller::getAndDrawComments() } } - /* Q_SLOTS * * diff --git a/DRAMSys/traceAnalyzer/presentation/traceselector.cpp b/DRAMSys/traceAnalyzer/presentation/traceselector.cpp index 9ca682fb..434f7ac2 100644 --- a/DRAMSys/traceAnalyzer/presentation/traceselector.cpp +++ b/DRAMSys/traceAnalyzer/presentation/traceselector.cpp @@ -124,6 +124,29 @@ void TraceSelectedTree::init(unsigned int groupsPerRank, unsigned int banksPerGr this->banksPerGroup = banksPerGroup; } +std::vector TraceSelectedTree::clonedItems() const +{ + std::vector clonedTopLevelItems; + + for (unsigned int i = 0; i < topLevelItemCount(); i++) + { + clonedTopLevelItems.push_back(topLevelItem(i)->clone()); + } + + return clonedTopLevelItems; +} + +void TraceSelectedTree::setItems(const std::vector &items) +{ + for (unsigned int i = topLevelItemCount(); i--;) + takeTopLevelItem(i); + + for (auto item : items) + addTopLevelItem(item); + + emit itemsChanged(); +} + QMimeData *TraceSelectedTree::mimeData(const QList items) const { QByteArray traceLineData; @@ -346,6 +369,16 @@ void TraceSelector::setUpTreeWidget(QTreeWidget *treeWidget) ); } +std::vector TraceSelector::getTraceSelectorState() const +{ + return selectedTree->clonedItems(); +} + +void TraceSelector::restoreTraceSelectorState(const std::vector &items) +{ + selectedTree->setItems(items); +} + TraceSelectorTreeItem *TraceSelectorTreeItem::createRankParentItem(unsigned int rank,unsigned int groupsPerRank, unsigned int banksPerGroup) { @@ -409,3 +442,19 @@ QString TraceSelectorTreeItem::getLabel(unsigned int rank, unsigned int bankgrou { return "RA" + QString::number(rank) + " BG" + QString::number(bankgroup) + " BA" + QString::number(bank); } + +QTreeWidgetItem *TraceSelectorTreeItem::clone() const +{ + TraceSelectorTreeItem *cloned = new TraceSelectorTreeItem(*this); + + std::vector clonedChildren; + for (unsigned int i = 0; i < childCount(); i++) + { + clonedChildren.push_back(static_cast(child(i)->clone())); + } + + for (auto child : clonedChildren) + cloned->addChild(child); + + return cloned; +} diff --git a/DRAMSys/traceAnalyzer/presentation/traceselector.h b/DRAMSys/traceAnalyzer/presentation/traceselector.h index 7d120da2..6a2a9fd3 100644 --- a/DRAMSys/traceAnalyzer/presentation/traceselector.h +++ b/DRAMSys/traceAnalyzer/presentation/traceselector.h @@ -70,6 +70,9 @@ public: explicit TraceSelectedTree(QWidget *parent = nullptr); void init(unsigned int groupsPerRank, unsigned int banksPerGroup); + std::vector clonedItems() const; + void setItems(const std::vector &items); + Q_SIGNALS: void itemsChanged(); @@ -108,6 +111,9 @@ public: static QString getLabel(unsigned int rank, unsigned int bankgroup, unsigned int bank); const unsigned int rank = 0, bankgroup = 0, bank = 0; + +protected: + QTreeWidgetItem *clone() const override; }; class TraceSelector : public QWidget @@ -118,6 +124,9 @@ public: explicit TraceSelector(QWidget *parent = nullptr); void init(TracePlot *traceplot); + std::vector getTraceSelectorState() const; + void restoreTraceSelectorState(const std::vector &items); + signals: void selectedTreeChanged(QTreeWidget *treeWidget); diff --git a/DRAMSys/traceAnalyzer/traceanalyzer.cpp b/DRAMSys/traceAnalyzer/traceanalyzer.cpp index dce1bbc3..d771a4ac 100644 --- a/DRAMSys/traceAnalyzer/traceanalyzer.cpp +++ b/DRAMSys/traceAnalyzer/traceanalyzer.cpp @@ -75,11 +75,10 @@ TraceAnalyzer::TraceAnalyzer(QSet paths, StartupOption option, setUpGui(); for (const QString &path : paths) - openTracefile(path); + openTracefileTab(path); - if (option == StartupOption::runTests) { + if (option == StartupOption::runTests) ui->actionTest->trigger(); - } } TraceAnalyzer::~TraceAnalyzer() @@ -93,24 +92,30 @@ void TraceAnalyzer::on_actionOpen_triggered() tr("Open Tracefile"), "../simulator/", tr("Tracefile (*.tdb)")); - if (paths.isEmpty()) { + if (paths.isEmpty()) return; - } - for (const QString &path : paths) { - openTracefile(path); - } + for (const QString &path : paths) + openTracefileTab(path); } -void TraceAnalyzer::openTracefile(const QString &path) +TraceFileTab *TraceAnalyzer::createTraceFileTab(const QString &path) +{ + TraceFileTab *traceFileTab = new TraceFileTab(this, path); + + connect(traceFileTab, &TraceFileTab::statusChanged, this, &TraceAnalyzer::statusChanged); + + return traceFileTab; +} + +void TraceAnalyzer::openTracefileTab(const QString &path) { if (openedTraceFiles.contains(path)) return; - TraceFileTab *tab = new TraceFileTab(this, path); - connect(tab, SIGNAL(statusChanged(QString, bool)), this, - SLOT(statusChanged(QString, bool))); - ui->traceFileTabs->addTab(tab, QFileInfo(path).baseName()); + TraceFileTab *traceFileTab = createTraceFileTab(path); + + ui->traceFileTabs->addTab(traceFileTab, QFileInfo(path).baseName()); openedTraceFiles.insert(path); statusLabel->clear(); @@ -119,19 +124,23 @@ void TraceAnalyzer::openTracefile(const QString &path) void TraceAnalyzer::on_menuFile_aboutToShow() { ui->actionOpen->setEnabled(true); + ui->actionQuit->setEnabled(true); bool tabsOpen = ui->traceFileTabs->count() > 0; bool exportAsVcdAvailable = PythonCaller::instance().vcdExportDependenciesAvailable(); + ui->actionSave->setEnabled(tabsOpen); + ui->actionSave_all->setEnabled(tabsOpen); + ui->actionReload->setEnabled(tabsOpen); ui->actionReload_all->setEnabled(tabsOpen); - ui->actionSaveChangesToDB->setEnabled(tabsOpen); ui->actionExportAsVCD->setEnabled(tabsOpen && exportAsVcdAvailable); - ui->actionClose_all->setEnabled(tabsOpen); ui->actionTest->setEnabled(tabsOpen); ui->actionMetrics->setEnabled(tabsOpen); + ui->actionClose->setEnabled(tabsOpen); + ui->actionClose_all->setEnabled(tabsOpen); } -void TraceAnalyzer::on_traceFileTabs_tabCloseRequested(int index) +void TraceAnalyzer::closeTab(int index) { TraceFileTab *traceFileTab = static_cast (ui->traceFileTabs->widget(index)); @@ -144,55 +153,76 @@ void TraceAnalyzer::on_traceFileTabs_tabCloseRequested(int index) } } +void TraceAnalyzer::on_traceFileTabs_tabCloseRequested(int index) +{ + closeTab(index); +} + +void TraceAnalyzer::on_actionClose_triggered() +{ + closeTab(ui->traceFileTabs->currentIndex()); +} + void TraceAnalyzer::on_actionClose_all_triggered() { for (unsigned int i = ui->traceFileTabs->count(); i--;) - { - on_traceFileTabs_tabCloseRequested(i); - } + closeTab(i); statusLabel->clear(); } -void TraceAnalyzer::on_actionReload_all_triggered() +void TraceAnalyzer::reloadTab(int index) { - TraceFileTab *traceFileTab; + auto traceFileTab = static_cast(ui->traceFileTabs->widget(index)); - // Remove all tabs - for (unsigned int i = ui->traceFileTabs->count(); i--;) - { - traceFileTab = static_cast(ui->traceFileTabs->widget(0)); - std::cout << "Closing tab #" << i << " \"" << traceFileTab->getPathToTraceFile().toStdString() << "\"" - << std::endl; + QString traceFile = traceFileTab->getPathToTraceFile(); + traceTime time = traceFileTab->getCurrentTraceTime(); + traceTime zoomLevel = traceFileTab->getZoomLevel(); + auto treeItems = traceFileTab->saveTraceSelectorState(); - if (!traceFileTab->close()) - return; + if (!traceFileTab->close()) + return; - ui->traceFileTabs->removeTab(0); - delete traceFileTab; - } + ui->traceFileTabs->removeTab(index); + delete traceFileTab; - QList list = openedTraceFiles.values(); - std::sort(list.begin(), list.end()); + traceFileTab = createTraceFileTab(traceFile); + traceFileTab->setZoomLevel(zoomLevel); + traceFileTab->navigateToTime(time); + traceFileTab->restoreTraceSelectorState(treeItems); - // Recreate all tabs - int tabIndex = 0; - for (auto path : list) { - std::cout << "Reopening tab# " << tabIndex << " \"" << path.toStdString() << - "\"" << std::endl; - - traceFileTab = new TraceFileTab(this, path); - connect(traceFileTab, SIGNAL(statusChanged(QString, bool)), this, - SLOT(statusChanged(QString, bool))); - ui->traceFileTabs->addTab(traceFileTab, QFileInfo(path).baseName()); - - tabIndex++; - } - - this->statusChanged(QString("All databases reloaded "), true); + ui->traceFileTabs->insertTab(index, traceFileTab, QFileInfo(traceFile).baseName()); + ui->traceFileTabs->setCurrentIndex(index); } -void TraceAnalyzer::on_actionSaveChangesToDB_triggered() +void TraceAnalyzer::on_actionReload_triggered() +{ + int index = ui->traceFileTabs->currentIndex(); + reloadTab(index); + this->statusChanged(QString("Reloaded tab ") + QString::number(index) + " "); +} + +void TraceAnalyzer::on_actionReload_all_triggered() +{ + int index = ui->traceFileTabs->currentIndex(); + + for (unsigned int i = ui->traceFileTabs->count(); i--;) + reloadTab(i); + + ui->traceFileTabs->setCurrentIndex(index); + + this->statusChanged(QString("All databases reloaded ")); +} + +void TraceAnalyzer::on_actionSave_triggered() +{ + auto traceFileTab = static_cast(ui->traceFileTabs->currentWidget()); + traceFileTab->commitChangesToDB(); + + this->statusChanged(QString("Saved database ") + QFileInfo(traceFileTab->getPathToTraceFile()).baseName() + " "); +} + +void TraceAnalyzer::on_actionSave_all_triggered() { for (int index = 0; index < ui->traceFileTabs->count(); index++) { // Changes in the database files will trigger the file watchers from @@ -209,10 +239,9 @@ void TraceAnalyzer::on_actionExportAsVCD_triggered() traceFileTab->exportAsVCD(); } -void TraceAnalyzer::statusChanged(QString message, bool saveChangesEnable) +void TraceAnalyzer::statusChanged(const QString &message) { statusLabel->setText(message + QTime::currentTime().toString()); - ui->actionSaveChangesToDB->setEnabled(saveChangesEnable); } void TraceAnalyzer::on_actionTest_triggered() diff --git a/DRAMSys/traceAnalyzer/traceanalyzer.h b/DRAMSys/traceAnalyzer/traceanalyzer.h index e6916862..aba70321 100644 --- a/DRAMSys/traceAnalyzer/traceanalyzer.h +++ b/DRAMSys/traceAnalyzer/traceanalyzer.h @@ -33,6 +33,7 @@ * Janik Schlemminger * Robert Gernhardt * Matthias Jung + * Derek Christ */ #ifndef TRACEANALYZER_H @@ -52,6 +53,8 @@ class TraceAnalyzer; enum class StartupOption {showPlots, runTests}; enum class OpenOptions {files, folders}; +class TraceFileTab; + class TraceAnalyzer : public QMainWindow { Q_OBJECT @@ -71,7 +74,11 @@ protected: void closeEvent(QCloseEvent *event) override; private: - void openTracefile(const QString &path); + TraceFileTab *createTraceFileTab(const QString &path); + void openTracefileTab(const QString &path); + void reloadTab(int index); + void closeTab(int index); + QLabel *statusLabel; QSet openedTraceFiles; @@ -80,15 +87,18 @@ private Q_SLOTS: void on_traceFileTabs_tabCloseRequested(int index); void on_actionOpen_triggered(); + void on_actionSave_triggered(); + void on_actionSave_all_triggered(); + void on_actionReload_triggered(); void on_actionReload_all_triggered(); - void on_actionSaveChangesToDB_triggered(); void on_actionExportAsVCD_triggered(); - void on_actionClose_all_triggered(); void on_actionTest_triggered(); void on_actionMetrics_triggered(); + void on_actionClose_triggered(); + void on_actionClose_all_triggered(); public Q_SLOTS: - void statusChanged(QString message, bool saveChangesEnable = false); + void statusChanged(const QString &message); private: Ui::TraceAnalyzer *ui; diff --git a/DRAMSys/traceAnalyzer/traceanalyzer.ui b/DRAMSys/traceAnalyzer/traceanalyzer.ui index 6a364223..470140dc 100644 --- a/DRAMSys/traceAnalyzer/traceanalyzer.ui +++ b/DRAMSys/traceAnalyzer/traceanalyzer.ui @@ -54,20 +54,27 @@ - File + &File + + + - + - + + + + + - Help + &Help @@ -77,54 +84,57 @@ + + + ../../../../.designer/backup../../../../.designer/backup + - Open + &Open... Ctrl+O - - - false + + + + ../../../../.designer/backup../../../../.designer/backup - Reload databases + &Reload Ctrl+R - - - false + + + + ../../../../.designer/backup../../../../.designer/backup - Save changes to DB + &Save Ctrl+S - - false - - Close all + C&lose all - Ctrl+Q + Ctrl+Shift+W - Info + &Info - About + &About @@ -136,39 +146,104 @@ - - false - - Test + &Test Ctrl+T - - false - - Metrics + &Metrics Ctrl+M - - false + + + ../../../../.designer/backup../../../../.designer/backup - Export as VCD + Export as &VCD... - Ctrl+E + Ctrl+V + + + + + + ../../../../.designer/backup../../../../.designer/backup + + + &Close + + + Ctrl+W + + + + + R&eload all + + + Ctrl+Shift+R + + + + + + ../../../../.designer/backup../../../../.designer/backup + + + &Quit + + + Ctrl+Q + + + + + + .. + + + Save &all + + + Ctrl+Shift+S + + + + + + .. + + + Save &as... - + + + actionQuit + triggered() + TraceAnalyzer + close() + + + -1 + -1 + + + 399 + 299 + + + + diff --git a/DRAMSys/traceAnalyzer/tracefiletab.cpp b/DRAMSys/traceAnalyzer/tracefiletab.cpp index ce8132fb..e6368c31 100644 --- a/DRAMSys/traceAnalyzer/tracefiletab.cpp +++ b/DRAMSys/traceAnalyzer/tracefiletab.cpp @@ -150,7 +150,7 @@ void TraceFileTab::setUpFileWatcher(QString path) void TraceFileTab::setUpTraceSelector() { - TraceSelector *selector = ui->tabCustomizePlot; + TraceSelector *selector = static_cast(ui->tabCustomizePlot); connect(selector, &TraceSelector::selectedTreeChanged, ui->traceplot, &TracePlot::updateTracePlotLines); selector->init(ui->traceplot); @@ -184,14 +184,13 @@ void TraceFileTab::tracefileChanged() // Database has changed due to user action (e.g., saving comments). // No need to disable the "Save changes to DB" menu. savingChangesToDB = false; - Q_EMIT statusChanged(QString("Changes saved "), true); + Q_EMIT statusChanged(QString("Changes saved ")); } else { // External event changed the database file (e.g., the database file // was overwritten when running a new test). // The "Save changes to DB" menu must be disabled to avoid saving // changes to a corrupted or inconsistent file. - Q_EMIT statusChanged(QString("At least one database has changed on disk "), - false); + Q_EMIT statusChanged(QString("At least one database has changed on disk ")); } navigator->refreshData(); } @@ -227,6 +226,42 @@ void TraceFileTab::closeEvent(QCloseEvent *event) event->accept(); } +traceTime TraceFileTab::getCurrentTraceTime() const +{ + return navigator->CurrentTraceTime(); +} + +void TraceFileTab::navigateToTime(traceTime time) +{ + navigator->navigateToTime(time); +} + +traceTime TraceFileTab::getZoomLevel() const +{ + TracePlot *traceplot = static_cast(ui->traceplot); + return traceplot->ZoomLevel(); +} + +void TraceFileTab::setZoomLevel(traceTime zoomLevel) +{ + TracePlot *traceplot = static_cast(ui->traceplot); + TraceScroller *tracescroller = static_cast(ui->traceScroller); + traceplot->setZoomLevel(zoomLevel); + tracescroller->tracePlotZoomChanged(); +} + +std::vector TraceFileTab::saveTraceSelectorState() const +{ + TraceSelector *selector = static_cast(ui->tabCustomizePlot); + return selector->getTraceSelectorState(); +} + +void TraceFileTab::restoreTraceSelectorState(const std::vector &items) +{ + TraceSelector *selector = static_cast(ui->tabCustomizePlot); + selector->restoreTraceSelectorState(items); +} + class ItemDelegate: public QItemDelegate { public: diff --git a/DRAMSys/traceAnalyzer/tracefiletab.h b/DRAMSys/traceAnalyzer/tracefiletab.h index ab2425b6..fb4c9392 100644 --- a/DRAMSys/traceAnalyzer/tracefiletab.h +++ b/DRAMSys/traceAnalyzer/tracefiletab.h @@ -73,6 +73,14 @@ public: void commitChangesToDB(void); void exportAsVCD(); + traceTime getCurrentTraceTime() const; + void navigateToTime(traceTime time); + traceTime getZoomLevel() const; + void setZoomLevel(traceTime zoomLevel); + + std::vector saveTraceSelectorState() const; + void restoreTraceSelectorState(const std::vector &items); + protected: void closeEvent(QCloseEvent *event) override; @@ -94,7 +102,7 @@ public Q_SLOTS: void tracefileChanged(); Q_SIGNALS: - void statusChanged(QString message, bool saveChangesEnable = false); + void statusChanged(const QString &message); void colorGroupingChanged(ColorGrouping colorgrouping); private Q_SLOTS: