]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Add "Act as Administrator" toggle action
authorFelix Ernst <felixernst@kde.org>
Sat, 11 May 2024 17:16:35 +0000 (17:16 +0000)
committerFelix Ernst <felixernst@kde.org>
Sat, 11 May 2024 17:16:35 +0000 (17:16 +0000)
This commit adds an "Act as Administrator" toggle action to the
View menu if kio-admin is installed. The action allows switching
between acting as an admin with root-access or not.

This was already possible in Dolphin when kio-admin is installed by
editing the location bar directly. However this is somewhat
unintuitive and there are no warnings at all about the dangers of
acting as an administrator.

This commit adds a warning dialog when triggering the action. It is
somewhat explicit about the risks because this is in fact very
dangerous.

Furthermore, while acting on a view with administrative privileges,
a bar above the view shows up that contains a warning. The bar can
be closed to stop acting with elevated privileges.

The warning dialog can be disabled and re-enabled from the Dolphin
settings but only if the action is even available.

There is a lot more to be done to further improve this feature both
security-wise as well as when it comes to usability. But
considering that we are already encouraging users to use this
feature without any warnings at all, I feel like now is a good time
to merge this.

This work is part of a project funded through the NGI0 Entrust
Fund, a fund established by NLnet with financial support from the
European Commission's Next Generation Internet programme, under the
aegis of DG Communications Networks, Content and Technology. As
such, please contact me if you plan on doing related work so what
you are doing doesn't collide with work I am being funded to do.

src/CMakeLists.txt
src/admin/bar.cpp [new file with mode: 0644]
src/admin/bar.h [new file with mode: 0644]
src/admin/workerintegration.cpp [new file with mode: 0644]
src/admin/workerintegration.h [new file with mode: 0644]
src/dolphinmainwindow.cpp
src/dolphinui.rc
src/dolphinviewcontainer.cpp
src/dolphinviewcontainer.h
src/settings/interface/confirmationssettingspage.cpp
src/settings/interface/confirmationssettingspage.h

index d8fdc5f4baee043d70f9c51d329f02ed89ae4532..55eda9dcd31de2b6978dc39e822a066e2d4396ab 100644 (file)
@@ -261,6 +261,8 @@ install(FILES dolphinpartactions.desktop DESTINATION "${KDE_INSTALL_DATADIR}/dol
 add_library(dolphinstatic STATIC)
 
 target_sources(dolphinstatic PRIVATE
+    admin/bar.cpp
+    admin/workerintegration.cpp
     animatedheightwidget.cpp
     disabledactionnotifier.cpp
     dolphinbookmarkhandler.cpp
@@ -320,6 +322,8 @@ target_sources(dolphinstatic PRIVATE
     global.cpp
     dolphin.qrc
 
+    admin/bar.h
+    admin/workerintegration.h
     animatedheightwidget.h
     dolphinbookmarkhandler.h
     dolphindockwidget.h
diff --git a/src/admin/bar.cpp b/src/admin/bar.cpp
new file mode 100644 (file)
index 0000000..2b65127
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+    This file is part of the KDE project
+    SPDX-FileCopyrightText: 2024 Felix Ernst <felixernst@kde.org>
+
+    SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
+*/
+
+#include "bar.h"
+
+#include "workerintegration.h"
+
+#include <KColorScheme>
+#include <KContextualHelpButton>
+#include <KLocalizedString>
+
+#include <QEvent>
+#include <QGuiApplication>
+#include <QHBoxLayout>
+#include <QLabel>
+#include <QPushButton>
+#include <QStyle>
+#include <QToolButton>
+#include <QWidgetAction>
+
+using namespace Admin;
+
+Bar::Bar(QWidget *parent)
+    : AnimatedHeightWidget{parent}
+{
+    setAutoFillBackground(true);
+    updateColors();
+
+    QWidget *contenntsContainer = prepareContentsContainer();
+
+    m_fullLabelString = i18nc("@info label above the view explaining the state", "Acting as an Administrator – Be careful!");
+    m_shortLabelString = i18nc("@info label above the view explaining the state, keep short", "Acting as Admin");
+    m_label = new QLabel(contenntsContainer);
+    m_label->setMinimumWidth(0);
+    m_label->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard | Qt::LinksAccessibleByKeyboard); // for keyboard accessibility
+
+    m_warningButton = new KContextualHelpButton(warningMessage(), nullptr, contenntsContainer);
+    m_warningButton->setIcon(QIcon::fromTheme(QStringLiteral("emblem-warning")));
+
+    m_closeButton = new QPushButton(QIcon::fromTheme(QStringLiteral("window-close-symbolic")), "", contenntsContainer);
+    m_closeButton->setToolTip(i18nc("@action:button", "Stop Acting as an Administrator"));
+    m_closeButton->setFlat(true);
+    connect(m_closeButton, &QAbstractButton::clicked, this, &Bar::activated); // Make sure the view connected to this bar is active before exiting admin mode.
+    connect(m_closeButton, &QAbstractButton::clicked, this, &WorkerIntegration::exitAdminMode);
+
+    QHBoxLayout *layout = new QHBoxLayout(contenntsContainer);
+    auto contentsMargins = layout->contentsMargins();
+    m_preferredHeight = contentsMargins.top() + m_label->sizeHint().height() + contentsMargins.bottom();
+    m_warningButton->setFixedHeight(m_preferredHeight);
+    m_closeButton->setFixedHeight(m_preferredHeight);
+    layout->setContentsMargins(0, 0, 0, 0);
+
+    layout->addStretch();
+    layout->addWidget(m_label);
+    layout->addWidget(m_warningButton);
+    layout->addStretch();
+    layout->addWidget(m_closeButton);
+}
+
+bool Bar::event(QEvent *event)
+{
+    if (event->type() == QEvent::PaletteChange) {
+        updateColors();
+    }
+    return AnimatedHeightWidget::event(event);
+}
+
+void Bar::resizeEvent(QResizeEvent *resizeEvent)
+{
+    updateLabelString();
+    return QWidget::resizeEvent(resizeEvent);
+}
+
+void Bar::updateColors()
+{
+    QPalette palette = parentWidget()->palette();
+    KColorScheme colorScheme{QPalette::Normal, KColorScheme::ColorSet::Window};
+    colorScheme.adjustBackground(palette, KColorScheme::NegativeBackground, QPalette::Window, KColorScheme::ColorSet::Window);
+    colorScheme.adjustForeground(palette, KColorScheme::NegativeText, QPalette::WindowText, KColorScheme::ColorSet::Window);
+    setPalette(palette);
+}
+
+void Bar::updateLabelString()
+{
+    QFontMetrics fontMetrics = m_label->fontMetrics();
+    if (fontMetrics.horizontalAdvance(m_fullLabelString) + m_warningButton->sizeHint().width() + m_closeButton->sizeHint().width()
+            + style()->pixelMetric(QStyle::PM_LayoutLeftMargin) * 2 + style()->pixelMetric(QStyle::PM_LayoutRightMargin) * 2
+        < width()) {
+        m_label->setText(m_fullLabelString);
+    } else {
+        m_label->setText(m_shortLabelString);
+    }
+}
+
+#include "moc_bar.cpp"
diff --git a/src/admin/bar.h b/src/admin/bar.h
new file mode 100644 (file)
index 0000000..5399fa6
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+    This file is part of the KDE project
+    SPDX-FileCopyrightText: 2024 Felix Ernst <felixernst@kde.org>
+
+    SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
+*/
+
+#ifndef ADMINBAR_H
+#define ADMINBAR_H
+
+#include "animatedheightwidget.h"
+
+class QLabel;
+class QPushButton;
+class QResizeEvent;
+class QToolButton;
+
+namespace Admin
+{
+
+/**
+ * @brief A bar appearing above the view while the user is acting with administrative privileges.
+ *
+ * It contains a warning and allows revoking this administrative mode by closing this bar.
+ */
+class Bar : public AnimatedHeightWidget
+{
+    Q_OBJECT
+
+public:
+    explicit Bar(QWidget *parent);
+
+    /** Used to recolor this bar when this application's color scheme changes. */
+    bool event(QEvent *event) override;
+
+Q_SIGNALS:
+    void activated();
+
+protected:
+    /** Calls updateLabelString() */
+    void resizeEvent(QResizeEvent *resizeEvent) override;
+
+private:
+    /** Recolors this bar based on the current color scheme. */
+    void updateColors();
+
+    /** Decides whether the m_fullLabelString or m_shortLabelString should be used based on available width. */
+    void updateLabelString();
+
+    /** @see AnimatedHeightWidget::preferredHeight() */
+    inline int preferredHeight() const override
+    {
+        return m_preferredHeight;
+    };
+
+private:
+    /** The text on this bar */
+    QLabel *m_label = nullptr;
+    /** Shows a warning about the dangers of acting with administrative privileges. */
+    QToolButton *m_warningButton = nullptr;
+    /** Closes this bar and exits the administrative mode. */
+    QPushButton *m_closeButton = nullptr;
+
+    /** @see updateLabelString() */
+    QString m_fullLabelString;
+    /** @see updateLabelString() */
+    QString m_shortLabelString;
+
+    /** @see preferredHeight() */
+    int m_preferredHeight;
+};
+
+}
+
+#endif //  ADMINBAR_H
diff --git a/src/admin/workerintegration.cpp b/src/admin/workerintegration.cpp
new file mode 100644 (file)
index 0000000..f9b5873
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+    This file is part of the KDE project
+    SPDX-FileCopyrightText: 2022 Felix Ernst <felixernst@kde.org>
+
+    SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
+*/
+
+#include "workerintegration.h"
+
+#include "dolphinmainwindow.h"
+#include "dolphinviewcontainer.h"
+
+#include <KActionCollection>
+#include <KLocalizedString>
+#include <KMessageBox>
+#include <KMessageDialog>
+#include <KProtocolInfo>
+
+#include <QAction>
+
+using namespace Admin;
+
+QString Admin::warningMessage()
+{
+    return xi18nc(
+        "@info",
+        "<para>You are about to use administrator privileges. While acting as an administrator you can change or replace any file or folder on this system. "
+        "This includes items which are critical for this system to function.</para><para>You are able to <emphasis>delete every users' data</emphasis> on this "
+        "computer and to <emphasis>break this installation beyond repair.</emphasis> Adding just one letter in a folder or file name or its contents can "
+        "render a system <emphasis>unbootable.</emphasis></para><para>There is probably not going to be another warning even if you are about to break this "
+        "system.</para><para>You might want to <emphasis>backup files and folders</emphasis> before proceeding.</para>");
+}
+
+namespace
+{
+/** The only WorkerIntegration object that is ever constructed. It is only ever accessed directly from within this file. */
+WorkerIntegration *instance = nullptr;
+}
+
+WorkerIntegration::WorkerIntegration(DolphinMainWindow *parent, QAction *actAsAdminAction)
+    : QObject{parent}
+    , m_actAsAdminAction{actAsAdminAction}
+{
+    Q_CHECK_PTR(parent);
+    Q_CHECK_PTR(actAsAdminAction);
+
+    connect(parent, &DolphinMainWindow::urlChanged, this, &WorkerIntegration::updateActAsAdminAction);
+
+    connect(actAsAdminAction, &QAction::triggered, this, &WorkerIntegration::toggleActAsAdmin);
+}
+
+void WorkerIntegration::createActAsAdminAction(KActionCollection *actionCollection, DolphinMainWindow *dolphinMainWindow)
+{
+    Q_ASSERT(!instance);
+    if (KProtocolInfo::isKnownProtocol(QStringLiteral("admin"))) {
+        QAction *actAsAdminAction = actionCollection->addAction(QStringLiteral("act_as_admin"));
+        actAsAdminAction->setText(i18nc("@action:inmenu", "Act as Administrator"));
+        actAsAdminAction->setIcon(QIcon::fromTheme(QStringLiteral("system-switch-user")));
+        actAsAdminAction->setCheckable(true);
+        actionCollection->setDefaultShortcut(actAsAdminAction, Qt::CTRL | Qt::SHIFT | Qt::ALT | Qt::Key_A);
+
+        instance = new WorkerIntegration(dolphinMainWindow, actAsAdminAction);
+    }
+}
+
+void WorkerIntegration::exitAdminMode()
+{
+    if (instance->m_actAsAdminAction->isChecked()) {
+        instance->m_actAsAdminAction->trigger();
+    }
+}
+
+void WorkerIntegration::toggleActAsAdmin()
+{
+    auto dolphinMainWindow = static_cast<DolphinMainWindow *>(parent());
+    QUrl url = dolphinMainWindow->activeViewContainer()->urlNavigator()->locationUrl();
+    if (url.scheme() == QStringLiteral("file")) {
+        bool risksAccepted = !KMessageBox::shouldBeShownContinue(warningDontShowAgainName);
+
+        if (!risksAccepted) {
+            KMessageDialog warningDialog{KMessageDialog::QuestionTwoActions, warningMessage(), dolphinMainWindow};
+            warningDialog.setCaption(i18nc("@title:window", "Risks of Acting as an Administrator"));
+            warningDialog.setIcon(QIcon::fromTheme(QStringLiteral("security-low")));
+            warningDialog.setButtons(KGuiItem{i18nc("@action:button", "I Understand and Accept These Risks"), QStringLiteral("data-warning")},
+                                     KStandardGuiItem::cancel());
+            warningDialog.setDontAskAgainText(i18nc("@option:check", "Do not warn me about these risks again"));
+
+            risksAccepted = warningDialog.exec() != 4 /* Cancel */;
+            if (warningDialog.isDontAskAgainChecked()) {
+                KMessageBox::saveDontShowAgainContinue(warningDontShowAgainName);
+            }
+
+            if (!risksAccepted) {
+                updateActAsAdminAction(); // Uncheck the action
+                return;
+            }
+        }
+
+        url.setScheme(QStringLiteral("admin"));
+    } else if (url.scheme() == QStringLiteral("admin")) {
+        url.setScheme(QStringLiteral("file"));
+    }
+    dolphinMainWindow->changeUrl(url);
+}
+
+void WorkerIntegration::updateActAsAdminAction()
+{
+    if (instance) {
+        const QString currentUrlScheme = static_cast<DolphinMainWindow *>(instance->parent())->activeViewContainer()->url().scheme();
+        if (currentUrlScheme == QStringLiteral("file")) {
+            instance->m_actAsAdminAction->setEnabled(true);
+            instance->m_actAsAdminAction->setChecked(false);
+        } else if (currentUrlScheme == QStringLiteral("admin")) {
+            instance->m_actAsAdminAction->setEnabled(true);
+            instance->m_actAsAdminAction->setChecked(true);
+        } else {
+            instance->m_actAsAdminAction->setEnabled(false);
+        }
+    }
+}
diff --git a/src/admin/workerintegration.h b/src/admin/workerintegration.h
new file mode 100644 (file)
index 0000000..5123037
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+    This file is part of the KDE project
+    SPDX-FileCopyrightText: 2022 Felix Ernst <felixernst@kde.org>
+
+    SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
+*/
+
+#ifndef ADMINWORKERINTEGRATION_H
+#define ADMINWORKERINTEGRATION_H
+
+#include <QObject>
+
+class DolphinMainWindow;
+class KActionCollection;
+class QAction;
+class QUrl;
+
+/**
+ * @brief This namespace contains everything that is necessary to nicely integrate "KIO Admin Worker" into Dolphin.
+ *
+ * @see https://commits.kde.org/kio-admin
+ */
+namespace Admin
+{
+/**
+ * Used with the KMessageBox API so users can disable the warning.
+ * @see KMessageBox::saveDontShowAgainContinue()
+ * @see KMessageBox::enableMessage()
+ */
+constexpr QLatin1String warningDontShowAgainName{"warnAboutRisksBeforeActingAsAdmin"};
+
+/** @returns an elaborate warning about the dangers of acting with administrative privileges. */
+QString warningMessage();
+
+/**
+ * @brief A class encapsulating the "Act as Admin"-toggle action.
+ *
+ * @see https://commits.kde.org/kio-admin
+ */
+class WorkerIntegration : public QObject
+{
+    Q_OBJECT
+
+public:
+    /**
+     * Adds a toggle action to the \a actionCollection.
+     * The action switches between acting as a normal user or acting as an administrator.
+     */
+    static void createActAsAdminAction(KActionCollection *actionCollection, DolphinMainWindow *dolphinMainWindow);
+
+    /**
+     * Triggers the m_actAsAdminAction only if it is currently checked.
+     */
+    static void exitAdminMode();
+
+private:
+    WorkerIntegration(DolphinMainWindow *parent, QAction *actAsAdminAction);
+
+    /**
+     * Toggles between acting with admin rights or not.
+     * This enables editing more files than the normal user account would be allowed to but requires re-authorization.
+     */
+    void toggleActAsAdmin();
+
+    /** Updates the toggled/checked state of the action depending on the state of the currently active view. */
+    static void updateActAsAdminAction();
+
+private:
+    /** @see createActAsAdminAction() */
+    QAction *const m_actAsAdminAction = nullptr;
+};
+
+}
+
+#endif // ADMINWORKERINTEGRATION_H
index cfdcb99d2ab88a8627628c8f8c40530c0da22c28..3b3d6b8d4f198b1a036e10c521ecee7ffa5ddeec 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "dolphinmainwindow.h"
 
+#include "admin/workerintegration.h"
 #include "dolphin_generalsettings.h"
 #include "dolphinbookmarkhandler.h"
 #include "dolphincontextmenu.h"
@@ -1864,6 +1865,8 @@ void DolphinMainWindow::setupActions()
     // setup 'View' menu
     // (note that most of it is set up in DolphinViewActionHandler)
 
+    Admin::WorkerIntegration::createActAsAdminAction(actionCollection(), this);
+
     m_splitViewAction = actionCollection()->add<KActionMenu>(QStringLiteral("split_view"));
     m_splitViewMenuAction = actionCollection()->addAction(QStringLiteral("split_view_menu"));
 
index dca0b61a98da00b5550077c45e015053c529d55e..2f7ea857d1c5f44ea617ae56aac8e369b19fb3f0 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <!DOCTYPE gui SYSTEM "kpartgui.dtd">
-<gui name="dolphin" version="39">
+<gui name="dolphin" version="40">
     <MenuBar>
         <Menu name="file">
             <Action name="new_menu" />
@@ -48,6 +48,7 @@
             <Action name="show_preview" />
             <Action name="show_in_groups" />
             <Action name="show_hidden_files" />
+            <Action name="act_as_admin" />
             <Separator/>
             <Action name="split_view_menu" />
             <Action name="popout_split_view" />
index cf7778c824ff160304f217be765a4f3838c6f986..5a424d17ba00002bc28026f4e26ebb21bfc2c30d 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "dolphinviewcontainer.h"
 
+#include "admin/bar.h"
 #include "dolphin_compactmodesettings.h"
 #include "dolphin_contentdisplaysettings.h"
 #include "dolphin_detailsmodesettings.h"
 // An overview of the widgets contained by this ViewContainer
 struct LayoutStructure {
     int searchBox = 0;
-    int messageWidget = 1;
-    int selectionModeTopBar = 2;
-    int view = 3;
-    int selectionModeBottomBar = 4;
-    int filterBar = 5;
-    int statusBar = 6;
+    int adminBar = 1;
+    int messageWidget = 2;
+    int selectionModeTopBar = 3;
+    int view = 4;
+    int selectionModeBottomBar = 5;
+    int filterBar = 6;
+    int statusBar = 7;
 };
 constexpr LayoutStructure positionFor;
 
@@ -62,6 +64,7 @@ DolphinViewContainer::DolphinViewContainer(const QUrl &url, QWidget *parent)
     , m_urlNavigatorConnected{nullptr}
     , m_searchBox(nullptr)
     , m_searchModeEnabled(false)
+    , m_adminBar{nullptr}
     , m_messageWidget(nullptr)
     , m_selectionModeTopBar{nullptr}
     , m_view(nullptr)
@@ -147,6 +150,7 @@ DolphinViewContainer::DolphinViewContainer(const QUrl &url, QWidget *parent)
     connect(m_view, &DolphinView::hiddenFilesShownChanged, this, &DolphinViewContainer::slotHiddenFilesShownChanged);
     connect(m_view, &DolphinView::sortHiddenLastChanged, this, &DolphinViewContainer::slotSortHiddenLastChanged);
     connect(m_view, &DolphinView::currentDirectoryRemoved, this, &DolphinViewContainer::slotCurrentDirectoryRemoved);
+    connect(m_view, &DolphinView::urlChanged, this, &DolphinViewContainer::updateAdminBarVisibility);
 
     // Initialize status bar
     m_statusBar = new DolphinStatusBar(this);
@@ -176,6 +180,7 @@ DolphinViewContainer::DolphinViewContainer(const QUrl &url, QWidget *parent)
     m_topLayout->addWidget(m_statusBar, positionFor.statusBar, 0);
 
     setSearchModeEnabled(isSearchUrl(url));
+    updateAdminBarVisibility(url);
 
     // Update view as the ContentDisplaySettings change
     // this happens here and not in DolphinView as DolphinviewContainer and DolphinView are not in the same build target ATM
@@ -768,6 +773,20 @@ void DolphinViewContainer::showItemInfo(const KFileItem &item)
     }
 }
 
+void DolphinViewContainer::updateAdminBarVisibility(const QUrl &url)
+{
+    if (url.scheme() == QStringLiteral("admin")) {
+        if (!m_adminBar) {
+            m_adminBar = new Admin::Bar(this);
+            m_topLayout->addWidget(m_adminBar, positionFor.adminBar, 0);
+            connect(m_adminBar, &Admin::Bar::activated, this, &DolphinViewContainer::activate);
+        }
+        m_adminBar->setVisible(true, WithAnimation);
+    } else if (m_adminBar) {
+        m_adminBar->setVisible(false, WithAnimation);
+    }
+}
+
 void DolphinViewContainer::closeFilterBar()
 {
     m_filterBar->closeFilterBar();
index 60c9b90d161848eeffd3d5810ca8fe815cc515d2..90df69c8e8b27d40b17e1dcd10f3132ffc342ada 100644 (file)
 #include <QPushButton>
 #include <QWidget>
 
+namespace Admin
+{
+class Bar;
+}
 class FilterBar;
 class KMessageWidget;
 class QAction;
@@ -331,6 +335,11 @@ private Q_SLOTS:
      */
     void showItemInfo(const KFileItem &item);
 
+    /**
+     * Sets the Admin::Bar visible or invisible based on whether \a url is an admin url.
+     */
+    void updateAdminBarVisibility(const QUrl &url);
+
     void closeFilterBar();
 
     /**
@@ -447,6 +456,9 @@ private:
     DolphinSearchBox *m_searchBox;
     bool m_searchModeEnabled;
 
+    /// 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;
+
     KMessageWidget *m_messageWidget;
 
     /// A bar shown at the top of the view to signify that selection mode is currently active.
index ec63cbb674271d9732f38f311574ed48e542d67b..ea8ef6dfd0e679486faa6790b8ec857cebae8cc0 100644 (file)
@@ -6,10 +6,13 @@
 
 #include "confirmationssettingspage.h"
 
+#include "admin/workerintegration.h"
 #include "dolphin_generalsettings.h"
 #include "global.h"
 
 #include <KLocalizedString>
+#include <KMessageBox>
+#include <KProtocolInfo>
 
 #include <QCheckBox>
 #include <QComboBox>
@@ -61,6 +64,7 @@ ConfirmationsSettingsPage::ConfirmationsSettingsPage(QWidget *parent)
 
     m_confirmOpenManyFolders = new QCheckBox(i18nc("@option:check Ask for confirmation in Dolphin when", "Opening many folders at once"), this);
     m_confirmOpenManyTerminals = new QCheckBox(i18nc("@option:check Ask for confirmation in Dolphin when", "Opening many terminals at once"), this);
+    m_confirmRisksOfActingAsAdmin = new QCheckBox(i18nc("@option:check Ask for confirmation in Dolphin when", "Switching to act as an administrator"), this);
 
     QLabel *executableScriptLabel = new QLabel(i18nc("@title:group", "When opening an executable file:"), this);
     executableScriptLabel->setWordWrap(true);
@@ -83,6 +87,11 @@ ConfirmationsSettingsPage::ConfirmationsSettingsPage(QWidget *parent)
 
     topLayout->addRow(nullptr, m_confirmOpenManyFolders);
     topLayout->addRow(nullptr, m_confirmOpenManyTerminals);
+    if (KProtocolInfo::isKnownProtocol(QStringLiteral("admin"))) {
+        topLayout->addRow(nullptr, m_confirmRisksOfActingAsAdmin);
+    } else {
+        m_confirmRisksOfActingAsAdmin->hide();
+    }
 
     topLayout->addItem(new QSpacerItem(0, Dolphin::VERTICAL_SPACER_HEIGHT, QSizePolicy::Fixed, QSizePolicy::Fixed));
     topLayout->addRow(executableScriptLabel, m_confirmScriptExecution);
@@ -96,6 +105,7 @@ ConfirmationsSettingsPage::ConfirmationsSettingsPage(QWidget *parent)
     connect(m_confirmClosingMultipleTabs, &QCheckBox::toggled, this, &ConfirmationsSettingsPage::changed);
     connect(m_confirmOpenManyFolders, &QCheckBox::toggled, this, &ConfirmationsSettingsPage::changed);
     connect(m_confirmOpenManyTerminals, &QCheckBox::toggled, this, &ConfirmationsSettingsPage::changed);
+    connect(m_confirmRisksOfActingAsAdmin, &QCheckBox::toggled, this, &ConfirmationsSettingsPage::changed);
 
 #if HAVE_TERMINAL
     connect(m_confirmClosingTerminalRunningProgram, &QCheckBox::toggled, this, &ConfirmationsSettingsPage::changed);
@@ -133,6 +143,11 @@ void ConfirmationsSettingsPage::applySettings()
     settings->setConfirmClosingMultipleTabs(m_confirmClosingMultipleTabs->isChecked());
     settings->setConfirmOpenManyFolders(m_confirmOpenManyFolders->isChecked());
     settings->setConfirmOpenManyTerminals(m_confirmOpenManyTerminals->isChecked());
+    if (m_confirmRisksOfActingAsAdmin->isChecked()) {
+        KMessageBox::enableMessage(Admin::warningDontShowAgainName);
+    } else {
+        KMessageBox::saveDontShowAgainContinue(Admin::warningDontShowAgainName);
+    }
 
 #if HAVE_TERMINAL
     settings->setConfirmClosingTerminalRunningProgram(m_confirmClosingTerminalRunningProgram->isChecked());
@@ -152,6 +167,7 @@ void ConfirmationsSettingsPage::restoreDefaults()
     m_confirmEmptyTrash->setChecked(ConfirmEmptyTrash);
     m_confirmDelete->setChecked(ConfirmDelete);
     m_confirmScriptExecution->setCurrentIndex(ConfirmScriptExecution);
+    KMessageBox::enableMessage(Admin::warningDontShowAgainName);
 }
 
 void ConfirmationsSettingsPage::loadSettings()
@@ -179,6 +195,7 @@ void ConfirmationsSettingsPage::loadSettings()
     // the UI has inversed meaning compared to the interpretation
     m_confirmOpenManyFolders->setChecked(GeneralSettings::confirmOpenManyFolders());
     m_confirmOpenManyTerminals->setChecked(GeneralSettings::confirmOpenManyTerminals());
+    m_confirmRisksOfActingAsAdmin->setChecked(KMessageBox::shouldBeShownContinue(Admin::warningDontShowAgainName));
 
 #if HAVE_TERMINAL
     m_confirmClosingTerminalRunningProgram->setChecked(GeneralSettings::confirmClosingTerminalRunningProgram());
index d9413d754f3200c209779c50e0ccf193904e743a..ff9aca20ea95588e01c88215af83bfa2c360b4c3 100644 (file)
@@ -45,6 +45,7 @@ private:
     QComboBox *m_confirmScriptExecution;
     QCheckBox *m_confirmOpenManyFolders;
     QCheckBox *m_confirmOpenManyTerminals;
+    QCheckBox *m_confirmRisksOfActingAsAdmin;
 };
 
 #endif