KXmlGui

khelpmenu.cpp
1 /*
2  This file is part of the KDE Libraries
3  SPDX-FileCopyrightText: 1999-2000 Espen Sand <[email protected]>
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 KHelpMenuPrivate
38 {
39 public:
40  KHelpMenuPrivate()
41  : mAboutData(KAboutData::applicationData())
42  {
43  }
44  ~KHelpMenuPrivate()
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 *mMenu = nullptr;
56  QDialog *mAboutApp = nullptr;
57  KAboutKdeDialog *mAboutKDE = nullptr;
58  KBugReport *mBugReport = nullptr;
59  QAction *mDonateAction = nullptr;
60  KSwitchLanguageDialog *mSwitchApplicationLanguage = nullptr;
61 
62  // TODO evaluate if we use static_cast<QWidget*>(parent()) instead of mParent to win that bit of memory
63  QWidget *mParent = nullptr;
64  QString mAboutAppText;
65 
66  bool mShowWhatsThis = false;
67  bool mActionsCreated = false;
68 
69  QAction *mHandBookAction = nullptr;
70  QAction *mWhatsThisAction = nullptr;
71  QAction *mReportBugAction = nullptr;
72  QAction *mSwitchApplicationLanguageAction = nullptr;
73  QAction *mAboutAppAction = nullptr;
74  QAction *mAboutKDEAction = nullptr;
75 
76  KAboutData mAboutData;
77 };
78 
79 KHelpMenu::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(this);
87 }
88 
89 KHelpMenu::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(this);
97 }
98 
100 {
101  delete d;
102 }
103 
104 void KHelpMenuPrivate::createActions(KHelpMenu *q)
105 {
106  if (mActionsCreated) {
107  return;
108  }
109  mActionsCreated = true;
110 
111  if (KAuthorized::authorizeAction(QStringLiteral("help_contents"))) {
113  }
114  if (mShowWhatsThis && KAuthorized::authorizeAction(QStringLiteral("help_whats_this"))) {
116  }
117 
118  if (KAuthorized::authorizeAction(QStringLiteral("help_report_bug")) && !mAboutData.bugAddress().isEmpty()) {
119  mReportBugAction = KStandardAction::reportBug(q, &KHelpMenu::reportBug, q);
120  }
121 
122  if (KAuthorized::authorizeAction(QStringLiteral("help_donate")) && mAboutData.bugAddress() == QLatin1String("[email protected]")) {
123  mDonateAction = KStandardAction::donate(q, &KHelpMenu::donate, q);
124  }
125 
126  if (KAuthorized::authorizeAction(QStringLiteral("switch_application_language"))) {
127  mSwitchApplicationLanguageAction = KStandardAction::switchApplicationLanguage(q, &KHelpMenu::switchApplicationLanguage, q);
128  }
129 
130  if (KAuthorized::authorizeAction(QStringLiteral("help_about_app"))) {
131  mAboutAppAction = KStandardAction::aboutApp(q, &KHelpMenu::aboutApplication, q);
132  }
133 
134  if (KAuthorized::authorizeAction(QStringLiteral("help_about_kde"))) {
135  mAboutKDEAction = KStandardAction::aboutKDE(q, &KHelpMenu::aboutKDE, q);
136  }
137 }
138 
139 // Used in the non-xml-gui case, like kfind or ksnapshot's help button.
141 {
142  if (!d->mMenu) {
143  d->mMenu = new QMenu(d->mParent);
144  connect(d->mMenu, &QObject::destroyed, this, &KHelpMenu::menuDestroyed);
145 
146  d->mMenu->setTitle(i18n("&Help"));
147 
148  d->createActions(this);
149 
150  bool need_separator = false;
151  if (d->mHandBookAction) {
152  d->mMenu->addAction(d->mHandBookAction);
153  need_separator = true;
154  }
155 
156  if (d->mWhatsThisAction) {
157  d->mMenu->addAction(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(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(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(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(d->mAboutAppAction);
191  }
192 
193  if (d->mAboutKDEAction) {
194  d->mMenu->addAction(d->mAboutKDEAction);
195  }
196  }
197 
198  return d->mMenu;
199 }
200 
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 
230 {
231  QDesktopServices::openUrl(QUrl(QStringLiteral("help:/")));
232 }
233 
235 {
236  if (receivers(SIGNAL(showAboutApplication())) > 0) {
238  } else { // if (d->mAboutData)
239  if (!d->mAboutApp) {
240  d->mAboutApp = new KAboutApplicationDialog(d->mAboutData, d->mParent);
241  connect(d->mAboutApp, &QDialog::finished, this, &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);
250  if (caption.isEmpty()) {
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);
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 
290 {
291  if (!d->mAboutKDE) {
292  d->mAboutKDE = new KAboutKdeDialog(d->mParent);
293  connect(d->mAboutKDE, &QDialog::finished, this, &KHelpMenu::dialogFinished);
294  }
295  d->mAboutKDE->show();
296 }
297 
299 {
300  if (!d->mBugReport) {
301  d->mBugReport = new KBugReport(d->mAboutData, d->mParent);
302  connect(d->mBugReport, &QDialog::finished, this, &KHelpMenu::dialogFinished);
303  }
304  d->mBugReport->show();
305 }
306 
308 {
309  if (!d->mSwitchApplicationLanguage) {
310  d->mSwitchApplicationLanguage = new KSwitchLanguageDialog(d->mParent);
311  connect(d->mSwitchApplicationLanguage, &QDialog::finished, this, &KHelpMenu::dialogFinished);
312  }
313  d->mSwitchApplicationLanguage->show();
314 }
315 
317 {
318  QDesktopServices::openUrl(QUrl(QLatin1String("https://www.kde.org/donate?app=") + d->mAboutData.componentName()));
319 }
320 
321 void KHelpMenu::dialogFinished()
322 {
323  QTimer::singleShot(0, this, &KHelpMenu::timerExpired);
324 }
325 
326 void KHelpMenu::timerExpired()
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::menuDestroyed()
350 {
351  d->mMenu = nullptr;
352 }
353 
355 {
357 }
QAction * donate(const QObject *recvr, const char *slot, QObject *parent)
QAction * switchApplicationLanguage(const QObject *recvr, const char *slot, QObject *parent)
QMenu * menu()
Returns a popup menu you can use in the menu bar or where you need it.
Definition: khelpmenu.cpp:140
void showAboutApplication()
This signal is emitted from aboutApplication() if no "about application" string has been defined...
void setPixmap(const QPixmap &)
void switchApplicationLanguage()
Opens the changing default application language dialog box.
Definition: khelpmenu.cpp:307
Standard "About Application" dialog box.
KHelpMenu(QWidget *parent=nullptr, const QString &aboutAppText=QString(), bool showWhatsThis=true)
Constructor.
Definition: khelpmenu.cpp:79
QAction * whatsThis(const QObject *recvr, const char *slot, QObject *parent)
A dialog box for sending bug reports.
Definition: kbugreport.h:33
void finished(int result)
QAction * reportBug(const QObject *recvr, const char *slot, QObject *parent)
QAction * aboutApp(const QObject *recvr, const char *slot, QObject *parent)
void addWidget(QWidget *widget, int stretch, Qt::Alignment alignment)
Standard KDE help menu with dialog boxes.
Definition: khelpmenu.h:108
QAction * helpContents(const QObject *recvr, const char *slot, QObject *parent)
bool isEmpty() const const
void setText(const QString &)
void reportBug()
Opens the standard "Report Bugs" dialog box.
Definition: khelpmenu.cpp:298
void donate()
Opens the donate url.
Definition: khelpmenu.cpp:316
QString i18n(const char *text, const TYPE &arg...)
PM_DefaultLayoutSpacing
void enterWhatsThisMode()
void setStandardButtons(QDialogButtonBox::StandardButtons buttons)
QAction * action(MenuId id) const
Returns the QAction * associated with the given parameter Will return a nullptr if menu() has not bee...
Definition: khelpmenu.cpp:201
~KHelpMenu() override
Destructor.
Definition: khelpmenu.cpp:99
void aboutApplication()
Opens an application specific dialog box.
Definition: khelpmenu.cpp:234
QAction * aboutKDE(const QObject *recvr, const char *slot, QObject *parent)
void aboutKDE()
Opens the standard "About KDE" dialog box.
Definition: khelpmenu.cpp:289
void contextHelpActivated()
Activates What&#39;s This help for the application.
Definition: khelpmenu.cpp:354
bool openUrl(const QUrl &url)
KCONFIGCORE_EXPORT bool authorizeAction(const QString &action)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const const
void setMargin(int margin)
QString applicationDisplayName()
void appHelpActivated()
Opens the help page for the application.
Definition: khelpmenu.cpp:229
void destroyed(QObject *obj)
void setSpacing(int spacing)
Q_EMITQ_EMIT
QString applicationName()
int receivers(const char *signal) const const
void addLayout(QLayout *layout, int stretch)
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Tue Nov 30 2021 22:46:21 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.