1 | /* |
2 | This file is part of the KDE Libraries |
3 | SPDX-FileCopyrightText: 1999-2000 Espen Sand <espen@kde.org> |
4 | |
5 | SPDX-License-Identifier: LGPL-2.0-or-later |
6 | */ |
7 | |
8 | // I (espen) prefer that header files are included alphabetically |
9 | |
10 | #include "khelpmenu.h" |
11 | |
12 | #include <QAction> |
13 | #include <QApplication> |
14 | #include <QDesktopServices> |
15 | #include <QDialogButtonBox> |
16 | #include <QLabel> |
17 | #include <QMenu> |
18 | #include <QStandardPaths> |
19 | #include <QStyle> |
20 | #include <QTimer> |
21 | #include <QUrl> |
22 | #include <QWhatsThis> |
23 | #include <QWidget> |
24 | |
25 | #include "kaboutapplicationdialog.h" |
26 | #include "kaboutkdedialog_p.h" |
27 | #include "kbugreport.h" |
28 | #include "kswitchlanguagedialog_p.h" |
29 | |
30 | #include <KAboutData> |
31 | #include <KAuthorized> |
32 | #include <KLocalizedString> |
33 | #include <KStandardAction> |
34 | |
35 | using namespace KDEPrivate; |
36 | |
37 | class |
38 | { |
39 | public: |
40 | () |
41 | : mAboutData(KAboutData::applicationData()) |
42 | { |
43 | } |
44 | () |
45 | { |
46 | delete mMenu; |
47 | delete mAboutApp; |
48 | delete mAboutKDE; |
49 | delete mBugReport; |
50 | delete mSwitchApplicationLanguage; |
51 | } |
52 | |
53 | void createActions(KHelpMenu *q); |
54 | |
55 | QMenu * = nullptr; |
56 | QDialog * = nullptr; |
57 | KAboutKdeDialog * = nullptr; |
58 | KBugReport * = nullptr; |
59 | QAction * = nullptr; |
60 | KSwitchLanguageDialog * = nullptr; |
61 | |
62 | // TODO evaluate if we use static_cast<QWidget*>(parent()) instead of mParent to win that bit of memory |
63 | QWidget * = nullptr; |
64 | QString ; |
65 | |
66 | bool = false; |
67 | bool = false; |
68 | |
69 | QAction *mHandBookAction = nullptr; |
70 | QAction * = nullptr; |
71 | QAction * = nullptr; |
72 | QAction * = nullptr; |
73 | QAction * = nullptr; |
74 | QAction * = nullptr; |
75 | |
76 | KAboutData ; |
77 | }; |
78 | |
79 | KHelpMenu::(QWidget *parent, const QString &aboutAppText, bool showWhatsThis) |
80 | : QObject(parent) |
81 | , d(new KHelpMenuPrivate) |
82 | { |
83 | d->mAboutAppText = aboutAppText; |
84 | d->mShowWhatsThis = showWhatsThis; |
85 | d->mParent = parent; |
86 | d->createActions(q: this); |
87 | } |
88 | |
89 | KHelpMenu::(QWidget *parent, const KAboutData &aboutData, bool showWhatsThis) |
90 | : QObject(parent) |
91 | , d(new KHelpMenuPrivate) |
92 | { |
93 | d->mShowWhatsThis = showWhatsThis; |
94 | d->mParent = parent; |
95 | d->mAboutData = aboutData; |
96 | d->createActions(q: this); |
97 | } |
98 | |
99 | KHelpMenu::() |
100 | { |
101 | delete d; |
102 | } |
103 | |
104 | void KHelpMenuPrivate::(KHelpMenu *q) |
105 | { |
106 | if (mActionsCreated) { |
107 | return; |
108 | } |
109 | mActionsCreated = true; |
110 | |
111 | if (KAuthorized::authorizeAction(QStringLiteral("help_contents" ))) { |
112 | mHandBookAction = KStandardAction::helpContents(recvr: q, slot: &KHelpMenu::appHelpActivated, parent: q); |
113 | } |
114 | if (mShowWhatsThis && KAuthorized::authorizeAction(QStringLiteral("help_whats_this" ))) { |
115 | mWhatsThisAction = KStandardAction::whatsThis(recvr: q, slot: &KHelpMenu::contextHelpActivated, parent: q); |
116 | } |
117 | |
118 | if (KAuthorized::authorizeAction(QStringLiteral("help_report_bug" )) && !mAboutData.bugAddress().isEmpty()) { |
119 | mReportBugAction = KStandardAction::reportBug(recvr: q, slot: &KHelpMenu::reportBug, parent: q); |
120 | } |
121 | |
122 | if (KAuthorized::authorizeAction(QStringLiteral("help_donate" )) && mAboutData.bugAddress() == QLatin1String("submit@bugs.kde.org" )) { |
123 | mDonateAction = KStandardAction::donate(recvr: q, slot: &KHelpMenu::donate, parent: q); |
124 | } |
125 | |
126 | if (KAuthorized::authorizeAction(QStringLiteral("switch_application_language" ))) { |
127 | mSwitchApplicationLanguageAction = KStandardAction::switchApplicationLanguage(recvr: q, slot: &KHelpMenu::switchApplicationLanguage, parent: q); |
128 | } |
129 | |
130 | if (KAuthorized::authorizeAction(QStringLiteral("help_about_app" ))) { |
131 | mAboutAppAction = KStandardAction::aboutApp(recvr: q, slot: &KHelpMenu::aboutApplication, parent: q); |
132 | } |
133 | |
134 | if (KAuthorized::authorizeAction(QStringLiteral("help_about_kde" ))) { |
135 | mAboutKDEAction = KStandardAction::aboutKDE(recvr: q, slot: &KHelpMenu::aboutKDE, parent: q); |
136 | } |
137 | } |
138 | |
139 | // Used in the non-xml-gui case, like kfind or ksnapshot's help button. |
140 | QMenu *KHelpMenu::() |
141 | { |
142 | if (!d->mMenu) { |
143 | d->mMenu = new QMenu(d->mParent); |
144 | connect(sender: d->mMenu, signal: &QObject::destroyed, context: this, slot: &KHelpMenu::menuDestroyed); |
145 | |
146 | d->mMenu->setTitle(i18n("&Help" )); |
147 | |
148 | d->createActions(q: this); |
149 | |
150 | bool need_separator = false; |
151 | if (d->mHandBookAction) { |
152 | d->mMenu->addAction(action: d->mHandBookAction); |
153 | need_separator = true; |
154 | } |
155 | |
156 | if (d->mWhatsThisAction) { |
157 | d->mMenu->addAction(action: d->mWhatsThisAction); |
158 | need_separator = true; |
159 | } |
160 | |
161 | if (d->mReportBugAction) { |
162 | if (need_separator) { |
163 | d->mMenu->addSeparator(); |
164 | } |
165 | d->mMenu->addAction(action: d->mReportBugAction); |
166 | need_separator = true; |
167 | } |
168 | |
169 | if (d->mDonateAction) { |
170 | if (need_separator) { |
171 | d->mMenu->addSeparator(); |
172 | } |
173 | d->mMenu->addAction(action: d->mDonateAction); |
174 | need_separator = true; |
175 | } |
176 | |
177 | if (d->mSwitchApplicationLanguageAction) { |
178 | if (need_separator) { |
179 | d->mMenu->addSeparator(); |
180 | } |
181 | d->mMenu->addAction(action: d->mSwitchApplicationLanguageAction); |
182 | need_separator = true; |
183 | } |
184 | |
185 | if (need_separator) { |
186 | d->mMenu->addSeparator(); |
187 | } |
188 | |
189 | if (d->mAboutAppAction) { |
190 | d->mMenu->addAction(action: d->mAboutAppAction); |
191 | } |
192 | |
193 | if (d->mAboutKDEAction) { |
194 | d->mMenu->addAction(action: d->mAboutKDEAction); |
195 | } |
196 | } |
197 | |
198 | return d->mMenu; |
199 | } |
200 | |
201 | QAction *KHelpMenu::(MenuId id) const |
202 | { |
203 | switch (id) { |
204 | case menuHelpContents: |
205 | return d->mHandBookAction; |
206 | |
207 | case menuWhatsThis: |
208 | return d->mWhatsThisAction; |
209 | |
210 | case menuReportBug: |
211 | return d->mReportBugAction; |
212 | |
213 | case menuSwitchLanguage: |
214 | return d->mSwitchApplicationLanguageAction; |
215 | |
216 | case menuAboutApp: |
217 | return d->mAboutAppAction; |
218 | |
219 | case menuAboutKDE: |
220 | return d->mAboutKDEAction; |
221 | |
222 | case menuDonate: |
223 | return d->mDonateAction; |
224 | } |
225 | |
226 | return nullptr; |
227 | } |
228 | |
229 | void KHelpMenu::() |
230 | { |
231 | QDesktopServices::openUrl(url: QUrl(QStringLiteral("help:/" ))); |
232 | } |
233 | |
234 | void KHelpMenu::() |
235 | { |
236 | if (receivers(SIGNAL(showAboutApplication())) > 0) { |
237 | Q_EMIT showAboutApplication(); |
238 | } else { // if (d->mAboutData) |
239 | if (!d->mAboutApp) { |
240 | d->mAboutApp = new KAboutApplicationDialog(d->mAboutData, d->mParent); |
241 | connect(sender: d->mAboutApp, signal: &QDialog::finished, context: this, slot: &KHelpMenu::dialogFinished); |
242 | } |
243 | d->mAboutApp->show(); |
244 | } |
245 | #if 0 // KF5: when can this happen? |
246 | else { |
247 | if (!d->mAboutApp) { |
248 | d->mAboutApp = new QDialog(d->mParent, Qt::Dialog); |
249 | QString caption = QGuiApplication::applicationDisplayName(); |
250 | if (caption.isEmpty()) { |
251 | caption = QCoreApplication::applicationName(); |
252 | } |
253 | d->mAboutApp->setWindowTitle(i18n("About %1" , caption)); |
254 | d->mAboutApp->setObjectName(QStringLiteral("about" )); |
255 | connect(d->mAboutApp, SIGNAL(finished(int)), this, SLOT(dialogFinished())); |
256 | |
257 | const int spacingHint = d->mAboutApp->style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing); |
258 | const int marginHint = d->mAboutApp->style()->pixelMetric(QStyle::PM_DefaultChildMargin); |
259 | |
260 | QVBoxLayout *vbox = new QVBoxLayout; |
261 | d->mAboutApp->setLayout(vbox); |
262 | |
263 | QHBoxLayout *hbox = new QHBoxLayout; |
264 | hbox->setSpacing(spacingHint * 3); |
265 | hbox->setMargin(marginHint * 1); |
266 | |
267 | const int size = IconSize(KIconLoader::Dialog); |
268 | QLabel *label1 = new QLabel(d->mAboutApp); |
269 | label1->setPixmap(qApp->windowIcon().pixmap(size, size)); |
270 | QLabel *label2 = new QLabel(d->mAboutApp); |
271 | label2->setText(d->mAboutAppText); |
272 | |
273 | hbox->addWidget(label1); |
274 | hbox->addWidget(label2); |
275 | |
276 | vbox->addLayout(hbox); |
277 | |
278 | QDialogButtonBox *buttonBox = new QDialogButtonBox(d->mAboutApp); |
279 | buttonBox->setStandardButtons(QDialogButtonBox::Close); |
280 | connect(buttonBox, SIGNAL(accepted()), d->mAboutApp, SLOT(accept())); |
281 | connect(buttonBox, SIGNAL(rejected()), d->mAboutApp, SLOT(reject())); |
282 | vbox->addWidget(buttonBox); |
283 | } |
284 | d->mAboutApp->show(); |
285 | } |
286 | #endif |
287 | } |
288 | |
289 | void KHelpMenu::() |
290 | { |
291 | if (!d->mAboutKDE) { |
292 | d->mAboutKDE = new KAboutKdeDialog(d->mParent); |
293 | connect(sender: d->mAboutKDE, signal: &QDialog::finished, context: this, slot: &KHelpMenu::dialogFinished); |
294 | } |
295 | d->mAboutKDE->show(); |
296 | } |
297 | |
298 | void KHelpMenu::() |
299 | { |
300 | if (!d->mBugReport) { |
301 | d->mBugReport = new KBugReport(d->mAboutData, d->mParent); |
302 | connect(sender: d->mBugReport, signal: &QDialog::finished, context: this, slot: &KHelpMenu::dialogFinished); |
303 | } |
304 | d->mBugReport->show(); |
305 | } |
306 | |
307 | void KHelpMenu::() |
308 | { |
309 | if (!d->mSwitchApplicationLanguage) { |
310 | d->mSwitchApplicationLanguage = new KSwitchLanguageDialog(d->mParent); |
311 | connect(sender: d->mSwitchApplicationLanguage, signal: &QDialog::finished, context: this, slot: &KHelpMenu::dialogFinished); |
312 | } |
313 | d->mSwitchApplicationLanguage->show(); |
314 | } |
315 | |
316 | void KHelpMenu::() |
317 | { |
318 | QDesktopServices::openUrl(url: QUrl(QLatin1String("https://www.kde.org/donate?app=" ) + d->mAboutData.componentName())); |
319 | } |
320 | |
321 | void KHelpMenu::() |
322 | { |
323 | QTimer::singleShot(interval: 0, receiver: this, slot: &KHelpMenu::timerExpired); |
324 | } |
325 | |
326 | void KHelpMenu::() |
327 | { |
328 | if (d->mAboutKDE && !d->mAboutKDE->isVisible()) { |
329 | delete d->mAboutKDE; |
330 | d->mAboutKDE = nullptr; |
331 | } |
332 | |
333 | if (d->mBugReport && !d->mBugReport->isVisible()) { |
334 | delete d->mBugReport; |
335 | d->mBugReport = nullptr; |
336 | } |
337 | |
338 | if (d->mSwitchApplicationLanguage && !d->mSwitchApplicationLanguage->isVisible()) { |
339 | delete d->mSwitchApplicationLanguage; |
340 | d->mSwitchApplicationLanguage = nullptr; |
341 | } |
342 | |
343 | if (d->mAboutApp && !d->mAboutApp->isVisible()) { |
344 | delete d->mAboutApp; |
345 | d->mAboutApp = nullptr; |
346 | } |
347 | } |
348 | |
349 | void KHelpMenu::() |
350 | { |
351 | d->mMenu = nullptr; |
352 | } |
353 | |
354 | void KHelpMenu::() |
355 | { |
356 | QWhatsThis::enterWhatsThisMode(); |
357 | } |
358 | |
359 | #include "moc_khelpmenu.cpp" |
360 | |