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 #if KCONFIGWIDGETS_WITH_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 
41 bool KCMultiDialogPrivate::resolveChanges(KCModuleProxy *currentProxy)
42 {
43  Q_Q(KCMultiDialog);
44  if (!currentProxy || !currentProxy->isChanged()) {
45  return true;
46  }
47 
48  // Let the user decide
49  const int queryUser = KMessageBox::warningTwoActionsCancel(q,
50  i18n("The settings of the current module have changed.\n"
51  "Do you want to apply the changes or discard them?"),
52  i18n("Apply Settings"),
56 
57  switch (queryUser) {
59  return moduleSave(currentProxy);
60 
62  currentProxy->load();
63  return true;
64 
65  case KMessageBox::Cancel:
66  return false;
67 
68  default:
69  Q_ASSERT(false);
70  return false;
71  }
72 }
73 
74 void KCMultiDialogPrivate::_k_slotCurrentPageChanged(KPageWidgetItem *current, KPageWidgetItem *previous)
75 {
76  Q_Q(KCMultiDialog);
77 
78  KCModuleProxy *previousModule = nullptr;
79  for (int i = 0; i < modules.count(); ++i) {
80  if (modules[i].item == previous) {
81  previousModule = modules[i].kcm;
82  }
83  }
84 
85  // Delete global margins and spacing, since we want the contents to
86  // be able to touch the edges of the window
87  q->layout()->setContentsMargins(0, 0, 0, 0);
88 
89  const KPageWidget *pageWidget = q->pageWidget();
90  pageWidget->layout()->setSpacing(0);
91 
92  // Then, we set the margins for the title header and the buttonBox footer
93  const QStyle *style = q->style();
94  const QMargins layoutMargins = QMargins(style->pixelMetric(QStyle::PM_LayoutLeftMargin),
98 
99  if (pageWidget->pageHeader()) {
100  pageWidget->pageHeader()->setContentsMargins(layoutMargins);
101  }
102 
103  // Do not set buttonBox's top margin as that space will be covered by the content's bottom margin
104  q->buttonBox()->setContentsMargins(layoutMargins.left(), 0, layoutMargins.right(), layoutMargins.bottom());
105 
106  q->blockSignals(true);
107  q->setCurrentPage(previous);
108 
109  if (resolveChanges(previousModule)) {
110  q->setCurrentPage(current);
111  }
112  q->blockSignals(false);
113 
114  // We need to get the state of the now active module
115  _k_clientChanged();
116 }
117 
118 void KCMultiDialogPrivate::_k_clientChanged()
119 {
120  Q_Q(KCMultiDialog);
121  // qDebug();
122  // Get the current module
123  KCModuleProxy *activeModule = nullptr;
124  for (int i = 0; i < modules.count(); ++i) {
125  if (modules[i].item == q->currentPage()) {
126  activeModule = modules[i].kcm;
127  break;
128  }
129  }
130 
131  bool change = false;
132  bool defaulted = false;
133  if (activeModule) {
134  change = activeModule->isChanged();
135  defaulted = activeModule->defaulted();
136 
137  QPushButton *applyButton = q->buttonBox()->button(QDialogButtonBox::Apply);
138  if (applyButton) {
140 #if KCONFIGWIDGETS_WITH_KAUTH
141  delete applyButton->findChild<KAuth::ObjectDecorator *>();
142 #endif
143  }
144 
145  QPushButton *okButton = q->buttonBox()->button(QDialogButtonBox::Ok);
146  if (okButton) {
148 #if KCONFIGWIDGETS_WITH_KAUTH
149  delete okButton->findChild<KAuth::ObjectDecorator *>();
150 #endif
151  }
152 
153 #if KCONFIGWIDGETS_WITH_KAUTH
154  if (activeModule->realModule()->needsAuthorization()) {
155  if (applyButton) {
156  KAuth::ObjectDecorator *decorator = new KAuth::ObjectDecorator(applyButton);
157  decorator->setAuthAction(activeModule->realModule()->authAction());
158  activeModule->realModule()->authAction().setParentWidget(activeModule->realModule());
160  }
161 
162  if (okButton) {
163  KAuth::ObjectDecorator *decorator = new KAuth::ObjectDecorator(okButton);
164  decorator->setAuthAction(activeModule->realModule()->authAction());
165  activeModule->realModule()->authAction().setParentWidget(activeModule->realModule());
167  }
168  } else {
169  if (applyButton) {
170  q->connect(applyButton, &QAbstractButton::clicked, q, &KCMultiDialog::slotApplyClicked);
171  delete applyButton->findChild<KAuth::ObjectDecorator *>();
172  }
173 
174  if (okButton) {
176  delete okButton->findChild<KAuth::ObjectDecorator *>();
177  }
178  }
179 #endif
180  }
181 
182  auto buttons = activeModule ? activeModule->buttons() : KCModule::NoAdditionalButton;
183 
184  QPushButton *resetButton = q->buttonBox()->button(QDialogButtonBox::Reset);
185  if (resetButton) {
186  resetButton->setVisible(buttons & KCModule::Apply);
187  resetButton->setEnabled(change);
188  }
189 
190  QPushButton *applyButton = q->buttonBox()->button(QDialogButtonBox::Apply);
191  if (applyButton) {
192  applyButton->setVisible(buttons & KCModule::Apply);
193  applyButton->setEnabled(change);
194  }
195 
196  QPushButton *cancelButton = q->buttonBox()->button(QDialogButtonBox::Cancel);
197  if (cancelButton) {
198  cancelButton->setVisible(buttons & KCModule::Apply);
199  }
200 
201  QPushButton *okButton = q->buttonBox()->button(QDialogButtonBox::Ok);
202  if (okButton) {
203  okButton->setVisible(buttons & KCModule::Apply);
204  }
205 
206  QPushButton *closeButton = q->buttonBox()->button(QDialogButtonBox::Close);
207  if (closeButton) {
208  closeButton->setHidden(buttons & KCModule::Apply);
209  }
210 
211  QPushButton *helpButton = q->buttonBox()->button(QDialogButtonBox::Help);
212  if (helpButton) {
213  helpButton->setVisible(buttons & KCModule::Help);
214  }
215 
216  QPushButton *defaultButton = q->buttonBox()->button(QDialogButtonBox::RestoreDefaults);
217  if (defaultButton) {
218  defaultButton->setVisible(buttons & KCModule::Default);
219  defaultButton->setEnabled(!defaulted);
220  }
221 }
222 
223 void KCMultiDialogPrivate::_k_updateHeader(bool use, const QString &message)
224 {
225  Q_Q(KCMultiDialog);
226  KPageWidgetItem *item = q->currentPage();
227  KCModuleProxy *kcm = qobject_cast<KCModuleProxy *>(item->widget());
228 
229  QString moduleName;
230  QString icon;
231 
232  if (kcm->metaData().isValid()) {
233  moduleName = kcm->metaData().name();
234  icon = kcm->metaData().iconName();
235  }
236 
237 #if KCMUTILS_BUILD_DEPRECATED_SINCE(5, 88)
238  if (kcm->moduleInfo().isValid()) {
239  moduleName = kcm->moduleInfo().moduleName();
240  icon = kcm->moduleInfo().icon();
241  }
242 #endif
243 
244  if (use) {
245  item->setHeader(QStringLiteral("<b>") + moduleName + QStringLiteral("</b><br><i>") + message + QStringLiteral("</i>"));
246  item->setIcon(KIconUtils::addOverlay(QIcon::fromTheme(icon), QIcon::fromTheme(QStringLiteral("dialog-warning")), Qt::BottomRightCorner));
247  } else {
248  item->setHeader(moduleName);
249  item->setIcon(QIcon::fromTheme(icon));
250  }
251 }
252 
253 void KCMultiDialogPrivate::init()
254 {
255  Q_Q(KCMultiDialog);
256  q->setFaceType(KPageDialog::Auto);
257  q->setWindowTitle(i18n("Configure"));
258  q->setModal(false);
259 
260  QDialogButtonBox *buttonBox = new QDialogButtonBox(q);
270  buttonBox->button(QDialogButtonBox::Close)->setVisible(false);
271  buttonBox->button(QDialogButtonBox::Reset)->setEnabled(false);
272  buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
273 
279 
280  q->setButtonBox(buttonBox);
281  q->connect(q, &KPageDialog::currentPageChanged, q, [this](KPageWidgetItem *current, KPageWidgetItem *before) {
282  _k_slotCurrentPageChanged(current, before);
283  });
284 }
285 
287  : KPageDialog(parent)
288  , d_ptr(new KCMultiDialogPrivate(this))
289 {
290  d_func()->init();
291 }
292 
294  : KPageDialog(pageWidget, parent, flags)
295  , d_ptr(new KCMultiDialogPrivate(this))
296 {
297  d_func()->init();
298 }
299 
300 KCMultiDialog::KCMultiDialog(KCMultiDialogPrivate &dd, KPageWidget *pageWidget, QWidget *parent, Qt::WindowFlags flags)
301  : KPageDialog(pageWidget, parent, flags)
302  , d_ptr(&dd)
303 {
304  d_func()->init();
305 }
306 
308 {
309  delete d_ptr;
310 }
311 
313 {
315  adjustSize();
316  /**
317  * adjustSize() relies on sizeHint but is limited to 2/3 of the desktop size
318  * Workaround for https://bugreports.qt.io/browse/QTBUG-3459
319  *
320  * We adjust the size after passing the show event
321  * because otherwise window pos is set to (0,0)
322  */
323 
324  const QSize maxSize = screen()->availableGeometry().size();
325  resize(qMin(sizeHint().width(), maxSize.width()), qMin(sizeHint().height(), maxSize.height()));
326 }
327 
329 {
331  const KPageWidgetItem *item = currentPage();
332  if (!item) {
333  return;
334  }
335 
336  for (int i = 0; i < d->modules.count(); ++i) {
337  if (d->modules[i].item == item) {
338  d->modules[i].kcm->defaults();
339  d->_k_clientChanged();
340  return;
341  }
342  }
343 }
344 
346 {
347  const KPageWidgetItem *item = currentPage();
348  if (!item) {
349  return;
350  }
351 
353  for (int i = 0; i < d->modules.count(); ++i) {
354  if (d->modules[i].item == item) {
355  d->modules[i].kcm->load();
356  d->_k_clientChanged();
357  return;
358  }
359  }
360 }
361 
362 bool KCMultiDialogPrivate::moduleSave(KCModuleProxy *module)
363 {
364  if (!module) {
365  return false;
366  }
367 
368  module->save();
369  return true;
370 }
371 
372 void KCMultiDialogPrivate::apply()
373 {
374  Q_Q(KCMultiDialog);
375  QStringList updatedComponents;
376 
377  for (const CreatedModule &module : std::as_const(modules)) {
378  KCModuleProxy *proxy = module.kcm;
379 
380  if (proxy->isChanged()) {
381  proxy->save();
382 #if KCMUTILS_BUILD_DEPRECATED_SINCE(5, 85)
383  /**
384  * Add name of the components the kcm belongs to the list
385  * of updated components.
386  */
387  const QStringList componentNames = module.componentNames;
388  for (const QString &componentName : componentNames) {
389  if (!updatedComponents.contains(componentName)) {
390  updatedComponents.append(componentName);
391  }
392  }
393 #endif
394  }
395  }
396 
397 #if KCMUTILS_BUILD_DEPRECATED_SINCE(5, 85)
398  // Send the configCommitted signal for every updated component.
399  for (const QString &name : std::as_const(updatedComponents)) {
400  Q_EMIT q->configCommitted(name.toLatin1());
401  }
402 #endif
403 
404  Q_EMIT q->configCommitted();
405 }
406 
408 {
410  applyButton->setFocus();
411 
412  d_func()->apply();
413 }
414 
416 {
418  okButton->setFocus();
419 
420  d_func()->apply();
421  accept();
422 }
423 
425 {
426  const KPageWidgetItem *item = currentPage();
427  if (!item) {
428  return;
429  }
430 
432  QString docPath;
433  for (int i = 0; i < d->modules.count(); ++i) {
434  if (d->modules[i].item == item) {
435 #if KCMUTILS_BUILD_DEPRECATED_SINCE(5, 88)
436  docPath = d->modules[i].kcm->moduleInfo().docPath();
437 #endif
438  if (docPath.isEmpty()) {
439  docPath = d->modules[i].kcm->metaData().value(QStringLiteral("X-DocPath"));
440  }
441  break;
442  }
443  }
444 
445  const QUrl docUrl = QUrl(QStringLiteral("help:/")).resolved(QUrl(docPath)); // same code as in KHelpClient::invokeHelp
446  const QString docUrlScheme = docUrl.scheme();
447  const QString helpExec = QStandardPaths::findExecutable(QStringLiteral("khelpcenter"));
448  const bool foundExec = !helpExec.isEmpty();
449  if (!foundExec) {
450  qCDebug(KCMUTILS_LOG) << "Couldn't find khelpcenter executable in PATH.";
451  }
452  if (foundExec && (docUrlScheme == QLatin1String("man") || docUrlScheme == QLatin1String("info"))) {
453  QProcess::startDetached(helpExec, QStringList() << docUrl.toString());
454  } else {
456  }
457 }
458 
460 {
463 
464  /**
465  * If we don't delete them, the DBUS registration stays, and trying to load the KCMs
466  * in other situations will lead to "module already loaded in Foo," while to the user
467  * doesn't appear so(the dialog is hidden)
468  */
469  for (auto &proxy : std::as_const(d->modules)) {
470  proxy.kcm->deleteClient();
471  }
472 }
473 
475 {
476  return addModule(metaData, QStringList());
477 }
478 
480 {
482  // Create the scroller
483  auto *moduleScroll = new UnboundScrollArea(this);
484  // Prepare the scroll area
485  moduleScroll->setWidgetResizable(true);
486  moduleScroll->setFrameStyle(QFrame::NoFrame);
487  moduleScroll->viewport()->setAutoFillBackground(false);
488 
489  KCModuleProxy *kcm = new KCModuleProxy(metaData, moduleScroll, args);
490  moduleScroll->setWidget(kcm);
491 
492  KPageWidgetItem *item = new KPageWidgetItem(moduleScroll, metaData.name());
493 
494  KCMultiDialogPrivate::CreatedModule createdModule;
495  createdModule.kcm = kcm;
496  createdModule.item = item;
497  d->modules.append(createdModule);
498 
499  if (qobject_cast<KCModuleQml *>(kcm->realModule())) {
500  item->setHeaderVisible(false);
501  }
502 
503  if (kcm->realModule() && kcm->realModule()->useRootOnlyMessage()) {
504  item->setHeader(QStringLiteral("<b>%1</b><br><i>%2</i>").arg(metaData.name(), kcm->realModule()->rootOnlyMessage()));
505  item->setIcon(KIconUtils::addOverlay(QIcon::fromTheme(metaData.iconName()), QIcon::fromTheme(QStringLiteral("dialog-warning")), Qt::BottomRightCorner));
506  } else {
507  item->setHeader(metaData.name());
508  item->setIcon(QIcon::fromTheme(metaData.iconName()));
509  }
510  const int weight = metaData.rawData().value(QStringLiteral("X-KDE-Weight")).toInt();
511  item->setProperty("_k_weight", weight);
512 
513  bool updateCurrentPage = false;
514  const KPageWidgetModel *model = qobject_cast<const KPageWidgetModel *>(pageWidget()->model());
515  Q_ASSERT(model);
516  const int siblingCount = model->rowCount();
517  int row = 0;
518  for (; row < siblingCount; ++row) {
519  KPageWidgetItem *siblingItem = model->item(model->index(row, 0));
520  if (siblingItem->property("_k_weight").toInt() > weight) {
521  // the item we found is heavier than the new module
522  // qDebug() << "adding KCM " << item->name() << " before " << siblingItem->name();
523  insertPage(siblingItem, item);
524  if (siblingItem == currentPage()) {
525  updateCurrentPage = true;
526  }
527 
528  break;
529  }
530  }
531  if (row == siblingCount) {
532  // the new module is either the first or the heaviest item
533  // qDebug() << "adding KCM " << item->name() << " at the top level";
534  addPage(item);
535  }
536 
537  QObject::connect(kcm, qOverload<bool>(&KCModuleProxy::changed), this, [d]() {
538  d->_k_clientChanged();
539  });
540 
541  QObject::connect(kcm->realModule(), &KCModule::rootOnlyMessageChanged, this, [d](bool use, const QString &message) {
542  d->_k_updateHeader(use, message);
543  });
544 
545  if (d->modules.count() == 1 || updateCurrentPage) {
546  setCurrentPage(item);
547  d->_k_clientChanged();
548  }
549  return item;
550 }
551 
552 #if KCMUTILS_BUILD_DEPRECATED_SINCE(5, 85)
554 {
555  QString complete = path;
556 
557  if (!path.endsWith(QLatin1String(".desktop"))) {
558  complete += QStringLiteral(".desktop");
559  }
560 
561  KService::Ptr service = KService::serviceByStorageId(complete);
562 
563  return addModule(KCModuleInfo(service), nullptr, args);
564 }
565 #endif
566 
567 #if KCMUTILS_BUILD_DEPRECATED_SINCE(5, 85)
569 {
571  if (!moduleInfo.isValid()) {
572  return nullptr;
573  }
574 
575  // KAuthorized::authorizeControlModule( moduleInfo.service()->menuId() ) is
576  // checked in noDisplay already
577  if (moduleInfo.service() && moduleInfo.service()->noDisplay()) {
578  return nullptr;
579  }
580 
581  // Create the scroller
582  auto *moduleScroll = new UnboundScrollArea(this);
583  // Prepare the scroll area
584  moduleScroll->setWidgetResizable(true);
585  moduleScroll->setFrameStyle(QFrame::NoFrame);
586  moduleScroll->viewport()->setAutoFillBackground(false);
587 
588  KCModuleProxy *kcm = new KCModuleProxy(moduleInfo, moduleScroll, args);
589  moduleScroll->setWidget(kcm);
590 
591  // qDebug() << moduleInfo.moduleName();
592  KPageWidgetItem *item = new KPageWidgetItem(moduleScroll, moduleInfo.moduleName());
593 
594  KCMultiDialogPrivate::CreatedModule cm;
595  cm.kcm = kcm;
596  cm.item = item;
597  cm.componentNames = moduleInfo.property(QStringLiteral("X-KDE-ParentComponents")).toStringList();
598  d->modules.append(cm);
599 
600  if (qobject_cast<KCModuleQml *>(kcm->realModule())) {
601  item->setHeaderVisible(false);
602  }
603 
604  if (kcm->realModule() && kcm->realModule()->useRootOnlyMessage()) {
605  item->setHeader(QStringLiteral("<b>") + moduleInfo.moduleName() + QStringLiteral("</b><br><i>") + kcm->realModule()->rootOnlyMessage()
606  + QStringLiteral("</i>"));
607  item->setIcon(KIconUtils::addOverlay(QIcon::fromTheme(moduleInfo.icon()), QIcon::fromTheme(QStringLiteral("dialog-warning")), Qt::BottomRightCorner));
608  } else {
609  item->setHeader(moduleInfo.moduleName());
610  item->setIcon(QIcon::fromTheme(moduleInfo.icon()));
611  }
612  item->setProperty("_k_weight", moduleInfo.weight());
613 
614  bool updateCurrentPage = false;
615  const KPageWidgetModel *model = qobject_cast<const KPageWidgetModel *>(pageWidget()->model());
616  Q_ASSERT(model);
617  if (parentItem) {
618  const QModelIndex parentIndex = model->index(parentItem);
619  const int siblingCount = model->rowCount(parentIndex);
620  int row = 0;
621  for (; row < siblingCount; ++row) {
622  KPageWidgetItem *siblingItem = model->item(model->index(row, 0, parentIndex));
623  if (siblingItem->property("_k_weight").toInt() > moduleInfo.weight()) {
624  // the item we found is heavier than the new module
625  // qDebug() << "adding KCM " << item->name() << " before " << siblingItem->name();
626  insertPage(siblingItem, item);
627  break;
628  }
629  }
630  if (row >= siblingCount) {
631  // the new module is either the first or the heaviest item
632  // qDebug() << "adding KCM " << item->name() << " with parent " << parentItem->name();
633  addSubPage(parentItem, item);
634  }
635  } else {
636  const int siblingCount = model->rowCount();
637  int row = 0;
638  for (; row < siblingCount; ++row) {
639  KPageWidgetItem *siblingItem = model->item(model->index(row, 0));
640  if (siblingItem->property("_k_weight").toInt() > moduleInfo.weight()) {
641  // the item we found is heavier than the new module
642  // qDebug() << "adding KCM " << item->name() << " before " << siblingItem->name();
643  insertPage(siblingItem, item);
644  if (siblingItem == currentPage()) {
645  updateCurrentPage = true;
646  }
647 
648  break;
649  }
650  }
651  if (row == siblingCount) {
652  // the new module is either the first or the heaviest item
653  // qDebug() << "adding KCM " << item->name() << " at the top level";
654  addPage(item);
655  }
656  }
657 
658  QObject::connect(kcm, qOverload<bool>(&KCModuleProxy::changed), this, [d]() {
659  d->_k_clientChanged();
660  });
661 
663  d->_k_updateHeader(use, message);
664  });
665 
666  if (d->modules.count() == 1 || updateCurrentPage) {
667  setCurrentPage(item);
668  d->_k_clientChanged();
669  }
670  return item;
671 }
672 #endif
673 
675 {
677  // qDebug() ;
678 
679  for (int i = 0; i < d->modules.count(); ++i) {
680  removePage(d->modules[i].item);
681  }
682 
683  d->modules.clear();
684 
685  d->_k_clientChanged();
686 }
687 
688 #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
int bottom() const const
KPageWidgetItem * addModule(const QString &module, const QStringList &args=QStringList())
Add a module.
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.
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
QByteArray toLatin1() const 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)
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
KGuiItem close()
void currentPageChanged(KPageWidgetItem *current, KPageWidgetItem *before)
QString findExecutable(const QString &executableName, const QStringList &paths)
KGuiItem cancel()
void slotApplyClicked()
This slot is called when the user presses the "Apply" Button.
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
QModelIndex index(const KPageWidgetItem *item) const
QString name(StandardShortcut id)
KGuiItem defaults()
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.
KGuiItem reset()
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
A class that provides information about a KCModule.
Definition: kcmoduleinfo.h:36
void setCurrentPage(KPageWidgetItem *item)
KGuiItem apply()
void authorized(const KAuth::Action &action)
void setHeader(const QString &header)
ButtonCode warningTwoActionsCancel(QWidget *parent, const QString &text, const QString &title, const KGuiItem &primaryAction, const KGuiItem &secondaryAction, const KGuiItem &cancelAction=KStandardGuiItem::cancel(), const QString &dontAskAgainName=QString(), Options options=Options(Notify|Dangerous))
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
KGuiItem discard()
Q_D(Todo)
virtual QSize sizeHint() const const override
KCModule * realModule() const
Access to the actual module.
QVariant property(const char *name) const const
KGuiItem help()
KCModuleInfo moduleInfo() const
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sun Mar 26 2023 04:11:06 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.