implify recent file handling in mainwindow.cpp

The old code used to be unnecessarily complex: the recent files list
was extended for each file and shrunk if a load failed.

By adding a file to the recent file list only if the load succeeded, a
whole method could be removed.

Other changes: keep track of the recent files using a QStringList and
clearly separate the actions:
 - Read recent files from settings [loadRecentFiles()]
 - Write recent files to settings [updateRecentFiles()]
 - Update the recent files actions in the menu [updateRecentFilesMenu()]
 - Add a file to the list of recent files [addRecentFile()]
With this reorganization the code hopefully became more clear.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2017-11-30 11:52:42 +01:00 committed by Lubomir I. Ivanov
parent 625298a7b8
commit 135ea00d88
2 changed files with 49 additions and 134 deletions

View file

@ -201,6 +201,7 @@ MainWindow::MainWindow() : QMainWindow(),
connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), divePlannerWidget(), SLOT(settingsChanged())); connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), divePlannerWidget(), SLOT(settingsChanged()));
connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), divePlannerSettingsWidget(), SLOT(settingsChanged())); connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), divePlannerSettingsWidget(), SLOT(settingsChanged()));
connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), TankInfoModel::instance(), SLOT(update())); connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), TankInfoModel::instance(), SLOT(update()));
// TODO: Make the number of actions depend on NUM_RECENT_FILES
connect(ui.actionRecent1, SIGNAL(triggered(bool)), this, SLOT(recentFileTriggered(bool))); connect(ui.actionRecent1, SIGNAL(triggered(bool)), this, SLOT(recentFileTriggered(bool)));
connect(ui.actionRecent2, SIGNAL(triggered(bool)), this, SLOT(recentFileTriggered(bool))); connect(ui.actionRecent2, SIGNAL(triggered(bool)), this, SLOT(recentFileTriggered(bool)));
connect(ui.actionRecent3, SIGNAL(triggered(bool)), this, SLOT(recentFileTriggered(bool))); connect(ui.actionRecent3, SIGNAL(triggered(bool)), this, SLOT(recentFileTriggered(bool)));
@ -1441,7 +1442,7 @@ void MainWindow::readSettings()
#if !defined(SUBSURFACE_MOBILE) #if !defined(SUBSURFACE_MOBILE)
QSettings s; //TODO: this 's' exists only for the loadRecentFiles, remove it. QSettings s; //TODO: this 's' exists only for the loadRecentFiles, remove it.
loadRecentFiles(&s); loadRecentFiles();
if (firstRun) { if (firstRun) {
checkSurvey(&s); checkSurvey(&s);
firstRun = false; firstRun = false;
@ -1523,49 +1524,32 @@ MainTab *MainWindow::information()
return qobject_cast<MainTab*>(applicationState["Default"].topLeft); return qobject_cast<MainTab*>(applicationState["Default"].topLeft);
} }
void MainWindow::loadRecentFiles(QSettings *s) void MainWindow::loadRecentFiles()
{ {
QStringList files; recentFiles.clear();
bool modified = false; QSettings s;
s.beginGroup("Recent_Files");
s->beginGroup("Recent_Files"); foreach (const QString &key, s.childKeys()) {
for (int c = 1; c <= 4; c++) { // TODO Sorting only correct up to 9 entries. Currently, only 4 used, so no problem.
QString key = QString("File_%1").arg(c); if (!key.startsWith("File_"))
if (s->contains(key)) { continue;
QString file = s->value(key).toString(); QString file = s.value(key).toString();
if (QFile::exists(file))
if (QFile::exists(file)) { recentFiles.append(file);
files.append(file); if (recentFiles.count() > NUM_RECENT_FILES)
} else {
modified = true;
}
} else {
break; break;
}
} }
s.endGroup();
updateRecentFilesMenu();
}
if (modified) { void MainWindow::updateRecentFilesMenu()
for (int c = 0; c < 4; c++) { {
QString key = QString("File_%1").arg(c + 1); for (int c = 0; c < NUM_RECENT_FILES; c++) {
if (files.count() > c) {
s->setValue(key, files.at(c));
} else {
if (s->contains(key)) {
s->remove(key);
}
}
}
s->sync();
}
s->endGroup();
for (int c = 0; c < 4; c++) {
QAction *action = this->findChild<QAction *>(QString("actionRecent%1").arg(c + 1)); QAction *action = this->findChild<QAction *>(QString("actionRecent%1").arg(c + 1));
if (files.count() > c) { if (recentFiles.count() > c) {
QFileInfo fi(files.at(c)); QFileInfo fi(recentFiles.at(c));
action->setText(fi.fileName()); action->setText(fi.fileName());
action->setToolTip(fi.absoluteFilePath()); action->setToolTip(fi.absoluteFilePath());
action->setVisible(true); action->setVisible(true);
@ -1575,99 +1559,32 @@ void MainWindow::loadRecentFiles(QSettings *s)
} }
} }
void MainWindow::addRecentFile(const QStringList &newFiles) void MainWindow::addRecentFile(const QString &file, bool update)
{ {
QStringList files; QString localFile = QDir::toNativeSeparators(file);
QSettings s; int index = recentFiles.indexOf(localFile);
if (index >= 0)
if (newFiles.isEmpty()) recentFiles.removeAt(index);
return; recentFiles.prepend(localFile);
while (recentFiles.count() > NUM_RECENT_FILES)
s.beginGroup("Recent_Files"); recentFiles.removeLast();
if (update)
for (int c = 1; c <= 4; c++) { updateRecentFiles();
QString key = QString("File_%1").arg(c);
if (s.contains(key)) {
QString file = s.value(key).toString();
files.append(file);
} else {
break;
}
}
foreach (const QString &file, newFiles) {
int index = files.indexOf(QDir::toNativeSeparators(file));
if (index >= 0) {
files.removeAt(index);
}
}
foreach (const QString &file, newFiles) {
if (QFile::exists(file)) {
files.prepend(QDir::toNativeSeparators(file));
}
}
while (files.count() > 4) {
files.removeLast();
}
for (int c = 1; c <= 4; c++) {
QString key = QString("File_%1").arg(c);
if (files.count() >= c) {
s.setValue(key, files.at(c - 1));
} else {
if (s.contains(key)) {
s.remove(key);
}
}
}
s.endGroup();
s.sync();
loadRecentFiles(&s);
} }
void MainWindow::removeRecentFile(QStringList failedFiles) void MainWindow::updateRecentFiles()
{ {
QStringList files;
QSettings s; QSettings s;
if (failedFiles.isEmpty())
return;
s.beginGroup("Recent_Files"); s.beginGroup("Recent_Files");
s.remove(""); // Remove all old entries
for (int c = 1; c <= 4; c++) { for (int c = 1; c <= recentFiles.count(); c++) {
QString key = QString("File_%1").arg(c); QString key = QString("File_%1").arg(c);
s.setValue(key, recentFiles.at(c - 1));
if (s.contains(key)) {
QString file = s.value(key).toString();
files.append(file);
} else {
break;
}
} }
foreach (const QString &file, failedFiles)
files.removeAll(file);
for (int c = 1; c <= 4; c++) {
QString key = QString("File_%1").arg(c);
if (files.count() >= c)
s.setValue(key, files.at(c - 1));
else if (s.contains(key))
s.remove(key);
}
s.endGroup(); s.endGroup();
s.sync(); s.sync();
updateRecentFilesMenu();
loadRecentFiles(&s);
} }
void MainWindow::recentFileTriggered(bool checked) void MainWindow::recentFileTriggered(bool checked)
@ -1735,7 +1652,7 @@ int MainWindow::file_save_as(void)
set_filename(filename.toUtf8().data(), true); set_filename(filename.toUtf8().data(), true);
setTitle(MWTF_FILENAME); setTitle(MWTF_FILENAME);
mark_divelist_changed(false); mark_divelist_changed(false);
addRecentFile(QStringList() << filename); addRecentFile(filename, true);
return 0; return 0;
} }
@ -1770,7 +1687,7 @@ int MainWindow::file_save(void)
if (is_cloud) if (is_cloud)
hideProgressBar(); hideProgressBar();
mark_divelist_changed(false); mark_divelist_changed(false);
addRecentFile(QStringList() << QString(existing_filename)); addRecentFile(QString(existing_filename), true);
return 0; return 0;
} }
@ -1873,25 +1790,19 @@ void MainWindow::loadFiles(const QStringList fileNames)
return; return;
} }
QByteArray fileNamePtr; QByteArray fileNamePtr;
QStringList failedParses;
showProgressBar(); showProgressBar();
for (int i = 0; i < fileNames.size(); ++i) { for (int i = 0; i < fileNames.size(); ++i) {
int error;
fileNamePtr = QFile::encodeName(fileNames.at(i)); fileNamePtr = QFile::encodeName(fileNames.at(i));
error = parse_file(fileNamePtr.data()); if (!parse_file(fileNamePtr.data())) {
if (!error) {
set_filename(fileNamePtr.data(), true); set_filename(fileNamePtr.data(), true);
addRecentFile(fileNamePtr, false);
setTitle(MWTF_FILENAME); setTitle(MWTF_FILENAME);
} else {
failedParses.append(fileNames.at(i));
} }
} }
hideProgressBar(); hideProgressBar();
updateRecentFiles();
process_dives(false, false); process_dives(false, false);
addRecentFile(fileNames);
removeRecentFile(failedParses);
refreshDisplay(); refreshDisplay();
ui.actionAutoGroup->setChecked(autogroup); ui.actionAutoGroup->setChecked(autogroup);

View file

@ -19,6 +19,8 @@
#include "core/windowtitleupdate.h" #include "core/windowtitleupdate.h"
#include "core/gpslocation.h" #include "core/gpslocation.h"
#define NUM_RECENT_FILES 4
class QSortFilterProxyModel; class QSortFilterProxyModel;
class DiveTripModel; class DiveTripModel;
class QItemSelection; class QItemSelection;
@ -63,9 +65,10 @@ public:
virtual ~MainWindow(); virtual ~MainWindow();
static MainWindow *instance(); static MainWindow *instance();
MainTab *information(); MainTab *information();
void loadRecentFiles(QSettings *s); void loadRecentFiles();
void addRecentFile(const QStringList &newFiles); void updateRecentFiles();
void removeRecentFile(QStringList failedFiles); void updateRecentFilesMenu();
void addRecentFile(const QString &file, bool update);
DiveListView *dive_list(); DiveListView *dive_list();
DivePlannerWidget *divePlannerWidget(); DivePlannerWidget *divePlannerWidget();
PlannerSettingsWidget *divePlannerSettingsWidget(); PlannerSettingsWidget *divePlannerSettingsWidget();
@ -218,6 +221,7 @@ private:
struct dive copyPasteDive; struct dive copyPasteDive;
struct dive_components what; struct dive_components what;
QList<QAction *> profileToolbarActions; QList<QAction *> profileToolbarActions;
QStringList recentFiles;
struct WidgetForQuadrant { struct WidgetForQuadrant {
WidgetForQuadrant(QWidget *tl = 0, QWidget *tr = 0, QWidget *bl = 0, QWidget *br = 0) : WidgetForQuadrant(QWidget *tl = 0, QWidget *tr = 0, QWidget *bl = 0, QWidget *br = 0) :