Implemented a new menu option to reload databases (issue#46).

Other improvements:
- Added option to save changes to databases (e.g., save comments).

- When a database file changes on disk (overwritten by a rerun of DRAMSys or
  changed by any external agent) the action save changes to DB is disabled,
  since it is not safe anymore.

- Implemented menu options coherence. All actions except for "Open" (reload,
  close, save, test and metrics) remain disabled until some database file is
  open.

- Created a shortcut to close all: CTRL+Q

- Status messages containing a timestamp are displayed in the lower left
  corner of the traceAnalyzer window when:
  - User reloads the databases.
  - User saves changes to the databases.
  - Any of the open database files has changed on disk.
This commit is contained in:
Éder F. Zulian
2016-02-09 16:21:43 -02:00
parent 8601c8f28b
commit b09aced9ed
6 changed files with 134 additions and 23 deletions

View File

@@ -52,10 +52,18 @@
using namespace std;
TraceDB::TraceDB(QString path,bool openExisting)
TraceDB::TraceDB(QString path, bool openExisting)
{
this->pathToDB = path;
database = QSqlDatabase::addDatabase("QSQLITE",path);
database = QSqlDatabase::database(path);
if (database.isValid() && database.isOpen()) {
// Close the database connection if it exists and was not closed yet.
database.removeDatabase(path);
database.close();
}
database = QSqlDatabase::addDatabase("QSQLITE", path);
database.setDatabaseName(path);
database.open();
if(!openExisting)

View File

@@ -63,9 +63,14 @@ TraceAnalyzer::TraceAnalyzer(QWidget *parent) :
ui(new Ui::TraceAnalyzer)
{
setUpGui();
// Disable actions except for "Open" until some file is open.
ui->actionReload_all->setEnabled(false);
ui->actionSaveChangesToDB->setEnabled(false);
ui->actionClose_all->setEnabled(false);
ui->actionTest->setEnabled(false);
ui->actionMetrics->setEnabled(false);
}
TraceAnalyzer::TraceAnalyzer(QSet<QString> paths, StartupOption option, QWidget *parent):
QMainWindow(parent),
ui(new Ui::TraceAnalyzer)
@@ -104,9 +109,18 @@ void TraceAnalyzer::openTracefile(const QString &path)
return;
TraceFileTab* tab = new TraceFileTab(this, path);
connect(tab, SIGNAL(statusChanged(QString)), this, SLOT(statusChanged(QString)));
connect(tab, SIGNAL(statusChanged(QString, bool)), this, SLOT(statusChanged(QString, bool)));
ui->traceFileTabs->addTab(tab,QFileInfo(path).baseName());
openedTraceFiles.insert(path);
// Enable actions
ui->actionReload_all->setEnabled(true);
ui->actionSaveChangesToDB->setEnabled(true);
ui->actionClose_all->setEnabled(true);
ui->actionTest->setEnabled(true);
ui->actionMetrics->setEnabled(true);
statusLabel->clear();
}
void TraceAnalyzer::on_traceFileTabs_tabCloseRequested(int index)
@@ -121,13 +135,65 @@ void TraceAnalyzer::on_actionClose_all_triggered()
{
while(ui->traceFileTabs->count())
on_traceFileTabs_tabCloseRequested(0);
// All files closed. Disable actions except for "Open".
ui->actionReload_all->setEnabled(false);
ui->actionSaveChangesToDB->setEnabled(false);
ui->actionClose_all->setEnabled(false);
ui->actionTest->setEnabled(false);
ui->actionMetrics->setEnabled(false);
statusLabel->clear();
}
void TraceAnalyzer::statusChanged(QString message)
void TraceAnalyzer::on_actionReload_all_triggered()
{
statusLabel->setText(message + " - (" + QTime::currentTime().toString() + ")");
TraceFileTab *traceFileTab;
// Remove all tabs
int tabIndex = 0;
while (ui->traceFileTabs->count() != 0) {
traceFileTab = static_cast<TraceFileTab*>(ui->traceFileTabs->widget(0));
std::cout << "Closing tab #" << tabIndex << " \"" << traceFileTab->getPathToTraceFile().toStdString() << "\"" << std::endl;
ui->traceFileTabs->removeTab(0);
delete traceFileTab;
tabIndex++;
}
QList<QString> list = openedTraceFiles.toList();
qSort(list);
// Recreate all tabs
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);
}
void TraceAnalyzer::on_actionSaveChangesToDB_triggered()
{
for (int index = 0; index < ui->traceFileTabs->count(); index++) {
// Changes in the database files will trigger the file watchers from
// the TraceFileTab class. They generate signals connected to TraceAnalyzer::statusChanged().
TraceFileTab *traceFileTab = static_cast<TraceFileTab *>(ui->traceFileTabs->widget(index));
traceFileTab->commitChangesToDB();
}
}
void TraceAnalyzer::statusChanged(QString message, bool saveChangesEnable)
{
statusLabel->setText(message + QTime::currentTime().toString());
ui->actionSaveChangesToDB->setEnabled(saveChangesEnable);
}
void TraceAnalyzer::on_actionTest_triggered()
@@ -142,5 +208,5 @@ void TraceAnalyzer::on_actionMetrics_triggered()
evaluationTool.raise();
evaluationTool.activateWindow();
evaluationTool.showAndEvaluateMetrics(openedTraceFiles.toList());
}

View File

@@ -73,6 +73,8 @@ private:
private Q_SLOTS:
void on_actionOpen_triggered();
void on_actionReload_all_triggered();
void on_actionSaveChangesToDB_triggered();
void on_traceFileTabs_tabCloseRequested(int index);
void on_actionClose_all_triggered();
void on_actionTest_triggered();
@@ -80,10 +82,11 @@ private Q_SLOTS:
void on_actionMetrics_triggered();
public Q_SLOTS:
void statusChanged(QString message);
void statusChanged(QString message, bool saveChangesEnable = false);
private:
Ui::TraceAnalyzer *ui;
};
#endif // TRACEANALYZER_H

View File

@@ -57,6 +57,8 @@
<string>File</string>
</property>
<addaction name="actionOpen"/>
<addaction name="actionReload_all"/>
<addaction name="actionSaveChangesToDB"/>
<addaction name="actionClose_all"/>
<addaction name="separator"/>
<addaction name="actionTest"/>
@@ -81,10 +83,29 @@
<string>Ctrl+O</string>
</property>
</action>
<action name="actionReload_all">
<property name="text">
<string>Reload databases</string>
</property>
<property name="shortcut">
<string>CTRL+R</string>
</property>
</action>
<action name="actionSaveChangesToDB">
<property name="text">
<string>Save changes to DB</string>
</property>
<property name="shortcut">
<string>CTRL+S</string>
</property>
</action>
<action name="actionClose_all">
<property name="text">
<string>Close all</string>
</property>
<property name="shortcut">
<string>CTRL+Q</string>
</property>
</action>
<action name="actionInfo">
<property name="text">

View File

@@ -41,14 +41,15 @@
#include "QFileInfo"
#include "qmessagebox.h"
#include <iostream>
#include <iostream>
TraceFileTab::TraceFileTab(QWidget *parent,const QString& path) :
QWidget(parent),
ui(new Ui::TraceFileTab)
QWidget(parent), ui(new Ui::TraceFileTab), savingChangesToDB(false)
{
ui->setupUi(this);
this->path = path;
std::cout << "Opening new tab for \"" << path.toStdString() << "\"" << std::endl;
initNavigatorAndItsDependentWidgets(path);
setUpFileWatcher(path);
ui->fileDescriptionEdit->setPlainText(navigator->GeneralTraceInfo().description);
@@ -57,10 +58,15 @@ TraceFileTab::TraceFileTab(QWidget *parent,const QString& path) :
TraceFileTab::~TraceFileTab()
{
navigator->commitChangesToDB();
delete ui;
}
void TraceFileTab::commitChangesToDB()
{
savingChangesToDB = true;
navigator->commitChangesToDB();
}
void TraceFileTab::initNavigatorAndItsDependentWidgets(QString path)
{
navigator = new TraceNavigator(path,this);
@@ -82,15 +88,20 @@ void TraceFileTab::setUpFileWatcher(QString path)
QObject::connect(fileWatcher,SIGNAL(fileChanged(QString)),this,SLOT(tracefileChanged()));
}
void TraceFileTab::tracefileChanged()
{
Q_EMIT statusChanged(QString("Last Database Refresh"));
if (savingChangesToDB == true) {
// 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);
} 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);
}
navigator->refreshData();
}

View File

@@ -60,6 +60,7 @@ public:
void setUpFileWatcher(QString filename);
void initNavigatorAndItsDependentWidgets(QString path);
QString getPathToTraceFile(){return path;}
void commitChangesToDB(void);
private:
QString path;
@@ -67,14 +68,15 @@ private:
TraceNavigator *navigator;
QFileSystemWatcher *fileWatcher;
void setUpQueryEditor(QString path);
bool savingChangesToDB;
public Q_SLOTS:
void tracefileChanged();
Q_SIGNALS:
void statusChanged(QString);
void statusChanged(QString message, bool saveChangesEnable = false);
void colorGroupingChanged(ColorGrouping colorgrouping);
};
#endif // TRACEFILETAB_H