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 | |
11 | SPDX-License-Identifier: LGPL-2.0-only |
12 | */ |
13 | |
14 | #ifndef KXMLGUIWINDOW_H |
15 | #define KXMLGUIWINDOW_H |
16 | |
17 | #include "kmainwindow.h" |
18 | #include "kxmlguibuilder.h" |
19 | #include "kxmlguiclient.h" |
20 | |
21 | class ; |
22 | class KXMLGUIFactory; |
23 | class KConfig; |
24 | class KConfigGroup; |
25 | class KToolBar; |
26 | class KXmlGuiWindowPrivate; |
27 | |
28 | /*! |
29 | * \class KXmlGuiWindow kxmlguiwindow.h KXmlGuiWindow |
30 | * \inmodule KXmlGui |
31 | * |
32 | * \brief KMainWindow with convenience functions and integration with XmlGui files. |
33 | * |
34 | * This class includes several convenience \c <action>Enabled() functions |
35 | * to toggle the presence of functionality in your main window, |
36 | * including a KCommandBar instance. |
37 | * |
38 | * The \l StandardWindowOptions enum can be used to pass additional options |
39 | * to describe the main window behavior/appearance. |
40 | * Use it in conjunction with setupGUI() to load an appnameui.rc file |
41 | * to manage the main window's actions. |
42 | * |
43 | * setCommandBarEnabled() is set by default. |
44 | * |
45 | * A minimal example can be created with |
46 | * QMainWindow::setCentralWidget() and setupGUI(): |
47 | * |
48 | * \code |
49 | * MainWindow::MainWindow(QWidget *parent) : KXmlGuiWindow(parent) { |
50 | * textArea = new KTextEdit(); |
51 | * setCentralWidget(textArea); |
52 | * setupGUI(Default); |
53 | * } |
54 | * \endcode |
55 | * |
56 | * With this, a ready-made main window with menubar and statusbar is created, |
57 | * as well as two default menus, Settings and Help. |
58 | * |
59 | * Management of QActions is made trivial in combination with |
60 | * KActionCollection and KStandardAction. |
61 | * |
62 | * \code |
63 | * void MainWindow::setupActions() { |
64 | * QAction *clearAction = new QAction(this); |
65 | * clearAction->setText(i18n("&Clear")); |
66 | * clearAction->setIcon(QIcon::fromTheme("document-new")); |
67 | * KActionCollection::setDefaultShortcut(clearAction, Qt::CTRL + Qt::Key_W); |
68 | * actionCollection()->addAction("clear", clearAction); |
69 | * connect(clearAction, &QAction::triggered, textArea, &KTextEdit::clear); |
70 | * KStandardAction::quit(qApp, &QCoreApplication::quit, actionCollection()); |
71 | * setupGUI(Default, "texteditorui.rc"); |
72 | * } |
73 | * \endcode |
74 | * |
75 | * See https://develop.kde.org/docs/use/kxmlgui/ for a tutorial |
76 | * on how to create a simple text editor using KXmlGuiWindow. |
77 | * |
78 | * See https://develop.kde.org/docs/use/session-managment for more information on session management. |
79 | * |
80 | * \sa KMainWindow |
81 | * \sa KActionCollection |
82 | * \sa KStandardAction |
83 | * \sa setupGUI() |
84 | * \sa createGUI() |
85 | * \sa setCommandBarEnabled() |
86 | */ |
87 | |
88 | class KXMLGUI_EXPORT KXmlGuiWindow : public KMainWindow, public KXMLGUIBuilder, virtual public KXMLGUIClient |
89 | { |
90 | Q_OBJECT |
91 | |
92 | /*! |
93 | * \property KXmlGuiWindow::hasMenuBar |
94 | */ |
95 | Q_PROPERTY(bool hasMenuBar READ hasMenuBar) |
96 | |
97 | /*! |
98 | * \property KXmlGuiWindow::autoSaveSettings |
99 | */ |
100 | Q_PROPERTY(bool autoSaveSettings READ autoSaveSettings) |
101 | |
102 | /*! |
103 | * \property KXmlGuiWindow::autoSaveGroup |
104 | */ |
105 | Q_PROPERTY(QString autoSaveGroup READ autoSaveGroup) |
106 | |
107 | /*! |
108 | * \property KXmlGuiWindow::standardToolBarMenuEnabled |
109 | */ |
110 | Q_PROPERTY(bool standardToolBarMenuEnabled READ isStandardToolBarMenuEnabled WRITE setStandardToolBarMenuEnabled) |
111 | Q_PROPERTY(QStringList toolBars READ toolBarNames) |
112 | |
113 | public: |
114 | /*! |
115 | * \brief Construct a main window. |
116 | * |
117 | * Note that by default a KXmlGuiWindow is created with the |
118 | * Qt::WA_DeleteOnClose attribute set, i.e. it is automatically destroyed |
119 | * when the window is closed. If you do not want this behavior, call: |
120 | * |
121 | * \code |
122 | * window->setAttribute(Qt::WA_DeleteOnClose, false); |
123 | * \endcode |
124 | * |
125 | * KXmlGuiWindows must be created on the heap with 'new', like: |
126 | * |
127 | * \code |
128 | * KXmlGuiWindow *kmw = new KXmlGuiWindow(...); |
129 | * kmw->setObjectName(...); |
130 | * \endcode |
131 | * |
132 | * \note For session management and window management to work |
133 | * properly, all main windows in the application should have a |
134 | * different name. Otherwise, the base class KMainWindow will create |
135 | * a unique name, but it's recommended to explicitly pass a window name that will |
136 | * also describe the type of the window. If there can be several windows of the same |
137 | * type, append '#' (hash) to the name, and KMainWindow will replace it with numbers to make |
138 | * the names unique. For example, for a mail client which has one main window showing |
139 | * the mails and folders, and which can also have one or more windows for composing |
140 | * mails, the name for the folders window should be e.g. "mainwindow" and |
141 | * for the composer windows "composer#". |
142 | * |
143 | * \a parent The widget parent. This is usually \c nullptr, |
144 | * but it may also be the window group leader. |
145 | * In that case, the KXmlGuiWindow becomes a secondary window. |
146 | * |
147 | * \a flags Specify the window flags. The default is none. |
148 | * |
149 | * \sa KMainWindow::KMainWindow |
150 | */ |
151 | explicit KXmlGuiWindow(QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags()); |
152 | |
153 | /*! |
154 | * \brief Destructor. |
155 | * |
156 | * Will also destroy the toolbars and menubar if needed. |
157 | */ |
158 | ~KXmlGuiWindow() override; |
159 | |
160 | /*! |
161 | * \brief Creates a standard help menu when calling createGUI() |
162 | * or setupGUI(). |
163 | * |
164 | * \a showHelpMenu Whether to create a Help Menu. \c true by default. |
165 | * |
166 | * \sa isHelpMenuEnabled() |
167 | */ |
168 | void (bool = true); |
169 | |
170 | /*! |
171 | * Returns \c true if the help menu is enabled, \c false if setHelpMenuEnabled(false) was set. |
172 | * \sa setHelpMenuEnabled() |
173 | */ |
174 | bool () const; |
175 | |
176 | /*! |
177 | * |
178 | */ |
179 | virtual KXMLGUIFactory *guiFactory(); |
180 | |
181 | /*! |
182 | * \brief Generates the interface based on a local XML file. |
183 | * |
184 | * This is the function that generates UI elements such as the main menu, |
185 | * toolbar (if any) and statusbar. This is called by setupGUI(Create) as well. |
186 | * |
187 | * Typically, in a regular application, you would use setupGUI() |
188 | * instead, as it sets up the toolbar/shortcut |
189 | * edit actions, among other things. |
190 | * |
191 | * If \a xmlfile is an empty string, this method will try to construct |
192 | * a local XML filename like appnameui.rc where 'appname' is your app's |
193 | * name. Typically that app name is what KXMLGUIClient::componentName() |
194 | * returns. If that file does not exist, then the XML UI code will use only |
195 | * the global (standard) XML file for its layout purposes. |
196 | * |
197 | * \a xmlfile The path (relative or absolute) to the local xmlfile. |
198 | * |
199 | * \sa setupGUI() |
200 | */ |
201 | void createGUI(const QString &xmlfile = QString()); |
202 | |
203 | /*! |
204 | * \brief Creates a toggle under the 'Settings' menu to show/hide the available toolbars. |
205 | * |
206 | * The standard toolbar menu toggles the visibility of one or multiple toolbars. |
207 | * |
208 | * If there is only one toolbar configured, a simple 'Show \<toolbar name\>' |
209 | * menu item is shown; if more than one toolbar is configured, a "Shown Toolbars" |
210 | * menu is created instead, with 'Show \<toolbar1 name\>', 'Show \<toolbar2 name\>' |
211 | * ... sub-menu actions. |
212 | * |
213 | * If your application uses a non-default XmlGui resource file, then you can |
214 | * specify the exact position of the menu/menu item by adding a |
215 | * \c <Merge name="StandardToolBarMenuHandler"> |
216 | * line to the settings menu section of your resource file ( usually appname.rc ). |
217 | * |
218 | * \a showToolBarMenu Whether to show the standard toolbar menu. \c false by default. |
219 | * |
220 | * \note This function only makes sense before calling createGUI(). |
221 | * Using setupGUI(ToolBar) overrides this function. |
222 | * |
223 | * \sa createGUI() |
224 | * \sa setupGUI() |
225 | * \sa KToggleBarAction |
226 | * \sa StandardWindowOption |
227 | * \sa KMainWindow::toolBar() |
228 | * \sa KMainWindow::toolBars() |
229 | * \sa QMainWindow::addToolBar() |
230 | * \sa QMainWindow::removeToolBar() |
231 | * \sa createStandardStatusBarAction() |
232 | */ |
233 | void setStandardToolBarMenuEnabled(bool ); |
234 | |
235 | /*! |
236 | * \brief Returns whether setStandardToolBarMenuEnabled() was set. |
237 | * |
238 | * \note This function only makes sense if createGUI() was used. |
239 | * This function returns true only if setStandardToolBarMenuEnabled() was set |
240 | * and will return false even if \l StandardWindowOption::ToolBar was used. |
241 | * |
242 | * Returns \c true if setStandardToolBarMenuEnabled() was set, \c false otherwise. |
243 | * |
244 | * \sa createGUI() |
245 | * \sa setupGUI() |
246 | * \sa setStandardToolBarMenuEnabled() |
247 | * \sa StandardWindowOption |
248 | */ |
249 | bool isStandardToolBarMenuEnabled() const; |
250 | |
251 | /*! |
252 | * \brief Creates a toggle under the 'Settings' menu to show/hide the statusbar. |
253 | * |
254 | * Calling this method will create a statusbar if one doesn't already exist. |
255 | * |
256 | * If an application maintains the action on its own (i.e. never calls |
257 | * this function), a connection needs to be made to let KMainWindow |
258 | * know when the hidden/shown status of the statusbar has changed. |
259 | * For example: |
260 | * \code |
261 | * connect(action, &QAction::triggered, |
262 | * kmainwindow, &KMainWindow::setSettingsDirty); |
263 | * \endcode |
264 | * Otherwise the status might not be saved by KMainWindow. |
265 | * |
266 | * \note This function only makes sense before calling createGUI() |
267 | * or when using setupGUI() without \l StandardWindowOption::StatusBar. |
268 | * |
269 | * \sa createGUI() |
270 | * \sa setupGUI() |
271 | * \sa StandardWindowOption |
272 | * \sa KStandardAction::showStatusbar() |
273 | * \sa setStandardToolBarMenuEnabled() |
274 | * \sa QMainWindow::setStatusBar() |
275 | * \sa QMainWindow::statusBar() |
276 | */ |
277 | void createStandardStatusBarAction(); |
278 | |
279 | /*! |
280 | * \enum KXmlGuiWindow::StandardWindowOption |
281 | * |
282 | * Use these options for the first argument of setupGUI(). |
283 | * \sa setupGUI() |
284 | * |
285 | * \value ToolBar |
286 | * Adds action(s) to show/hide the toolbar(s) and adds a menu |
287 | * action to configure the toolbar(s). |
288 | * \sa setStandardToolBarMenuEnabled() |
289 | * \sa isStandardToolBarMenuEnabled() |
290 | * \value Keys |
291 | * Adds an action in the 'Settings' menu to open the configure |
292 | * keyboard shortcuts dialog. |
293 | * \value StatusBar |
294 | * Adds an action to show/hide the statusbar in the 'Settings' menu. |
295 | * Note that setting this value will create a statusbar |
296 | * if one doesn't already exist. |
297 | * \sa createStandardStatusBarAction() |
298 | * \value Save |
299 | * Autosaves (and loads) the toolbar/menubar/statusbar settings and |
300 | * window size using the default name. |
301 | * Like KMainWindow::setAutoSaveSettings(), enabling this causes the application |
302 | * to save state data upon close in a KConfig-managed configuration file. |
303 | * Typically you want to let the default window size be determined by |
304 | * the widgets' size hints. Make sure that setupGUI() is called after |
305 | * all the widgets are created (including QMainWindow::setCentralWidget()) |
306 | * so that the default size is managed properly. |
307 | * \sa KMainWindow::setAutoSaveSettings() |
308 | * \sa KConfig |
309 | * \value Create |
310 | * Calls createGUI() once ToolBar, Keys and Statusbar have been |
311 | * taken care of. |
312 | * \sa createGUI() |
313 | * \value Default |
314 | * Sets all of the above options as true. |
315 | * |
316 | * \note In the case of KXmlGuiWindow::Create, when using KParts::MainWindow, |
317 | * remove this flag from the setupGUI() call, since you'll be using |
318 | * createGUI(part) instead: |
319 | * \code |
320 | * setupGUI(ToolBar | Keys | StatusBar | Save); |
321 | * \endcode |
322 | */ |
323 | enum StandardWindowOption { |
324 | ToolBar = 1, |
325 | Keys = 2, |
326 | StatusBar = 4, |
327 | Save = 8, |
328 | Create = 16, |
329 | Default = ToolBar | Keys | StatusBar | Save | Create, |
330 | }; |
331 | Q_FLAG(StandardWindowOption) |
332 | Q_DECLARE_FLAGS(StandardWindowOptions, StandardWindowOption) |
333 | |
334 | /*! |
335 | * \brief Configures the current window and its actions in the typical KDE |
336 | * fashion. |
337 | * |
338 | * You can specify which window options/features are going to be set up using |
339 | * \a options, see the \l StandardWindowOptions enum for more details. |
340 | * |
341 | * \code |
342 | * MainWindow::MainWindow(QWidget* parent) : KXmlGuiWindow(parent){ |
343 | * textArea = new KTextEdit(); |
344 | * setCentralWidget(textArea); |
345 | * setupGUI(Default, "appnameui.rc"); |
346 | * } |
347 | * \endcode |
348 | * |
349 | * Use a bitwise OR (|) to select multiple enum choices for setupGUI() |
350 | * (except when using StandardWindowOptions::Default). |
351 | * |
352 | * \code |
353 | * setupGUI(Save | Create, "appnameui.rc"); |
354 | * \endcode |
355 | * |
356 | * Typically this function replaces createGUI(), |
357 | * but it is possible to call setupGUI(Create) together with helper functions |
358 | * such as setStandardToolBarMenuEnabled() and createStandardStatusBarAction(). |
359 | * |
360 | * \warning To use createGUI() and setupGUI() |
361 | * for the same window, you must avoid using |
362 | * \l StandardWindowOption::Create. Prefer using only setupGUI(). |
363 | * |
364 | * \note When \l StandardWindowOption::Save is used, |
365 | * this method will restore the state of the application |
366 | * window (toolbar, dockwindows positions ...etc), so you need to have |
367 | * added all your actions to your UI before calling this |
368 | * method. |
369 | * |
370 | * \a options A combination of \l StandardWindowOptions to specify |
371 | * UI elements to be present in your application window. |
372 | * |
373 | * \a xmlfile The relative or absolute path to the local xmlfile. |
374 | * If this is an empty string, the code will look for a local XML file |
375 | * appnameui.rc, where 'appname' is the name of your app. See the note |
376 | * about the xmlfile argument in createGUI(). |
377 | * |
378 | * \sa StandardWindowOption |
379 | */ |
380 | void setupGUI(StandardWindowOptions options = Default, const QString &xmlfile = QString()); |
381 | |
382 | /*! |
383 | * \brief This is an overloaded function. |
384 | * |
385 | * \a defaultSize A manually specified window size that overrides the saved size. |
386 | * |
387 | * \a options A combination of \l StandardWindowOptions to specify |
388 | * UI elements to be present in your application window. |
389 | * |
390 | * \a xmlfile The relative or absolute path to the local xmlfile. |
391 | * \sa setupGUI() |
392 | */ |
393 | void setupGUI(const QSize &defaultSize, StandardWindowOptions options = Default, const QString &xmlfile = QString()); |
394 | |
395 | /*! |
396 | * Returns a pointer to the main window's action responsible for the toolbar's menu. |
397 | */ |
398 | QAction *(); |
399 | |
400 | /*! |
401 | * \internal for KToolBar |
402 | */ |
403 | void (); |
404 | |
405 | /*! |
406 | * Returns a list of all toolbars for this window in string form |
407 | * \sa KMainWindow::toolBars() |
408 | * \since 6.10 |
409 | */ |
410 | QStringList toolBarNames() const; |
411 | |
412 | /*! |
413 | * |
414 | */ |
415 | void finalizeGUI(bool force); |
416 | using KXMLGUIBuilder::finalizeGUI; |
417 | |
418 | // reimplemented for internal reasons |
419 | void applyMainWindowSettings(const KConfigGroup &config) override; |
420 | |
421 | /*! |
422 | * \brief Enable a KCommandBar to list and quickly execute actions. |
423 | * |
424 | * A KXmlGuiWindow by default automatically creates a KCommandBar, |
425 | * but it is inaccessible unless createGUI() or setupGUI(Create) is used. |
426 | * |
427 | * It provides a HUD-like menu that lists all QActions in your application |
428 | * and can be activated via Ctrl+Atl+i or via an action in the 'Help' menu. |
429 | * |
430 | * If you need more than a global set of QActions listed for your application, |
431 | * use KCommandBar directly instead. |
432 | * |
433 | * \a showCommandBar Whether to show the command bar. \c true by default. |
434 | * |
435 | * \since 5.83 |
436 | * |
437 | * \sa KCommandBar |
438 | * \sa KCommandBar::setActions() |
439 | * \sa isCommandBarEnabled() |
440 | */ |
441 | void setCommandBarEnabled(bool showCommandBar); |
442 | |
443 | /*! |
444 | * \brief Whether a KCommandBar was set. |
445 | * |
446 | * Returns \c true by default, \c false if setCommandBarEnabled(false) was set. |
447 | * |
448 | * \since 5.83 |
449 | * \sa setCommandBarEnabled() |
450 | */ |
451 | bool isCommandBarEnabled() const; |
452 | |
453 | public Q_SLOTS: |
454 | /*! |
455 | * \brief Show a standard configure toolbar dialog. |
456 | * |
457 | * This slot can be connected directly to the action to configure the toolbar. |
458 | * |
459 | * Example code: |
460 | * \code |
461 | * KStandardAction::configureToolbars(this, &KXmlGuiWindow::configureToolbars, actionCollection); |
462 | * \endcode |
463 | */ |
464 | virtual void configureToolbars(); |
465 | |
466 | /*! |
467 | * \brief Applies a state change |
468 | * |
469 | * Reimplement this to enable and disable actions as defined in the XmlGui rc file. |
470 | * |
471 | * \a newstate The state change to be applied. |
472 | */ |
473 | virtual void slotStateChanged(const QString &newstate); |
474 | |
475 | /*! |
476 | * \brief Applies a state change |
477 | * |
478 | * Reimplement this to enable and disable actions as defined in the XmlGui rc file. |
479 | * |
480 | * This function can "reverse" the state (disable the actions which should be |
481 | * enabled, and vice-versa) if specified. |
482 | * |
483 | * \a newstate The state change to be applied. |
484 | * |
485 | * \a reverse Whether to reverse \a newstate or not. |
486 | */ |
487 | void slotStateChanged(const QString &newstate, bool reverse); |
488 | |
489 | /*! |
490 | * \brief Checks the visual state of a given toolbar. If an invalid name is |
491 | * given, the method will always return false. |
492 | * |
493 | * This does not utilize KMainWindow::toolBar(), as that method would |
494 | * create a new toolbar in the case of an invalid name, which is not |
495 | * something that should be freely accessable via the dbus. |
496 | * |
497 | * \a name The internal name of the toolbar. |
498 | * |
499 | * Returns whether the toolbar with the specified name is currently visible |
500 | * |
501 | * \sa toolBarNames() |
502 | * \sa setToolBarVisible() |
503 | * \sa KMainWindow::toolBar() |
504 | * \since 6.10 |
505 | */ |
506 | bool isToolBarVisible(const QString &name); |
507 | |
508 | /*! |
509 | * \brief Sets the visibility of a given toolbar. If an invalid name is |
510 | * given, nothing happens. |
511 | * |
512 | * \a name The internal name of the toolbar. |
513 | * |
514 | * \a visible The new state of the toolbar's visibility. |
515 | * \since 6.10 |
516 | */ |
517 | void setToolBarVisible(const QString &name, bool visible); |
518 | |
519 | protected: |
520 | /*! |
521 | * Reimplemented to return the \a event QEvent::Polish in order to adjust the object name |
522 | * if needed, once all constructor code for the main window has run. |
523 | * |
524 | * Also reimplemented to catch when a QDockWidget is added or removed. |
525 | */ |
526 | bool event(QEvent *event) override; |
527 | |
528 | /*! |
529 | * \brief Checks if there are actions using the same shortcut. |
530 | * |
531 | * This is called automatically from createGUI(). |
532 | * |
533 | * \since 5.30 |
534 | */ |
535 | void checkAmbiguousShortcuts(); |
536 | |
537 | protected Q_SLOTS: |
538 | /*! |
539 | * \brief Rebuilds the GUI after KEditToolBar changes the toolbar layout. |
540 | * \sa configureToolbars() |
541 | */ |
542 | virtual void saveNewToolbarConfig(); |
543 | |
544 | private: |
545 | Q_DECLARE_PRIVATE(KXmlGuiWindow) |
546 | }; |
547 | |
548 | Q_DECLARE_OPERATORS_FOR_FLAGS(KXmlGuiWindow::StandardWindowOptions) |
549 | |
550 | #endif |
551 | |