File indexing completed on 2024-04-21 14:53:50

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2004 Frans Englich <frans.englich@telia.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "kcmodulecontainer.h"
0009 #include <kcmutils_debug.h>
0010 
0011 #include <QTabWidget>
0012 #include <QVBoxLayout>
0013 
0014 #include <KService>
0015 #include <kcmoduleinfo.h>
0016 #include <kcmoduleproxy.h>
0017 
0018 typedef QList<KCModuleProxy *> ModuleList;
0019 
0020 #if KCMUTILS_BUILD_DEPRECATED_SINCE(5, 66)
0021 
0022 /***********************************************************************/
0023 class Q_DECL_HIDDEN KCModuleContainer::KCModuleContainerPrivate
0024 {
0025 public:
0026     KCModuleContainerPrivate(const QStringList &mods)
0027         : modules(mods)
0028     {
0029     }
0030 
0031     QStringList modules;
0032     QTabWidget *tabWidget = nullptr;
0033     KCModule::Buttons buttons;
0034     QVBoxLayout *topLayout = nullptr;
0035 
0036     /**
0037      * A list containing KCModuleProxy objects which
0038      * have changed and must be saved.
0039      */
0040     ModuleList changedModules;
0041 
0042     /**
0043      * A list of all modules which are encapsulated.
0044      */
0045     ModuleList allModules;
0046 };
0047 /***********************************************************************/
0048 
0049 // The KCModuleContainer is only a wrapper around real KCModules.
0050 /***********************************************************************/
0051 KCModuleContainer::KCModuleContainer(QWidget *parent, const QString &mods)
0052     : KCModule(parent)
0053     , d(new KCModuleContainerPrivate(QString(mods).remove(QLatin1Char(' ')).split(QLatin1Char(','), Qt::SkipEmptyParts)))
0054 {
0055     init();
0056 }
0057 
0058 KCModuleContainer::KCModuleContainer(QWidget *parent, const QStringList &mods)
0059     : KCModule(parent)
0060     , d(new KCModuleContainerPrivate(mods))
0061 {
0062     init();
0063 }
0064 
0065 void KCModuleContainer::init()
0066 {
0067     d->topLayout = new QVBoxLayout(this);
0068     d->topLayout->setContentsMargins(0, 0, 0, 0);
0069     d->topLayout->setObjectName(QStringLiteral("topLayout"));
0070     d->tabWidget = new QTabWidget(this);
0071     d->tabWidget->setObjectName(QStringLiteral("tabWidget"));
0072     connect(d->tabWidget, &QTabWidget::currentChanged, this, &KCModuleContainer::tabSwitched);
0073     d->topLayout->addWidget(d->tabWidget);
0074 
0075     if (!d->modules.isEmpty()) {
0076         /* Add our modules */
0077         for (QStringList::const_iterator it = d->modules.constBegin(), total = d->modules.constEnd(); it != total; ++it) {
0078             addModule((*it));
0079         }
0080     }
0081 }
0082 
0083 void KCModuleContainer::addModule(const QString &module)
0084 {
0085     /* In case it doesn't exist we just silently drop it.
0086      * This allows people to easily extend containers.
0087      * For example, KCM monitor gamma can be in kdegraphics.
0088      */
0089     KService::Ptr service = KService::serviceByDesktopName(module);
0090     if (!service) {
0091         // qDebug() << "KCModuleContainer: module '" <<
0092         // module << "' was not found and thus not loaded" << endl;
0093         return;
0094     }
0095 
0096     if (service->noDisplay()) {
0097         return;
0098     }
0099 
0100     KCModuleProxy *proxy = new KCModuleProxy(service, d->tabWidget);
0101     d->allModules.append(proxy);
0102 
0103     proxy->setObjectName(module);
0104 
0105     d->tabWidget->addTab(proxy,
0106                          QIcon::fromTheme(proxy->moduleInfo().icon()),
0107                          /* Qt eats ampersands for dinner. But not this time. */
0108                          proxy->moduleInfo().moduleName().replace(QLatin1Char('&'), QStringLiteral("&&")));
0109 
0110     d->tabWidget->setTabToolTip(d->tabWidget->indexOf(proxy), proxy->moduleInfo().comment());
0111 
0112     connect(proxy, qOverload<KCModuleProxy *>(&KCModuleProxy::changed), this, &KCModuleContainer::moduleChanged);
0113 
0114     /* Collect our buttons - we go for the common deliminator */
0115     setButtons(buttons() | proxy->realModule()->buttons());
0116 }
0117 
0118 void KCModuleContainer::tabSwitched(int index)
0119 {
0120     KCModuleProxy *mod = static_cast<KCModuleProxy *>(d->tabWidget->widget(index));
0121     setQuickHelp(mod->quickHelp());
0122     setAboutData(mod->aboutData());
0123 }
0124 
0125 void KCModuleContainer::save()
0126 {
0127     ModuleList list = d->changedModules;
0128     ModuleList::iterator it;
0129     for (it = list.begin(); it != list.end(); ++it) {
0130         (*it)->save();
0131     }
0132 
0133     Q_EMIT changed(false);
0134 }
0135 
0136 void KCModuleContainer::load()
0137 {
0138     ModuleList list = d->allModules;
0139     ModuleList::iterator it;
0140     for (it = list.begin(); it != list.end(); ++it) {
0141         (*it)->load();
0142     }
0143 
0144     Q_EMIT changed(false);
0145 }
0146 
0147 void KCModuleContainer::defaults()
0148 {
0149     ModuleList list = d->allModules;
0150     ModuleList::iterator it;
0151     for (it = list.begin(); it != list.end(); ++it) {
0152         (*it)->defaults();
0153     }
0154 
0155     Q_EMIT changed(true);
0156 }
0157 
0158 void KCModuleContainer::moduleChanged(KCModuleProxy *proxy)
0159 {
0160     d->changedModules.append(proxy);
0161     if (d->changedModules.isEmpty()) {
0162         return;
0163     }
0164 
0165     Q_EMIT changed(true);
0166 }
0167 
0168 KCModuleContainer::~KCModuleContainer()
0169 {
0170     delete d;
0171 }
0172 
0173 #include "moc_kcmodulecontainer.cpp"
0174 
0175 #endif
0176 
0177 /***********************************************************************/