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 * \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
88class 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
113public:
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 setHelpMenuEnabled(bool showHelpMenu = 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 isHelpMenuEnabled() 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 showToolBarMenu);
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 *toolBarMenuAction();
399
400 /*!
401 * \internal for KToolBar
402 */
403 void setupToolbarMenuActions();
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
453public 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
519protected:
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
537protected Q_SLOTS:
538 /*!
539 * \brief Rebuilds the GUI after KEditToolBar changes the toolbar layout.
540 * \sa configureToolbars()
541 */
542 virtual void saveNewToolbarConfig();
543
544private:
545 Q_DECLARE_PRIVATE(KXmlGuiWindow)
546};
547
548Q_DECLARE_OPERATORS_FOR_FLAGS(KXmlGuiWindow::StandardWindowOptions)
549
550#endif
551

source code of kxmlgui/src/kxmlguiwindow.h