| 1 | /* |
| 2 | This file is part of the KDE libraries |
| 3 | SPDX-FileCopyrightText: 2000 Reginald Stadlbauer <reggie@kde.org> |
| 4 | SPDX-FileCopyrightText: 1997 Stephan Kulow <coolo@kde.org> |
| 5 | SPDX-FileCopyrightText: 1997-2000 Sven Radej <radej@kde.org> |
| 6 | SPDX-FileCopyrightText: 1997-2000 Matthias Ettrich <ettrich@kde.org> |
| 7 | SPDX-FileCopyrightText: 1999 Chris Schlaeger <cs@kde.org> |
| 8 | SPDX-FileCopyrightText: 2002 Joseph Wenninger <jowenn@kde.org> |
| 9 | SPDX-FileCopyrightText: 2005-2006 Hamish Rodda <rodda@kde.org> |
| 10 | SPDX-FileCopyrightText: 2000-2008 David Faure <faure@kde.org> |
| 11 | |
| 12 | SPDX-License-Identifier: LGPL-2.0-only |
| 13 | */ |
| 14 | |
| 15 | #ifndef KMAINWINDOW_H |
| 16 | #define KMAINWINDOW_H |
| 17 | |
| 18 | #include <kxmlgui_export.h> |
| 19 | |
| 20 | #include <QMainWindow> |
| 21 | #include <memory> |
| 22 | |
| 23 | class ; |
| 24 | class KConfig; |
| 25 | class KConfigGroup; |
| 26 | class KMWSessionManager; |
| 27 | class KMainWindowPrivate; |
| 28 | class KToolBar; |
| 29 | |
| 30 | /*! |
| 31 | * \class KMainWindow |
| 32 | * \inmodule KXmlGui |
| 33 | * |
| 34 | * \brief KMainWindow represents a top-level main window. |
| 35 | * |
| 36 | * It extends QMainWindow with session management capabilities. For ready-made window functionality and simpler UI management, use KXmlGuiWindow instead. |
| 37 | * |
| 38 | * Define the minimum/maximum height/width of your central widget and KMainWindow will take this into account. |
| 39 | * For fixed size windows set your main widget to a fixed size. Fixed aspect ratios (QWidget::heightForWidth()) and fixed width widgets are not supported. |
| 40 | * |
| 41 | * Use toolBar() to generate a main toolbar "mainToolBar" or refer to a specific toolbar. |
| 42 | * For a simpler way to manage your toolbars, use KXmlGuiWindow::setupGUI() instead. |
| 43 | * |
| 44 | * Use setAutoSaveSettings() to automatically save and restore the window geometry and toolbar/menubar/statusbar state when the application is restarted. |
| 45 | * |
| 46 | * Use kRestoreMainWindows() in your main function to restore your windows when the session is restored. |
| 47 | * |
| 48 | * The window state is saved when the application is exited. |
| 49 | * Reimplement queryClose() to warn the user of unsaved data upon close or exit. |
| 50 | * |
| 51 | * Reimplement saveProperties() / readProperties() or saveGlobalProperties() / readGlobalProperties() |
| 52 | * to save/restore application-specific state during session management. |
| 53 | * |
| 54 | * Note that session saving is automatically called, session restoring is not, |
| 55 | * and so it needs to be implemented in your main() function. |
| 56 | * |
| 57 | * See \l https://develop.kde.org/docs/features/session-managment for more information on session management. |
| 58 | */ |
| 59 | |
| 60 | class KXMLGUI_EXPORT KMainWindow : public QMainWindow |
| 61 | { |
| 62 | friend class KMWSessionManager; |
| 63 | friend class DockResizeListener; |
| 64 | Q_OBJECT |
| 65 | |
| 66 | /*! |
| 67 | * \property KMainWindow::hasMenuBar |
| 68 | */ |
| 69 | Q_PROPERTY(bool hasMenuBar READ hasMenuBar) |
| 70 | |
| 71 | /*! |
| 72 | * \property KMainWindow::autoSaveSettings |
| 73 | */ |
| 74 | Q_PROPERTY(bool autoSaveSettings READ autoSaveSettings) |
| 75 | |
| 76 | /*! |
| 77 | * \property KMainWindow::autoSaveGroup |
| 78 | */ |
| 79 | Q_PROPERTY(QString autoSaveGroup READ autoSaveGroup) |
| 80 | |
| 81 | public: |
| 82 | /*! |
| 83 | * \brief Constructs a main window. |
| 84 | * |
| 85 | * \a parent The parent widget. This is usually \c nullptr, but it may also be |
| 86 | * the window group leader. In that case, |
| 87 | * the KMainWindow becomes a secondary window. |
| 88 | * |
| 89 | * \a flags Specify the window flags. The default is none. |
| 90 | * |
| 91 | * Note that by default a KMainWindow is created with the |
| 92 | * Qt::WA_DeleteOnClose attribute set, i.e. it is automatically destroyed |
| 93 | * when the window is closed. If you do not want this behavior, call |
| 94 | * \code |
| 95 | * window->setAttribute(Qt::WA_DeleteOnClose, false); |
| 96 | * \endcode |
| 97 | * |
| 98 | * KMainWindows must be created on the heap with 'new', like: |
| 99 | * \code |
| 100 | * KMainWindow *kmw = new KMainWindow(...); |
| 101 | * kmw->setObjectName(...); |
| 102 | * \endcode |
| 103 | * |
| 104 | * Since KDE Frameworks 5.16, KMainWindow will enter information regarding |
| 105 | * the application's translators by default, using KAboutData::setTranslator(). This only occurs |
| 106 | * if no translators are already assigned in KAboutData (see KAboutData::setTranslator() for |
| 107 | * details -- the auto-assignment here uses the same translated strings as specified for that |
| 108 | * function). |
| 109 | * |
| 110 | * \warning For session management and window management to work |
| 111 | * properly, all main windows in the application should have a |
| 112 | * different name. Otherwise, KMainWindow will create |
| 113 | * a unique name, but it's recommended to explicitly pass a window name that will |
| 114 | * also describe the type of the window. If there can be several windows of the same |
| 115 | * type, append '#' (hash) to the name, and KMainWindow will replace it with numbers to make |
| 116 | * the names unique. For example, for a mail client which has one main window showing |
| 117 | * the mails and folders, and which can also have one or more windows for composing |
| 118 | * mails, the name for the folders window should be e.g. "mainwindow" and |
| 119 | * for the composer windows "composer#". |
| 120 | * |
| 121 | * \sa KAboutData |
| 122 | */ |
| 123 | explicit KMainWindow(QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags()); |
| 124 | |
| 125 | /*! |
| 126 | * \brief Destructor. |
| 127 | * |
| 128 | * Will also destroy the toolbars and menubar if |
| 129 | * needed. |
| 130 | */ |
| 131 | ~KMainWindow() override; |
| 132 | |
| 133 | /*! |
| 134 | * Returns \c true if the number of KMainWindow instances of the previous session did contain the requested \a numberOfInstances, \c false otherwise. |
| 135 | * |
| 136 | * \a numberOfInstances The number of KMainWindow instances in the application. |
| 137 | * |
| 138 | * \sa restore() |
| 139 | **/ |
| 140 | static bool canBeRestored(int numberOfInstances); |
| 141 | |
| 142 | /*! |
| 143 | * \brief Useful if your application uses |
| 144 | * different kinds of top-level windows. |
| 145 | * |
| 146 | * Returns The class name of the top-level window to be restored |
| 147 | * that corresponds to \a instanceNumber. |
| 148 | * |
| 149 | * \sa restore() |
| 150 | */ |
| 151 | static const QString classNameOfToplevel(int instanceNumber); |
| 152 | |
| 153 | /*! |
| 154 | * \brief Attempt to restore the top-level widget as defined by \a numberOfInstances (1..X). |
| 155 | * |
| 156 | * You should call canBeRestored() first. |
| 157 | * |
| 158 | * If the session did not contain so high a number, the configuration |
| 159 | * is not changed and \c false is returned. |
| 160 | * |
| 161 | * That means clients could simply do the following: |
| 162 | * \code |
| 163 | * if (qApp->isSessionRestored()){ |
| 164 | * int n = 1; |
| 165 | * while (KMainWindow::canBeRestored(n)){ |
| 166 | * (new childMW)->restore(n); |
| 167 | * n++; |
| 168 | * } |
| 169 | * } else { |
| 170 | * // create default application as usual |
| 171 | * } |
| 172 | * \endcode |
| 173 | * Note that if \a show is \c true (default), QWidget::show() is called |
| 174 | * implicitly in restore. |
| 175 | * |
| 176 | * With this you can easily restore all top-level windows of your |
| 177 | * application. |
| 178 | * |
| 179 | * If your application uses different kinds of top-level |
| 180 | * windows, then you can use KMainWindow::classNameOfToplevel(n) |
| 181 | * to determine the exact type before calling the childMW |
| 182 | * constructor in the example from above. |
| 183 | * |
| 184 | * \note You don't need to deal with this function. Use the |
| 185 | * kRestoreMainWindows() convenience template function instead! |
| 186 | * |
| 187 | * \a numberOfInstances The number of KMainWindow instances from the last session. |
| 188 | * |
| 189 | * \a show Whether the KMainWindow instances will be visible by default. |
| 190 | * |
| 191 | * Returns \c true if the session contained |
| 192 | * the same number of instances as the requested number, |
| 193 | * \c false if the session contained less instances than the requested number, |
| 194 | * in which case no configuration is changed. |
| 195 | * |
| 196 | * \sa kRestoreMainWindows() |
| 197 | * \sa readProperties() |
| 198 | * \sa canBeRestored() |
| 199 | */ |
| 200 | bool restore(int numberOfInstances, bool show = true); |
| 201 | |
| 202 | /*! |
| 203 | * Returns \c true if there is a menubar, \c false otherwise. |
| 204 | */ |
| 205 | bool hasMenuBar(); |
| 206 | |
| 207 | /*! |
| 208 | * Returns The list of members of the KMainWindow class. |
| 209 | */ |
| 210 | static QList<KMainWindow *> memberList(); |
| 211 | |
| 212 | /*! |
| 213 | * \brief This is useful to both call specific toolbars that have been created |
| 214 | * or to generate a default one upon call. |
| 215 | * |
| 216 | * This refers to toolbars created dynamically from the XML UI |
| 217 | * framework via KConfig or appnameui.rc. |
| 218 | * |
| 219 | * If the toolbar does not exist, one will be created. |
| 220 | * |
| 221 | * \a name The internal name of the toolbar. If no name is specified, |
| 222 | * "mainToolBar" is assumed. |
| 223 | * |
| 224 | * Returns A pointer to the toolbar with the specified name. |
| 225 | * \sa toolBars() |
| 226 | **/ |
| 227 | KToolBar *toolBar(const QString &name = QString()); |
| 228 | |
| 229 | /*! |
| 230 | * Returns a list of all toolbars for this window |
| 231 | */ |
| 232 | QList<KToolBar *> toolBars() const; |
| 233 | |
| 234 | /*! |
| 235 | * \brief This enables autosave of toolbar/menubar/statusbar settings |
| 236 | * (and optionally window size). |
| 237 | * |
| 238 | * \a groupName A name that identifies the type of window. |
| 239 | * You can have several types of window in the same application. |
| 240 | * If no \a groupName is specified, the value defaults to "MainWindow". |
| 241 | * |
| 242 | * \a saveWindowSize Whether to include the window size |
| 243 | * when saving. \c true by default. |
| 244 | * |
| 245 | * If the *bars were modified when the window is closed, |
| 246 | * \c {saveMainWindowSettings( KConfigGroup(KSharedConfig::openConfig(), groupName) )} will be called. |
| 247 | * |
| 248 | * Typically, you will call setAutoSaveSettings() in your |
| 249 | * KMainWindow-inherited class constructor, and it will take care |
| 250 | * of restoring and saving automatically. |
| 251 | * |
| 252 | * By default, this generates an |
| 253 | * appnamerc ini file as if using default KConfig constructor or KConfig::SimpleConfig. |
| 254 | * |
| 255 | * Make sure you call this \b after all your *bars have been created. |
| 256 | * |
| 257 | * To make sure that KMainWindow properly obtains the default |
| 258 | * size of the window you should do the following: |
| 259 | * - Remove hardcoded resize() calls in the constructor or main |
| 260 | * to let the automatic resizing determine the default window size. |
| 261 | * Hardcoded window sizes will be wrong for users that have big fonts, |
| 262 | * use different styles, long/small translations, large toolbars, and other factors. |
| 263 | * - Put the setAutoSaveSettings() call after all widgets |
| 264 | * have been created and placed inside the main window |
| 265 | * (for most apps this means QMainWindow::setCentralWidget()) |
| 266 | * - QWidget-based objects should overload "virtual QSize sizeHint() const;" |
| 267 | * to specify a default size. |
| 268 | * \sa KConfig |
| 269 | * \sa KSharedConfig |
| 270 | * \sa saveMainWindowSettings() |
| 271 | * \sa toolBar() |
| 272 | * \sa KXmlGuiWindow::setupGUI() |
| 273 | */ |
| 274 | void setAutoSaveSettings(const QString &groupName = QStringLiteral("MainWindow" ), bool saveWindowSize = true); |
| 275 | |
| 276 | /*! |
| 277 | * \overload KMainWindow::setAutoSaveSettings(const QString &groupName = QStringLiteral("MainWindow"), bool saveWindowSize = true) |
| 278 | * |
| 279 | * This allows the settings to be saved into a different file |
| 280 | * that does not correspond to that used for KSharedConfig::openConfig(). |
| 281 | * |
| 282 | * \a group A name that identifies the type of window. |
| 283 | * You can have several types of window in the same application. |
| 284 | * |
| 285 | * \a saveWindowSize Whether to include the window size |
| 286 | * when saving. \c true by default. |
| 287 | * |
| 288 | * \sa setAutoSaveSettings(const QString &groupName, bool saveWindowSize) |
| 289 | * \sa KConfig |
| 290 | * \sa KSharedConfig |
| 291 | * \since 4.1 |
| 292 | */ |
| 293 | void setAutoSaveSettings(const KConfigGroup &group, bool saveWindowSize = true); |
| 294 | |
| 295 | /*! |
| 296 | * \brief Disables the autosave settings feature. |
| 297 | * You don't normally need to call this, ever. |
| 298 | * \sa setAutoSaveSettings() |
| 299 | * \sa autoSaveSettings() |
| 300 | */ |
| 301 | void resetAutoSaveSettings(); |
| 302 | |
| 303 | /*! |
| 304 | * Returns \c true if setAutoSaveSettings() was called, |
| 305 | * \c false by default or if resetAutoSaveSettings() was called. |
| 306 | * \sa setAutoSaveSettings() |
| 307 | * \sa resetAutoSaveSettings() |
| 308 | */ |
| 309 | bool autoSaveSettings() const; |
| 310 | |
| 311 | /*! |
| 312 | * Returns The group used for autosaving settings. |
| 313 | * |
| 314 | * Do not mistake this with autoSaveConfigGroup. |
| 315 | * |
| 316 | * Only meaningful if setAutoSaveSettings(const QString&, bool) was called. |
| 317 | * |
| 318 | * Do not use this method if setAutoSaveSettings(const KConfigGroup&, bool) was called. |
| 319 | * |
| 320 | * This can be useful for forcing a save or an apply, e.g. before and after |
| 321 | * using KEditToolBar. |
| 322 | * |
| 323 | * \note Prefer saveAutoSaveSettings() for saving or autoSaveConfigGroup() for loading. |
| 324 | * |
| 325 | * \sa autoSaveSettings() |
| 326 | * \sa setAutoSaveSettings() |
| 327 | * \sa saveAutoSaveSettings() |
| 328 | * \sa resetAutoSaveSettings() |
| 329 | * \sa autoSaveConfigGroup() |
| 330 | */ |
| 331 | QString autoSaveGroup() const; |
| 332 | |
| 333 | /*! |
| 334 | * Returns The group used for autosaving settings. |
| 335 | * |
| 336 | * Only meaningful if setAutoSaveSettings(const QString&, bool) was called. |
| 337 | * |
| 338 | * Do not use this method if setAutoSaveSettings(const KConfigGroup&, bool) was called. |
| 339 | * |
| 340 | * This can be useful for forcing an apply, e.g. after using KEditToolBar. |
| 341 | * |
| 342 | * \sa setAutoSaveSettings() |
| 343 | * \sa autoSaveGroup() |
| 344 | * \since 4.1 |
| 345 | */ |
| 346 | KConfigGroup autoSaveConfigGroup() const; |
| 347 | |
| 348 | /*! |
| 349 | * \brief Assigns the config group name for the KConfigGroup returned by stateConfigGroup. |
| 350 | * |
| 351 | * \a configGroup The config group to be assigned. |
| 352 | * |
| 353 | * Window size and state are stored in the resulting KConfigGroup when this function is called. |
| 354 | * \note If this is used in combination with setAutoSaveSettings, you should call this method first. |
| 355 | * |
| 356 | * \sa KConfigGroup |
| 357 | * \sa KSharedConfig::openStateConfig() |
| 358 | * \sa stateConfigGroup() |
| 359 | * |
| 360 | * \since 5.88 |
| 361 | */ |
| 362 | void setStateConfigGroup(const QString &configGroup); |
| 363 | |
| 364 | /*! |
| 365 | * Returns The KConfigGroup used to store state data like window sizes or window state. |
| 366 | * |
| 367 | * The resulting group is invalid if setStateConfig is not called explicitly. |
| 368 | * |
| 369 | * \sa KConfigGroup |
| 370 | * \since 5.88 |
| 371 | */ |
| 372 | KConfigGroup stateConfigGroup() const; |
| 373 | |
| 374 | /*! |
| 375 | * \brief Read settings for statusbar, menubar and toolbar from their respective |
| 376 | * groups in the config file and apply them. |
| 377 | * |
| 378 | * \a config Config group to read the settings from. |
| 379 | */ |
| 380 | virtual void applyMainWindowSettings(const KConfigGroup &config); |
| 381 | |
| 382 | /*! |
| 383 | * \brief Manually save the settings for statusbar, menubar and toolbar to their respective |
| 384 | * groups in the KConfigGroup \a config. |
| 385 | * |
| 386 | * Usage example: |
| 387 | * \code |
| 388 | * KConfigGroup group(KSharedConfig::openConfig(), "MainWindow"); |
| 389 | * saveMainWindowSettings(group); |
| 390 | * \endcode |
| 391 | * |
| 392 | * \a config Config group to save the settings to. |
| 393 | * \sa setAutoSaveSettings() |
| 394 | * \sa KConfig |
| 395 | * \sa KSharedConfig |
| 396 | * \sa KConfigGroup |
| 397 | */ |
| 398 | void saveMainWindowSettings(KConfigGroup &config); |
| 399 | |
| 400 | /*! |
| 401 | * Returns The path for the exported window's D-Bus object. |
| 402 | * \since 4.0.1 |
| 403 | */ |
| 404 | QString dbusName() const; |
| 405 | |
| 406 | public Q_SLOTS: |
| 407 | /*! |
| 408 | * \brief Assigns a KDE compliant caption (window title). |
| 409 | * |
| 410 | * \a caption The string that will be |
| 411 | * displayed in the window title, before the application name. |
| 412 | * |
| 413 | * \note This function does the same as setPlainCaption(). |
| 414 | * |
| 415 | * \note Do not include the application name |
| 416 | * in this string. It will be added automatically according to the KDE |
| 417 | * standard. |
| 418 | * |
| 419 | * \sa setPlainCaption() |
| 420 | */ |
| 421 | virtual void setCaption(const QString &caption); |
| 422 | /*! |
| 423 | * \brief Makes a KDE compliant caption. |
| 424 | * |
| 425 | * \a caption Your caption. |
| 426 | * |
| 427 | * \a modified Whether the document is modified. This displays |
| 428 | * an additional sign in the title bar, usually "**". |
| 429 | * |
| 430 | * \overload |
| 431 | * |
| 432 | * \note Do not include the application name |
| 433 | * in this string. It will be added automatically according to the KDE |
| 434 | * standard. |
| 435 | */ |
| 436 | virtual void setCaption(const QString &caption, bool modified); |
| 437 | |
| 438 | /*! |
| 439 | * \brief Make a plain caption without any modifications. |
| 440 | * |
| 441 | * \a caption The string that will be |
| 442 | * displayed in the window title, before the application name. |
| 443 | * |
| 444 | * \note This function does the same as setCaption(). |
| 445 | * |
| 446 | * \note Do not include the application name |
| 447 | * in this string. It will be added automatically according to the KDE |
| 448 | * standard. |
| 449 | * |
| 450 | * \sa setCaption() |
| 451 | */ |
| 452 | virtual void setPlainCaption(const QString &caption); |
| 453 | |
| 454 | /*! |
| 455 | * \brief Opens the help page for the application. |
| 456 | * |
| 457 | * The application name is |
| 458 | * used as a key to determine what to display and the system will attempt |
| 459 | * to open \<appName\>/index.html. |
| 460 | * |
| 461 | * This method is intended for use by a help button in the toolbar or |
| 462 | * components outside the regular help menu. |
| 463 | * |
| 464 | * Use helpMenu() when you |
| 465 | * want to provide access to the help system from the help menu. |
| 466 | * |
| 467 | * Example (adding a help button to the first toolbar): |
| 468 | * |
| 469 | * \code |
| 470 | * toolBar()->addAction(QIcon::fromTheme("help-contents"), i18n("Help"), |
| 471 | * this, &KMainWindow::appHelpActivated); |
| 472 | * \endcode |
| 473 | * |
| 474 | * \sa helpMenu() |
| 475 | * \sa toolBar() |
| 476 | */ |
| 477 | void appHelpActivated(); |
| 478 | |
| 479 | /*! |
| 480 | * \brief Tell the main window that it should save its settings when being closed. |
| 481 | * |
| 482 | * This is part of the autosave settings feature. |
| 483 | * |
| 484 | * For everything related to toolbars this happens automatically, |
| 485 | * but you have to call setSettingsDirty() in the slot that toggles |
| 486 | * the visibility of the statusbar. |
| 487 | * |
| 488 | * \sa saveAutoSaveSettings() |
| 489 | */ |
| 490 | void setSettingsDirty(); |
| 491 | |
| 492 | protected: |
| 493 | /*! |
| 494 | * Reimplemented to return the \a event QEvent::Polish in order to adjust the object name |
| 495 | * if needed, once all constructor code for the main window has run. |
| 496 | * Also reimplemented to catch when a QDockWidget is added or removed. |
| 497 | * |
| 498 | * \reimp |
| 499 | */ |
| 500 | bool event(QEvent *event) override; |
| 501 | |
| 502 | /*! |
| 503 | * \brief Reimplemented to open context menus on Shift+F10. |
| 504 | * |
| 505 | * \a keyEvent The event assigned to a key press. |
| 506 | * |
| 507 | * \reimp |
| 508 | */ |
| 509 | void keyPressEvent(QKeyEvent *keyEvent) override; |
| 510 | |
| 511 | /*! |
| 512 | * Reimplemented to autosave settings and call queryClose(). |
| 513 | * |
| 514 | * We recommend that you reimplement queryClose() rather than closeEvent(). |
| 515 | * If you do it anyway, ensure to call the base implementation to keep |
| 516 | * the feature of autosaving window settings working. |
| 517 | * |
| 518 | * \reimp |
| 519 | */ |
| 520 | void closeEvent(QCloseEvent *) override; |
| 521 | |
| 522 | /*! |
| 523 | * \brief This function is called before the window is closed, |
| 524 | * either by the user or indirectly by the session manager. |
| 525 | * |
| 526 | * This can be used to prompt the user to save unsaved data before the window is closed. |
| 527 | * |
| 528 | * Usage example: |
| 529 | * \code |
| 530 | * switch ( KMessageBox::warningTwoActionsCancel( this, |
| 531 | * i18n("Save changes to document foo?"), QString(), |
| 532 | * KStandardGuiItem::save(), KStandardGuiItem::discard())) ) { |
| 533 | * case KMessageBox::PrimaryAction : |
| 534 | * // save document here. If saving fails, return false; |
| 535 | * return true; |
| 536 | * case KMessageBox::SecondaryAction : |
| 537 | * return true; |
| 538 | * default: // cancel |
| 539 | * return false; |
| 540 | * \endcode |
| 541 | * |
| 542 | * \note Do \b not close the document from within this method, |
| 543 | * as it may be called by the session manager before the |
| 544 | * session is saved. If the document is closed before the session save occurs, |
| 545 | * its location might not be properly saved. In addition, the session shutdown |
| 546 | * may be canceled, in which case the document should remain open. |
| 547 | * |
| 548 | * Returns \c true by default, \c false according to the reimplementation. |
| 549 | * Returning \c false will cancel the closing operation, |
| 550 | * and if KApplication::sessionSaving() is true, it cancels logout. |
| 551 | */ |
| 552 | virtual bool queryClose(); |
| 553 | |
| 554 | /*! |
| 555 | * \brief Saves your instance-specific properties. |
| 556 | * |
| 557 | * The function is |
| 558 | * invoked when the session manager requests your application |
| 559 | * to save its state. |
| 560 | * |
| 561 | * Reimplement this function in child classes. |
| 562 | * |
| 563 | * Usage example: |
| 564 | * \code |
| 565 | * void MainWindow::saveProperties(KConfigGroup &config) { |
| 566 | * config.writeEntry("myKey", "newValue"); |
| 567 | * ... |
| 568 | * } |
| 569 | * \endcode |
| 570 | * |
| 571 | * \note No user interaction is allowed in this function! |
| 572 | * |
| 573 | */ |
| 574 | virtual void saveProperties(KConfigGroup &) |
| 575 | { |
| 576 | } |
| 577 | |
| 578 | /*! |
| 579 | * \brief Reads your instance-specific properties. |
| 580 | * |
| 581 | * This function is called indirectly by restore(). |
| 582 | * |
| 583 | * \code |
| 584 | * void MainWindow::readProperties(KConfigGroup &config) { |
| 585 | * if (config.hasKey("myKey")) { |
| 586 | * config.readEntry("myKey", "DefaultValue"); |
| 587 | * } |
| 588 | * ... |
| 589 | * } |
| 590 | * \endcode |
| 591 | * |
| 592 | * \sa readGlobalProperties() |
| 593 | */ |
| 594 | virtual void readProperties(const KConfigGroup &) |
| 595 | { |
| 596 | } |
| 597 | |
| 598 | /*! |
| 599 | * \brief Saves your application-wide properties. |
| 600 | * |
| 601 | * \a sessionConfig A pointer to the KConfig instance |
| 602 | * used to save the session data. |
| 603 | * |
| 604 | * This function is invoked when the session manager |
| 605 | * requests your application to save its state. |
| 606 | * It is similar to saveProperties(), but it is only called for |
| 607 | * the first main window. This is useful to save global state of your application |
| 608 | * that isn't bound to a particular window. |
| 609 | * |
| 610 | * The default implementation does nothing. |
| 611 | * |
| 612 | * \sa readGlobalProperties() |
| 613 | * \sa saveProperties() |
| 614 | */ |
| 615 | virtual void saveGlobalProperties(KConfig *sessionConfig); |
| 616 | |
| 617 | /*! |
| 618 | * \brief Reads your application-wide properties. |
| 619 | * |
| 620 | * \a sessionConfig A pointer to the KConfig instance |
| 621 | * used to load the session data. |
| 622 | * |
| 623 | * \sa saveGlobalProperties() |
| 624 | * \sa readProperties() |
| 625 | * |
| 626 | */ |
| 627 | virtual void readGlobalProperties(KConfig *sessionConfig); |
| 628 | void savePropertiesInternal(KConfig *, int); |
| 629 | bool readPropertiesInternal(KConfig *, int); |
| 630 | |
| 631 | /*! |
| 632 | * \brief Returns whether there are unsaved changes. |
| 633 | * |
| 634 | * For inherited classes. |
| 635 | */ |
| 636 | bool settingsDirty() const; |
| 637 | |
| 638 | protected Q_SLOTS: |
| 639 | /*! |
| 640 | * This slot should only be called in case you reimplement closeEvent() and |
| 641 | * if you are using the autosave feature. In all other cases, |
| 642 | * setSettingsDirty() should be called instead to benefit from the delayed |
| 643 | * saving. |
| 644 | * |
| 645 | * Usage example: |
| 646 | * \code |
| 647 | * |
| 648 | * void MyMainWindow::closeEvent( QCloseEvent *e ) |
| 649 | * { |
| 650 | * // Save settings if autosave is enabled, and settings have changed |
| 651 | * if ( settingsDirty() && autoSaveSettings() ) |
| 652 | * saveAutoSaveSettings(); |
| 653 | * .. |
| 654 | * } |
| 655 | * \endcode |
| 656 | * |
| 657 | * \sa setAutoSaveSettings() |
| 658 | * \sa setSettingsDirty() |
| 659 | */ |
| 660 | void saveAutoSaveSettings(); |
| 661 | |
| 662 | protected: |
| 663 | KXMLGUI_NO_EXPORT KMainWindow(KMainWindowPrivate &dd, QWidget *parent, Qt::WindowFlags f); |
| 664 | |
| 665 | std::unique_ptr<KMainWindowPrivate> const d_ptr; |
| 666 | |
| 667 | private: |
| 668 | Q_DECLARE_PRIVATE(KMainWindow) |
| 669 | |
| 670 | Q_PRIVATE_SLOT(d_func(), void _k_slotSettingsChanged(int)) |
| 671 | Q_PRIVATE_SLOT(d_func(), void _k_slotSaveAutoSaveSize()) |
| 672 | Q_PRIVATE_SLOT(d_func(), void _k_slotSaveAutoSavePosition()) |
| 673 | }; |
| 674 | |
| 675 | /*! |
| 676 | * \macro KDE_RESTORE_MAIN_WINDOWS_NUM_TEMPLATE_ARGS |
| 677 | * |
| 678 | * \relates KMainWindow |
| 679 | * |
| 680 | * Returns the maximal number of arguments that are actually |
| 681 | * supported by kRestoreMainWindows(). |
| 682 | **/ |
| 683 | #define KDE_RESTORE_MAIN_WINDOWS_NUM_TEMPLATE_ARGS 3 |
| 684 | |
| 685 | /*! |
| 686 | * \fn template<typename T> void kRestoreMainWindows() |
| 687 | * \brief Restores the last session. (To be used in your main function). |
| 688 | * |
| 689 | * \relates KMainWindow |
| 690 | * |
| 691 | * These functions work also if you have more than one kind of top-level |
| 692 | * widget (each derived from KMainWindow, of course). |
| 693 | * |
| 694 | * Imagine you have three kinds of top-level widgets: the classes \c ChildMW1, |
| 695 | * \c ChildMW2 and \c ChildMW3. Then you can just do: |
| 696 | * |
| 697 | * \code |
| 698 | * int main(int argc, char *argv[]) |
| 699 | * { |
| 700 | * // [...] |
| 701 | * if (qApp->isSessionRestored()) |
| 702 | * kRestoreMainWindows<ChildMW1, ChildMW2, ChildMW3>(); |
| 703 | * else { |
| 704 | * // create default application as usual |
| 705 | * } |
| 706 | * // [...] |
| 707 | * } |
| 708 | * \endcode |
| 709 | * |
| 710 | * kRestoreMainWindows will create (on the heap) as many instances |
| 711 | * of your main windows as have existed in the last session and |
| 712 | * call KMainWindow::restore() with the correct arguments. Note that |
| 713 | * also QWidget::show() is called implicitly. |
| 714 | * |
| 715 | * Currently, these functions are provided for up to three |
| 716 | * template arguments. If you need more, tell us. To help you in |
| 717 | * deciding whether or not you can use kRestoreMainWindows, a |
| 718 | * define KDE_RESTORE_MAIN_WINDOWS_NUM_TEMPLATE_ARGS is provided. |
| 719 | * |
| 720 | * \note Prefer this function over directly calling KMainWindow::restore(). |
| 721 | * |
| 722 | * \sa KMainWindow::restore() |
| 723 | * \sa KMainWindow::classNameOfToplevel() |
| 724 | */ |
| 725 | template<typename T> |
| 726 | inline void kRestoreMainWindows() |
| 727 | { |
| 728 | for (int n = 1; KMainWindow::canBeRestored(numberOfInstances: n); ++n) { |
| 729 | const QString className = KMainWindow::classNameOfToplevel(instanceNumber: n); |
| 730 | if (className == QLatin1String(T::staticMetaObject.className())) { |
| 731 | (new T)->restore(n); |
| 732 | } |
| 733 | } |
| 734 | } |
| 735 | |
| 736 | template<typename T0, typename T1, typename... Tn> |
| 737 | inline void kRestoreMainWindows() |
| 738 | { |
| 739 | kRestoreMainWindows<T0>(); |
| 740 | kRestoreMainWindows<T1, Tn...>(); |
| 741 | } |
| 742 | |
| 743 | #endif |
| 744 | |