From 09aaaf44df876590b9e09c37bcd8eb59d18a30ac Mon Sep 17 00:00:00 2001 From: Chris Moore Date: Sat, 20 Feb 2021 06:28:19 -0500 Subject: [PATCH] Avoid opening another window if path is already open We have a window registry so that the current path of each open window is maintained in the registry. When a folder is opened, the registry is checked - if a window with the path is already opened, then this window is raised instead of opening another window. Signed-off-by: Chris Moore --- filer/CMakeLists.txt | 1 + filer/launcher.cpp | 8 ++++++ filer/mainwindow.cpp | 37 +++++++++++++++++++++++++ filer/mainwindow.h | 2 ++ filer/tabpage.cpp | 5 ++++ filer/windowregistry.cpp | 54 ++++++++++++++++++++++++++++++++++++ filer/windowregistry.h | 59 ++++++++++++++++++++++++++++++++++++++++ 7 files changed, 166 insertions(+) create mode 100644 filer/windowregistry.cpp create mode 100644 filer/windowregistry.h diff --git a/filer/CMakeLists.txt b/filer/CMakeLists.txt index 93adbd04..74c9c347 100644 --- a/filer/CMakeLists.txt +++ b/filer/CMakeLists.txt @@ -33,6 +33,7 @@ set(filer_SRCS autorundialog.cpp settings.cpp metadata.cpp + windowregistry.cpp ) qt5_add_dbus_adaptor(filer_SRCS diff --git a/filer/launcher.cpp b/filer/launcher.cpp index 809063c8..705c0df0 100644 --- a/filer/launcher.cpp +++ b/filer/launcher.cpp @@ -21,6 +21,7 @@ #include "launcher.h" #include "mainwindow.h" #include "application.h" +#include "windowregistry.h" namespace Filer { @@ -39,8 +40,15 @@ Launcher::~Launcher() { bool Launcher::openFolder(GAppLaunchContext* ctx, GList* folder_infos, GError** err) { qDebug("probono: Launcher::openFolder called"); qDebug("probono: ffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + GList* l = folder_infos; FmFileInfo* fi = FM_FILE_INFO(l->data); + + // just raise the window if it's already open + if (WindowRegistry::instance().checkPathAndRaise(fm_path_to_str(fm_file_info_get_path(fi)))) { + return true; + } + Application* app = static_cast(qApp); MainWindow* mainWindow = mainWindow_; if(!mainWindow) { diff --git a/filer/mainwindow.cpp b/filer/mainwindow.cpp index 4e7c6124..88ed8a58 100644 --- a/filer/mainwindow.cpp +++ b/filer/mainwindow.cpp @@ -43,6 +43,7 @@ #include "application.h" #include "../libfm-qt/path.h" #include "metadata.h" +#include "windowregistry.h" // #include "qmodeltest/modeltest.h" @@ -220,9 +221,20 @@ MainWindow::MainWindow(FmPath* path): if(settings.windowMaximized()) setWindowState(windowState() | Qt::WindowMaximized); } + + // register current path with the window registry + WindowRegistry::instance().registerPath(fm_path_to_str(path)); + connect(&WindowRegistry::instance(), &WindowRegistry::raiseWindow, + this, &MainWindow::onRaiseWindow); } MainWindow::~MainWindow() { + // update registry + TabPage* page = currentPage(); + if(page) { + QString path = page->pathName(); + WindowRegistry::instance().deregisterPath(path); + } if(bookmarks) g_object_unref(bookmarks); } @@ -256,6 +268,9 @@ void MainWindow::addTab(FmPath* path) { if(!settings.alwaysShowTabs()) { ui.tabBar->setVisible(ui.tabBar->count() > 1); } + + // update registry + WindowRegistry::instance().registerPath(fm_path_to_str(path)); } void MainWindow::addWindow(FmPath *path) @@ -532,6 +547,11 @@ void MainWindow::onFilterStringChanged(QString str) { } void MainWindow::closeTab(int index) { + // update registry + if (TabPage* page = static_cast(ui.stackedWidget->widget(index))) { + WindowRegistry::instance().deregisterPath(page->pathName()); + } + QWidget* page = ui.stackedWidget->widget(index); if(page) { ui.stackedWidget->removeWidget(page); // this does not delete the page widget @@ -938,6 +958,23 @@ void MainWindow::onBackForwardContextMenu(QPoint pos) { } } +void MainWindow::onRaiseWindow(const QString& path) +{ + // all tab pages + int n = ui.stackedWidget->count(); + for(int i = 0; i < n; ++i) { + TabPage* page = static_cast(ui.stackedWidget->widget(i)); + if (page) { + QString ourPath = page->pathName(); + if (path == ourPath) { + raise(); + activateWindow(); + break; + } + } + } +} + void MainWindow::updateFromSettings(Settings& settings) { // apply settings diff --git a/filer/mainwindow.h b/filer/mainwindow.h index 1f998b79..4e4ca8dc 100644 --- a/filer/mainwindow.h +++ b/filer/mainwindow.h @@ -144,6 +144,8 @@ protected Q_SLOTS: void onBackForwardContextMenu(QPoint pos); + void onRaiseWindow(const QString& path); + protected: // void changeEvent( QEvent * event); void closeTab(int index); diff --git a/filer/tabpage.cpp b/filer/tabpage.cpp index 6bbd3a46..2df349f2 100644 --- a/filer/tabpage.cpp +++ b/filer/tabpage.cpp @@ -22,6 +22,7 @@ #include "filelauncher.h" #include "filemenu.h" #include "mountoperation.h" +#include "windowregistry.h" #include #include #include @@ -329,6 +330,10 @@ void TabPage::chdir(FmPath* newPath, bool addHistory) { if(fm_path_equal(newPath, fm_folder_get_path(folder_))) return; + // update registry + QString oldPath = fm_path_to_str(fm_folder_get_path(folder_)); + WindowRegistry::instance().updatePath(oldPath, fm_path_to_str(newPath)); + if(addHistory) { // store current scroll pos in the browse history BrowseHistoryItem& item = history_.currentItem(); diff --git a/filer/windowregistry.cpp b/filer/windowregistry.cpp new file mode 100644 index 00000000..432c4224 --- /dev/null +++ b/filer/windowregistry.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2021 Chris Moore + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "windowregistry.h" + +WindowRegistry::~WindowRegistry() { + // do nothing +} + +void WindowRegistry::registerPath(const QString& path) +{ + registry_.insert(path); +} + +void WindowRegistry::updatePath(const QString& fromPath, const QString& toPath) +{ + registry_.remove(fromPath); + registry_.insert(toPath); +} + +void WindowRegistry::deregisterPath(const QString& path) +{ + registry_.remove(path); +} + +bool WindowRegistry::checkPathAndRaise(const QString& path) +{ + if (registry_.contains(path)) { + Q_EMIT raiseWindow(path); + return true; + } + return false; +} + +WindowRegistry::WindowRegistry(QObject* parent): + QObject(), + registry_() { + // do nothing +} diff --git a/filer/windowregistry.h b/filer/windowregistry.h new file mode 100644 index 00000000..dd4696c4 --- /dev/null +++ b/filer/windowregistry.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2021 Chris Moore + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef WINDOWREGISTRY_H +#define WINDOWREGISTRY_H + +#include +#include +#include + +class WindowRegistry : public QObject { + Q_OBJECT + +public: + virtual ~WindowRegistry(); + + // singleton function + static WindowRegistry& instance() + { + static WindowRegistry instance; + return instance; + } + + void registerPath(const QString& path); + void updatePath(const QString& fromPath, const QString& toPath); + void deregisterPath(const QString& path); + + /* + * if the window is in the registry, raise the window + * and return true; otherwise return false + */ + bool checkPathAndRaise(const QString& path); + +Q_SIGNALS: + void raiseWindow(const QString& path); + +private: // functions + explicit WindowRegistry(QObject* parent = nullptr); + +private: // data + QSet registry_; // set of paths of open windows +}; + +#endif // WINDOWREGISTRY_H