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

KDE's Doxygen guidelines are available online.