]> cloud.milkyroute.net Git - dolphin.git/blob - src/admin/bar.cpp
SVN_SILENT made messages (.desktop file) - always resolve ours
[dolphin.git] / src / admin / bar.cpp
1 /*
2 This file is part of the KDE project
3 SPDX-FileCopyrightText: 2024 Felix Ernst <felixernst@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6 */
7
8 #include "bar.h"
9
10 #include "dolphinviewcontainer.h"
11 #include "workerintegration.h"
12
13 #include <KColorScheme>
14 #include <KContextualHelpButton>
15 #include <KIO/JobUiDelegateFactory>
16 #include <KIO/SimpleJob>
17 #include <KLocalizedString>
18
19 #include <QEvent>
20 #include <QGuiApplication>
21 #include <QHBoxLayout>
22 #include <QLabel>
23 #include <QPointer>
24 #include <QPushButton>
25 #include <QStyle>
26 #include <QToolButton>
27 #include <QWidgetAction>
28
29 using namespace Admin;
30
31 namespace
32 {
33 QPointer<KIO::SimpleJob> waitingForExpirationOfAuthorization;
34 }
35
36 Bar::Bar(DolphinViewContainer *parentViewContainer)
37 : AnimatedHeightWidget{parentViewContainer}
38 , m_parentViewContainer{parentViewContainer}
39 {
40 setAutoFillBackground(true);
41 updateColors();
42
43 QWidget *contenntsContainer = prepareContentsContainer();
44
45 m_fullLabelString = i18nc("@info label above the view explaining the state", "Acting as an Administrator — Be careful!");
46 m_shortLabelString = i18nc("@info label above the view explaining the state, keep short", "Acting as Admin");
47 m_label = new QLabel(contenntsContainer);
48 m_label->setMinimumWidth(0);
49 m_label->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard | Qt::LinksAccessibleByKeyboard); // for keyboard accessibility
50
51 m_warningButton = new KContextualHelpButton(warningMessage(), nullptr, contenntsContainer);
52 m_warningButton->setIcon(QIcon::fromTheme(QStringLiteral("emblem-warning")));
53
54 m_closeButton = new QPushButton(QIcon::fromTheme(QStringLiteral("window-close-symbolic")),
55 i18nc("@action:button Finish/Stop/Done acting as an admin", "Finish"),
56 contenntsContainer);
57 m_closeButton->setToolTip(i18nc("@info:tooltip", "Finish acting as an administrator"));
58 m_closeButton->setFlat(true);
59 connect(m_closeButton, &QAbstractButton::clicked, m_parentViewContainer, [this]() {
60 m_parentViewContainer->setActive(true); // Make sure the view connected to this bar is active before exiting admin mode.
61 QAction *actAsAdminAction = WorkerIntegration::FriendAccess::actAsAdminAction();
62 if (actAsAdminAction->isChecked()) {
63 actAsAdminAction->trigger();
64 }
65 });
66 connect(m_parentViewContainer->view(), &DolphinView::urlChanged, this, [this](const QUrl &url) {
67 // The bar is closely related to administrative rights, so we want to hide it instantly when we are no longer using the admin protocol.
68 if (url.scheme() != QStringLiteral("admin")) {
69 setVisible(false, WithAnimation);
70 }
71 });
72
73 QHBoxLayout *layout = new QHBoxLayout(contenntsContainer);
74 auto contentsMargins = layout->contentsMargins();
75 m_preferredHeight = contentsMargins.top() + m_label->sizeHint().height() + contentsMargins.bottom();
76 m_warningButton->setFixedHeight(m_preferredHeight);
77 m_closeButton->setFixedHeight(m_preferredHeight);
78 layout->setContentsMargins(0, 0, 0, 0);
79
80 layout->addStretch();
81 layout->addWidget(m_label);
82 layout->addWidget(m_warningButton);
83 layout->addStretch();
84 layout->addWidget(m_closeButton);
85 }
86
87 bool Bar::event(QEvent *event)
88 {
89 switch (event->type()) {
90 case QEvent::PaletteChange:
91 updateColors();
92 break;
93 case QEvent::Show:
94 hideTheNextTimeAuthorizationExpires();
95 break;
96 default:
97 break;
98 }
99 return AnimatedHeightWidget::event(event);
100 }
101
102 void Bar::resizeEvent(QResizeEvent *resizeEvent)
103 {
104 updateLabelString();
105 return QWidget::resizeEvent(resizeEvent);
106 }
107
108 void Bar::hideTheNextTimeAuthorizationExpires()
109 {
110 if (waitingForExpirationOfAuthorization.isNull()) {
111 QByteArray packedArgs;
112 QDataStream stream(&packedArgs, QIODevice::WriteOnly);
113 stream << (int)1;
114 waitingForExpirationOfAuthorization = KIO::special(QUrl(QStringLiteral("admin:/")), packedArgs, KIO::HideProgressInfo);
115 waitingForExpirationOfAuthorization->setUiDelegate(KIO::createDefaultJobUiDelegate(KJobUiDelegate::AutoWarningHandlingEnabled, m_parentViewContainer));
116
117 connect(waitingForExpirationOfAuthorization, &KJob::finished, this, [](KJob *job) {
118 if (job->error()) {
119 job->uiDelegate()->showErrorMessage();
120 }
121 });
122 }
123
124 connect(waitingForExpirationOfAuthorization, &KJob::finished, this, [this](KJob *job) {
125 if (job->error()) {
126 return;
127 }
128 // We exit admin mode now to avoid random password prompts popping up.
129 QUrl viewContainerUrl = m_parentViewContainer->url();
130 if (viewContainerUrl.scheme() != QStringLiteral("admin")) {
131 return;
132 }
133 viewContainerUrl.setScheme("file");
134 m_parentViewContainer->setUrl(viewContainerUrl);
135
136 // Explain to users that their admin authorization expired.
137 if (!m_reenableActAsAdminAction) { // This code is similar to parts of DolphinViewContainer::slotViewErrorMessage().
138 auto actAsAdminAction = WorkerIntegration::FriendAccess::actAsAdminAction();
139 m_reenableActAsAdminAction =
140 new QAction{actAsAdminAction->icon(), i18nc("@action:button shown after acting as admin ended", "Act as Administrator Again"), this};
141 m_reenableActAsAdminAction->setToolTip(actAsAdminAction->toolTip());
142 m_reenableActAsAdminAction->setWhatsThis(actAsAdminAction->whatsThis());
143 connect(m_reenableActAsAdminAction, &QAction::triggered, this, [this, actAsAdminAction]() {
144 m_parentViewContainer->setActive(true);
145 actAsAdminAction->trigger();
146 });
147 }
148 m_parentViewContainer->showMessage(i18nc("@info", "Administrator authorization has expired."),
149 KMessageWidget::Information,
150 {m_reenableActAsAdminAction});
151 });
152 }
153
154 void Bar::updateColors()
155 {
156 QPalette palette = parentWidget()->palette();
157 KColorScheme colorScheme{QPalette::Normal, KColorScheme::ColorSet::Window};
158 colorScheme.adjustBackground(palette, KColorScheme::NegativeBackground, QPalette::Window, KColorScheme::ColorSet::Window);
159 colorScheme.adjustForeground(palette, KColorScheme::NegativeText, QPalette::WindowText, KColorScheme::ColorSet::Window);
160 setPalette(palette);
161 }
162
163 void Bar::updateLabelString()
164 {
165 QFontMetrics fontMetrics = m_label->fontMetrics();
166 if (fontMetrics.horizontalAdvance(m_fullLabelString) + m_warningButton->sizeHint().width() + m_closeButton->sizeHint().width()
167 + style()->pixelMetric(QStyle::PM_LayoutLeftMargin) * 2 + style()->pixelMetric(QStyle::PM_LayoutRightMargin) * 2
168 < width()) {
169 m_label->setText(m_fullLabelString);
170 } else {
171 m_label->setText(m_shortLabelString);
172 }
173 }
174
175 #include "moc_bar.cpp"