1 /* 2 This file is part of the KDE libraries 3 SPDX-FileCopyrightText: 1999 Matthias Hoelzer-Kluepfel <hoelzer@kde.org> 4 5 SPDX-License-Identifier: LGPL-2.0-or-later 6 */ 7 8 #ifndef KCMODULE_H 9 #define KCMODULE_H 10 11 #include <kconfigwidgets_export.h> 12 13 #ifndef KCONFIGWIDGETS_NO_KAUTH 14 #include <KAuthAction> 15 #endif 16 17 #include <QVariant> 18 #include <QWidget> 19 #include <memory> 20 21 class KAboutData; 22 class KConfigDialogManager; 23 class KCoreConfigSkeleton; 24 class KConfigSkeleton; 25 class KCModulePrivate; 26 27 /** 28 * @class KCModule kcmodule.h KCModule 29 * 30 * The base class for configuration modules. 31 * 32 * Configuration modules are realized as plugins that are loaded only when 33 * needed. 34 * 35 * The module in principle is a simple widget displaying the 36 * item to be changed. The module has a very small interface. 37 * 38 * All the necessary glue logic and the GUI bells and whistles 39 * are provided by the control center and must not concern 40 * the module author. 41 * 42 * To write a config module, you have to create a library 43 * that contains a factory function like the following: 44 * 45 * \code 46 * #include <KPluginFactory> 47 * 48 * K_PLUGIN_FACTORY(MyKCModuleFactory, registerPlugin<MyKCModule>() ) 49 * \endcode 50 * 51 * The constructor of the KCModule then looks like this: 52 * \code 53 * YourKCModule::YourKCModule( QWidget* parent ) 54 * : KCModule( parent ) 55 * { 56 * KAboutData *about = new KAboutData( 57 * <kcm name>, i18n( "..." ), 58 * KDE_VERSION_STRING, QString(), KAboutLicense::GPL, 59 * i18n( "Copyright 2006 ..." ) ); 60 * about->addAuthor( i18n(...) ); 61 * setAboutData( about ); 62 * . 63 * . 64 * . 65 * } 66 * \endcode 67 * 68 * If you want to make the KCModule available only conditionally (i.e. show in 69 * the list of available modules only if some test succeeds) then you can use 70 * Hidden in the .desktop file. An example: 71 * \code 72 * Hidden[$e]=$(if test -e /dev/js*; then echo "false"; else echo "true"; fi) 73 * \endcode 74 * The example executes the given code in a shell and uses the stdout output for 75 * the Hidden value (so it's either Hidden=true or Hidden=false). 76 * 77 * See http://techbase.kde.org/Development/Tutorials/KCM_HowTo 78 * for more detailed documentation. 79 * 80 * @author Matthias Hoelzer-Kluepfel <hoelzer@kde.org> 81 */ 82 class KCONFIGWIDGETS_EXPORT KCModule : public QWidget 83 { 84 Q_OBJECT 85 86 public: 87 /** 88 * An enumeration type for the buttons used by this module. 89 * You should only use Help, Default and Apply. The rest is obsolete. 90 * NoAdditionalButton can be used when we do not want have other button that Ok Cancel 91 * 92 * @see KCModule::buttons 93 * @see KCModule::setButtons 94 * @see Buttons 95 */ 96 enum Button { NoAdditionalButton = 0, Help = 1, Default = 2, Apply = 4, Export = 8 }; 97 /** 98 * Stores a combination of #Button values. 99 */ 100 Q_DECLARE_FLAGS(Buttons, Button) 101 102 #if KCONFIGWIDGETS_ENABLE_DEPRECATED_SINCE(5, 85) 103 /** 104 * Base class for all KControlModules. 105 * 106 * @note do not emit changed signals here, since they are not yet connected 107 * to any slot. 108 * @param aboutData becomes owned by the KCModule 109 * @deprecated since 5.85, use other constructor and setAboutData() 110 */ 111 KCONFIGWIDGETS_DEPRECATED_VERSION(5, 85, "Use other constructor and setAboutData()") 112 explicit KCModule(const KAboutData *aboutData, QWidget *parent = nullptr, const QVariantList &args = QVariantList()); 113 #endif 114 115 /** 116 * Base class for all KControlModules. 117 * 118 * @note do not emit changed signals here, since they are not yet connected 119 * to any slot. 120 */ 121 explicit KCModule(QWidget *parent = nullptr, const QVariantList &args = QVariantList()); 122 123 /** 124 * Destroys the module. 125 */ 126 ~KCModule() override; 127 128 /** 129 * Return a quick-help text. 130 * 131 * This method may be called when the module is docked. The quick help would generally 132 * be used as "what's this" text if the view container supports the "what's this" 133 * system. 134 * The quick-help text should contain a short description of the module and 135 * links to the module's help files. You can use QML formatting tags in the text. 136 * 137 * @note make sure the quick help text gets translated (use i18n()). 138 */ 139 virtual QString quickHelp() const; 140 141 /** 142 * This is generally only called for the KBugReport. 143 * If you override you should have it return a pointer to a constant. 144 * 145 * 146 * @returns the KAboutData for this module 147 */ 148 virtual const KAboutData *aboutData() const; 149 150 /** 151 * This sets the KAboutData returned by aboutData() 152 * The about data is now owned by KCModule. 153 */ 154 void setAboutData(const KAboutData *about); 155 156 /** 157 * Indicate which buttons will be used. 158 * 159 * The return value is a value or'ed together from 160 * the Button enumeration type. 161 * 162 * @see KCModule::setButtons 163 */ 164 Buttons buttons() const; 165 166 /** 167 * Get the RootOnly message for this module. 168 * 169 * When the module must be run as root, or acts differently 170 * for root and a normal user, it is sometimes useful to 171 * customize the message that appears at the top of the module 172 * when used as a normal user. This function returns this 173 * customized message. If none has been set, a default message 174 * will be used. 175 * 176 * @see KCModule::setRootOnlyMessage 177 */ 178 QString rootOnlyMessage() const; 179 180 /** 181 * Tell if KControl should show a RootOnly message when run as 182 * a normal user. 183 * 184 * In some cases, the module don't want a RootOnly message to 185 * appear (for example if it has already one). This function 186 * tells KControl if a RootOnly message should be shown 187 * 188 * @see KCModule::setUseRootOnlyMessage 189 */ 190 bool useRootOnlyMessage() const; 191 192 KAboutData componentData() const; 193 194 /** 195 * @return a list of @ref KConfigDialogManager's in use, if any. 196 */ 197 QList<KConfigDialogManager *> configs() const; 198 199 /** 200 * @brief Set if the module's save() method requires authorization to be executed. 201 * 202 * The module can set this property to @c true if it requires authorization. 203 * It will still have to execute the action itself using the KAuth library, so 204 * this method is not technically needed to perform the action, but 205 * using this and/or the setAuthAction() method will ensure that hosting 206 * applications like System Settings or kcmshell behave correctly. 207 * 208 * Called with @c true, this method will set the action to "org.kde.kcontrol.name.save" where 209 * "name" is aboutData()->appName() return value. This default action won't be set if 210 * the aboutData() object is not valid. 211 * 212 * Note that called with @c false, this method will reset the action name set with setAuthAction(). 213 * 214 * @param needsAuth Tells if the module's save() method requires authorization to be executed. 215 */ 216 void setNeedsAuthorization(bool needsAuth); 217 218 /** 219 * Returns the value previously set with setNeedsAuthorization() or setAuthAction(). By default it's @c false. 220 * 221 * @return @c true if the module's save() method requires authorization, @c false otherwise 222 */ 223 bool needsAuthorization() const; 224 225 /** 226 * Returns whether an indicator is shown when a setting differs from default. 227 * 228 * @since 5.73 229 */ 230 bool defaultsIndicatorsVisible() const; 231 232 #ifndef KCONFIGWIDGETS_NO_KAUTH 233 /** 234 * @brief Set if the module's save() method requires authorization to be executed 235 * 236 * It will still have to execute the action itself using the KAuth library, so 237 * this method is not technically needed to perform the action, but 238 * using this method will ensure that hosting 239 * applications like System Settings or kcmshell behave correctly. 240 * 241 * @param action the action that will be used by this KCModule 242 */ 243 void setAuthAction(const KAuth::Action &action); 244 245 /** 246 * Returns the action previously set with setAuthAction(). By default its an invalid action. 247 * 248 * @return The action that has to be authorized to execute the save() method. 249 */ 250 KAuth::Action authAction() const; 251 #endif 252 253 #if KCONFIGWIDGETS_ENABLE_DEPRECATED_SINCE(5, 0) 254 /** 255 * Returns the value set by setExportText(); 256 * @deprecated since 5.0, obsolete feature 257 */ 258 KCONFIGWIDGETS_DEPRECATED_VERSION(5, 0, "Obsolete feature") 259 QString exportText() const; 260 #endif 261 262 #if KCONFIGWIDGETS_ENABLE_DEPRECATED_SINCE(5, 0) 263 /** 264 * Sets the export QString value, used for exporting data. 265 * @deprecated since 5.0, obsolete feature 266 */ 267 KCONFIGWIDGETS_DEPRECATED_VERSION(5, 0, "Obsolete feature") 268 void setExportText(const QString &); 269 #endif 270 271 public Q_SLOTS: 272 /** 273 * Load the configuration data into the module. 274 * 275 * The load method sets the user interface elements of the 276 * module to reflect the current settings stored in the 277 * configuration files. 278 * 279 * This method is invoked whenever the module should read its configuration 280 * (most of the times from a config file) and update the user interface. 281 * This happens when the user clicks the "Reset" button in the control 282 * center, to undo all of his changes and restore the currently valid 283 * settings. It is also called right after construction. 284 */ 285 virtual void load(); 286 287 /** 288 * Save the configuration data. 289 * 290 * The save method stores the config information as shown 291 * in the user interface in the config files. 292 * 293 * If necessary, this method also updates the running system, 294 * e.g. by restarting applications. This normally does not apply for 295 * KSettings::Dialog modules where the updating is taken care of by 296 * KSettings::Dispatcher. 297 * 298 * save is called when the user clicks "Apply" or "Ok". 299 * 300 * If you use KConfigXT, saving is taken care off automatically and 301 * you do not need to load manually. However, if you for some reason reimplement it and 302 * also are using KConfigXT, you must call this function, otherwise the saving of KConfigXT 303 * options will not work. Call it at the very end of your reimplementation, to avoid 304 * changed() signals getting emitted when you modify widgets. 305 */ 306 virtual void save(); 307 308 /** 309 * Sets the configuration to sensible default values. 310 * 311 * This method is called when the user clicks the "Default" 312 * button. It should set the display to useful values. 313 * 314 * If you use KConfigXT, you do not have to reimplement this function since 315 * the fetching and settings of default values is done automatically. However, if you 316 * reimplement and also are using KConfigXT, remember to call the base function at the 317 * very end of your reimplementation. 318 */ 319 virtual void defaults(); 320 321 /** 322 * Show an indicator when settings value differ from default 323 * 324 * @since 5.73 325 */ 326 void setDefaultsIndicatorsVisible(bool show); 327 328 protected: 329 /** 330 * Adds a KCoreConfigskeleton @p config to watch the widget @p widget 331 * 332 * This function is useful if you need to handle multiple configuration files. 333 * 334 * @return a pointer to the KCoreConfigDialogManager in use 335 * @param config the KCoreConfigSkeleton to use 336 * @param widget the widget to watch 337 */ 338 KConfigDialogManager *addConfig(KCoreConfigSkeleton *config, QWidget *widget); 339 340 #if KCONFIGWIDGETS_ENABLE_DEPRECATED_SINCE(5, 84) 341 // No deprecation warning by compiler here, as the replacement will be 342 // automatically picked by the compiler in the future, being the method 343 // overload using the base-class of the argument type. 344 // Avoids the need to do extra-casting right now on the caller side. 345 /** 346 * Adds a KConfigskeleton @p config to watch the widget @p widget 347 * 348 * This function is useful if you need to handle multiple configuration files. 349 * 350 * @return a pointer to the KConfigDialogManager in use 351 * @param config the KConfigSkeleton to use 352 * @param widget the widget to watch 353 * @deprecated since 5.84, use addConfig(KCoreConfigSkeleton *config, QWidget *widget); 354 */ 355 KConfigDialogManager *addConfig(KConfigSkeleton *config, QWidget *widget); 356 #endif 357 358 /** 359 * Sets the quick help. 360 */ 361 void setQuickHelp(const QString &help); 362 363 void showEvent(QShowEvent *ev) override; 364 365 friend class KCModuleProxy; 366 367 Q_SIGNALS: 368 369 /** 370 * Indicate that the state of the modules contents has changed. 371 * 372 * This signal is emitted whenever the state of the configuration 373 * shown in the module changes. It allows the module container to 374 * keep track of unsaved changes. 375 */ 376 void changed(bool state); // clazy:exclude=overloaded-signal 377 378 /** 379 * Indicate that the state of the modules contents matches the default 380 * settings. 381 * 382 * This signal is emitted whenever the state of the configuration 383 * shown in the module changes. It allows the module container to 384 * keep track of defaults. 385 * 386 * @since 5.65 387 */ 388 void defaulted(bool state); 389 390 /** 391 * Indicate that the module's quickhelp has changed. 392 * 393 * Emit this signal whenever the module's quickhelp changes. 394 * Modules implemented as tabbed dialogs might want to implement 395 * per-tab quickhelp for example. 396 * 397 */ 398 void quickHelpChanged(); 399 400 /** 401 * Indicate that the module's root message has changed. 402 * 403 * Emits this signal whenever the module's root message changes. 404 * 405 * @since 4.4 406 * 407 */ 408 void rootOnlyMessageChanged(bool use, QString message); 409 410 /** 411 * Emitted when show defaults indicators changed 412 * @since 5.73 413 */ 414 void defaultsIndicatorsVisibleChanged(bool show); 415 416 protected Q_SLOTS: 417 418 #if KCONFIGWIDGETS_ENABLE_DEPRECATED_SINCE(5, 64) 419 /** 420 * Calling this slot is equivalent to emitting changed(true). 421 * @deprecated Since 5.64, use markAsChanged 422 */ 423 KCONFIGWIDGETS_DEPRECATED_VERSION(5, 64, "Use KCModule::markAsChanged()") 424 void changed(); 425 #endif 426 427 /** 428 * Calling this slot is equivalent to emitting changed(true). 429 * @since 5.64 430 */ 431 void markAsChanged(); 432 433 /** 434 * A managed widget was changed, the widget settings and the current 435 * settings are compared and a corresponding changed() signal is emitted 436 */ 437 void widgetChanged(); 438 439 #ifndef KCONFIGWIDGETS_NO_KAUTH 440 /** 441 * The status of the auth action, if one, has changed 442 */ 443 void authStatusChanged(KAuth::Action::AuthStatus status); 444 #endif 445 446 protected: 447 /** 448 * Sets the buttons to display. 449 * 450 * Help: shows a "Help" button. 451 * 452 * Default: shows a "Use Defaults" button. 453 * 454 * Apply: in kcontrol this will show an "Apply" and "Reset" button, 455 * in kcmshell this will show an "Ok", "Apply", "Reset" and "Cancel" button. 456 * 457 * If Apply is not specified, kcmshell will show a "Close" button. 458 * 459 * @see KCModule::buttons 460 */ 461 void setButtons(Buttons btn); 462 463 /** 464 * Sets the RootOnly message. 465 * 466 * This message will be shown at the top of the module if useRootOnlyMessage is 467 * set. If no message is set, a default one will be used. 468 * 469 * @see KCModule::rootOnlyMessage 470 */ 471 void setRootOnlyMessage(const QString &message); 472 473 /** 474 * Change whether or not the RootOnly message should be shown. 475 * 476 * Following the value of @p on, the RootOnly message will be 477 * shown or not. 478 * 479 * @see KCModule::useRootOnlyMessage 480 */ 481 void setUseRootOnlyMessage(bool on); 482 483 /** 484 * Returns the changed state of automatically managed widgets in this dialog 485 */ 486 bool managedWidgetChangeState() const; 487 488 /** 489 * Returns the defaulted state of automatically managed widgets in this dialog 490 * 491 * @since 5.65 492 */ 493 bool managedWidgetDefaultState() const; 494 495 /** 496 * Call this method when your manually managed widgets change state between 497 * changed and not changed 498 */ 499 void unmanagedWidgetChangeState(bool); 500 501 /** 502 * Call this method when your manually managed widgets change state between 503 * defaulted and not defaulted 504 * 505 * @since 5.65 506 */ 507 void unmanagedWidgetDefaultState(bool); 508 509 private: 510 std::unique_ptr<KCModulePrivate> const d; 511 }; 512 513 Q_DECLARE_OPERATORS_FOR_FLAGS(KCModule::Buttons) 514 515 #endif // KCMODULE_H 516