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

source code of kxmlgui/src/kxmlguiwindow.h