KCMUtils

kcmultidialog.cpp
1 /*
2  SPDX-FileCopyrightText: 2000 Matthias Elter <[email protected]>
3  SPDX-FileCopyrightText: 2003 Daniel Molkentin <[email protected]>
4  SPDX-FileCopyrightText: 2003, 2006 Matthias Kretz <[email protected]>
5  SPDX-FileCopyrightText: 2004 Frans Englich <[email protected]>
6  SPDX-FileCopyrightText: 2006 Tobias Koenig <[email protected]>
7  SPDX-FileCopyrightText: 2021 Alexander Lohnau <[email protected]>
8 
9  SPDX-License-Identifier: LGPL-2.0-or-later
10 */
11 
12 #include "kcmultidialog.h"
13 #include "kcmultidialog_p.h"
14 
15 #include "kcmoduleproxy.h"
16 #include "kcmoduleqml_p.h"
17 #include <kcmutils_debug.h>
18 
19 #include <QApplication>
20 #include <QDesktopServices>
21 #include <QJsonArray>
22 #include <QLayout>
23 #include <QProcess>
24 #include <QPushButton>
25 #include <QScreen>
26 #include <QStandardPaths>
27 #include <QStringList>
28 #include <QStyle>
29 #include <QUrl>
30 
31 #ifndef KCONFIGWIDGETS_NO_KAUTH
32 #include <KAuth/Action>
33 #include <KAuth/ObjectDecorator>
34 #endif
35 #include <KGuiItem>
36 #include <KIconUtils>
37 #include <KLocalizedString>
38 #include <KMessageBox>
39 #include <KPageWidgetModel>
40 #include <KPluginInfo>
41 
42 bool KCMultiDialogPrivate::resolveChanges(KCModuleProxy *currentProxy)
43 {
44  Q_Q(KCMultiDialog);
45  if (!currentProxy || !currentProxy->isChanged()) {
46  return true;
47  }
48 
49  // Let the user decide
50  const int queryUser = KMessageBox::warningYesNoCancel(q,
51  i18n("The settings of the current module have changed.\n"
52  "Do you want to apply the changes or discard them?"),
53  i18n("Apply Settings"),
57 
58  switch (queryUser) {
59  case KMessageBox::Yes:
60  return moduleSave(currentProxy);
61 
62  case KMessageBox::No:
63  currentProxy->load();
64  return true;
65 
66  case KMessageBox::Cancel:
67  return false;
68 
69  default:
70  Q_ASSERT(false);
71  return false;
72  }
73 }
74 
75 void KCMultiDialogPrivate::_k_slotCurrentPageChanged(KPageWidgetItem *current, KPageWidgetItem *previous)
76 {
77  Q_Q(KCMultiDialog);
78 
79  KCModuleProxy *previousModule = nullptr;
80  for (int i = 0; i < modules.count(); ++i) {
81  if (modules[i].item == previous) {
82  previousModule = modules[i].kcm;
83  }
84  }
85 
86  // Delete global margins and spacing, since we want the contents to
87  // be able to touch the edges of the window
88  q->layout()->setContentsMargins(0, 0, 0, 0);
89 
90  const KPageWidget *pageWidget = q->pageWidget();
91  pageWidget->layout()->setSpacing(0);
92 
93  // Then, we set the margins for the title header and the buttonBox footer
94  const QStyle *style = q->style();
95  const QMargins layoutMargins = QMargins(style->pixelMetric(QStyle::PM_LayoutLeftMargin),
99 
100  if (pageWidget->pageHeader()) {
101  pageWidget->pageHeader()->setContentsMargins(layoutMargins);
102  }
103 
104  // Do not set buttonBox's top margin as that space will be covered by the content's bottom margin
105  q->buttonBox()->setContentsMargins(layoutMargins.left(), 0, layoutMargins.right(), layoutMargins.bottom());
106 
107  q->blockSignals(true);
108  q->setCurrentPage(previous);
109 
110  if (resolveChanges(previousModule)) {
111  q->setCurrentPage(current);
112  }
113  q->blockSignals(false);
114 
115  // We need to get the state of the now active module
116  _k_clientChanged();
117 }
118 
119 void KCMultiDialogPrivate::_k_clientChanged()
120 {
121  Q_Q(KCMultiDialog);
122  // qDebug();
123  // Get the current module
124  KCModuleProxy *activeModule = nullptr;
125  for (int i = 0; i < modules.count(); ++i) {
126  if (modules[i].item == q->currentPage()) {
127  activeModule = modules[i].kcm;
128  break;
129  }
130  }
131 
132  bool change = false;
133  bool defaulted = false;
134  if (activeModule) {
135  change = activeModule->isChanged();
136  defaulted = activeModule->defaulted();
137 
138  QPushButton *applyButton = q->buttonBox()->button(QDialogButtonBox::Apply);
139  if (applyButton) {
141 #ifndef KCONFIGWIDGETS_NO_KAUTH
142  delete applyButton->findChild<KAuth::ObjectDecorator *>();
143 #endif
144  }
145 
146  QPushButton *okButton = q->buttonBox()->button(QDialogButtonBox::Ok);
147  if (okButton) {
149 #ifndef KCONFIGWIDGETS_NO_KAUTH
150  delete okButton->findChild<KAuth::ObjectDecorator *>();
151 #endif
152  }
153 
154 #ifndef KCONFIGWIDGETS_NO_KAUTH
155  if (activeModule->realModule()->needsAuthorization()) {
156  if (applyButton) {
157  KAuth::ObjectDecorator *decorator = new KAuth::ObjectDecorator(applyButton);
158  decorator->setAuthAction(activeModule->realModule()->authAction());
159  activeModule->realModule()->authAction().setParentWidget(activeModule->realModule());
161  }
162 
163  if (okButton) {
164  KAuth::ObjectDecorator *decorator = new KAuth::ObjectDecorator(okButton);
165  decorator->setAuthAction(activeModule->realModule()->authAction());
166  activeModule->realModule()->authAction().setParentWidget(activeModule->realModule());
168  }
169  } else {
170  if (applyButton) {
171  q->connect(applyButton, &QAbstractButton::clicked, q, &KCMultiDialog::slotApplyClicked);
172  delete applyButton->findChild<KAuth::ObjectDecorator *>();
173  }
174 
175  if (okButton) {
177  delete okButton->findChild<KAuth::ObjectDecorator *>();
178  }
179  }
180 #endif
181  }
182 
183  auto buttons = activeModule ? activeModule->buttons() : KCModule::NoAdditionalButton;
184 
185  QPushButton *resetButton = q->buttonBox()->button(QDialogButtonBox::Reset);
186  if (resetButton) {
187  resetButton->setVisible(buttons & KCModule::Apply);
188  resetButton->setEnabled(change);
189  }
190 
191  QPushButton *applyButton = q->buttonBox()->button(QDialogButtonBox::Apply);
192  if (applyButton) {
193  applyButton->setVisible(buttons & KCModule::Apply);
194  applyButton->setEnabled(change);
195  }
196 
197  QPushButton *cancelButton = q->buttonBox()->button(QDialogButtonBox::Cancel);
198  if (cancelButton) {
199  cancelButton->setVisible(buttons & KCModule::Apply);
200  }
201 
202  QPushButton *okButton = q->buttonBox()->button(QDialogButtonBox::Ok);
203  if (okButton) {
204  okButton->setVisible(buttons & KCModule::Apply);
205  }
206 
207  QPushButton *closeButton = q->buttonBox()->button(QDialogButtonBox::Close);
208  if (closeButton) {
209  closeButton->setHidden(buttons & KCModule::Apply);
210  }
211 
212  QPushButton *helpButton = q->buttonBox()->button(QDialogButtonBox::Help);
213  if (helpButton) {
214  helpButton->setVisible(buttons & KCModule::Help);
215  }
216 
217  QPushButton *defaultButton = q->buttonBox()->button(QDialogButtonBox::RestoreDefaults);
218  if (defaultButton) {
219  defaultButton->setVisible(buttons & KCModule::Default);
220  defaultButton->setEnabled(!defaulted);
221  }
222 }
223 
224 void KCMultiDialogPrivate::_k_updateHeader(bool use, const QString &message)
225 {
226  Q_Q(KCMultiDialog);
227  KPageWidgetItem *item = q->currentPage();
228  KCModuleProxy *kcm = qobject_cast<KCModuleProxy *>(item->widget());
229 
230  QString moduleName;
231  QString icon;
232 
233  if (kcm->metaData().isValid()) {
234  moduleName = kcm->metaData().name();
235  icon = kcm->metaData().iconName();
236  }
237 
238 #if KCMUTILS_BUILD_DEPRECATED_SINCE(5, 88)
239  if (kcm->moduleInfo().isValid()) {
240  moduleName = kcm->moduleInfo().moduleName();
241  icon = kcm->moduleInfo().icon();
242  }
243 #endif
244 
245  if (use) {
246  item->setHeader(QStringLiteral("<b>") + moduleName + QStringLiteral("</b><br><i>") + message + QStringLiteral("</i>"));
247  item->setIcon(KIconUtils::addOverlay(QIcon::fromTheme(icon), QIcon::fromTheme(QStringLiteral("dialog-warning")), Qt::BottomRightCorner));
248  } else {
249  item->setHeader(moduleName);
250  item->setIcon(QIcon::fromTheme(icon));
251  }
252 }
253 
254 void KCMultiDialogPrivate::init()
255 {
256  Q_Q(KCMultiDialog);
257  q->setFaceType(KPageDialog::Auto);
258  q->setWindowTitle(i18n("Configure"));
259  q->setModal(false);
260 
261  QDialogButtonBox *buttonBox = new QDialogButtonBox(q);
271  buttonBox->button(QDialogButtonBox::Close)->setVisible(false);
272  buttonBox->button(QDialogButtonBox::Reset)->setEnabled(false);
273  buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
274 
280 
281  q->setButtonBox(buttonBox);
282  q->connect(q, &KPageDialog::currentPageChanged, q, [this](KPageWidgetItem *current, KPageWidgetItem *before) {
283  _k_slotCurrentPageChanged(current, before);
284  });
285 }
286 
288  : KPageDialog(parent)
289  , d_ptr(new KCMultiDialogPrivate(this))
290 {
291  d_func()->init();
292 }
293 
295  : KPageDialog(pageWidget, parent, flags)
296  , d_ptr(new KCMultiDialogPrivate(this))
297 {
298  d_func()->init();
299 }
300 
301 KCMultiDialog::KCMultiDialog(KCMultiDialogPrivate &dd, KPageWidget *pageWidget, QWidget *parent, Qt::WindowFlags flags)
302  : KPageDialog(pageWidget, parent, flags)
303  , d_ptr(&dd)
304 {
305  d_func()->init();
306 }
307 
309 {
310  delete d_ptr;
311 }
312 
314 {
316  adjustSize();
317  /**
318  * adjustSize() relies on sizeHint but is limited to 2/3 of the desktop size
319  * Workaround for https://bugreports.qt.io/browse/QTBUG-3459
320  *
321  * We adjust the size after passing the show event
322  * because otherwise window pos is set to (0,0)
323  */
324 
325  const QSize maxSize = screen()->availableGeometry().size();
326  resize(qMin(sizeHint().width(), maxSize.width()), qMin(sizeHint().height(), maxSize.height()));
327 }
328 
330 {
332  const KPageWidgetItem *item = currentPage();
333  if (!item) {
334  return;
335  }
336 
337  for (int i = 0; i < d->modules.count(); ++i) {
338  if (d->modules[i].item == item) {
339  d->modules[i].kcm->defaults();
340  d->_k_clientChanged();
341  return;
342  }
343  }
344 }
345 
347 {
348  const KPageWidgetItem *item = currentPage();
349  if (!item) {
350  return;
351  }
352 
354  for (int i = 0; i < d->modules.count(); ++i) {
355  if (d->modules[i].item == item) {
356  d->modules[i].kcm->load();
357  d->_k_clientChanged();
358  return;
359  }
360  }
361 }
362 
363 bool KCMultiDialogPrivate::moduleSave(KCModuleProxy *module)
364 {
365  if (!module) {
366  return false;
367  }
368 
369  module->save();
370  return true;
371 }
372 
373 void KCMultiDialogPrivate::apply()
374 {
375  Q_Q(KCMultiDialog);
376  QStringList updatedComponents;
377 
378  for (const CreatedModule &module : std::as_const(modules)) {
379  KCModuleProxy *proxy = module.kcm;
380 
381  if (proxy->isChanged()) {
382  proxy->save();
383 #if KCMUTILS_BUILD_DEPRECATED_SINCE(5, 85)
384  /**
385  * Add name of the components the kcm belongs to the list
386  * of updated components.
387  */
388  const QStringList componentNames = module.componentNames;
389  for (const QString &componentName : componentNames) {
390  if (!updatedComponents.contains(componentName)) {
391  updatedComponents.append(componentName);
392  }
393  }
394 #endif
395  }
396  }
397 
398 #if KCMUTILS_BUILD_DEPRECATED_SINCE(5, 85)
399  // Send the configCommitted signal for every updated component.
400  for (const QString &name : std::as_const(updatedComponents)) {
401  Q_EMIT q->configCommitted(name.toLatin1());
402  }
403 #endif
404 
405  Q_EMIT q->configCommitted();
406 }
407 
409 {
411  applyButton->setFocus();
412 
413  d_func()->apply();
414 }
415 
417 {
419  okButton->setFocus();
420 
421  d_func()->apply();
422  accept();
423 }
424 
426 {
427  const KPageWidgetItem *item = currentPage();
428  if (!item) {
429  return;
430  }
431 
433  QString docPath;
434  for (int i = 0; i < d->modules.count(); ++i) {
435  if (d->modules[i].item == item) {
436 #if KCMUTILS_BUILD_DEPRECATED_SINCE(5, 88)
437  docPath = d->modules[i].kcm->moduleInfo().docPath();
438 #endif
439  if (docPath.isEmpty()) {
440  docPath = d->modules[i].kcm->metaData().value(QStringLiteral("X-DocPath"));
441  }
442  break;
443  }
444  }
445 
446  const QUrl docUrl = QUrl(QStringLiteral("help:/")).resolved(QUrl(docPath)); // same code as in KHelpClient::invokeHelp
447  const QString docUrlScheme = docUrl.scheme();
448  const QString helpExec = QStandardPaths::findExecutable(QStringLiteral("khelpcenter"));
449  const bool foundExec = !helpExec.isEmpty();
450  if (!foundExec) {
451  qCDebug(KCMUTILS_LOG) << "Couldn't find khelpcenter executable in PATH.";
452  }
453  if (foundExec && (docUrlScheme == QLatin1String("man") || docUrlScheme == QLatin1String("info"))) {
454  QProcess::startDetached(helpExec, QStringList() << docUrl.toString());
455  } else {
457  }
458 }
459 
461 {
464 
465  /**
466  * If we don't delete them, the DBUS registration stays, and trying to load the KCMs
467  * in other situations will lead to "module already loaded in Foo," while to the user
468  * doesn't appear so(the dialog is hidden)
469  */
470  for (auto &proxy : std::as_const(d->modules)) {
471  proxy.kcm->deleteClient();
472  }
473 }
474 
476 {
477  return addModule(metaData, QStringList());
478 }
479 
481 {
483  // Create the scroller
484  auto *moduleScroll = new UnboundScrollArea(this);
485  // Prepare the scroll area
486  moduleScroll->setWidgetResizable(true);
487  moduleScroll->setFrameStyle(QFrame::NoFrame);
488  moduleScroll->viewport()->setAutoFillBackground(false);
489 
490  KCModuleProxy *kcm = new KCModuleProxy(metaData, moduleScroll, args);
491  moduleScroll->setWidget(kcm);
492 
493  KPageWidgetItem *item = new KPageWidgetItem(moduleScroll, metaData.name());
494 
495  KCMultiDialogPrivate::CreatedModule createdModule;
496  createdModule.kcm = kcm;
497  createdModule.item = item;
498  d->modules.append(createdModule);
499 
500  if (qobject_cast<KCModuleQml *>(kcm->realModule())) {
501  item->setHeaderVisible(false);
502  }
503 
504  if (kcm->realModule() && kcm->realModule()->useRootOnlyMessage()) {
505  item->setHeader(QStringLiteral("<b>%1</b><br><i>%2</i>").arg(metaData.name(), kcm->realModule()->rootOnlyMessage()));
506  item->setIcon(KIconUtils::addOverlay(QIcon::fromTheme(metaData.iconName()), QIcon::fromTheme(QStringLiteral("dialog-warning")), Qt::BottomRightCorner));
507  } else {
508  item->setHeader(metaData.name());
509  item->setIcon(QIcon::fromTheme(metaData.iconName()));
510  }
511  const int weight = metaData.rawData().value(QStringLiteral("X-KDE-Weight")).toInt();
512  item->setProperty("_k_weight", weight);
513 
514  bool updateCurrentPage = false;
515  const KPageWidgetModel *model = qobject_cast<const KPageWidgetModel *>(pageWidget()->model());
516  Q_ASSERT(model);
517  const int siblingCount = model->rowCount();
518  int row = 0;
519  for (; row < siblingCount; ++row) {
520  KPageWidgetItem *siblingItem = model->item(model->index(row, 0));
521  if (siblingItem->property("_k_weight").toInt() > weight) {
522  // the item we found is heavier than the new module
523  // qDebug() << "adding KCM " << item->name() << " before " << siblingItem->name();
524  insertPage(siblingItem, item);
525  if (siblingItem == currentPage()) {
526  updateCurrentPage = true;
527  }
528 
529  break;
530  }
531  }
532  if (row == siblingCount) {
533  // the new module is either the first or the heaviest item
534  // qDebug() << "adding KCM " << item->name() << " at the top level";
535  addPage(item);
536  }
537 
538  QObject::connect(kcm, qOverload<bool>(&KCModuleProxy::changed), this, [d]() {
539  d->_k_clientChanged();
540  });
541 
542  QObject::connect(kcm->realModule(), &KCModule::rootOnlyMessageChanged, this, [d](bool use, const QString &message) {
543  d->_k_updateHeader(use, message);
544  });
545 
546  if (d->modules.count() == 1 || updateCurrentPage) {
547  setCurrentPage(item);
548  d->_k_clientChanged();
549  }
550  return item;
551 }
552 
553 #if KCMUTILS_BUILD_DEPRECATED_SINCE(5, 85)
555 {
556  QString complete = path;
557 
558  if (!path.endsWith(QLatin1String(".desktop"))) {
559  complete += QStringLiteral(".desktop");
560  }
561 
562  KService::Ptr service = KService::serviceByStorageId(complete);
563 
564  return addModule(KCModuleInfo(service), nullptr, args);
565 }
566 #endif
567 
568 #if KCMUTILS_BUILD_DEPRECATED_SINCE(5, 85)
570 {
572  if (!moduleInfo.isValid()) {
573  return nullptr;
574  }
575 
576  // KAuthorized::authorizeControlModule( moduleInfo.service()->menuId() ) is
577  // checked in noDisplay already
578  if (moduleInfo.service() && moduleInfo.service()->noDisplay()) {
579  return nullptr;
580  }
581 
582  // Create the scroller
583  auto *moduleScroll = new UnboundScrollArea(this);
584  // Prepare the scroll area
585  moduleScroll->setWidgetResizable(true);
586  moduleScroll->setFrameStyle(QFrame::NoFrame);
587  moduleScroll->viewport()->setAutoFillBackground(false);
588 
589  KCModuleProxy *kcm = new KCModuleProxy(moduleInfo, moduleScroll, args);
590  moduleScroll->setWidget(kcm);
591 
592  // qDebug() << moduleInfo.moduleName();
593  KPageWidgetItem *item = new KPageWidgetItem(moduleScroll, moduleInfo.moduleName());
594 
595  KCMultiDialogPrivate::CreatedModule cm;
596  cm.kcm = kcm;
597  cm.item = item;
598  cm.componentNames = moduleInfo.property(QStringLiteral("X-KDE-ParentComponents")).toStringList();
599  d->modules.append(cm);
600 
601  if (qobject_cast<KCModuleQml *>(kcm->realModule())) {
602  item->setHeaderVisible(false);
603  }
604 
605  if (kcm->realModule() && kcm->realModule()->useRootOnlyMessage()) {
606  item->setHeader(QStringLiteral("<b>") + moduleInfo.moduleName() + QStringLiteral("</b><br><i>") + kcm->realModule()->rootOnlyMessage()
607  + QStringLiteral("</i>"));
608  item->setIcon(KIconUtils::addOverlay(QIcon::fromTheme(moduleInfo.icon()), QIcon::fromTheme(QStringLiteral("dialog-warning")), Qt::BottomRightCorner));
609  } else {
610  item->setHeader(moduleInfo.moduleName());
611  item->setIcon(QIcon::fromTheme(moduleInfo.icon()));
612  }
613  item->setProperty("_k_weight", moduleInfo.weight());
614 
615  bool updateCurrentPage = false;
616  const KPageWidgetModel *model = qobject_cast<const KPageWidgetModel *>(pageWidget()->model());
617  Q_ASSERT(model);
618  if (parentItem) {
619  const QModelIndex parentIndex = model->index(parentItem);
620  const int siblingCount = model->rowCount(parentIndex);
621  int row = 0;
622  for (; row < siblingCount; ++row) {
623  KPageWidgetItem *siblingItem = model->item(model->index(row, 0, parentIndex));
624  if (siblingItem->property("_k_weight").toInt() > moduleInfo.weight()) {
625  // the item we found is heavier than the new module
626  // qDebug() << "adding KCM " << item->name() << " before " << siblingItem->name();
627  insertPage(siblingItem, item);
628  break;
629  }
630  }
631  if (row >= siblingCount) {
632  // the new module is either the first or the heaviest item
633  // qDebug() << "adding KCM " << item->name() << " with parent " << parentItem->name();
634  addSubPage(parentItem, item);
635  }
636  } else {
637  const int siblingCount = model->rowCount();
638  int row = 0;
639  for (; row < siblingCount; ++row) {
640  KPageWidgetItem *siblingItem = model->item(model->index(row, 0));
641  if (siblingItem->property("_k_weight").toInt() > moduleInfo.weight()) {
642  // the item we found is heavier than the new module
643  // qDebug() << "adding KCM " << item->name() << " before " << siblingItem->name();
644  insertPage(siblingItem, item);
645  if (siblingItem == currentPage()) {
646  updateCurrentPage = true;
647  }
648 
649  break;
650  }
651  }
652  if (row == siblingCount) {
653  // the new module is either the first or the heaviest item
654  // qDebug() << "adding KCM " << item->name() << " at the top level";
655  addPage(item);
656  }
657  }
658 
659  QObject::connect(kcm, qOverload<bool>(&KCModuleProxy::changed), this, [d]() {
660  d->_k_clientChanged();
661  });
662 
664  d->_k_updateHeader(use, message);
665  });
666 
667  if (d->modules.count() == 1 || updateCurrentPage) {
668  setCurrentPage(item);
669  d->_k_clientChanged();
670  }
671  return item;
672 }
673 #endif
674 
676 {
678  // qDebug() ;
679 
680  for (int i = 0; i < d->modules.count(); ++i) {
681  removePage(d->modules[i].item);
682  }
683 
684  d->modules.clear();
685 
686  d->_k_clientChanged();
687 }
688 
689 #include "moc_kcmultidialog.cpp"
void append(const T &value)
QList< QString > componentNames()
Definition: dispatcher.cpp:38
void adjustSize()
void setContentsMargins(int left, int top, int right, int bottom)
bool defaulted() const
QJsonObject rawData() const
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const const
KGuiItem close()
int bottom() const const
KPageWidgetItem * addModule(const QString &module, const QStringList &args=QStringList())
Add a module.
KGuiItem help()
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
void setHeaderVisible(bool visible)
virtual int rowCount(const QModelIndex &parent) const const=0
Encapsulates a KCModule for embedding.
Definition: kcmoduleproxy.h:55
void load()
Calling it will cause the contained module to run its load() routine.
void setParentWidget(QWidget *parent)
KGuiItem apply()
int toInt(int defaultValue) const const
QString scheme() const const
bool needsAuthorization() const
QLayout * layout() const const
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
KPageWidget * pageWidget()
void clicked(bool checked)
virtual bool event(QEvent *event) override
bool isChanged() const
void showEvent(QShowEvent *event) override
QIcon fromTheme(const QString &name)
bool isValid() const
void slotOkClicked()
This slot is called when the user presses the "OK" Button.
QScreen * screen() const const
KCModule::Buttons buttons() const
bool openUrl(const QUrl &url)
BottomRightCorner
int width() const const
KService::Ptr service() const
virtual void closeEvent(QCloseEvent *e) override
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
KGuiItem defaults()
QString iconName() const
void setStandardButtons(QDialogButtonBox::StandardButtons buttons)
int weight() const
virtual int pixelMetric(QStyle::PixelMetric metric, const QStyleOption *option, const QWidget *widget) const const=0
void currentPageChanged(KPageWidgetItem *current, KPageWidgetItem *before)
QString findExecutable(const QString &executableName, const QStringList &paths)
void slotApplyClicked()
This slot is called when the user presses the "Apply" Button.
KGuiItem reset()
void setIcon(const QIcon &icon)
QString icon() const
virtual void setVisible(bool visible)
int right() const const
typedef WindowFlags
void save()
Calling it will cause the contained module to run its save() routine.
void closeEvent(QCloseEvent *event) override
void setHidden(bool hidden)
bool changed() const
static void assign(QPushButton *button, const KGuiItem &item)
QString toString(QUrl::FormattingOptions options) const const
QString i18n(const char *text, const TYPE &arg...)
int height() const const
QString rootOnlyMessage() const
KPageWidgetItem * item(const QModelIndex &index) const
QString name() const
bool isEmpty() const const
~KCMultiDialog() override
Destructor.
void deleteClient()
Calling this, results in deleting the contained module, and unregistering from DCOP.
virtual void showEvent(QShowEvent *event) override
virtual void accept()
int toInt(bool *ok) const const
KCMultiDialog(QWidget *parent=nullptr)
Constructs a new KCMultiDialog.
void addPage(KPageWidgetItem *item)
QString moduleName() const
QJsonValue value(const QString &key) const const
void rootOnlyMessageChanged(bool use, QString message)
bool useRootOnlyMessage() const
KPluginMetaData metaData() const
Returns the KPluginMetaData used to load the KCM.
void slotHelpClicked()
This slot is called when the user presses the "Help" Button.
QUrl resolved(const QUrl &relative) const const
Custom QScrollArea class that doesn't limit its size hint.
QVariant property(const QString &key) const
QIcon addOverlay(const QIcon &icon, const QIcon &overlay, Qt::Corner position)
void setEnabled(bool)
PM_LayoutLeftMargin
T findChild(const QString &name, Qt::FindChildOptions options) const const
bool setProperty(const char *name, const QVariant &value)
bool startDetached(qint64 *pid)
void resize(int w, int h)
QWidget * widget() const
void removePage(KPageWidgetItem *item)
QPushButton * button(QDialogButtonBox::StandardButton which) const const
static Ptr serviceByStorageId(const QString &_storageId)
void slotDefaultClicked()
This slot is called when the user presses the "Default" Button.
int left() const const
ButtonCode warningYesNoCancel(QWidget *parent, const QString &text, const QString &caption=QString(), const KGuiItem &buttonYes=KStandardGuiItem::yes(), const KGuiItem &buttonNo=KStandardGuiItem::no(), const KGuiItem &buttonCancel=KStandardGuiItem::cancel(), const QString &dontAskAgainName=QString(), Options options=Notify)
QModelIndex index(const KPageWidgetItem *item) const
KAuth::Action authAction() const
const char * name(StandardAction id)
void clear()
Removes all modules from the dialog.
void addSubPage(KPageWidgetItem *parent, KPageWidgetItem *item)
void setContentsMargins(int left, int top, int right, int bottom)
void setSpacing(int)
void slotUser1Clicked()
This slot is called when the user presses the "Reset" Button.
void setAuthAction(const KAuth::Action &action)
bool isValid() const
Returns true if the KCM was found.
KPageWidgetItem * currentPage() const
QWidget * pageHeader() const
QStringList toStringList() const const
KGuiItem discard()
A class that provides information about a KCModule.
Definition: kcmoduleinfo.h:36
void setCurrentPage(KPageWidgetItem *item)
KGuiItem cancel()
void authorized(const KAuth::Action &action)
void setHeader(const QString &header)
void setFocus()
void insertPage(KPageWidgetItem *before, KPageWidgetItem *item)
QDialogButtonBox * buttonBox()
A class that offers a KPageDialog containing arbitrary KControl Modules.
Definition: kcmultidialog.h:28
QString message
Q_D(Todo)
virtual QSize sizeHint() const const override
KCModule * realModule() const
Access to the actual module.
QVariant property(const char *name) const const
KCModuleInfo moduleInfo() const
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Wed Jun 29 2022 03:55:18 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.