From 3235bdaa84eb7642c9b44848849f6a85ca7c7d04 Mon Sep 17 00:00:00 2001 From: ShaopengLin Date: Tue, 26 Mar 2024 15:40:09 -0400 Subject: [PATCH 1/2] Add Auto Reopening of Tabs from Previous Session Users can now restore tabs opened before close in the same order and same url. Fix #186 --- src/kiwixapp.cpp | 32 +++++++++++++++++++++++++++++++- src/kiwixapp.h | 3 +++ src/tabbar.cpp | 14 ++++++++++++++ src/tabbar.h | 1 + src/webview.cpp | 3 ++- 5 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/kiwixapp.cpp b/src/kiwixapp.cpp index 5330eb3a..1800abf1 100644 --- a/src/kiwixapp.cpp +++ b/src/kiwixapp.cpp @@ -32,7 +32,8 @@ KiwixApp::KiwixApp(int& argc, char *argv[]) mp_manager(nullptr), mp_mainWindow(nullptr), mp_nameMapper(std::make_shared(m_library.getKiwixLibrary(), false)), - m_server(m_library.getKiwixLibrary(), mp_nameMapper) + m_server(m_library.getKiwixLibrary(), mp_nameMapper), + mp_session(nullptr) { try { m_translation.setTranslation(QLocale()); @@ -113,6 +114,8 @@ void KiwixApp::init() m_library.asyncUpdateFromDir(dir); } } + + restoreTabs(); } KiwixApp::~KiwixApp() @@ -176,6 +179,28 @@ QString KiwixApp::findLibraryDirectory() return currentDataDir; } +void KiwixApp::restoreTabs() +{ + /* Place session file in our global library path */ + QDir dir(m_libraryDirectory); + mp_session = new QSettings(dir.filePath("kiwix-desktop.session"), + QSettings::defaultFormat(), this); + QStringList tabsToOpen = mp_session->value("reopenTabList").toStringList(); + + /* Restart a new session to prevent duplicate records in openURL */ + saveListOfOpenTabs(); + for (const auto &zimUrl : tabsToOpen) + { + try + { + /* Throws exception if zim file cannot be found */ + m_library.getArchive(QUrl(zimUrl).host().split('.')[0]); + openUrl(QUrl(zimUrl)); + } + catch (std::exception &e) { /* Blank */ } + } +} + KiwixApp *KiwixApp::instance() { return static_cast(QApplication::instance()); @@ -504,3 +529,8 @@ QString KiwixApp::parseStyleFromFile(QString filePath) file.close(); return styleSheet; } + +void KiwixApp::saveListOfOpenTabs() +{ + return mp_session->setValue("reopenTabList", getTabWidget()->getTabUrls()); +} diff --git a/src/kiwixapp.h b/src/kiwixapp.h index c09a1d0d..0daece6f 100644 --- a/src/kiwixapp.h +++ b/src/kiwixapp.h @@ -87,6 +87,7 @@ class KiwixApp : public QtSingleApplication void setMonitorDir(const QString &dir); bool isCurrentArticleBookmarked(); QString parseStyleFromFile(QString filePath); + void saveListOfOpenTabs(); public slots: void newTab(); @@ -116,10 +117,12 @@ public slots: kiwix::Server m_server; Translation m_translation; QFileSystemWatcher m_watcher; + QSettings* mp_session; QAction* mpa_actions[MAX_ACTION]; QString findLibraryDirectory(); + void restoreTabs(); }; QString gt(const QString &key); diff --git a/src/tabbar.cpp b/src/tabbar.cpp index b2659652..cbc88469 100644 --- a/src/tabbar.cpp +++ b/src/tabbar.cpp @@ -268,6 +268,16 @@ void TabBar::closeTabsByZimId(const QString &id) } } +QStringList TabBar::getTabUrls() const { + QStringList idList; + for (int index = 0; index <= mp_stackedWidget->count(); index++) + { + if (ZimView* zv = qobject_cast(mp_stackedWidget->widget(index))) + idList.push_back(zv->getWebView()->url().url()); + } + return idList; +} + void TabBar::closeTab(int index) { // The first and last tabs (i.e. the library tab and the + (new tab) button) @@ -285,6 +295,8 @@ void TabBar::closeTab(int index) removeTab(index); view->close(); view->deleteLater(); + + KiwixApp::instance()->saveListOfOpenTabs(); } void TabBar::onCurrentChanged(int index) @@ -466,4 +478,6 @@ void TabBar::onTabMoved(int from, int to) QWidget *w_from = mp_stackedWidget->widget(from); mp_stackedWidget->removeWidget(w_from); mp_stackedWidget->insertWidget(to, w_from); + + KiwixApp::instance()->saveListOfOpenTabs(); } diff --git a/src/tabbar.h b/src/tabbar.h index edd02f50..26d5b111 100644 --- a/src/tabbar.h +++ b/src/tabbar.h @@ -49,6 +49,7 @@ class TabBar : public QTabBar virtual QSize tabSizeHint(int index) const; void openFindInPageBar(); void closeTabsByZimId(const QString &id); + QStringList getTabUrls() const; protected: void mousePressEvent(QMouseEvent *event); diff --git a/src/webview.cpp b/src/webview.cpp index 9446a07b..de17f618 100644 --- a/src/webview.cpp +++ b/src/webview.cpp @@ -166,12 +166,13 @@ QWebEngineView* WebView::createWindow(QWebEnginePage::WebWindowType type) void WebView::onUrlChanged(const QUrl& url) { auto zimId = getZimIdFromUrl(url); + auto app = KiwixApp::instance(); + app->saveListOfOpenTabs(); if (m_currentZimId == zimId ) { return; } m_currentZimId = zimId; emit zimIdChanged(m_currentZimId); - auto app = KiwixApp::instance(); std::shared_ptr archive; try { archive = app->getLibrary()->getArchive(m_currentZimId); From 01a66988a06ef957486df9d036e06a8565766604 Mon Sep 17 00:00:00 2001 From: ShaopengLin Date: Tue, 26 Mar 2024 15:46:03 -0400 Subject: [PATCH 2/2] Add CheckBox in Settings for Tab Reopen Behavior Added a checkbox in settings where user can define if they want the tab reopening feature to be active. Fix #186 --- resources/i18n/en.json | 3 ++- resources/i18n/qqq.json | 3 ++- src/kiwixapp.cpp | 9 ++++++--- src/settingsmanager.cpp | 11 ++++++++++- src/settingsmanager.h | 5 +++++ src/settingsview.cpp | 19 +++++++++++++++++- src/settingsview.h | 8 ++++++-- ui/settings.ui | 44 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 93 insertions(+), 9 deletions(-) diff --git a/resources/i18n/en.json b/resources/i18n/en.json index 504dc0da..67cbb6a7 100644 --- a/resources/i18n/en.json +++ b/resources/i18n/en.json @@ -162,5 +162,6 @@ "content-type-searcher-placeholder": "Filter content type", "no-details": "Introduction only", "no-pictures": "No Pictures", - "no-videos": "No Videos" + "no-videos": "No Videos", + "open-previous-tabs-at-startup": "Open previous tabs at startup" } diff --git a/resources/i18n/qqq.json b/resources/i18n/qqq.json index 5f7f5df8..38198f0b 100644 --- a/resources/i18n/qqq.json +++ b/resources/i18n/qqq.json @@ -45,5 +45,6 @@ "monitor-dir-dialog-msg": "\"Monitor\" means \"watch\" in this context. The monitor directory is monitored/watched for new ZIM files.", "monitor-clear-dir-dialog-title": "\"Monitor\" means \"watch\" in this context. The monitor directory is monitored/watched for new ZIM files.", "monitor-clear-dir-dialog-msg": "\"Monitor\" means \"watch\" in this context. The monitor directory is monitored/watched for new ZIM files.", - "open-book": "\"Open\" is a imperative, not an adjective." + "open-book": "\"Open\" is a imperative, not an adjective.", + "open-previous-tabs-at-startup": "The tabs that were open when the user closed the application is opened again when the application is restarted." } diff --git a/src/kiwixapp.cpp b/src/kiwixapp.cpp index 1800abf1..cdbac486 100644 --- a/src/kiwixapp.cpp +++ b/src/kiwixapp.cpp @@ -189,15 +189,18 @@ void KiwixApp::restoreTabs() /* Restart a new session to prevent duplicate records in openURL */ saveListOfOpenTabs(); - for (const auto &zimUrl : tabsToOpen) + if (m_settingsManager.getReopenTab()) { - try + for (const auto &zimUrl : tabsToOpen) { + try + { /* Throws exception if zim file cannot be found */ m_library.getArchive(QUrl(zimUrl).host().split('.')[0]); openUrl(QUrl(zimUrl)); + } + catch (std::exception &e) { /* Blank */ } } - catch (std::exception &e) { /* Blank */ } } } diff --git a/src/settingsmanager.cpp b/src/settingsmanager.cpp index f83165bb..e475bcd0 100644 --- a/src/settingsmanager.cpp +++ b/src/settingsmanager.cpp @@ -19,7 +19,8 @@ SettingsView* SettingsManager::getView() { if (m_view == nullptr) { auto view = new SettingsView(); - view->init(m_zoomFactor * 100, m_downloadDir, m_monitorDir, m_moveToTrash); + view->init(m_zoomFactor * 100, m_downloadDir, m_monitorDir, + m_moveToTrash, m_reopenTab); connect(view, &QObject::destroyed, this, [=]() { m_view = nullptr; }); m_view = view; } @@ -99,6 +100,13 @@ void SettingsManager::setMoveToTrash(bool moveToTrash) emit(moveToTrashChanged(m_moveToTrash)); } +void SettingsManager::setReopenTab(bool reopenTab) +{ + m_reopenTab = reopenTab; + setSettings("reopenTab", m_reopenTab); + emit(reopenTabChanged(reopenTab)); +} + QList SettingsManager::flattenPair(FilterList pairList) { QList res; @@ -148,6 +156,7 @@ void SettingsManager::initSettings() m_kiwixServerIpAddress = m_settings.value("localKiwixServer/ipAddress", QString("0.0.0.0")).toString(); m_monitorDir = m_settings.value("monitor/dir", QString("")).toString(); m_moveToTrash = m_settings.value("moveToTrash", true).toBool(); + m_reopenTab = m_settings.value("reopenTab", false).toBool(); QString defaultLang = QLocale::languageToString(QLocale().language()) + '|' + QLocale().name().split("_").at(0); /* diff --git a/src/settingsmanager.h b/src/settingsmanager.h index 5646008d..3b60306c 100644 --- a/src/settingsmanager.h +++ b/src/settingsmanager.h @@ -29,6 +29,7 @@ class SettingsManager : public QObject QString getDownloadDir() const { return m_downloadDir; } QString getMonitorDir() const { return m_monitorDir; } bool getMoveToTrash() const { return m_moveToTrash; } + bool getReopenTab() const { return m_reopenTab; } FilterList getLanguageList() { return deducePair(m_langList); } FilterList getCategoryList() { return deducePair(m_categoryList); } FilterList getContentType() { return deducePair(m_contentTypeList); } @@ -40,9 +41,11 @@ public slots: void setDownloadDir(QString downloadDir); void setMonitorDir(QString monitorDir); void setMoveToTrash(bool moveToTrash); + void setReopenTab(bool reopenTab); void setLanguage(FilterList langList); void setCategory(FilterList categoryList); void setContentType(FilterList contentTypeList); + private: void initSettings(); QList flattenPair(FilterList pairList); @@ -54,6 +57,7 @@ public slots: void downloadDirChanged(QString downloadDir); void monitorDirChanged(QString monitorDir); void moveToTrashChanged(bool moveToTrash); + void reopenTabChanged(bool reopenTab); void languageChanged(QList langList); void categoryChanged(QList categoryList); void contentTypeChanged(QList contentTypeList); @@ -67,6 +71,7 @@ public slots: QString m_downloadDir; QString m_monitorDir; bool m_moveToTrash; + bool m_reopenTab; QList m_langList; QList m_categoryList; QList m_contentTypeList; diff --git a/src/settingsview.cpp b/src/settingsview.cpp index 7b59b1a0..bffa528d 100644 --- a/src/settingsview.cpp +++ b/src/settingsview.cpp @@ -12,6 +12,7 @@ SettingsView::SettingsView(QWidget *parent) ui->widget->setStyleSheet(KiwixApp::instance()->parseStyleFromFile(":/css/_settingsManager.css")); connect(ui->zoomPercentSpinBox, QOverload::of(&QSpinBox::valueChanged), this, &SettingsView::setZoom); connect(ui->moveToTrashToggle, &QCheckBox::clicked, this, &SettingsView::setMoveToTrash); + connect(ui->reopenTabToggle, &QCheckBox::clicked, this, &SettingsView::setReopenTab); connect(ui->browseButton, &QPushButton::clicked, this, &SettingsView::browseDownloadDir); connect(ui->resetButton, &QPushButton::clicked, this, &SettingsView::resetDownloadDir); connect(ui->monitorBrowse, &QPushButton::clicked, this, &SettingsView::browseMonitorDir); @@ -20,6 +21,7 @@ SettingsView::SettingsView(QWidget *parent) connect(KiwixApp::instance()->getSettingsManager(), &SettingsManager::monitorDirChanged, this, &SettingsView::onMonitorDirChanged); connect(KiwixApp::instance()->getSettingsManager(), &SettingsManager::zoomChanged, this, &SettingsView::onZoomChanged); connect(KiwixApp::instance()->getSettingsManager(), &SettingsManager::moveToTrashChanged, this, &SettingsView::onMoveToTrashChanged); + connect(KiwixApp::instance()->getSettingsManager(), &SettingsManager::reopenTabChanged, this, &SettingsView::onReopenTabChanged); ui->settingsLabel->setText(gt("settings")); ui->zoomPercentLabel->setText(gt("zoom-level-setting")); ui->downloadDirLabel->setText(gt("download-directory-setting")); @@ -31,14 +33,18 @@ SettingsView::SettingsView(QWidget *parent) ui->monitorHelp->setText("?"); ui->monitorHelp->setToolTip(gt("monitor-directory-tooltip")); ui->moveToTrashLabel->setText(gt("move-files-to-trash")); + ui->reopenTabLabel->setText(gt("open-previous-tabs-at-startup")); #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) + ui->line_5->hide(); ui->moveToTrashLabel->hide(); ui->moveToTrashToggle->hide(); #endif } -void SettingsView::init(int zoomPercent, const QString &downloadDir, const QString &monitorDir, const bool moveToTrash) +void SettingsView::init(int zoomPercent, const QString &downloadDir, + const QString &monitorDir, const bool moveToTrash, + bool reopentab) { ui->zoomPercentSpinBox->setValue(zoomPercent); ui->downloadDirPath->setText(downloadDir); @@ -47,6 +53,7 @@ void SettingsView::init(int zoomPercent, const QString &downloadDir, const QStri } ui->monitorDirPath->setText(monitorDir); ui->moveToTrashToggle->setChecked(moveToTrash); + ui->reopenTabToggle->setChecked(reopentab); } bool SettingsView::confirmDialog( QString messageText, QString messageTitle) { @@ -142,6 +149,11 @@ void SettingsView::setMoveToTrash(bool moveToTrash) KiwixApp::instance()->getSettingsManager()->setMoveToTrash(moveToTrash); } +void SettingsView::setReopenTab(bool reopen) +{ + KiwixApp::instance()->getSettingsManager()->setReopenTab(reopen); +} + void SettingsView::onDownloadDirChanged(const QString &dir) { ui->downloadDirPath->setText(dir); @@ -167,3 +179,8 @@ void SettingsView::onMoveToTrashChanged(bool moveToTrash) { ui->moveToTrashToggle->setChecked(moveToTrash); } + +void SettingsView::onReopenTabChanged(bool reopen) +{ + ui->reopenTabToggle->setChecked(reopen); +} diff --git a/src/settingsview.h b/src/settingsview.h index d68faefe..e59ff494 100644 --- a/src/settingsview.h +++ b/src/settingsview.h @@ -11,18 +11,22 @@ class SettingsView : public QWidget public: SettingsView(QWidget *parent = nullptr); ~SettingsView(){}; - void init(int zoomPercent, const QString &downloadDir, const QString &monitorDir, const bool moveToTrash); -public Q_SLOTS: + void init(int zoomPercent, const QString &downloadDir, + const QString &monitorDir, const bool moveToTrash, + bool reopentab); + public Q_SLOTS: void resetDownloadDir(); void browseDownloadDir(); void browseMonitorDir(); void clearMonitorDir(); void setZoom(int zoomPercent); void setMoveToTrash(bool moveToTrash); + void setReopenTab(bool reopen); void onDownloadDirChanged(const QString &dir); void onMonitorDirChanged(const QString &dir); void onZoomChanged(qreal zoomFactor); void onMoveToTrashChanged(bool moveToTrash); + void onReopenTabChanged(bool reopen); private: bool confirmDialogDownloadDir(const QString& dir); bool confirmDialog(QString messageText, QString messageTitle); diff --git a/ui/settings.ui b/ui/settings.ui index 33c4235a..949712c2 100644 --- a/ui/settings.ui +++ b/ui/settings.ui @@ -328,6 +328,50 @@ + + + + Qt::Horizontal + + + + + + + 0 + + + 0 + + + + + Re-open closed tabs + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + +