aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--src/mainwindow.cpp28
-rw-r--r--src/mainwindow.h3
-rw-r--r--src/recent_files.cpp70
-rw-r--r--src/recent_files.h54
-rw-r--r--src/settings_interface.cpp2
-rw-r--r--src/widgets/tab_welcome.cpp8
-rw-r--r--src/widgets/tab_welcome.h9
8 files changed, 160 insertions, 16 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 55418ef..67f1399 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -59,6 +59,8 @@ set(PROJECT_SOURCES
src/aboutdialog.ui
src/settings_interface.cpp
src/settings_interface.h
+ src/recent_files.cpp
+ src/recent_files.h
src/widgets/status_info.cpp
src/widgets/status_info.h
src/widgets/status_info.ui
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 89351ae..58fb991 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -2,6 +2,7 @@
#include "./ui_mainwindow.h"
#include "src/archive/base_archive.h"
#include "src/command_line.h"
+#include "src/recent_files.h"
#include "src/settingsdialog.h"
#include "src/aboutdialog.h"
#include "src/widgets/tab_activity_list.h"
@@ -17,6 +18,15 @@ MainWindow::MainWindow(QWidget *parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
+
+ recent_files_menu = recent_files.create_menu(tr("Recent files…"));
+ ui->menuFile->insertMenu(ui->actionSettings, recent_files_menu.get());
+ connect(recent_files_menu.get(), &QMenu::triggered, this, [&](QAction* action) {
+ // Needed for interepreting a QAction as a RecentFiles::Action so that we can retrieve the file_path and open it
+ if (auto* ac = qobject_cast<RecentFiles::Action*>(action); ac)
+ this->open_file(ac->file_path);
+ });
+
create_initial_tabs();
connect(&archive_thread_watcher, &QFutureWatcher<Archive::InitError>::finished, this, &MainWindow::archive_thread_watcher_done);
}
@@ -27,11 +37,9 @@ MainWindow::~MainWindow()
}
void MainWindow::create_initial_tabs() {
- welcome_tab = new TabWelcome();
+ welcome_tab = new TabWelcome(recent_files_menu);
ui->tabWidget->addTab(welcome_tab, tr("Welcome"));
connect(welcome_tab, &TabWelcome::show_file_open_dialog, this, &MainWindow::on_actionOpen_triggered);
- // TODO: recent files
- //connect(welcome_tab, &TabWelcome::show_recent_files, this, &MainWindow::);
activity_list_tab = new TabActivityList(&data_archive);
ui->tabWidget->addTab(activity_list_tab, tr("Activity List"));
@@ -101,12 +109,6 @@ void MainWindow::on_actionOpen_triggered() {
if (fileDialog.exec()) {
QStringList files = fileDialog.selectedFiles();
open_file(files[0]);
-
- // Close the welcome tab as it's not needed anymore
- if (welcome_tab) {
- welcome_tab->deleteLater();
- welcome_tab = nullptr;
- }
}
}
@@ -137,12 +139,20 @@ void MainWindow::on_actionAbout_triggered(bool checked) {
}
void MainWindow::open_file(const QString &filename) {
+ // Close the welcome tab as it's not needed anymore
+ // Done here as this method is directly called when opening a recent file
+ if (welcome_tab) {
+ welcome_tab->deleteLater();
+ welcome_tab = nullptr;
+ }
+
if (data_archive) {
delete data_archive;
data_archive = nullptr;
}
open_file_filename = filename;
+ recent_files.add_file(filename);
// BUG: the overwritten cursor seems to get "lost" and revert in moc_mainwindow.cpp (after the end of the function we're in) when opening a file through a file dialog.
// The cursor behaves properly when opening a file throught the command line.
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 03daaad..68ecf18 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -8,6 +8,7 @@
#include "archive/base_archive.h"
#include "src/list_item.h"
#include "src/settingsdialog.h"
+#include "src/recent_files.h"
#include "src/widgets/tab_activity_list.h"
#include "src/widgets/tab_actor_info.h"
#include "src/widgets/tab_welcome.h"
@@ -58,6 +59,8 @@ private:
TabActorInfo* actor_info_tab = nullptr;
QString open_file_filename;
+ RecentFiles recent_files;
+ RecentFiles::QMenuPtr recent_files_menu;
Ui::MainWindow *ui;
diff --git a/src/recent_files.cpp b/src/recent_files.cpp
new file mode 100644
index 0000000..2382f1a
--- /dev/null
+++ b/src/recent_files.cpp
@@ -0,0 +1,70 @@
+#include "recent_files.h"
+#include <QFileInfo>
+
+RecentFiles::RecentFiles(unsigned int size, bool force_empty) : size(size) {
+ if (not force_empty)
+ list = settings_interface.read_setting("ui/recent_files").value<QStringList>();
+}
+
+RecentFiles::~RecentFiles() {
+ if (has_list_changed) {
+ settings_interface.write_setting("ui/recent_files", list);
+ settings_interface.commit();
+ }
+}
+
+RecentFiles::QMenuPtr RecentFiles::create_menu(const QString& title, QWidget* parent) {
+ if (menu) return menu;
+
+ menu = std::make_shared<QMenu>(title, parent);
+ generate_menu_actions();
+
+ return menu;
+}
+
+void RecentFiles::generate_menu_actions() {
+ menu->clear();
+
+ if (not list.isEmpty()) {
+ int i = 1;
+ for (const QString& path : list) {
+ Action* action = new Action(QStringLiteral("&%1. %2").arg(i++).arg(QFileInfo(path).fileName()));
+ action->file_path = path;
+ menu->addAction(action);
+ }
+ } else {
+ Action* action = new Action(QWidget::tr("No recent files"));
+ action->setStatusTip(QWidget::tr("To view recent files, open a file"));
+ action->setEnabled(false);
+ menu->addAction(action);
+ }
+}
+
+void RecentFiles::add_file(const QString& path) {
+ if (not list.contains(path)) {
+ list.prepend(path);
+ if (list.size() > size)
+#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
+ list.resize(size);
+#else
+ do list.removeLast();
+ while (list.size() > size);
+#endif
+ has_list_changed = true;
+ generate_menu_actions();
+ }
+}
+
+const QStringList& RecentFiles::get_files() {
+ return list;
+}
+
+void RecentFiles::clear() {
+ list.empty();
+}
+
+RecentFiles::Action::Action(const QString &text, QObject *parent) : QAction(text, parent) {
+ connect(this, &QAction::triggered, this, [=](bool checked) {
+ emit this->chosen_file(file_path);
+ });
+}
diff --git a/src/recent_files.h b/src/recent_files.h
new file mode 100644
index 0000000..7edfb3d
--- /dev/null
+++ b/src/recent_files.h
@@ -0,0 +1,54 @@
+#pragma once
+#include "src/settings_interface.h"
+#include <QStringList>
+#include <QMenu>
+#include <memory>
+
+class RecentFiles {
+public:
+ // QAction extension to signal file path
+ class Action;
+
+ // size: length of the list before removing older files
+ // force_empty: work from an empty list
+ RecentFiles(unsigned int size = 10, bool force_empty = false);
+ // Note: recent files list is committed on destruction
+ ~RecentFiles();
+
+ // Submit a file to the recent files list
+ // It will not be added if it's already in the list
+ void add_file(const QString& path);
+
+ // Get the list of recent files
+ const QStringList& get_files();
+
+ // Clear the list of recent files
+ void clear();
+
+ // Create a QMenu with the list of recent files
+ // The caller is responsable of managing the pointer's lifetime. It works like any other QMnenu, but is already populated.
+ // title: the text shown
+ // parent: the QMenu's parent
+ typedef std::shared_ptr<QMenu> QMenuPtr;
+ QMenuPtr create_menu(const QString& title, QWidget* parent = nullptr);
+
+private:
+ SettingsInterface settings_interface;
+ QStringList list;
+ unsigned int size;
+ bool has_list_changed = false;
+
+ QMenuPtr menu;
+
+ void generate_menu_actions();
+};
+
+class RecentFiles::Action : public QAction {
+ Q_OBJECT
+public:
+ Action(const QString &text, QObject *parent = nullptr);
+ QString file_path;
+
+signals:
+ void chosen_file(const QString& file_path);
+};
diff --git a/src/settings_interface.cpp b/src/settings_interface.cpp
index e14da92..13e2066 100644
--- a/src/settings_interface.cpp
+++ b/src/settings_interface.cpp
@@ -115,6 +115,8 @@ const QVariant default_setting(const QString &key) {
else if (key == "net/instance/address"
or key == "net/instance/token")
return "";
+ else if (key == "ui/recent_files")
+ return QStringList();
else
return -1;
}
diff --git a/src/widgets/tab_welcome.cpp b/src/widgets/tab_welcome.cpp
index 2c8dc56..49b4f2a 100644
--- a/src/widgets/tab_welcome.cpp
+++ b/src/widgets/tab_welcome.cpp
@@ -1,7 +1,8 @@
#include "tab_welcome.h"
+#include <QAction>
-TabWelcome::TabWelcome(QWidget* parent)
- : QWidget(parent), ui(new Ui::TabWelcome)
+TabWelcome::TabWelcome(RecentFiles::QMenuPtr recent_files_menu, QWidget* parent)
+ : recent_files_menu(recent_files_menu), QWidget(parent), ui(new Ui::TabWelcome)
{
ui->setupUi(this);
ui->horizontalLayout->setContentsMargins(0, 0, 0, 0);
@@ -20,5 +21,6 @@ void TabWelcome::on_openFileButton_clicked(bool checked) {
}
void TabWelcome::on_openRecentButton_clicked(bool checked) {
- emit show_recent_files();
+ if (recent_files_menu)
+ recent_files_menu->popup(ui->openRecentButton->mapToGlobal(QPoint(0,0)));
}
diff --git a/src/widgets/tab_welcome.h b/src/widgets/tab_welcome.h
index effc84f..497aae2 100644
--- a/src/widgets/tab_welcome.h
+++ b/src/widgets/tab_welcome.h
@@ -1,6 +1,7 @@
#pragma once
#include <QWidget>
#include "./ui_tab_welcome.h"
+#include "../recent_files.h"
QT_BEGIN_NAMESPACE
namespace Ui { class TabWelcome; }
@@ -10,15 +11,14 @@ class TabWelcome : public QWidget {
Q_OBJECT
public:
- TabWelcome(QWidget* parent = nullptr);
+ TabWelcome(RecentFiles::QMenuPtr recent_files_menu = nullptr, QWidget* parent = nullptr);
~TabWelcome();
signals:
// Show Open file dialog
void show_file_open_dialog();
-
- // Show recents dropdown
- void show_recent_files();
+ // Open this file path
+ void open_file(const QString& path);
private slots:
void on_openFileButton_clicked(bool checked);
@@ -26,4 +26,5 @@ private slots:
private:
Ui::TabWelcome* ui;
+ RecentFiles::QMenuPtr recent_files_menu;
};