1 | /* This file is part of the KDE libraries |
2 | Copyright (C) 2000 Simon Hausmann <hausmann@kde.org> |
3 | Copyright (C) 2000 Kurt Granroth <granroth@kde.org> |
4 | |
5 | This library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Library General Public |
7 | License version 2 as published by the Free Software Foundation. |
8 | |
9 | This library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | Library General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Library General Public License |
15 | along with this library; see the file COPYING.LIB. If not, write to |
16 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
17 | Boston, MA 02110-1301, USA. |
18 | */ |
19 | #ifndef KXMLGUICLIENT_H |
20 | #define KXMLGUICLIENT_H |
21 | |
22 | #include <kdeui_export.h> |
23 | |
24 | #include <QtCore/QMap> |
25 | #include <QtCore/QStringList> |
26 | |
27 | class QDomDocument; |
28 | class QDomElement; |
29 | class QWidget; |
30 | |
31 | class QAction; |
32 | class KActionCollection; |
33 | class KComponentData; |
34 | class KXMLGUIClientPrivate; |
35 | class KXMLGUIFactory; |
36 | class KXMLGUIBuilder; |
37 | |
38 | namespace KDEPrivate { class KEditToolBarWidget; } |
39 | |
40 | /** |
41 | * |
42 | * A KXMLGUIClient can be used with KXMLGUIFactory to create a |
43 | * GUI from actions and an XML document, and can be dynamically merged |
44 | * with other KXMLGUIClients. |
45 | */ |
46 | class KDEUI_EXPORT KXMLGUIClient |
47 | { |
48 | friend class KDEPrivate::KEditToolBarWidget; // for setXMLFile(3 args) |
49 | public: |
50 | /** |
51 | * Constructs a KXMLGUIClient which can be used with a |
52 | * KXMLGUIFactory to create a GUI from actions and an XML document, and |
53 | * which can be dynamically merged with other KXMLGUIClients. |
54 | */ |
55 | KXMLGUIClient(); |
56 | |
57 | /** |
58 | * Constructs a KXMLGUIClient which can be used with a KXMLGUIFactory |
59 | * to create a GUI from actions and an XML document, |
60 | * and which can be dynamically merged with other KXMLGUIClients. |
61 | * |
62 | * This constructor takes an additional @p parent argument, which makes |
63 | * the client a child client of the parent. |
64 | * |
65 | * Child clients are automatically added to the GUI if the parent is added. |
66 | * |
67 | */ |
68 | explicit KXMLGUIClient( KXMLGUIClient *parent ); |
69 | |
70 | /** |
71 | * Destructs the KXMLGUIClient. |
72 | * |
73 | * If the client was in a factory, the factory is NOT informed about the client |
74 | * being removed. This is a feature, it makes window destruction fast (the xmlgui |
75 | * is not updated for every client being deleted), but if you want to simply remove |
76 | * one client and to keep using the window, make sure to call factory->removeClient(client) |
77 | * before deleting the client. |
78 | */ |
79 | virtual ~KXMLGUIClient(); |
80 | |
81 | /** |
82 | * Retrieves an action of the client by name. If not found, it looks in its child clients. |
83 | * This method is provided for convenience, as it uses actionCollection() |
84 | * to get the action object. |
85 | */ |
86 | QAction* action( const char* name ) const; |
87 | |
88 | /** |
89 | * Retrieves an action for a given QDomElement. The default |
90 | * implementation uses the "name" attribute to query the action |
91 | * object via the other action() method. |
92 | */ |
93 | virtual QAction *action( const QDomElement &element ) const; |
94 | |
95 | /** |
96 | * Retrieves the entire action collection for the GUI client. |
97 | */ |
98 | virtual KActionCollection* actionCollection() const; |
99 | |
100 | /** |
101 | * @return The componentData ( KComponentData ) for this GUI client. |
102 | */ |
103 | virtual KComponentData componentData() const; |
104 | |
105 | /** |
106 | * @return The parsed XML in a QDomDocument, set by |
107 | * setXMLFile() or setXML(). |
108 | * This document describes the layout of the GUI. |
109 | */ |
110 | virtual QDomDocument domDocument() const; |
111 | |
112 | /** |
113 | * This will return the name of the XML file as set by setXMLFile(). |
114 | * If setXML() is used directly, then this will return NULL. |
115 | * |
116 | * The filename that this returns is obvious for components as each |
117 | * component has exactly one XML file. In non-components, however, |
118 | * there are usually two: the global file and the local file. This |
119 | * function doesn't really care about that, though. It will always |
120 | * return the last XML file set. This, in almost all cases, will |
121 | * be the local XML file. |
122 | * |
123 | * @return The name of the XML file or QString() |
124 | */ |
125 | virtual QString xmlFile() const; |
126 | |
127 | virtual QString localXMLFile() const; |
128 | |
129 | /** |
130 | * @internal |
131 | */ |
132 | void setXMLGUIBuildDocument( const QDomDocument &doc ); |
133 | /** |
134 | * @internal |
135 | */ |
136 | QDomDocument xmlguiBuildDocument() const; |
137 | |
138 | /** |
139 | * This method is called by the KXMLGUIFactory as soon as the client |
140 | * is added to the KXMLGUIFactory's GUI. |
141 | */ |
142 | void setFactory( KXMLGUIFactory *factory ); |
143 | /** |
144 | * Retrieves a pointer to the KXMLGUIFactory this client is |
145 | * associated with (will return 0 if the client's GUI has not been built |
146 | * by a KXMLGUIFactory. |
147 | */ |
148 | KXMLGUIFactory *factory() const; |
149 | |
150 | /** |
151 | * KXMLGUIClients can form a simple child/parent object tree. This |
152 | * method returns a pointer to the parent client or 0 if it has no |
153 | * parent client assigned. |
154 | */ |
155 | KXMLGUIClient *parentClient() const; |
156 | |
157 | /** |
158 | * Use this method to make a client a child client of another client. |
159 | * Usually you don't need to call this method, as it is called |
160 | * automatically when using the second constructor, which takes a |
161 | * parent argument. |
162 | */ |
163 | void insertChildClient( KXMLGUIClient *child ); |
164 | |
165 | /** |
166 | * Removes the given @p child from the client's children list. |
167 | */ |
168 | void removeChildClient( KXMLGUIClient *child ); |
169 | |
170 | /** |
171 | * Retrieves a list of all child clients. |
172 | */ |
173 | QList<KXMLGUIClient*> childClients(); |
174 | |
175 | /** |
176 | * A client can have an own KXMLGUIBuilder. |
177 | * Use this method to assign your builder instance to the client (so that the |
178 | * KXMLGUIFactory can use it when building the client's GUI) |
179 | * |
180 | * Client specific guibuilders are useful if you want to create |
181 | * custom container widgets for your GUI. |
182 | */ |
183 | void setClientBuilder( KXMLGUIBuilder *builder ); |
184 | |
185 | /** |
186 | * Retrieves the client's GUI builder or 0 if no client specific |
187 | * builder has been assigned via setClientBuilder() |
188 | */ |
189 | KXMLGUIBuilder *clientBuilder() const; |
190 | |
191 | /** |
192 | * Forces this client to re-read its XML resource file. This is |
193 | * intended to be used when you know that the resource file has |
194 | * changed and you will soon be rebuilding the GUI. This will only have |
195 | * an effect if the client is then removed and re-added to the factory. |
196 | * |
197 | * This method is only for child clients, do not call it for a mainwindow! |
198 | * For a mainwindow, use loadStandardsXmlFile + setXmlFile(xmlFile()) instead. |
199 | */ |
200 | void reloadXML(); |
201 | |
202 | /** |
203 | * ActionLists are a way for XMLGUI to support dynamic lists of |
204 | * actions. E.g. if you are writing a file manager, and there is a |
205 | * menu file whose contents depend on the mimetype of the file that |
206 | * is selected, then you can achieve this using ActionLists. It |
207 | * works as follows: |
208 | * In your xxxui.rc file ( the one that you set in setXMLFile() / pass to setupGUI() |
209 | * ), you put a tag <tt>\<ActionList name="xxx"\></tt>. |
210 | * |
211 | * Example: |
212 | * \code |
213 | * <gui name="xxx_part" version="1"> |
214 | * <MenuBar> |
215 | * <Menu name="file"> |
216 | * ... <!-- some useful actions--> |
217 | * <ActionList name="xxx_file_actionlist" /> |
218 | * ... <!-- even more useful actions--> |
219 | * </Menu> |
220 | * ... |
221 | * </MenuBar> |
222 | * </gui> |
223 | * \endcode |
224 | * |
225 | * This tag will get expanded to a list of actions. In the example |
226 | * above ( a file manager with a dynamic file menu ), you would call |
227 | * \code |
228 | * QList<QAction*> file_actions; |
229 | * for( ... ) |
230 | * if( ... ) |
231 | * file_actions.append( cool_action ); |
232 | * unplugActionList( "xxx_file_actionlist" ); |
233 | * plugActionList( "xxx_file_actionlist", file_actions ); |
234 | * \endcode |
235 | * every time a file is selected, unselected or ... |
236 | * |
237 | * \note You should not call createGUI() after calling this |
238 | * function. In fact, that would remove the newly added |
239 | * actionlists again... |
240 | * \note Forgetting to call unplugActionList() before |
241 | * plugActionList() would leave the previous actions in the |
242 | * menu too.. |
243 | * \see unplugActionList() |
244 | */ |
245 | void plugActionList( const QString &name, const QList<QAction*> &actionList ); |
246 | |
247 | /** |
248 | * Unplugs the action list \p name from the XMLGUI. |
249 | * Calling this removes the specified action list, i.e. this is the |
250 | * complement to plugActionList(). See plugActionList() for a more |
251 | * detailed example. |
252 | * \see plugActionList() |
253 | */ |
254 | void unplugActionList( const QString &name ); |
255 | |
256 | static QString findMostRecentXMLFile( const QStringList &files, QString &doc ); |
257 | |
258 | void addStateActionEnabled(const QString& state, const QString& action); |
259 | |
260 | void addStateActionDisabled(const QString& state, const QString& action); |
261 | |
262 | enum ReverseStateChange { StateNoReverse, StateReverse }; |
263 | struct StateChange |
264 | { |
265 | QStringList actionsToEnable; |
266 | QStringList actionsToDisable; |
267 | }; |
268 | |
269 | StateChange getActionsToChangeForState(const QString& state); |
270 | |
271 | void beginXMLPlug( QWidget * ); |
272 | void endXMLPlug(); |
273 | void prepareXMLUnplug( QWidget * ); |
274 | |
275 | /** |
276 | * Sets a new xmlFile() and localXMLFile(). The purpose of this public |
277 | * method is to allow non-inherited objects to replace the ui definition |
278 | * of an embedded client with a customized version. It corresponds to the |
279 | * usual calls to setXMLFile() and setLocalXMLFile(). |
280 | * |
281 | * @param xmlfile The xml file to use. Contrary to setXMLFile(), this |
282 | * must be an absolute file path. |
283 | * @param localxmfile The local xml file to set. This should be the full path |
284 | * to a writeable file, usually inside |
285 | * KStandardDirs::localkdedir(). You can set this to |
286 | * QString(), but no user changes to shortcuts / toolbars |
287 | * will be possible in this case. @see setLocalXMLFile() |
288 | * @param merge Whether to merge with the global document |
289 | * |
290 | * @note If in any doubt whether you need this or not, use setXMLFile() |
291 | * and setLocalXMLFile(), instead of this function. |
292 | * @note Just like setXMLFile(), this function has to be called before |
293 | * the client is added to a KXMLGUIFactory in order to have an |
294 | * effect. |
295 | * |
296 | * @since 4.4 |
297 | */ |
298 | void replaceXMLFile( const QString& xmlfile, const QString& localxmlfile, bool merge = false ); |
299 | |
300 | protected: |
301 | /** |
302 | * Returns true if client was added to super client list. |
303 | * Returns false if client was already in list. |
304 | */ |
305 | //bool addSuperClient( KXMLGUIClient * ); |
306 | |
307 | /** |
308 | * Sets the componentData ( KComponentData) for this part. |
309 | * |
310 | * Call this first in the inherited class constructor. |
311 | * (At least before setXMLFile().) |
312 | */ |
313 | virtual void setComponentData(const KComponentData &componentData); |
314 | |
315 | /** |
316 | * Sets the name of the rc file containing the XML for the part. |
317 | * |
318 | * Call this in the inherited class constructor, for parts and plugins. |
319 | * NOTE: for mainwindows, don't call this, pass the name of the xml file |
320 | * to KXmlGuiWindow::setupGUI() or KXmlGuiWindow::createGUI(). |
321 | * |
322 | * @param file Either an absolute path for the file, or simply the |
323 | * filename, which will then be assumed to be installed |
324 | * in the "data" resource, under a directory named like |
325 | * the componentData. |
326 | * If you pass an absolute path here, make sure to also call |
327 | * setLocalXMLFile, otherwise toolbar editing won't work. |
328 | * @param merge Whether to merge with the global document. |
329 | * @param setXMLDoc Specify whether to call setXML. Default is true. |
330 | **/ |
331 | virtual void setXMLFile( const QString& file, bool merge = false, bool setXMLDoc = true ); |
332 | |
333 | /** |
334 | * Load the ui_standards.rc file. Usually followed by setXMLFile(xmlFile, true), for merging. |
335 | * @since 4.6 |
336 | */ |
337 | void loadStandardsXmlFile(); |
338 | |
339 | /** |
340 | * Set the full path to the "local" xml file, the one used for saving |
341 | * toolbar and shortcut changes. You normally don't need to call this, |
342 | * if you pass a simple filename to setXMLFile. |
343 | */ |
344 | virtual void setLocalXMLFile( const QString &file ); |
345 | |
346 | /** |
347 | * Sets the XML for the part. |
348 | * |
349 | * Call this in the Part-inherited class constructor if you |
350 | * don't call setXMLFile(). |
351 | **/ |
352 | virtual void setXML( const QString &document, bool merge = false ); |
353 | |
354 | /** |
355 | * Sets the Document for the part, describing the layout of the GUI. |
356 | * |
357 | * Call this in the Part-inherited class constructor if you don't call |
358 | * setXMLFile or setXML. |
359 | * |
360 | * WARNING: using this method is not recommended. Many code paths |
361 | * lead to reloading from the XML file on disk. And editing toolbars requires |
362 | * that the result is written to disk anyway, and loaded from there the next time. |
363 | * |
364 | * For application-specific changes to a client's XML, it is a better idea to |
365 | * save the modified dom document to an app/default-client.xml and define a local-xml-file |
366 | * to something specific like app/local-client.xml, using replaceXMLFile. |
367 | * See kdepimlibs/kontactinterface/plugin.cpp for an example. |
368 | */ |
369 | virtual void setDOMDocument( const QDomDocument &document, bool merge = false ); |
370 | |
371 | /** |
372 | * Actions can collectively be assigned a "State". To accomplish this |
373 | * the respective actions are tagged as \<enable\> or \<disable\> in |
374 | * a \<State\> \</State\> group of the XMLfile. During program execution the |
375 | * programmer can call stateChanged() to set actions to a defined state. |
376 | * |
377 | * @param newstate Name of a State in the XMLfile. |
378 | * @param reverse If the flag reverse is set to StateReverse, the State is reversed. |
379 | * (actions to be enabled will be disabled and action to be disabled will be enabled) |
380 | * Default is reverse=false. |
381 | */ |
382 | virtual void stateChanged(const QString &newstate, ReverseStateChange reverse = StateNoReverse); |
383 | |
384 | // KDE5 TODO: virtual void loadActionLists() {}, called when the guiclient is added to the xmlgui factory |
385 | |
386 | protected: |
387 | virtual void virtual_hook( int id, void* data ); |
388 | |
389 | private: |
390 | KXMLGUIClientPrivate * const d; |
391 | }; |
392 | |
393 | #endif |
394 | |