File indexing completed on 2024-09-08 09:34:33
0001 /* 0002 This file is part of the KDE libraries 0003 0004 SPDX-FileCopyrightText: 2001 Michael Goffioul <kdeprint@swing.be> 0005 SPDX-FileCopyrightText: 2004 Frans Englich <frans.englich@telia.com> 0006 SPDX-FileCopyrightText: 2009 Dario Freddi <drf@kde.org> 0007 0008 SPDX-License-Identifier: LGPL-2.0-or-later 0009 */ 0010 0011 #include "kcmodule.h" 0012 #include "kconfigwidgets_debug.h" 0013 0014 #include <KAboutData> 0015 #include <KConfigSkeleton> 0016 #include <KLocalizedString> 0017 #include <kconfigdialogmanager.h> 0018 #if KCONFIGWIDGETS_WITH_KAUTH 0019 #include <KAuth/ExecuteJob> 0020 #endif 0021 0022 class KCModulePrivate 0023 { 0024 public: 0025 KCModulePrivate() 0026 : _buttons(KCModule::Help | KCModule::Default | KCModule::Apply) 0027 , _about(nullptr) 0028 , _useRootOnlyMessage(false) 0029 , _firstshow(true) 0030 , _needsAuthorization(false) 0031 , _unmanagedWidgetChangeState(false) 0032 , _unmanagedWidgetDefaultState(false) 0033 , _unmanagedWidgetDefaultStateCalled(false) 0034 , _defaultsIndicatorsVisible(false) 0035 { 0036 } 0037 0038 void authStatusChanged(int status); 0039 0040 KCModule::Buttons _buttons; 0041 const KAboutData *_about; 0042 QString _rootOnlyMessage; 0043 QList<KConfigDialogManager *> managers; 0044 QString _quickHelp; 0045 #if KCONFIGWIDGETS_BUILD_DEPRECATED_SINCE(5, 0) 0046 QString m_ExportText; 0047 #endif 0048 bool _useRootOnlyMessage : 1; 0049 bool _firstshow : 1; 0050 0051 bool _needsAuthorization : 1; 0052 #if KCONFIGWIDGETS_WITH_KAUTH 0053 KAuth::Action _authAction; 0054 #endif 0055 0056 // this member is used to record the state on non-automatically 0057 // managed widgets, allowing for mixed KConfigXT-drive and manual 0058 // widgets to coexist peacefully and do the correct thing with 0059 // the changed(bool) signal 0060 bool _unmanagedWidgetChangeState : 1; 0061 bool _unmanagedWidgetDefaultState : 1; 0062 bool _unmanagedWidgetDefaultStateCalled : 1; 0063 0064 bool _defaultsIndicatorsVisible : 1; 0065 }; 0066 0067 #if KCONFIGWIDGETS_BUILD_DEPRECATED_SINCE(5, 85) 0068 KCModule::KCModule(const KAboutData *aboutData, QWidget *parent, const QVariantList &) 0069 : QWidget(parent) 0070 , d(new KCModulePrivate) 0071 { 0072 setAboutData(aboutData); 0073 } 0074 #endif 0075 0076 KCModule::KCModule(QWidget *parent, const QVariantList &) 0077 : QWidget(parent) 0078 , d(new KCModulePrivate) 0079 { 0080 } 0081 0082 void KCModule::showEvent(QShowEvent *ev) 0083 { 0084 if (d->_firstshow) { 0085 d->_firstshow = false; 0086 QMetaObject::invokeMethod(this, &KCModule::load, Qt::QueuedConnection); 0087 auto changedFunc = [this]() { 0088 changed(false); 0089 }; 0090 QMetaObject::invokeMethod(this, changedFunc, Qt::QueuedConnection); 0091 } 0092 0093 QWidget::showEvent(ev); 0094 } 0095 0096 KCModule::Buttons KCModule::buttons() const 0097 { 0098 return d->_buttons; 0099 } 0100 0101 void KCModule::setButtons(Buttons buttons) 0102 { 0103 d->_buttons = buttons; 0104 } 0105 0106 KConfigDialogManager *KCModule::addConfig(KCoreConfigSkeleton *config, QWidget *widget) 0107 { 0108 KConfigDialogManager *manager = new KConfigDialogManager(widget, config); 0109 manager->setObjectName(objectName()); 0110 connect(manager, &KConfigDialogManager::widgetModified, this, &KCModule::widgetChanged); 0111 connect(manager, &QObject::destroyed, this, [this, manager]() { 0112 d->managers.removeOne(manager); 0113 }); 0114 d->managers.append(manager); 0115 return manager; 0116 } 0117 0118 #if KCONFIGWIDGETS_BUILD_DEPRECATED_SINCE(5, 84) 0119 KConfigDialogManager *KCModule::addConfig(KConfigSkeleton *config, QWidget *widget) 0120 { 0121 KConfigDialogManager *manager = new KConfigDialogManager(widget, config); 0122 manager->setObjectName(objectName()); 0123 connect(manager, &KConfigDialogManager::widgetModified, this, &KCModule::widgetChanged); 0124 connect(manager, &QObject::destroyed, this, [this, manager]() { 0125 d->managers.removeOne(manager); 0126 }); 0127 d->managers.append(manager); 0128 return manager; 0129 } 0130 #endif 0131 0132 void KCModule::setNeedsAuthorization(bool needsAuth) 0133 { 0134 d->_needsAuthorization = needsAuth; 0135 #if KCONFIGWIDGETS_WITH_KAUTH 0136 if (needsAuth && d->_about) { 0137 d->_authAction = KAuth::Action(QLatin1String("org.kde.kcontrol.") + d->_about->componentName() + QLatin1String(".save")); 0138 d->_needsAuthorization = d->_authAction.isValid(); 0139 d->_authAction.setHelperId(QStringLiteral("org.kde.kcontrol.") + d->_about->componentName()); 0140 d->_authAction.setParentWidget(this); 0141 authStatusChanged(d->_authAction.status()); 0142 } else { 0143 d->_authAction = KAuth::Action(); 0144 } 0145 #endif 0146 } 0147 0148 bool KCModule::needsAuthorization() const 0149 { 0150 return d->_needsAuthorization; 0151 } 0152 0153 void KCModule::setDefaultsIndicatorsVisible(bool show) 0154 { 0155 if (d->_defaultsIndicatorsVisible == show) { 0156 return; 0157 } 0158 0159 d->_defaultsIndicatorsVisible = show; 0160 for (KConfigDialogManager *manager : std::as_const(d->managers)) { 0161 manager->setDefaultsIndicatorsVisible(show); 0162 } 0163 Q_EMIT defaultsIndicatorsVisibleChanged(show); 0164 } 0165 0166 bool KCModule::defaultsIndicatorsVisible() const 0167 { 0168 return d->_defaultsIndicatorsVisible; 0169 } 0170 0171 #if KCONFIGWIDGETS_WITH_KAUTH 0172 void KCModule::setAuthAction(const KAuth::Action &action) 0173 { 0174 if (!action.isValid()) { 0175 qCWarning(KCONFIG_WIDGETS_LOG) << "Auth action" << action.name() << "is invalid"; 0176 d->_needsAuthorization = false; 0177 return; 0178 } 0179 d->_authAction = action; 0180 d->_needsAuthorization = true; 0181 d->_authAction.setParentWidget(this); 0182 authStatusChanged(d->_authAction.status()); 0183 } 0184 0185 KAuth::Action KCModule::authAction() const 0186 { 0187 return d->_authAction; 0188 } 0189 0190 void KCModule::authStatusChanged(KAuth::Action::AuthStatus status) 0191 { 0192 switch (status) { 0193 case KAuth::Action::AuthorizedStatus: 0194 setUseRootOnlyMessage(false); 0195 break; 0196 case KAuth::Action::AuthRequiredStatus: 0197 setUseRootOnlyMessage(true); 0198 setRootOnlyMessage(i18n("You will be asked to authenticate before saving")); 0199 break; 0200 default: 0201 setUseRootOnlyMessage(true); 0202 setRootOnlyMessage(i18n("You are not allowed to save the configuration")); 0203 break; 0204 } 0205 0206 qCDebug(KCONFIG_WIDGETS_LOG) << useRootOnlyMessage(); 0207 } 0208 #endif 0209 0210 KCModule::~KCModule() 0211 { 0212 qDeleteAll(d->managers); 0213 d->managers.clear(); 0214 delete d->_about; 0215 } 0216 0217 void KCModule::load() 0218 { 0219 for (KConfigDialogManager *manager : std::as_const(d->managers)) { 0220 manager->updateWidgets(); 0221 } 0222 widgetChanged(); 0223 } 0224 0225 void KCModule::save() 0226 { 0227 for (KConfigDialogManager *manager : std::as_const(d->managers)) { 0228 manager->updateSettings(); 0229 } 0230 Q_EMIT changed(false); 0231 } 0232 0233 void KCModule::defaults() 0234 { 0235 for (KConfigDialogManager *manager : std::as_const(d->managers)) { 0236 manager->updateWidgetsDefault(); 0237 } 0238 } 0239 0240 void KCModule::widgetChanged() 0241 { 0242 Q_EMIT changed(d->_unmanagedWidgetChangeState || managedWidgetChangeState()); 0243 if (d->_unmanagedWidgetDefaultStateCalled) { 0244 Q_EMIT defaulted(d->_unmanagedWidgetDefaultState && managedWidgetDefaultState()); 0245 } else { 0246 Q_EMIT defaulted(!d->managers.isEmpty() && managedWidgetDefaultState()); 0247 } 0248 } 0249 0250 bool KCModule::managedWidgetChangeState() const 0251 { 0252 for (KConfigDialogManager *manager : std::as_const(d->managers)) { 0253 if (manager->hasChanged()) { 0254 return true; 0255 } 0256 } 0257 0258 return false; 0259 } 0260 0261 bool KCModule::managedWidgetDefaultState() const 0262 { 0263 for (KConfigDialogManager *manager : std::as_const(d->managers)) { 0264 if (!manager->isDefault()) { 0265 return false; 0266 } 0267 } 0268 0269 return true; 0270 } 0271 0272 void KCModule::unmanagedWidgetChangeState(bool changed) 0273 { 0274 d->_unmanagedWidgetChangeState = changed; 0275 widgetChanged(); 0276 } 0277 0278 void KCModule::unmanagedWidgetDefaultState(bool defaulted) 0279 { 0280 d->_unmanagedWidgetDefaultStateCalled = true; 0281 d->_unmanagedWidgetDefaultState = defaulted; 0282 widgetChanged(); 0283 } 0284 0285 #if KCONFIGWIDGETS_BUILD_DEPRECATED_SINCE(5, 90) 0286 const KAboutData *KCModule::aboutData() const 0287 { 0288 return d->_about; 0289 } 0290 #endif 0291 0292 #if KCONFIGWIDGETS_BUILD_DEPRECATED_SINCE(5, 106) 0293 void KCModule::setAboutData(const KAboutData *about) 0294 { 0295 if (about != d->_about) { 0296 delete d->_about; 0297 d->_about = about; 0298 } 0299 } 0300 #endif 0301 0302 void KCModule::setRootOnlyMessage(const QString &message) 0303 { 0304 d->_rootOnlyMessage = message; 0305 Q_EMIT rootOnlyMessageChanged(d->_useRootOnlyMessage, d->_rootOnlyMessage); 0306 } 0307 0308 QString KCModule::rootOnlyMessage() const 0309 { 0310 return d->_rootOnlyMessage; 0311 } 0312 0313 void KCModule::setUseRootOnlyMessage(bool on) 0314 { 0315 d->_useRootOnlyMessage = on; 0316 Q_EMIT rootOnlyMessageChanged(d->_useRootOnlyMessage, d->_rootOnlyMessage); 0317 } 0318 0319 bool KCModule::useRootOnlyMessage() const 0320 { 0321 return d->_useRootOnlyMessage; 0322 } 0323 0324 #if KCONFIGWIDGETS_BUILD_DEPRECATED_SINCE(5, 64) 0325 void KCModule::changed() 0326 { 0327 markAsChanged(); 0328 } 0329 #endif 0330 0331 void KCModule::markAsChanged() 0332 { 0333 Q_EMIT changed(true); 0334 } 0335 0336 #if KCONFIGWIDGETS_BUILD_DEPRECATED_SINCE(5, 90) 0337 KAboutData KCModule::componentData() const 0338 { 0339 return *d->_about; 0340 } 0341 #endif 0342 0343 #if KCONFIGWIDGETS_BUILD_DEPRECATED_SINCE(5, 0) 0344 QString KCModule::exportText() const 0345 { 0346 return d->m_ExportText; 0347 } 0348 #endif 0349 0350 #if KCONFIGWIDGETS_BUILD_DEPRECATED_SINCE(5, 0) 0351 void KCModule::setExportText(const QString &text) 0352 { 0353 d->m_ExportText = text; 0354 } 0355 #endif 0356 0357 void KCModule::setQuickHelp(const QString &help) 0358 { 0359 d->_quickHelp = help; 0360 Q_EMIT quickHelpChanged(); 0361 } 0362 0363 QString KCModule::quickHelp() const 0364 { 0365 return d->_quickHelp; 0366 } 0367 0368 QList<KConfigDialogManager *> KCModule::configs() const 0369 { 0370 return d->managers; 0371 } 0372 0373 #include "moc_kcmodule.cpp"