]> cloud.milkyroute.net Git - dolphin.git/commitdiff
do not open excessive tab
authorAndrey Butirsky <butirsky@gmail.com>
Tue, 24 May 2022 13:24:24 +0000 (16:24 +0300)
committerAndrey Butirsky <butirsky@gmail.com>
Wed, 22 Jun 2022 18:49:37 +0000 (21:49 +0300)
even if directory of the file to be created is not the top-most opened in
TreeView

BUG: 440663

src/dolphinmainwindow.cpp
src/dolphinmainwindow.h
src/dolphintabwidget.cpp
src/dolphintabwidget.h
src/global.cpp

index 0b0f4f96addc19dad687356fd7454200db318d44..24da841326c0c9af97ce2129246c36d086d7886d 100644 (file)
@@ -285,6 +285,11 @@ void DolphinMainWindow::activateWindow()
     KWindowSystem::activateWindow(window()->effectiveWinId());
 }
 
+bool DolphinMainWindow::isActiveWindow()
+{
+    return window()->isActiveWindow();
+}
+
 void DolphinMainWindow::showCommand(CommandType command)
 {
     DolphinStatusBar* statusBar = m_activeViewContainer->statusBar();
@@ -2627,3 +2632,7 @@ bool DolphinMainWindow::isUrlOpen(const QString &url)
     return m_tabWidget->isUrlOpen(QUrl::fromUserInput(url));
 }
 
+bool DolphinMainWindow::isUrlOrParentOpen(const QString &url)
+{
+    return m_tabWidget->isUrlOrParentOpen(QUrl::fromUserInput(url));
+}
index 030c8bb28cc703f0a7e8e5f1b7477f16e3b89e2b..e26bf50dd40a4e2d5f0493be29ff87451adb4a16 100644 (file)
@@ -138,6 +138,8 @@ public Q_SLOTS:
      */
     void activateWindow();
 
+    bool isActiveWindow();
+
     /**
      * Determines if a URL is open in any tab.
      * @note Use of QString instead of QUrl is required to be callable via DBus.
@@ -147,6 +149,15 @@ public Q_SLOTS:
      */
     bool isUrlOpen(const QString &url);
 
+    /**
+     * Determines if a URL or it's parent is open in any tab.
+     * @note Use of QString instead of QUrl is required to be callable via DBus.
+     *
+     * @param url URL to look for
+     * @returns true if url or it's parent is currently open in a tab, false otherwise.
+     */
+    bool isUrlOrParentOpen(const QString &url);
+
 
     /**
      * Pastes the clipboard data into the currently selected folder
index 5586c9df26ad8887e6c159bdb5bb8646e719fbc0..de7a18db3622636385910225d8af5b51ae090b6c 100644 (file)
@@ -117,6 +117,11 @@ bool DolphinTabWidget::isUrlOpen(const QUrl &url) const
     return indexByUrl(url).first >= 0;
 }
 
+bool DolphinTabWidget::isUrlOrParentOpen(const QUrl &url) const
+{
+    return indexByUrl(url, ReturnIndexForOpenedParentAlso).first >= 0;
+}
+
 void DolphinTabWidget::openNewActivatedTab()
 {
     std::unique_ptr<DolphinUrlNavigator::VisualState> oldNavigatorState;
@@ -182,7 +187,7 @@ void DolphinTabWidget::openNewTab(const QUrl& primaryUrl, const QUrl& secondaryU
     }
 }
 
-void DolphinTabWidget::openDirectories(const QList<QUrl>& dirs, bool splitView)
+void DolphinTabWidget::openDirectories(const QList<QUrl>& dirs, bool splitView, bool skipChildUrls)
 {
     Q_ASSERT(dirs.size() > 0);
 
@@ -191,12 +196,12 @@ void DolphinTabWidget::openDirectories(const QList<QUrl>& dirs, bool splitView)
     QList<QUrl>::const_iterator it = dirs.constBegin();
     while (it != dirs.constEnd()) {
         const QUrl& primaryUrl = *(it++);
-        const QPair<int, bool> indexInfo = indexByUrl(primaryUrl);
+        const QPair<int, bool> indexInfo = indexByUrl(primaryUrl, skipChildUrls ? ReturnIndexForOpenedParentAlso : ReturnIndexForOpenedUrlOnly);
         const int index = indexInfo.first;
         const bool isInPrimaryView = indexInfo.second;
 
-        // When the user asks for a URL that's already open, activate it instead
-        // of opening a second copy
+        // When the user asks for a URL that's already open (or it's parent is open if skipChildUrls is set),
+        // activate it instead of opening a new tab
         if (index >= 0) {
             somethingWasAlreadyOpen = true;
             activateTab(index);
@@ -243,7 +248,7 @@ void DolphinTabWidget::openFiles(const QList<QUrl>& files, bool splitView)
     }
 
     const int oldTabCount = count();
-    openDirectories(dirs, splitView);
+    openDirectories(dirs, splitView, true);
     const int tabCount = count();
 
     // Select the files. Although the files can be split between several
@@ -475,17 +480,29 @@ QString DolphinTabWidget::tabName(DolphinTabPage* tabPage) const
     return name.replace('&', QLatin1String("&&"));
 }
 
-QPair<int, bool> DolphinTabWidget::indexByUrl(const QUrl& url) const
+QPair<int, bool> DolphinTabWidget::indexByUrl(const QUrl& url, ChildUrlBehavior childUrlBehavior) const
 {
-    for (int i = 0; i < count(); i++) {
+    int i = currentIndex();
+    if (i < 0) {
+        return qMakePair(-1, false);
+    }
+    // loop over the tabs starting from the current one
+    do {
         const auto tabPage = tabPageAt(i);
-        if (url == tabPage->primaryViewContainer()->url()) {
+        if (tabPage->primaryViewContainer()->url() == url ||
+                childUrlBehavior == ReturnIndexForOpenedParentAlso && tabPage->primaryViewContainer()->url().isParentOf(url)) {
             return qMakePair(i, true);
         }
 
-        if (tabPage->splitViewEnabled() && url == tabPage->secondaryViewContainer()->url()) {
+        if (tabPage->splitViewEnabled() &&
+                (url == tabPage->secondaryViewContainer()->url() ||
+                 childUrlBehavior == ReturnIndexForOpenedParentAlso && tabPage->secondaryViewContainer()->url().isParentOf(url))) {
             return qMakePair(i, false);
         }
+
+        i = (i + 1) % count();
     }
+    while (i != currentIndex());
+
     return qMakePair(-1, false);
 }
index e0146d7c71bb5d25671a7d63c2c2da9c311359bb..7905912dacbdf5b5fa0f0ef40fbfc1e34959aadb 100644 (file)
@@ -60,11 +60,17 @@ public:
     void refreshViews();
 
     /**
-     * @return Whether any of the tab pages contains @p url in their primary
-     * or secondary view.
+     * @return Whether any of the tab pages has @p url opened
+     * in their primary or secondary view.
      */
     bool isUrlOpen(const QUrl& url) const;
 
+    /**
+     * @return Whether any of the tab pages has @p url or it's parent opened
+     * in their primary or secondary view.
+     */
+    bool isUrlOrParentOpen(const QUrl& url) const;
+
 Q_SIGNALS:
     /**
      * Is emitted when the active view has been changed, by changing the current
@@ -110,11 +116,12 @@ public Q_SLOTS:
     void openNewTab(const QUrl &primaryUrl, const QUrl &secondaryUrl = QUrl());
 
     /**
-     * Opens each directory in \p dirs in a separate tab. If \a splitView is set,
-     * 2 directories are collected within one tab.
+     * Opens each directory in \p dirs in a separate tab unless it is already open.
+     * If \a splitView is set, 2 directories are collected within one tab.
+     * If \a skipChildUrls is set, do not open a directory if it's parent is already open.
      * \pre \a dirs must contain at least one url.
      */
-    void openDirectories(const QList<QUrl>& dirs, bool splitView);
+    void openDirectories(const QList<QUrl>& dirs, bool splitView, bool skipChildUrls = false);
 
     /**
      * Opens the directories which contain the files \p files and selects all files.
@@ -205,15 +212,21 @@ private:
      */
     QString tabName(DolphinTabPage* tabPage) const;
 
+    enum ChildUrlBehavior {
+        ReturnIndexForOpenedUrlOnly,
+        ReturnIndexForOpenedParentAlso
+    };
+
     /**
      * @param url The URL that we would like
-     * @return a QPair with first containing the index of the tab with the
-     * desired URL or -1 if not found. Second says true if URL is in primary
-     * view container, false otherwise. False means the URL is in the secondary
-     * view container, unless first == -1. In that case the value of second
-     * is meaningless.
-     */
-    QPair<int, bool> indexByUrl(const QUrl& url) const;
+     * @param childUrlBehavior Whether a tab with opened parent of the URL can be returned too
+     * @return a QPair with:
+     * First containing the index of the tab with the desired URL or -1 if not found.
+     * Second says true if URL is in primary view container, false otherwise.
+     * False means the URL is in the secondary view container, unless first == -1.
+     * In that case the value of second is meaningless.
+     */
+    QPair<int, bool> indexByUrl(const QUrl& url, ChildUrlBehavior childUrlBehavior = ReturnIndexForOpenedUrlOnly) const;
 
 private:
     QPointer<DolphinTabPage> m_lastViewedTab;
index 0712aa173f8c7429d7e6c80ce0f86a7692e4c441..5d6d90b59e16259dc2d2c6e610c5e274a23babba 100644 (file)
@@ -71,33 +71,55 @@ bool Dolphin::attachToExistingInstance(const QList<QUrl>& inputUrls, bool openFi
         return false;
     }
 
-    QStringList newUrls;
+    int activeWindowIndex = -1;
+    for (const auto& interface: qAsConst(dolphinInterfaces)) {
+        ++activeWindowIndex;
+
+        auto isActiveWindowReply = interface.first->isActiveWindow();
+        isActiveWindowReply.waitForFinished();
+        if (!isActiveWindowReply.isError() && isActiveWindowReply.value()) {
+            break;
+        }
+    }
 
-    // check to see if any instances already have any of the given URLs open
+    // check to see if any instances already have any of the given URLs or their parents open
     const auto urls = QUrl::toStringList(inputUrls);
     for (const QString& url : urls) {
         bool urlFound = false;
-        for (auto& interface: dolphinInterfaces) {
-            auto isUrlOpenReply = interface.first->isUrlOpen(url);
+
+        // looping through the windows starting from the active one
+        int i = activeWindowIndex;
+        do {
+            auto &interface = dolphinInterfaces[i];
+
+            auto isUrlOpenReply = openFiles ? interface.first->isUrlOrParentOpen(url) : interface.first->isUrlOpen(url);
             isUrlOpenReply.waitForFinished();
             if (!isUrlOpenReply.isError() && isUrlOpenReply.value()) {
                 interface.second.append(url);
                 urlFound = true;
                 break;
             }
+
+            i = (i + 1) % dolphinInterfaces.size();
         }
+        while (i != activeWindowIndex);
+
         if (!urlFound) {
-            newUrls.append(url);
+            dolphinInterfaces[activeWindowIndex].second.append(url);
         }
     }
 
     for (const auto& interface: qAsConst(dolphinInterfaces)) {
-        auto reply = openFiles ? interface.first->openFiles(newUrls, splitView) : interface.first->openDirectories(newUrls, splitView);
+        if (interface.second.isEmpty()) {
+            continue;
+        }
+        auto reply = openFiles ?
+                    interface.first->openFiles(interface.second, splitView) :
+                    interface.first->openDirectories(interface.second, splitView);
         reply.waitForFinished();
         if (!reply.isError()) {
             interface.first->activateWindow();
             attached = true;
-            break;
         }
     }
     return attached;