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

KDE's Doxygen guidelines are available online.