1 /*
2     This file is part of the KDE libraries
3      Copyright
4      (C) 2000 Reginald Stadlbauer (reggie@kde.org)
5      (C) 1997 Stephan Kulow (coolo@kde.org)
6      (C) 1997-2000 Sven Radej (radej@kde.org)
7      (C) 1997-2000 Matthias Ettrich (ettrich@kde.org)
8      (C) 1999 Chris Schlaeger (cs@kde.org)
9      (C) 2002 Joseph Wenninger (jowenn@kde.org)
10      (C) 2005-2006 Hamish Rodda (rodda@kde.org)
11 
12     This library is free software; you can redistribute it and/or
13     modify it under the terms of the GNU Library General Public
14     License version 2 as published by the Free Software Foundation.
15 
16     This library is distributed in the hope that it will be useful,
17     but WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19     Library General Public License for more details.
20 
21     You should have received a copy of the GNU Library General Public License
22     along with this library; see the file COPYING.LIB.  If not, write to
23     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24     Boston, MA 02110-1301, USA.
25 
26 */
27 
28 #ifndef KXMLGUIWINDOW_H
29 #define KXMLGUIWINDOW_H
30 
31 #include "kxmlguiclient.h"
32 #include "kxmlguibuilder.h"
33 #include "kmainwindow.h"
34 #include <QMetaClassInfo>
35 
36 class KMenu;
37 class KXMLGUIFactory;
38 class KConfig;
39 class KConfigGroup;
40 class KToolBar;
41 class KXmlGuiWindowPrivate;
42 
43 /**
44  * @short %KDE top level main window with predefined action layout
45  *
46  * Instead of creating a KMainWindow manually and assigning menus, menu entries,
47  * toolbar buttons and actions to it by hand, this class can be used to load an
48  * rc file to manage the main window's actions.
49  *
50  * See http://techbase.kde.org/Development/Tutorials/Using_KActions#XMLGUI
51  * for essential information on the XML file format and usage of this class.
52  *
53  * @see KMainWindow
54  * @author Reginald Stadlbauer (reggie@kde.org) Stephan Kulow (coolo@kde.org), Matthias Ettrich (ettrich@kde.org), Chris Schlaeger (cs@kde.org), Sven Radej (radej@kde.org). Maintained by Sven Radej (radej@kde.org)
55 
56  */
57 
58 class KRITAWIDGETUTILS_EXPORT KXmlGuiWindow : public KMainWindow, public KXMLGUIBuilder, virtual public KXMLGUIClient
59 {
60     XMLGUI_DECLARE_PRIVATE(KXmlGuiWindow)
61     Q_OBJECT
62     Q_PROPERTY(bool hasMenuBar READ hasMenuBar)
63     Q_PROPERTY(bool autoSaveSettings READ autoSaveSettings)
64     Q_PROPERTY(QString autoSaveGroup READ autoSaveGroup)
65     Q_PROPERTY(bool standardToolBarMenuEnabled READ isStandardToolBarMenuEnabled WRITE setStandardToolBarMenuEnabled)
66     Q_FLAGS(StandardWindowOption)
67 
68 public:
69     /**
70      * Construct a main window.
71      *
72      * @param parent The widget parent. This is usually 0 but it may also be the window
73      * group leader. In that case, the KMainWindow becomes sort of a
74      * secondary window.
75      *
76      * @param f Specify the widget flags. The default is
77      * Qt::Window and Qt::WA_DeleteOnClose.  Qt::Window indicates that a
78      * main window is a toplevel window, regardless of whether it has a
79      * parent or not. Qt::WA_DeleteOnClose indicates that a main window is
80      * automatically destroyed when its window is closed. Pass 0 if
81      * you do not want this behavior.
82      *
83      * @see http://doc.trolltech.com/qt.html#WindowType-enum
84      *
85      * KMainWindows must be created on the heap with 'new', like:
86      * \code
87      * KMainWindow *kmw = new KMainWindow(...);
88      * kmw->setObjectName(...);
89      * \endcode
90      *
91      * IMPORTANT: For session management and window management to work
92      * properly, all main windows in the application should have a
93      * different name. If you don't do it, KMainWindow will create
94      * a unique name, but it's recommended to explicitly pass a window name that will
95      * also describe the type of the window. If there can be several windows of the same
96      * type, append '#' (hash) to the name, and KMainWindow will replace it with numbers to make
97      * the names unique. For example, for a mail client which has one main window showing
98      * the mails and folders, and which can also have one or more windows for composing
99      * mails, the name for the folders window should be e.g. "mainwindow" and
100      * for the composer windows "composer#".
101      *
102      */
103     explicit KXmlGuiWindow(QWidget *parent = 0, Qt::WindowFlags f = Qt::WindowFlags());
104 
105     /**
106      * \brief Destructor.
107      *
108      * Will also destroy the toolbars, and menubar if
109      * needed.
110      */
111     ~KXmlGuiWindow() override;
112 
113     /**
114      * Enables the build of a standard help menu when calling createGUI/setupGUI().
115      *
116      * The default behavior is to build one, you must call this function
117      * to disable it
118      */
119     void setHelpMenuEnabled(bool showHelpMenu = true);
120 
121     /**
122      * Return @p true when the help menu is enabled
123      */
124     bool isHelpMenuEnabled() const;
125 
126     virtual KXMLGUIFactory *guiFactory();
127 
128     /**
129      * Create a GUI given a local XML file. In a regular app you usually want to use
130      * setupGUI() instead of this one since it does more things for free
131      * like setting up the toolbar/shortcut edit actions, etc.
132      *
133      * If @p xmlfile is 0,
134      * then it will try to construct a local XML filename like
135      * appnameui.xmlgui where 'appname' is your app's name.  If that file
136      * does not exist, then the XML UI code will only use the global
137      * (standard) XML file for the layout purposes.
138      *
139      * @param xmlfile The local xmlfile (relative or absolute)
140      */
141     void createGUI(const QString &xmlfile = QString());
142 
143     /**
144      * Sets whether KMainWindow should provide a menu that allows showing/hiding
145      * the available toolbars ( using KToggleToolBarAction ) . In case there
146      * is only one toolbar configured a simple 'Show \<toolbar name here\>' menu item
147      * is shown.
148      *
149      * The menu / menu item is implemented using xmlgui. It will be inserted in your
150      * menu structure in the 'Settings' menu.
151      *
152      * If your application uses a non-standard xmlgui resource file then you can
153      * specify the exact position of the menu / menu item by adding a
154      * &lt;Merge name="StandardToolBarMenuHandler" /&gt;
155      * line to the settings menu section of your resource file ( usually appname.xmlgui ).
156      *
157      * Note that you should enable this feature before calling createGUI() ( or similar ) .
158      */
159     void setStandardToolBarMenuEnabled(bool enable);
160     bool isStandardToolBarMenuEnabled() const;
161 
162     /**
163      * Sets whether KMainWindow should provide a menu that allows showing/hiding
164      * of the statusbar ( using KToggleStatusBarAction ).
165      *
166      * The menu / menu item is implemented using xmlgui. It will be inserted
167      * in your menu structure in the 'Settings' menu.
168      *
169      * Note that you should enable this feature before calling createGUI()
170      * ( or similar ).
171      *
172      * If an application maintains the action on its own (i.e. never calls
173      * this function) a connection needs to be made to let KMainWindow
174      * know when that status (hidden/shown) of the statusbar has changed.
175      * For example:
176      * connect(action, SIGNAL(activated()),
177      *         kmainwindow, SLOT(setSettingsDirty()));
178      * Otherwise the status (hidden/show) of the statusbar might not be saved
179      * by KMainWindow.
180      */
181     void createStandardStatusBarAction();
182 
183     /**
184      * @see setupGUI()
185      */
186     enum StandardWindowOption {
187         /**
188          * adds action to show/hide the toolbar(s) and adds
189          * action to configure the toolbar(s).
190          * @see setStandardToolBarMenuEnabled
191          */
192         ToolBar = 1,
193 
194         /**
195          * adds action to show the key configure action.
196          */
197         Keys = 2,
198 
199         /**
200          * adds action to show/hide the statusbar if the
201          * statusbar exists.  @see createStandardStatusBarAction
202          */
203         StatusBar = 4,
204 
205         /**
206          * auto-saves (and loads) the toolbar/menubar/statusbar settings and
207          * window size using the default name.  @see setAutoSaveSettings
208          *
209          * Typically you want to let the default window size be determined by
210          * the widgets size hints. Make sure that setupGUI() is called after
211          * all the widgets are created ( including setCentralWidget ) so the
212          * default size's will be correct. @see setAutoSaveSettings for
213          * more information on this topic.
214          */
215         Save = 8,
216 
217         /**
218          * calls createGUI() once ToolBar, Keys and Statusbar have been
219          * taken care of.  @see createGUI
220          *
221          * NOTE: when using KParts::MainWindow, remove this flag from the
222          * setupGUI call, since you'll be using createGUI(part) instead.
223          * @code
224          *     setupGUI(ToolBar | Keys | StatusBar | Save);
225          * @endcode
226          */
227         Create = 16,
228 
229         /**
230          * All the above option
231          * (this is the default)
232          */
233         Default = ToolBar | Keys | StatusBar | Save | Create
234     };
235     Q_DECLARE_FLAGS(StandardWindowOptions, StandardWindowOption)
236 
237     /**
238      * Configures the current windows and its actions in the typical KDE
239      * fashion.  The options are all enabled by default but can be turned
240      * off if desired through the params or if the prereqs don't exists.
241      *
242      * Typically this function replaces createGUI().
243      *
244      * @see StandardWindowOptions
245      * @note Since this method will restore the state of the application (toolbar, dockwindows
246      *       positions...), you need to have added all your actions to your toolbars etc before
247      *       calling to this method. (This note is only applicable if you are using the Default or
248      *       Save flag).
249      * @warning If you are calling createGUI yourself, remember to remove the Create flag from
250      *          the @p options parameter.
251      *
252      */
253     void setupGUI(StandardWindowOptions options = Default, const QString &xmlfile = QString());
254 
255     /**
256      * Configures the current windows and its actions in the typical KDE
257      * fashion.  The options are all enabled by default but can be turned
258      * off if desired through the params or if the prereqs don't exists.
259      *
260      * @p defaultSize The default size of the window
261      *
262      * Typically this function replaces createGUI().
263      *
264      * @see StandardWindowOptions
265      * @note Since this method will restore the state of the application (toolbar, dockwindows
266      *       positions...), you need to have added all your actions to your toolbars etc before
267      *       calling to this method. (This note is only applicable if you are using the Default or
268      *       Save flag).
269      * @warning If you are calling createGUI yourself, remember to remove the Create flag from
270      *          the @p options parameter. Also, call setupGUI always after you call createGUI.
271      */
272     void setupGUI(const QSize &defaultSize, StandardWindowOptions options = Default, const QString &xmlfile = QString());
273 
274     /**
275      * Returns a pointer to the mainwindows action responsible for the toolbars menu
276      */
277     QAction *toolBarMenuAction();
278 
279     /**
280      * @internal for KToolBar
281      */
282     void setupToolbarMenuActions();
283 
284     // KDE5 TODO: change it to "using KXMLGUIBuilder::finalizeGUI;"
285     void finalizeGUI(KXMLGUIClient *client) override;
286 
287     /**
288      * @internal
289      */
290     void finalizeGUI(bool force);
291 
292     // reimplemented for internal reasons
293     void applyMainWindowSettings(const KConfigGroup &config) override;
294 
295 public Q_SLOTS:
296     /**
297      * Show a standard configure toolbar dialog.
298      *
299      * This slot can be connected directly to the action to configure toolbar.
300      * This is very simple to do that by adding a single line
301      * \code
302      * KStandardAction::configureToolbars( this, SLOT( configureToolbars() ),
303      *                                actionCollection() );
304      * \endcode
305      */
306     virtual void configureToolbars();
307 
308     /**
309      * Apply a state change
310      *
311      * Enable and disable actions as defined in the XML rc file
312      */
313     virtual void slotStateChanged(const QString &newstate);
314 
315     /**
316      * Apply a state change
317      *
318      * Enable and disable actions as defined in the XML rc file,
319      * can "reverse" the state (disable the actions which should be
320      * enabled, and vice-versa) if specified.
321      */
322     void slotStateChanged(const QString &newstate,
323                           bool reverse);
324 
325 protected:
326     /**
327      * Reimplemented to catch QEvent::Polish in order to adjust the object name
328      * if needed, once all constructor code for the main window has run.
329      * Also reimplemented to catch when a QDockWidget is added or removed.
330      */
331     bool event(QEvent *event) override;
332 
333 protected Q_SLOTS:
334     /**
335      * Rebuilds the GUI after KEditToolbar changed the toolbar layout.
336      * @see configureToolbars()
337      */
338     virtual void saveNewToolbarConfig();
339 
340 private:
341     Q_PRIVATE_SLOT(k_func(), void _k_slotFactoryMakingChanges(bool))
342 };
343 
344 Q_DECLARE_OPERATORS_FOR_FLAGS(KXmlGuiWindow::StandardWindowOptions)
345 
346 #endif
347