]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/dolphinviewcontainer.cpp
Ignore trailing slashes when comparing place URLs
[dolphin.git] / src / dolphinviewcontainer.cpp
index 27f845fa798fa3245248241167ca22775b8bca24..e55519d04300b270967fcf744b026907d5f76e21 100644 (file)
@@ -7,6 +7,7 @@
 #include "dolphinviewcontainer.h"
 
 #include "admin/bar.h"
+#include "admin/workerintegration.h"
 #include "dolphin_compactmodesettings.h"
 #include "dolphin_contentdisplaysettings.h"
 #include "dolphin_detailsmodesettings.h"
@@ -40,6 +41,7 @@
 #include <QRegularExpression>
 #include <QTimer>
 #include <QUrl>
+#include <QUrlQuery>
 
 // An overview of the widgets contained by this ViewContainer
 struct LayoutStructure {
@@ -62,6 +64,7 @@ DolphinViewContainer::DolphinViewContainer(const QUrl &url, QWidget *parent)
     , m_searchBox(nullptr)
     , m_searchModeEnabled(false)
     , m_adminBar{nullptr}
+    , m_authorizeToEnterFolderAction{nullptr}
     , m_messageWidget(nullptr)
     , m_selectionModeTopBar{nullptr}
     , m_view(nullptr)
@@ -139,7 +142,7 @@ DolphinViewContainer::DolphinViewContainer(const QUrl &url, QWidget *parent)
     connect(m_view, &DolphinView::directoryLoadingCanceled, this, &DolphinViewContainer::slotDirectoryLoadingCanceled);
     connect(m_view, &DolphinView::itemCountChanged, this, &DolphinViewContainer::delayedStatusBarUpdate);
     connect(m_view, &DolphinView::selectionChanged, this, &DolphinViewContainer::delayedStatusBarUpdate);
-    connect(m_view, &DolphinView::errorMessage, this, &DolphinViewContainer::showErrorMessage);
+    connect(m_view, &DolphinView::errorMessage, this, &DolphinViewContainer::slotErrorMessageFromView);
     connect(m_view, &DolphinView::urlIsFileError, this, &DolphinViewContainer::slotUrlIsFileError);
     connect(m_view, &DolphinView::activated, this, &DolphinViewContainer::activate);
     connect(m_view, &DolphinView::hiddenFilesShownChanged, this, &DolphinViewContainer::slotHiddenFilesShownChanged);
@@ -531,6 +534,15 @@ QString DolphinViewContainer::captionWindowTitle() const
 
 QString DolphinViewContainer::caption() const
 {
+    // see KUrlNavigatorPrivate::firstButtonText().
+    if (url().path().isEmpty() || url().path() == QLatin1Char('/')) {
+        QUrlQuery query(url());
+        const QString title = query.queryItemValue(QStringLiteral("title"));
+        if (!title.isEmpty()) {
+            return title;
+        }
+    }
+
     if (isSearchModeEnabled()) {
         if (currentSearchText().isEmpty()) {
             return i18n("Search");
@@ -540,12 +552,11 @@ QString DolphinViewContainer::caption() const
     }
 
     KFilePlacesModel *placesModel = DolphinPlacesModelSingleton::instance().placesModel();
-    const QString pattern = url().adjusted(QUrl::StripTrailingSlash).toString(QUrl::FullyEncoded).append("/?");
-    const auto &matchedPlaces =
-        placesModel->match(placesModel->index(0, 0), KFilePlacesModel::UrlRole, QRegularExpression::anchoredPattern(pattern), 1, Qt::MatchRegularExpression);
 
-    if (!matchedPlaces.isEmpty()) {
-        return placesModel->text(matchedPlaces.first());
+    QModelIndex url_index = placesModel->closestItem(url());
+
+    if (url_index.isValid() && placesModel->url(url_index).matches(url(), QUrl::StripTrailingSlash)) {
+        return placesModel->text(url_index);
     }
 
     if (!url().isLocalFile()) {
@@ -739,6 +750,18 @@ void DolphinViewContainer::slotfileMiddleClickActivated(const KFileItem &item)
         job->setUiDelegate(KIO::createDefaultJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this));
         connect(job, &KIO::OpenUrlJob::finished, this, &DolphinViewContainer::slotOpenUrlFinished);
         job->start();
+    } else {
+        // If no 2nd service available, try to open archives in new tabs, regardless of the "Open archives as folder" setting.
+        const QUrl &url = DolphinView::openItemAsFolderUrl(item);
+        const auto modifiers = QGuiApplication::keyboardModifiers();
+        if (!url.isEmpty()) {
+            // keep in sync with KUrlNavigator::slotNavigatorButtonClicked
+            if (modifiers & Qt::ShiftModifier) {
+                Q_EMIT activeTabRequested(url);
+            } else {
+                Q_EMIT tabRequested(url);
+            }
+        }
     }
 }
 
@@ -897,6 +920,28 @@ void DolphinViewContainer::slotStatusBarZoomLevelChanged(int zoomLevel)
     m_view->setZoomLevel(zoomLevel);
 }
 
+void DolphinViewContainer::slotErrorMessageFromView(const QString &message, const int kioErrorCode)
+{
+    if (kioErrorCode == KIO::ERR_CANNOT_ENTER_DIRECTORY && m_view->url().scheme() == QStringLiteral("file")
+        && KProtocolInfo::isKnownProtocol(QStringLiteral("admin")) && !rootItem().isReadable()) {
+        // Explain to users that they need authentication to see the folder contents.
+        if (!m_authorizeToEnterFolderAction) { // This code is similar to parts of Admin::Bar::hideTheNextTimeAuthorizationExpires().
+            // We should not simply use the actAsAdminAction() itself here because that one always refers to the active view instead of this->m_view.
+            auto actAsAdminAction = Admin::WorkerIntegration::FriendAccess::actAsAdminAction();
+            m_authorizeToEnterFolderAction = new QAction{actAsAdminAction->icon(), actAsAdminAction->text(), this};
+            m_authorizeToEnterFolderAction->setToolTip(actAsAdminAction->toolTip());
+            m_authorizeToEnterFolderAction->setWhatsThis(actAsAdminAction->whatsThis());
+            connect(m_authorizeToEnterFolderAction, &QAction::triggered, this, [this, actAsAdminAction]() {
+                setActive(true);
+                actAsAdminAction->trigger();
+            });
+        }
+        showMessage(i18nc("@info", "Authorization required to enter this folder."), KMessageWidget::Error, {m_authorizeToEnterFolderAction});
+        return;
+    }
+    Q_EMIT showErrorMessage(message);
+}
+
 void DolphinViewContainer::showErrorMessage(const QString &message)
 {
     showMessage(message, KMessageWidget::Error);