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

KDE's Doxygen guidelines are available online.