diff options
| -rw-r--r-- | src/admin/bar.cpp | 6 | ||||
| -rw-r--r-- | src/admin/workerintegration.cpp | 10 | ||||
| -rw-r--r-- | src/admin/workerintegration.h | 20 | ||||
| -rw-r--r-- | src/dolphinviewcontainer.cpp | 26 | ||||
| -rw-r--r-- | src/dolphinviewcontainer.h | 7 | ||||
| -rw-r--r-- | src/kitemviews/kfileitemmodel.cpp | 5 | ||||
| -rw-r--r-- | src/kitemviews/kfileitemmodel.h | 2 | ||||
| -rw-r--r-- | src/views/dolphinview.cpp | 14 | ||||
| -rw-r--r-- | src/views/dolphinview.h | 2 |
9 files changed, 68 insertions, 24 deletions
diff --git a/src/admin/bar.cpp b/src/admin/bar.cpp index 52bbc3772..e01ef81a5 100644 --- a/src/admin/bar.cpp +++ b/src/admin/bar.cpp @@ -58,7 +58,7 @@ Bar::Bar(DolphinViewContainer *parentViewContainer) m_closeButton->setFlat(true); connect(m_closeButton, &QAbstractButton::clicked, m_parentViewContainer, [this]() { m_parentViewContainer->setActive(true); // Make sure the view connected to this bar is active before exiting admin mode. - QAction *actAsAdminAction = WorkerIntegration::actAsAdminAction(); + QAction *actAsAdminAction = WorkerIntegration::FriendAccess::actAsAdminAction(); if (actAsAdminAction->isChecked()) { actAsAdminAction->trigger(); } @@ -134,8 +134,8 @@ void Bar::hideTheNextTimeAuthorizationExpires() m_parentViewContainer->setUrl(viewContainerUrl); // Explain to users that their admin authorization expired. - if (!m_reenableActAsAdminAction) { - auto actAsAdminAction = WorkerIntegration::actAsAdminAction(); + if (!m_reenableActAsAdminAction) { // This code is similar to parts of DolphinViewContainer::slotViewErrorMessage(). + auto actAsAdminAction = WorkerIntegration::FriendAccess::actAsAdminAction(); m_reenableActAsAdminAction = new QAction{actAsAdminAction->icon(), i18nc("@action:button shown after acting as admin ended", "Act as Administrator Again"), this}; m_reenableActAsAdminAction->setToolTip(actAsAdminAction->toolTip()); diff --git a/src/admin/workerintegration.cpp b/src/admin/workerintegration.cpp index 0b95ec782..80d8fda1b 100644 --- a/src/admin/workerintegration.cpp +++ b/src/admin/workerintegration.cpp @@ -134,6 +134,11 @@ void WorkerIntegration::createActAsAdminAction(KActionCollection *actionCollecti } } +QAction *WorkerIntegration::FriendAccess::actAsAdminAction() +{ + return instance->m_actAsAdminAction; +} + void WorkerIntegration::toggleActAsAdmin() { auto dolphinMainWindow = static_cast<DolphinMainWindow *>(parent()); @@ -187,8 +192,3 @@ void WorkerIntegration::updateActAsAdminAction() } } } - -QAction *WorkerIntegration::actAsAdminAction() -{ - return instance->m_actAsAdminAction; -} diff --git a/src/admin/workerintegration.h b/src/admin/workerintegration.h index 19cc5c172..1e32c33d3 100644 --- a/src/admin/workerintegration.h +++ b/src/admin/workerintegration.h @@ -11,6 +11,7 @@ #include <QObject> class DolphinMainWindow; +class DolphinViewContainer; class KActionCollection; class QAction; class QUrl; @@ -57,6 +58,20 @@ public: */ static void createActAsAdminAction(KActionCollection *actionCollection, DolphinMainWindow *dolphinMainWindow); + /** + * An interface that only allows friend classes to show the WorkerIntegration::m_actAsAdminAction to users. + * Aside from these friend classes the action is only accessible through the actionCollection of DolphinMainWindow. + */ + class FriendAccess + { + /** @returns WorkerIntegration::m_actAsAdminAction or crashes if WorkerIntegration::createActAsAdminAction() has not been called previously. */ + static QAction *actAsAdminAction(); + + friend class Bar; /// Allows the bar to access the actAsAdminAction, so users can use the bar to change who they are acting as. + friend DolphinViewContainer; // Allows the view container to access the actAsAdminAction, so the action can be shown to users when they are trying to + // view a folder for which they are lacking read permissions. + }; + private: WorkerIntegration(DolphinMainWindow *parent, QAction *actAsAdminAction); @@ -69,14 +84,9 @@ private: /** Updates the toggled/checked state of the action depending on the state of the currently active view. */ static void updateActAsAdminAction(); - /** Used by the friend class Bar to show the m_actAsAdminAction to users. */ - static QAction *actAsAdminAction(); - private: /** @see createActAsAdminAction() */ QAction *const m_actAsAdminAction = nullptr; - - friend class Bar; // Allows the bar to access the actAsAdminAction, so users can use the bar to change who they are acting as. }; } diff --git a/src/dolphinviewcontainer.cpp b/src/dolphinviewcontainer.cpp index 27f845fa7..3fedef6fc 100644 --- a/src/dolphinviewcontainer.cpp +++ b/src/dolphinviewcontainer.cpp @@ -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" @@ -62,6 +63,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 +141,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); @@ -897,6 +899,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); diff --git a/src/dolphinviewcontainer.h b/src/dolphinviewcontainer.h index c5da6b48b..be28ecdeb 100644 --- a/src/dolphinviewcontainer.h +++ b/src/dolphinviewcontainer.h @@ -388,6 +388,11 @@ private Q_SLOTS: void slotStatusBarZoomLevelChanged(int zoomLevel); /** + * Creates and shows an error message based on \p message and \p kioErrorCode. + */ + void slotErrorMessageFromView(const QString &message, const int kioErrorCode); + + /** * Slot that calls showMessage(message, KMessageWidget::Error). */ void showErrorMessage(const QString &message); @@ -449,6 +454,8 @@ private: /// A bar shown at the top of the view to signify that the view is currently viewed and acted on with elevated privileges. Admin::Bar *m_adminBar; + /// An action to switch to the admin protocol. This variable will always be nullptr unless kio-admin was installed. @see Admin::WorkerIntegration. + QAction *m_authorizeToEnterFolderAction; KMessageWidget *m_messageWidget; diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp index c694da9f2..d18754ec7 100644 --- a/src/kitemviews/kfileitemmodel.cpp +++ b/src/kitemviews/kfileitemmodel.cpp @@ -2856,13 +2856,14 @@ bool KFileItemModel::isConsistent() const void KFileItemModel::slotListerError(KIO::Job *job) { - if (job->error() == KIO::ERR_IS_FILE) { + const int jobError = job->error(); + if (jobError == KIO::ERR_IS_FILE) { if (auto *listJob = qobject_cast<KIO::ListJob *>(job)) { Q_EMIT urlIsFileError(listJob->url()); } } else { const QString errorString = job->errorString(); - Q_EMIT errorMessage(!errorString.isEmpty() ? errorString : i18nc("@info:status", "Unknown error.")); + Q_EMIT errorMessage(!errorString.isEmpty() ? errorString : i18nc("@info:status", "Unknown error."), jobError); } } diff --git a/src/kitemviews/kfileitemmodel.h b/src/kitemviews/kfileitemmodel.h index ce58f89ac..5662d4fa8 100644 --- a/src/kitemviews/kfileitemmodel.h +++ b/src/kitemviews/kfileitemmodel.h @@ -258,7 +258,7 @@ Q_SIGNALS: * Is emitted if an error message (e.g. "Unknown location") * should be shown. */ - void errorMessage(const QString &message); + void errorMessage(const QString &message, const int kioErrorCode); /** * Is emitted if a redirection from the current URL \a oldUrl diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp index d42d9cfcd..85e652ecf 100644 --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -231,7 +231,9 @@ DolphinView::DolphinView(const QUrl &url, QWidget *parent) m_versionControlObserver->setView(this); m_versionControlObserver->setModel(m_model); connect(m_versionControlObserver, &VersionControlObserver::infoMessage, this, &DolphinView::infoMessage); - connect(m_versionControlObserver, &VersionControlObserver::errorMessage, this, &DolphinView::errorMessage); + connect(m_versionControlObserver, &VersionControlObserver::errorMessage, this, [this](const QString &message) { + Q_EMIT errorMessage(message, KIO::ERR_UNKNOWN); + }); connect(m_versionControlObserver, &VersionControlObserver::operationCompletedMessage, this, &DolphinView::operationCompletedMessage); m_twoClicksRenamingTimer = new QTimer(this); @@ -1453,7 +1455,7 @@ void DolphinView::onDirectoryLoadingCompletedAfterJob() void DolphinView::slotJobResult(KJob *job) { if (job->error() && job->error() != KIO::ERR_USER_CANCELED) { - Q_EMIT errorMessage(job->errorString()); + Q_EMIT errorMessage(job->errorString(), job->error()); } if (!m_selectJobCreatedItems) { m_selectedUrls.clear(); @@ -1826,7 +1828,7 @@ void DolphinView::slotTrashFileFinished(KJob *job) selectNextItem(); // Fixes BUG: 419914 via selecting next item Q_EMIT operationCompletedMessage(i18nc("@info:status", "Trash operation completed.")); } else if (job->error() != KIO::ERR_USER_CANCELED) { - Q_EMIT errorMessage(job->errorString()); + Q_EMIT errorMessage(job->errorString(), job->error()); } } @@ -1836,7 +1838,7 @@ void DolphinView::slotDeleteFileFinished(KJob *job) selectNextItem(); // Fixes BUG: 419914 via selecting next item Q_EMIT operationCompletedMessage(i18nc("@info:status", "Delete operation completed.")); } else if (job->error() != KIO::ERR_USER_CANCELED) { - Q_EMIT errorMessage(job->errorString()); + Q_EMIT errorMessage(job->errorString(), job->error()); } } @@ -2048,9 +2050,9 @@ void DolphinView::loadDirectory(const QUrl &url, bool reload) if (!url.isValid()) { const QString location(url.toDisplayString(QUrl::PreferLocalFile)); if (location.isEmpty()) { - Q_EMIT errorMessage(i18nc("@info:status", "The location is empty.")); + Q_EMIT errorMessage(i18nc("@info:status", "The location is empty."), KIO::ERR_UNKNOWN); } else { - Q_EMIT errorMessage(i18nc("@info:status", "The location '%1' is invalid.", location)); + Q_EMIT errorMessage(i18nc("@info:status", "The location '%1' is invalid.", location), KIO::ERR_UNKNOWN); } return; } diff --git a/src/views/dolphinview.h b/src/views/dolphinview.h index b55e2ee9b..c985f4eb9 100644 --- a/src/views/dolphinview.h +++ b/src/views/dolphinview.h @@ -567,7 +567,7 @@ Q_SIGNALS: * Is emitted if an error message with the content \a msg * should be shown. */ - void errorMessage(const QString &msg); + void errorMessage(const QString &message, const int kioErrorCode); /** * Is emitted if an "operation completed" message with the content \a msg |
