1 | /* |
2 | This file is part of the KDE libraries |
3 | SPDX-FileCopyrightText: 1999 Simon Hausmann <hausmann@kde.org> |
4 | SPDX-FileCopyrightText: 2000 Kurt Granroth <granroth@kde.org> |
5 | |
6 | SPDX-License-Identifier: LGPL-2.0-only |
7 | */ |
8 | |
9 | #ifndef kxmlguifactory_h |
10 | #define kxmlguifactory_h |
11 | |
12 | #include <kxmlgui_export.h> |
13 | |
14 | #include <QObject> |
15 | #include <memory> |
16 | |
17 | class QAction; |
18 | class KXMLGUIFactoryPrivate; |
19 | class KXMLGUIClient; |
20 | class KXMLGUIBuilder; |
21 | |
22 | class QDomAttr; |
23 | class QDomDocument; |
24 | class QDomElement; |
25 | class QDomNode; |
26 | class QDomNamedNodeMap; |
27 | |
28 | namespace KXMLGUI |
29 | { |
30 | struct MergingIndex; |
31 | struct ContainerNode; |
32 | struct ContainerClient; |
33 | class BuildHelper; |
34 | } |
35 | |
36 | /** |
37 | * @class KXMLGUIFactory kxmlguifactory.h KXMLGUIFactory |
38 | * |
39 | * KXMLGUIFactory, together with KXMLGUIClient objects, can be used to create |
40 | * a GUI of container widgets (like menus, toolbars, etc.) and container items |
41 | * (menu items, toolbar buttons, etc.) from an XML document and action objects. |
42 | * |
43 | * Each KXMLGUIClient represents a part of the GUI, composed from containers and |
44 | * actions. KXMLGUIFactory takes care of building (with the help of a KXMLGUIBuilder) |
45 | * and merging the GUI from an unlimited number of clients. |
46 | * |
47 | * Each client provides XML through a QDomDocument and actions through a |
48 | * KActionCollection . The XML document contains the rules for how to merge the |
49 | * GUI. |
50 | * |
51 | * KXMLGUIFactory processes the DOM tree provided by a client and plugs in the client's actions, |
52 | * according to the XML and the merging rules of previously inserted clients. Container widgets |
53 | * are built via a KXMLGUIBuilder , which has to be provided with the KXMLGUIFactory constructor. |
54 | */ |
55 | class KXMLGUI_EXPORT KXMLGUIFactory : public QObject |
56 | { |
57 | friend class KXMLGUI::BuildHelper; |
58 | Q_OBJECT |
59 | public: |
60 | /** |
61 | * Constructs a KXMLGUIFactory. The provided @p builder KXMLGUIBuilder will be called |
62 | * for creating and removing container widgets, when clients are added/removed from the GUI. |
63 | * |
64 | * Note that the ownership of the given KXMLGUIBuilder object won't be transferred to this |
65 | * KXMLGUIFactory, so you have to take care of deleting it properly. |
66 | */ |
67 | explicit KXMLGUIFactory(KXMLGUIBuilder *builder, QObject *parent = nullptr); |
68 | |
69 | /** |
70 | * Destructor |
71 | */ |
72 | ~KXMLGUIFactory() override; |
73 | |
74 | // XXX move to somewhere else? (Simon) |
75 | /// @internal |
76 | static QString readConfigFile(const QString &filename, const QString &componentName = QString()); |
77 | /// @internal |
78 | static bool saveConfigFile(const QDomDocument &doc, const QString &filename, const QString &componentName = QString()); |
79 | |
80 | /** |
81 | * @internal |
82 | * Find or create the ActionProperties element, used when saving custom action properties |
83 | */ |
84 | static QDomElement actionPropertiesElement(QDomDocument &doc); |
85 | |
86 | /** |
87 | * @internal |
88 | * Find or create the element for a given action, by name. |
89 | * Used when saving custom action properties |
90 | */ |
91 | static QDomElement findActionByName(QDomElement &elem, const QString &sName, bool create); |
92 | |
93 | /** |
94 | * Creates the GUI described by the QDomDocument of the client, |
95 | * using the client's actions, and merges it with the previously |
96 | * created GUI. |
97 | * This also means that the order in which clients are added to the factory |
98 | * is relevant; assuming that your application supports plugins, you should |
99 | * first add your application to the factory and then the plugin, so that the |
100 | * plugin's UI is merged into the UI of your application, and not the other |
101 | * way round. |
102 | */ |
103 | void addClient(KXMLGUIClient *client); |
104 | |
105 | /** |
106 | * Removes the GUI described by the client, by unplugging all |
107 | * provided actions and removing all owned containers (and storing |
108 | * container state information in the given client) |
109 | */ |
110 | void removeClient(KXMLGUIClient *client); |
111 | |
112 | void plugActionList(KXMLGUIClient *client, const QString &name, const QList<QAction *> &actionList); |
113 | void unplugActionList(KXMLGUIClient *client, const QString &name); |
114 | |
115 | /** |
116 | * Returns a list of all clients currently added to this factory |
117 | */ |
118 | QList<KXMLGUIClient *> clients() const; |
119 | |
120 | /** |
121 | * Use this method to get access to a container widget with the name specified with @p containerName |
122 | * and which is owned by the @p client. The container name is specified with a "name" attribute in the |
123 | * XML document. |
124 | * |
125 | * This function is particularly useful for getting hold of a popupmenu defined in an XMLUI file. |
126 | * For instance: |
127 | * \code |
128 | * QMenu *popup = static_cast<QMenu*>(guiFactory()->container("my_popup",this)); |
129 | * \endcode |
130 | * where @p "my_popup" is the name of the menu in the XMLUI file, and |
131 | * @p "this" is XMLGUIClient which owns the popupmenu (e.g. the mainwindow, or the part, or the plugin...) |
132 | * |
133 | * @param containerName Name of the container widget |
134 | * @param client Owner of the container widget |
135 | * @param useTagName Specifies whether to compare the specified name with the name attribute or |
136 | * the tag name. |
137 | * |
138 | * This method may return nullptr if no container with the given name exists or is not owned by the client. |
139 | */ |
140 | QWidget *container(const QString &containerName, KXMLGUIClient *client, bool useTagName = false); |
141 | |
142 | QList<QWidget *> containers(const QString &tagName); |
143 | |
144 | /** |
145 | * Use this method to free all memory allocated by the KXMLGUIFactory. This deletes the internal node |
146 | * tree and therefore resets the internal state of the class. Please note that the actual GUI is |
147 | * NOT touched at all, meaning no containers are deleted nor any actions unplugged. That is |
148 | * something you have to do on your own. So use this method only if you know what you are doing :-) |
149 | * |
150 | * (also note that this will call KXMLGUIClient::setFactory(nullptr) for all inserted clients) |
151 | */ |
152 | void reset(); |
153 | |
154 | /** |
155 | * Use this method to free all memory allocated by the KXMLGUIFactory for a specific container, |
156 | * including all child containers and actions. This deletes the internal node subtree for the |
157 | * specified container. The actual GUI is not touched, no containers are deleted or any actions |
158 | * unplugged. Use this method only if you know what you are doing :-) |
159 | * |
160 | * (also note that this will call KXMLGUIClient::setFactory(nullptr) for all clients of the |
161 | * container) |
162 | */ |
163 | void resetContainer(const QString &containerName, bool useTagName = false); |
164 | |
165 | /** |
166 | * Use this method to reset and reread action properties (shortcuts, etc.) for all actions. |
167 | * This is needed, for example, when you change shortcuts scheme at runtime. |
168 | */ |
169 | void refreshActionProperties(); |
170 | |
171 | public Q_SLOTS: |
172 | /** |
173 | * Shows a dialog (KShortcutsDialog) that lists every action in this factory, |
174 | * and which can be used to change the shortcuts associated with each action. |
175 | * |
176 | * This slot can be connected directly to the configure shortcuts action, |
177 | * for example: |
178 | * @code |
179 | * KStandardAction::keyBindings(guiFactory(), &KXMLGUIFactory::showConfigureShortcutsDialog, actionCollection()); |
180 | * @endcode |
181 | * |
182 | * This method constructs a KShortcutsDialog with the default arguments |
183 | * (KShortcutsEditor::AllActions and KShortcutsEditor::LetterShortcutsAllowed). |
184 | * |
185 | * @see KShortcutsDialog, KShortcutsEditor::ActionTypes, KShortcutsEditor::LetterShortcuts |
186 | * |
187 | * By default the changes will be saved back to the @c *ui.rc file |
188 | * which they were initially read from. |
189 | * |
190 | * If you need to run some extra code if the dialog is accepted and the settings |
191 | * are saved, you can simply connect to the @ref KXMLGUIFactory::shortcutsSaved() |
192 | * signal before calling this method, for example: |
193 | * @code |
194 | * connect(guiFactory(), &KXMLGUIFactory::shortcutsSaved, this, &MyClass::slotShortcutSaved); |
195 | * guiFactory()->showConfigureShortcutsDialog(); |
196 | * @endcode |
197 | * |
198 | * @since 5.84 |
199 | */ |
200 | void showConfigureShortcutsDialog(); |
201 | |
202 | void changeShortcutScheme(const QString &scheme); |
203 | |
204 | Q_SIGNALS: |
205 | void clientAdded(KXMLGUIClient *client); |
206 | void clientRemoved(KXMLGUIClient *client); |
207 | |
208 | /** |
209 | * Emitted when the factory is currently making changes to the GUI, |
210 | * i.e. adding or removing clients. |
211 | * makingChanges(true) is emitted before any change happens, and |
212 | * makingChanges(false) is emitted after the change is done. |
213 | * This allows e.g. KMainWindow to know that the GUI is |
214 | * being changed programmatically and not by the user (so there is no reason to |
215 | * save toolbar settings afterwards). |
216 | * @since 4.1.3 |
217 | */ |
218 | void makingChanges(bool); |
219 | |
220 | /** |
221 | * Emitted when the shortcuts have been saved (i.e. the user accepted the dialog). |
222 | * |
223 | * If you're using multiple instances of the same KXMLGUIClient, you probably want to |
224 | * connect to this signal and call @c KXMLGUIClient::reloadXML() for each of your |
225 | * KXMLGUIClients, so that the other instances update their shortcuts settings. |
226 | * |
227 | * @since 5.79 |
228 | */ |
229 | void shortcutsSaved(); |
230 | |
231 | private: |
232 | /// Internal, called by KXMLGUIClient destructor |
233 | KXMLGUI_NO_EXPORT void forgetClient(KXMLGUIClient *client); |
234 | |
235 | private: |
236 | friend class KXMLGUIClient; |
237 | std::unique_ptr<KXMLGUIFactoryPrivate> const d; |
238 | }; |
239 | |
240 | #endif |
241 | |