Applied [ 594925 ] Implement wxArtProvider and XRC together
[wxWidgets.git] / include / wx / xrc / xmlres.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: xmlres.h
3 // Purpose: XML resources
4 // Author: Vaclav Slavik
5 // Created: 2000/03/05
6 // RCS-ID: $Id$
7 // Copyright: (c) 2000 Vaclav Slavik
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 #ifndef _WX_XMLRES_H_
12 #define _WX_XMLRES_H_
13
14 #ifdef __GNUG__
15 #pragma interface "xmlres.h"
16 #endif
17
18 #include "wx/defs.h"
19 #include "wx/string.h"
20 #include "wx/dynarray.h"
21 #include "wx/datetime.h"
22 #include "wx/list.h"
23 #include "wx/gdicmn.h"
24 #include "wx/filesys.h"
25 #include "wx/bitmap.h"
26 #include "wx/icon.h"
27 #include "wx/artprov.h"
28
29 #include "wx/xrc/xml.h"
30
31 class WXDLLEXPORT wxMenu;
32 class WXDLLEXPORT wxMenuBar;
33 class WXDLLEXPORT wxDialog;
34 class WXDLLEXPORT wxPanel;
35 class WXDLLEXPORT wxWindow;
36 class WXDLLEXPORT wxFrame;
37 class WXDLLEXPORT wxToolBar;
38
39 class WXXMLDLLEXPORT wxXmlResourceHandler;
40
41
42 // These macros indicate current version of XML resources (this information is
43 // encoded in root node of XRC file as "version" property).
44 //
45 // Rules for increasing version number:
46 // - change it only if you made incompatible change to the format. Addition of new
47 // attribute to control handler is _not_ incompatible change, because older
48 // versions of the library may ignore it.
49 // - if you change version number, follow these steps:
50 // - set major, minor and release numbers to respective version numbers of
51 // the wxWindows library (see wx/version.h)
52 // - reset revision to 0 unless the first three are same as before, in which
53 // case you should increase revision by one
54 #define WX_XMLRES_CURRENT_VERSION_MAJOR 2
55 #define WX_XMLRES_CURRENT_VERSION_MINOR 3
56 #define WX_XMLRES_CURRENT_VERSION_RELEASE 0
57 #define WX_XMLRES_CURRENT_VERSION_REVISION 1
58 #define WX_XMLRES_CURRENT_VERSION_STRING "2.3.0.1"
59
60 #define WX_XMLRES_CURRENT_VERSION \
61 (WX_XMLRES_CURRENT_VERSION_MAJOR * 256*256*256 + \
62 WX_XMLRES_CURRENT_VERSION_MINOR * 256*256 + \
63 WX_XMLRES_CURRENT_VERSION_RELEASE * 256 + \
64 WX_XMLRES_CURRENT_VERSION_REVISION)
65
66 class WXXMLDLLEXPORT wxXmlResourceDataRecord
67 {
68 public:
69 wxXmlResourceDataRecord() : Doc(NULL), Time(wxDateTime::Now()) {}
70 ~wxXmlResourceDataRecord() {delete Doc;}
71
72 wxString File;
73 wxXmlDocument *Doc;
74 wxDateTime Time;
75 };
76
77
78 #ifdef WXXMLISDLL
79 WX_DECLARE_EXPORTED_OBJARRAY(wxXmlResourceDataRecord, wxXmlResourceDataRecords);
80 #else
81 WX_DECLARE_OBJARRAY(wxXmlResourceDataRecord, wxXmlResourceDataRecords);
82 #endif
83
84 enum wxXmlResourceFlags
85 {
86 wxXRC_USE_LOCALE = 1,
87 wxXRC_NO_SUBCLASSING = 2
88 };
89
90 // This class holds XML resources from one or more .xml files
91 // (or derived forms, either binary or zipped -- see manual for
92 // details).
93 class WXXMLDLLEXPORT wxXmlResource : public wxObject
94 {
95 public:
96 // Constructor.
97 // Flags: wxXRC_USE_LOCALE
98 // translatable strings will be translated via _()
99 // wxXRC_NO_SUBCLASSING
100 // subclass property of object nodes will be ignored
101 // (useful for previews in XRC editors)
102 wxXmlResource(int flags = wxXRC_USE_LOCALE);
103
104 // Constructor.
105 // Flags: wxXRC_USE_LOCALE
106 // translatable strings will be translated via _()
107 // wxXRC_NO_SUBCLASSING
108 // subclass property of object nodes will be ignored
109 // (useful for previews in XRC editors)
110 wxXmlResource(const wxString& filemask, int flags = wxXRC_USE_LOCALE);
111
112 // Destructor.
113 ~wxXmlResource();
114
115 // Loads resources from XML files that match given filemask.
116 // This method understands VFS (see filesys.h).
117 bool Load(const wxString& filemask);
118
119 // Initialize handlers for all supported controls/windows. This will
120 // make the executable quite big because it forces linking against
121 // most of the wxWindows library.
122 void InitAllHandlers();
123
124 // Initialize only a specific handler (or custom handler). Convention says
125 // that handler name is equal to the control's name plus 'XmlHandler', for example
126 // wxTextCtrlXmlHandler, wxHtmlWindowXmlHandler. The XML resource compiler
127 // (xmlres) can create include file that contains initialization code for
128 // all controls used within the resource.
129 void AddHandler(wxXmlResourceHandler *handler);
130
131 // Removes all handlers
132 void ClearHandlers();
133
134 // Loads menu from resource. Returns NULL on failure.
135 wxMenu *LoadMenu(const wxString& name);
136
137 // Loads menubar from resource. Returns NULL on failure.
138 wxMenuBar *LoadMenuBar(wxWindow *parent, const wxString& name);
139
140 // Loads menubar from resource. Returns NULL on failure.
141 wxMenuBar *LoadMenuBar(const wxString& name) { return LoadMenuBar(NULL, name); }
142
143 #if wxUSE_TOOLBAR
144 // Loads a toolbar.
145 wxToolBar *LoadToolBar(wxWindow *parent, const wxString& name);
146 #endif
147
148 // Loads a dialog. dlg points to parent window (if any).
149 wxDialog *LoadDialog(wxWindow *parent, const wxString& name);
150
151 // Loads a dialog. dlg points to parent window (if any). This form
152 // is used to finish creation of already existing instance (main reason
153 // for this is that you may want to use derived class with new event table)
154 // Example (typical usage):
155 // MyDialog dlg;
156 // wxTheXmlResource->LoadDialog(&dlg, mainFrame, "my_dialog");
157 // dlg->ShowModal();
158 bool LoadDialog(wxDialog *dlg, wxWindow *parent, const wxString& name);
159
160 // Loads a panel. panel points to parent window (if any).
161 wxPanel *LoadPanel(wxWindow *parent, const wxString& name);
162
163 // Loads a panel. panel points to parent window (if any). This form
164 // is used to finish creation of already existing instance.
165 bool LoadPanel(wxPanel *panel, wxWindow *parent, const wxString& name);
166
167 // Loads a frame.
168 bool LoadFrame(wxFrame* frame, wxWindow *parent, const wxString& name);
169
170 // Loads a bitmap resource from a file.
171 wxBitmap LoadBitmap(const wxString& name);
172
173 // Loads an icon resource from a file.
174 wxIcon LoadIcon(const wxString& name);
175
176 // Attaches an unknown control to the given panel/window/dialog.
177 // Unknown controls are used in conjunction with <object class="unknown">.
178 bool AttachUnknownControl(const wxString& name, wxWindow *control,
179 wxWindow *parent = NULL);
180
181 // Returns a numeric ID that is equivalent to the string id used in an XML
182 // resource. To be used in event tables.
183 // Macro XRCID is provided for convenience
184 static int GetXRCID(const wxChar *str_id);
185
186 // Returns version information (a.b.c.d = d+ 256*c + 256^2*b + 256^3*a).
187 long GetVersion() const { return m_version; }
188
189 // Compares resources version to argument. Returns -1 if resources version
190 // is less than the argument, +1 if greater and 0 if they equal.
191 int CompareVersion(int major, int minor, int release, int revision) const
192 { return GetVersion() -
193 (major*256*256*256 + minor*256*256 + release*256 + revision); }
194
195 //// Singleton accessors.
196
197 // Gets the global resources object or creates one if none exists.
198 static wxXmlResource *Get();
199
200 // Sets the global resources object and returns a pointer to the previous one (may be NULL).
201 static wxXmlResource *Set(wxXmlResource *res);
202
203 protected:
204 // Scans the resources list for unloaded files and loads them. Also reloads
205 // files that have been modified since last loading.
206 void UpdateResources();
207
208 // Finds a resource (calls UpdateResources) and returns a node containing it.
209 wxXmlNode *FindResource(const wxString& name, const wxString& classname, bool recursive = FALSE);
210
211 // Helper function: finds a resource (calls UpdateResources) and returns a node containing it.
212 wxXmlNode *DoFindResource(wxXmlNode *parent, const wxString& name, const wxString& classname, bool recursive);
213
214 // Creates a resource from information in the given node.
215 wxObject *CreateResFromNode(wxXmlNode *node, wxObject *parent, wxObject *instance = NULL);
216
217 // Returns flags, which may be a bitlist of wxXRC_USE_LOCALE and wxXRC_NO_SUBCLASSING.
218 int GetFlags() { return m_flags; }
219
220 private:
221 long m_version;
222
223 int m_flags;
224 wxList m_handlers;
225 wxXmlResourceDataRecords m_data;
226 #if wxUSE_FILESYSTEM
227 wxFileSystem m_curFileSystem;
228 wxFileSystem& GetCurFileSystem() { return m_curFileSystem; }
229 #endif
230
231 friend class wxXmlResourceHandler;
232
233 // singleton instance:
234 static wxXmlResource *ms_instance;
235 };
236
237
238 // This macro translates string identifier (as used in XML resource,
239 // e.g. <menuitem id="my_menu">...</menuitem>) to integer id that is needed by
240 // wxWindows event tables.
241 // Example:
242 // BEGIN_EVENT_TABLE(MyFrame, wxFrame)
243 // EVT_MENU(XRCID("quit"), MyFrame::OnQuit)
244 // EVT_MENU(XRCID("about"), MyFrame::OnAbout)
245 // EVT_MENU(XRCID("new"), MyFrame::OnNew)
246 // EVT_MENU(XRCID("open"), MyFrame::OnOpen)
247 // END_EVENT_TABLE()
248
249 #define XRCID(str_id) \
250 wxXmlResource::GetXRCID(wxT(str_id))
251
252
253 // This macro returns pointer to particular control in dialog
254 // created using XML resources. You can use it to set/get values from
255 // controls.
256 // Example:
257 // wxDialog dlg;
258 // wxXmlResource::Get()->LoadDialog(&dlg, mainFrame, "my_dialog");
259 // XRCCTRL(dlg, "my_textctrl", wxTextCtrl)->SetValue(wxT("default value"));
260
261 #ifdef __WXDEBUG__
262 #define XRCCTRL(window, id, type) \
263 (wxDynamicCast((window).FindWindow(XRCID(id)), type))
264 #else
265 #define XRCCTRL(window, id, type) \
266 ((type*)((window).FindWindow(XRCID(id))))
267 #endif
268
269 // wxXmlResourceHandler is an abstract base class for resource handlers
270 // capable of creating a control from an XML node.
271
272 class WXXMLDLLEXPORT wxXmlResourceHandler : public wxObject
273 {
274 public:
275 // Constructor.
276 wxXmlResourceHandler();
277
278 // Destructor.
279 virtual ~wxXmlResourceHandler() {}
280
281 // Creates an object (menu, dialog, control, ...) from an XML node.
282 // Should check for validity.
283 // parent is a higher-level object (usually window, dialog or panel)
284 // that is often neccessary to create the resource.
285 // If instance is non-NULL it should not create a new instance via 'new' but
286 // should rather use this one, and call its Create method.
287 wxObject *CreateResource(wxXmlNode *node, wxObject *parent,
288 wxObject *instance);
289
290 // This one is called from CreateResource after variables
291 // were filled.
292 virtual wxObject *DoCreateResource() = 0;
293
294 // Returns TRUE if it understands this node and can create
295 // a resource from it, FALSE otherwise.
296 virtual bool CanHandle(wxXmlNode *node) = 0;
297
298 // Sets the parent resource.
299 void SetParentResource(wxXmlResource *res) { m_resource = res; }
300
301 protected:
302 wxXmlResource *m_resource;
303 wxArrayString m_styleNames;
304 wxArrayInt m_styleValues;
305
306 // Variables (filled by CreateResource)
307 wxXmlNode *m_node;
308 wxString m_class;
309 wxObject *m_parent, *m_instance;
310 wxWindow *m_parentAsWindow, *m_instanceAsWindow;
311
312 // --- Handy methods:
313
314 // Returns true if the node has a property class equal to classname,
315 // e.g. <object class="wxDialog">.
316 bool IsOfClass(wxXmlNode *node, const wxString& classname)
317 { return node->GetPropVal(wxT("class"), wxEmptyString) == classname; }
318
319 // Gets node content from wxXML_ENTITY_NODE
320 // The problem is, <tag>content<tag> is represented as
321 // wxXML_ENTITY_NODE name="tag", content=""
322 // |-- wxXML_TEXT_NODE or
323 // wxXML_CDATA_SECTION_NODE name="" content="content"
324 wxString GetNodeContent(wxXmlNode *node);
325
326 // Check to see if a parameter exists.
327 bool HasParam(const wxString& param);
328
329 // Finds the node or returns NULL.
330 wxXmlNode *GetParamNode(const wxString& param);
331
332 // Finds the parameter value or returns the empty string.
333 wxString GetParamValue(const wxString& param);
334
335 // Add a style flag (e.g. wxMB_DOCKABLE) to the list of flags
336 // understood by this handler.
337 void AddStyle(const wxString& name, int value);
338
339 // Add styles common to all wxWindow-derived classes.
340 void AddWindowStyles();
341
342 // Gets style flags from text in form "flag | flag2| flag3 |..."
343 // Only understads flags added with AddStyle
344 int GetStyle(const wxString& param = wxT("style"), int defaults = 0);
345
346 // Gets text from param and does some conversions:
347 // - replaces \n, \r, \t by respective chars (according to C syntax)
348 // - replaces _ by & and __ by _ (needed for _File => &File because of XML)
349 // - calls wxGetTranslations (unless disabled in wxXmlResource)
350 wxString GetText(const wxString& param, bool translate = TRUE);
351
352 // Returns the XRCID.
353 int GetID();
354
355 // Returns the wxArtID for a wxArtProvider-managed bitmap.
356 wxArtID GetStockID(const wxString& param);
357
358 // Returns the wxArtClient for a wxArtProvider-managed bitmap.
359 wxArtClient GetStockClient(const wxString& param);
360
361 // Returns the resource name.
362 wxString GetName();
363
364 // Gets a bool flag (1, t, yes, on, true are TRUE, everything else is FALSE).
365 bool GetBool(const wxString& param, bool defaultv = FALSE);
366
367 // Gets the integer value from the parameter.
368 long GetLong( const wxString& param, long defaultv = 0 );
369
370 // Gets colour in HTML syntax (#RRGGBB).
371 wxColour GetColour(const wxString& param);
372
373 // Gets the size (may be in dialog units).
374 wxSize GetSize(const wxString& param = wxT("size"));
375
376 // Gets the position (may be in dialog units).
377 wxPoint GetPosition(const wxString& param = wxT("pos"));
378
379 // Gets a dimension (may be in dialog units).
380 wxCoord GetDimension(const wxString& param, wxCoord defaultv = 0);
381
382 // Gets a bitmap.
383 wxBitmap GetBitmap(const wxString& param = wxT("bitmap"),
384 wxSize size = wxDefaultSize);
385
386 // Gets an icon.
387 wxIcon GetIcon(const wxString& param = wxT("icon"),
388 wxSize size = wxDefaultSize);
389
390 // Gets a font.
391 wxFont GetFont(const wxString& param = wxT("font"));
392
393 // Sets common window options.
394 void SetupWindow(wxWindow *wnd);
395
396 // Creates children.
397 void CreateChildren(wxObject *parent, bool this_hnd_only = FALSE);
398
399 // Helper function.
400 void CreateChildrenPrivately(wxObject *parent, wxXmlNode *rootnode = NULL);
401
402 // Creates a resource from a node.
403 wxObject *CreateResFromNode(wxXmlNode *node,
404 wxObject *parent, wxObject *instance = NULL)
405 { return m_resource->CreateResFromNode(node, parent, instance); }
406
407 // helper
408 #if wxUSE_FILESYSTEM
409 wxFileSystem& GetCurFileSystem() { return m_resource->GetCurFileSystem(); }
410 #endif
411 };
412
413
414 // Programmer-friendly macros for writing XRC handlers:
415
416 #define XRC_ADD_STYLE(style) AddStyle(wxT(#style), style)
417
418 #define XRC_MAKE_INSTANCE(variable, classname) \
419 classname *variable = NULL; \
420 if (m_instance) \
421 variable = wxStaticCast(m_instance, classname); \
422 if (!variable) \
423 variable = new classname;
424
425
426 // FIXME -- remove this $%^#$%#$@# as soon as Ron checks his changes in!!
427 void wxXmlInitResourceModule();
428
429
430 /* -------------------------------------------------------------------------
431 Backward compatibility macros. Do *NOT* use, they may disappear in future
432 versions of the XRC library!
433 ------------------------------------------------------------------------- */
434 #define ADD_STYLE XRC_ADD_STYLE
435 #define wxTheXmlResource wxXmlResource::Get()
436 #define XMLID XRCID
437 #define XMLCTRL XRCCTRL
438 #define GetXMLID GetXRCID
439
440
441 #endif // _WX_XMLRES_H_