]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/dolphintabwidget.cpp
DolphinTabWidget: Allow specifying new tab position in openNewTab
[dolphin.git] / src / dolphintabwidget.cpp
index cfb695e7db24a05a1f3a931f0823859ff917adf3..7eae6f297ec3ef4154c6b31abf8144dbe028248f 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;
@@ -152,7 +157,7 @@ void DolphinTabWidget::openNewActivatedTab(const QUrl& primaryUrl, const QUrl& s
     }
 }
 
-void DolphinTabWidget::openNewTab(const QUrl& primaryUrl, const QUrl& secondaryUrl)
+void DolphinTabWidget::openNewTab(const QUrl& primaryUrl, const QUrl& secondaryUrl, DolphinTabWidget::NewTabPosition position)
 {
     QWidget* focusWidget = QApplication::focusWidget();
 
@@ -162,10 +167,25 @@ void DolphinTabWidget::openNewTab(const QUrl& primaryUrl, const QUrl& secondaryU
             this, &DolphinTabWidget::activeViewChanged);
     connect(tabPage, &DolphinTabPage::activeViewUrlChanged,
             this, &DolphinTabWidget::tabUrlChanged);
+    connect(tabPage->activeViewContainer(), &DolphinViewContainer::captionChanged, this, [this, tabPage]() {
+        const int tabIndex = indexOf(tabPage);
+        Q_ASSERT(tabIndex >= 0);
+        tabBar()->setTabText(tabIndex, tabName(tabPage));
+    });
+
+    if (position == NewTabPosition::FollowSetting) {
+        if (GeneralSettings::openNewTabAfterLastTab()) {
+            position = NewTabPosition::AtEnd;
+        } else {
+            position = NewTabPosition::AfterCurrent;
+        }
+    }
+
     int newTabIndex = -1;
-    if (!GeneralSettings::openNewTabAfterLastTab()) {
+    if (position == NewTabPosition::AfterCurrent || (position == NewTabPosition::FollowSetting && !GeneralSettings::openNewTabAfterLastTab())) {
         newTabIndex = currentIndex() + 1;
     }
+
     insertTab(newTabIndex, tabPage, QIcon() /* loaded in tabInserted */, tabName(tabPage));
 
     if (focusWidget) {
@@ -175,7 +195,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);
 
@@ -184,12 +204,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);
@@ -229,14 +249,14 @@ void DolphinTabWidget::openFiles(const QList<QUrl>& files, bool splitView)
     // directories are shown inside one tab (see openDirectories()).
     QList<QUrl> dirs;
     for (const QUrl& url : files) {
-        const QUrl dir(url.adjusted(QUrl::RemoveFilename));
+        const QUrl dir(url.adjusted(QUrl::RemoveFilename | QUrl::StripTrailingSlash));
         if (!dirs.contains(dir)) {
             dirs.append(dir);
         }
     }
 
     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
@@ -383,7 +403,9 @@ void DolphinTabWidget::tabUrlChanged(const QUrl& url)
         tabBar()->setTabText(index, tabName(tabPageAt(index)));
         tabBar()->setTabToolTip(index, url.toDisplayString(QUrl::PreferLocalFile));
         if (tabBar()->isVisible()) {
-            tabBar()->setTabIcon(index, QIcon::fromTheme(KIO::iconNameForUrl(url)));
+            // ensure the path url ends with a slash to have proper folder icon for remote folders
+            const QUrl pathUrl = QUrl(url.adjusted(QUrl::StripTrailingSlash).toString(QUrl::FullyEncoded).append("/"));
+            tabBar()->setTabIcon(index, QIcon::fromTheme(KIO::iconNameForUrl(pathUrl)));
         } else {
             // Mark as dirty, actually load once the tab bar actually gets shown
             tabBar()->setTabIcon(index, QIcon());
@@ -427,7 +449,9 @@ void DolphinTabWidget::tabInserted(int index)
         for (int i = 0; i < count(); ++i) {
             const QUrl url = tabPageAt(i)->activeViewContainer()->url();
             if (tabBar()->tabIcon(i).isNull()) {
-                tabBar()->setTabIcon(i, QIcon::fromTheme(KIO::iconNameForUrl(url)));
+                // ensure the path url ends with a slash to have proper folder icon for remote folders
+                const QUrl pathUrl = QUrl(url.adjusted(QUrl::StripTrailingSlash).toString(QUrl::FullyEncoded).append("/"));
+                tabBar()->setTabIcon(i, QIcon::fromTheme(KIO::iconNameForUrl(pathUrl)));
             }
             if (tabBar()->tabToolTip(i).isEmpty()) {
                 tabBar()->setTabToolTip(index, url.toDisplayString(QUrl::PreferLocalFile));
@@ -464,17 +488,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);
 }