]> git.saurik.com Git - wxWidgets.git/blame - contrib/src/xml/xmlres.cpp
added wxHtmlHelpController::GetHelpData and removed SetBookBasePath (you can use...
[wxWidgets.git] / contrib / src / xml / xmlres.cpp
CommitLineData
56d2f750
VS
1/////////////////////////////////////////////////////////////////////////////
2// Name: xmlres.cpp
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#ifdef __GNUG__
12#pragma implementation "xmlres.h"
13#endif
14
15// For compilers that support precompilation, includes "wx.h".
16#include "wx/wxprec.h"
17
18#ifdef __BORLANDC__
19 #pragma hdrstop
20#endif
21
22#include "wx/dialog.h"
23#include "wx/panel.h"
1486ed87 24#include "wx/frame.h"
56d2f750
VS
25#include "wx/wfstream.h"
26#include "wx/filesys.h"
27#include "wx/log.h"
28#include "wx/intl.h"
29#include "wx/tokenzr.h"
d33a1e8b 30#include "wx/fontenum.h"
56d2f750 31#include "wx/module.h"
792064e9
VS
32#include "wx/bitmap.h"
33#include "wx/image.h"
dc743689 34#include "wx/fontmap.h"
56d2f750
VS
35
36#include "wx/xml/xml.h"
37#include "wx/xml/xmlres.h"
38
39#include "wx/arrimpl.cpp"
40WX_DEFINE_OBJARRAY(wxXmlResourceDataRecords);
41
42
f485492a 43wxXmlResource::wxXmlResource(bool use_locale)
56d2f750 44{
ab708d5d
VS
45 m_handlers.DeleteContents(TRUE);
46 m_useLocale = use_locale;
56d2f750
VS
47}
48
f485492a 49wxXmlResource::wxXmlResource(const wxString& filemask, bool use_locale)
56d2f750 50{
ab708d5d
VS
51 m_useLocale = use_locale;
52 m_handlers.DeleteContents(TRUE);
0ceae932 53 Load(filemask);
56d2f750
VS
54}
55
56wxXmlResource::~wxXmlResource()
57{
58 ClearHandlers();
59}
60
61
0ceae932 62bool wxXmlResource::Load(const wxString& filemask)
56d2f750
VS
63{
64 wxString fnd;
65 wxXmlResourceDataRecord *drec;
0ceae932 66 bool iswild = wxIsWild(filemask);
56d2f750
VS
67
68#if wxUSE_FILESYSTEM
69 wxFileSystem fsys;
70# define wxXmlFindFirst fsys.FindFirst(filemask, wxFILE)
71# define wxXmlFindNext fsys.FindNext()
72#else
73# define wxXmlFindFirst wxFindFirstFile(filemask, wxFILE)
74# define wxXmlFindNext wxFindNextFile()
56d2f750 75#endif
0ceae932
VS
76 if (iswild)
77 fnd = wxXmlFindFirst;
78 else
79 fnd = filemask;
56d2f750
VS
80 while (!!fnd)
81 {
82#if wxUSE_FILESYSTEM
0ceae932
VS
83 if (filemask.Lower().Matches("*.zip") ||
84 filemask.Lower().Matches("*.rsc"))
56d2f750
VS
85 {
86 wxFileSystem fs2;
87 wxString fnd2;
88
89 fnd2 = fs2.FindFirst(fnd + wxT("#zip:*.xmb"), wxFILE);
90 while (!!fnd2)
91 {
92 drec = new wxXmlResourceDataRecord;
93 drec->File = fnd2;
ab708d5d 94 m_data.Add(drec);
56d2f750
VS
95 fnd2 = fs2.FindNext();
96 }
97 }
98 else
99#endif
100 {
101 drec = new wxXmlResourceDataRecord;
102 drec->File = fnd;
ab708d5d 103 m_data.Add(drec);
56d2f750 104 }
0ceae932
VS
105
106 if (iswild)
107 fnd = wxXmlFindNext;
108 else
109 fnd = wxEmptyString;
56d2f750
VS
110 }
111# undef wxXmlFindFirst
112# undef wxXmlFindNext
113 return TRUE;
114}
115
116
117
118void wxXmlResource::AddHandler(wxXmlResourceHandler *handler)
119{
ab708d5d 120 m_handlers.Append(handler);
56d2f750
VS
121 handler->SetParentResource(this);
122}
123
124
125
126void wxXmlResource::ClearHandlers()
127{
ab708d5d 128 m_handlers.Clear();
56d2f750
VS
129}
130
131
132
133wxMenu *wxXmlResource::LoadMenu(const wxString& name)
134{
e066e256 135 return (wxMenu*)CreateResFromNode(FindResource(name, wxT("wxMenu")), NULL, NULL);
56d2f750
VS
136}
137
138
139
140wxMenuBar *wxXmlResource::LoadMenuBar(const wxString& name)
141{
e066e256 142 return (wxMenuBar*)CreateResFromNode(FindResource(name, wxT("wxMenuBar")), NULL, NULL);
56d2f750
VS
143}
144
145
146
792064e9
VS
147wxToolBar *wxXmlResource::LoadToolBar(wxWindow *parent, const wxString& name)
148{
e066e256 149 return (wxToolBar*)CreateResFromNode(FindResource(name, wxT("wxToolBar")), parent, NULL);
792064e9
VS
150}
151
152
153
56d2f750
VS
154wxDialog *wxXmlResource::LoadDialog(wxWindow *parent, const wxString& name)
155{
156 wxDialog *dialog = new wxDialog;
157 if (!LoadDialog(dialog, parent, name))
158 { delete dialog; return NULL; }
159 else return dialog;
160}
161
162bool wxXmlResource::LoadDialog(wxDialog *dlg, wxWindow *parent, const wxString& name)
163{
e066e256 164 return CreateResFromNode(FindResource(name, wxT("wxDialog")), parent, dlg) != NULL;
56d2f750
VS
165}
166
167
168
169wxPanel *wxXmlResource::LoadPanel(wxWindow *parent, const wxString& name)
170{
e066e256 171 return (wxPanel*)CreateResFromNode(FindResource(name, wxT("wxPanel")), parent, NULL);
56d2f750
VS
172}
173
174bool wxXmlResource::LoadPanel(wxPanel *panel, wxWindow *parent, const wxString& name)
175{
e066e256 176 return CreateResFromNode(FindResource(name, wxT("wxPanel")), parent, panel) != NULL;
56d2f750
VS
177}
178
2e4c3bf8
GT
179bool wxXmlResource::LoadFrame(wxFrame* frame, wxWindow *parent, const wxString& name)
180{
181 return CreateResFromNode(FindResource(name, wxT("wxFrame")), parent, frame) != NULL;
182}
56d2f750 183
d33a1e8b
VS
184wxBitmap wxXmlResource::LoadBitmap(const wxString& name)
185{
186 wxBitmap *bmp = (wxBitmap*)CreateResFromNode(
e066e256 187 FindResource(name, wxT("wxBitmap")), NULL, NULL);
d33a1e8b
VS
188 wxBitmap rt;
189
190 if (bmp) { rt = *bmp; delete bmp; }
191 return rt;
192}
193
194wxIcon wxXmlResource::LoadIcon(const wxString& name)
195{
196 wxIcon *icon = (wxIcon*)CreateResFromNode(
e066e256 197 FindResource(name, wxT("wxIcon")), NULL, NULL);
d33a1e8b
VS
198 wxIcon rt;
199
200 if (icon) { rt = *icon; delete icon; }
201 return rt;
202}
203
204
205
29b5f2cc
VS
206void wxXmlResource::ProcessPlatformProperty(wxXmlNode *node)
207{
208 wxString s;
209 bool isok;
210
211 wxXmlNode *c = node->GetChildren();
212 while (c)
213 {
214 isok = FALSE;
a559d708 215 if (!c->GetPropVal(wxT("platform"), &s))
29b5f2cc
VS
216 isok = TRUE;
217 else
218 {
219 wxStringTokenizer tkn(s, " |");
220
221 while (tkn.HasMoreTokens())
222 {
223 s = tkn.GetNextToken();
224 if (
225#ifdef __WXMSW__
a559d708 226 s == wxString(wxT("win"))
29b5f2cc 227#elif defined(__UNIX__)
a559d708 228 s == wxString(wxT("unix"))
29b5f2cc 229#elif defined(__MAC__)
a559d708 230 s == wxString(wxT("mac"))
29b5f2cc 231#elif defined(__OS2__)
a559d708 232 s == wxString(wxT("os2"))
29b5f2cc
VS
233#else
234 FALSE
235#endif
236 ) isok = TRUE;
237 }
238 }
239
240 if (isok)
241 ProcessPlatformProperty(c);
242 else
243 {
244 node->RemoveChild(c);
245 delete c;
246 }
247
248 c = c->GetNext();
249 }
250}
251
252
253
56d2f750
VS
254void wxXmlResource::UpdateResources()
255{
256 bool modif;
257# if wxUSE_FILESYSTEM
16008659 258 wxFSFile *file = NULL;
56d2f750
VS
259 wxFileSystem fsys;
260# endif
261
ab708d5d 262 for (size_t i = 0; i < m_data.GetCount(); i++)
56d2f750 263 {
ab708d5d 264 modif = (m_data[i].Doc == NULL);
56d2f750
VS
265
266 if (!modif)
267 {
268# if wxUSE_FILESYSTEM
ab708d5d
VS
269 file = fsys.OpenFile(m_data[i].File);
270 modif = file && file->GetModificationTime() > m_data[i].Time;
56d2f750 271 if (!file)
ab708d5d 272 wxLogError(_("Cannot open file '%s'."), m_data[i].File.c_str());
16008659 273 wxDELETE(file);
56d2f750 274# else
ab708d5d 275 modif = wxDateTime(wxFileModificationTime(m_data[i].File)) > m_data[i].Time;
56d2f750
VS
276# endif
277 }
278
279 if (modif)
280 {
16008659 281 wxInputStream *stream = NULL;
56d2f750
VS
282
283# if wxUSE_FILESYSTEM
ab708d5d 284 file = fsys.OpenFile(m_data[i].File);
16008659
GT
285 if (file)
286 stream = file->GetStream();
56d2f750 287# else
ab708d5d 288 stream = new wxFileInputStream(m_data[i].File);
56d2f750
VS
289# endif
290
291 if (stream)
292 {
ab708d5d
VS
293 delete m_data[i].Doc;
294 m_data[i].Doc = new wxXmlDocument;
56d2f750 295 }
ab708d5d 296 if (!stream || !m_data[i].Doc->Load(*stream))
0ceae932 297 {
ab708d5d
VS
298 wxLogError(_("Cannot load resources from file '%s'."), m_data[i].File.c_str());
299 wxDELETE(m_data[i].Doc);
0ceae932 300 }
ab708d5d 301 else if (m_data[i].Doc->GetRoot()->GetName() != wxT("resource"))
0ceae932 302 {
ab708d5d
VS
303 wxLogError(_("Invalid XML resource '%s': doesn't have root node 'resource'."), m_data[i].File.c_str());
304 wxDELETE(m_data[i].Doc);
0ceae932
VS
305 }
306 else
16008659 307 {
ab708d5d
VS
308 ProcessPlatformProperty(m_data[i].Doc->GetRoot());
309 m_data[i].Time = file->GetModificationTime();
16008659 310 }
29b5f2cc 311
56d2f750 312# if wxUSE_FILESYSTEM
16008659 313 wxDELETE(file);
56d2f750 314# else
16008659 315 wxDELETE(stream);
56d2f750
VS
316# endif
317 }
318 }
319}
320
321
322
e066e256 323wxXmlNode *wxXmlResource::FindResource(const wxString& name, const wxString& classname)
56d2f750
VS
324{
325 UpdateResources(); //ensure everything is up-to-date
326
327 wxString dummy;
ab708d5d 328 for (size_t f = 0; f < m_data.GetCount(); f++)
56d2f750 329 {
ab708d5d
VS
330 if (m_data[f].Doc == NULL || m_data[f].Doc->GetRoot() == NULL) continue;
331 for (wxXmlNode *node = m_data[f].Doc->GetRoot()->GetChildren();
56d2f750 332 node; node = node->GetNext())
e066e256
VS
333 if (node->GetType() == wxXML_ELEMENT_NODE &&
334 (!classname ||
335 node->GetPropVal(wxT("class"), wxEmptyString) == classname) &&
336 node->GetName() == wxT("object") &&
337 node->GetPropVal(wxT("name"), &dummy) &&
338 dummy == name)
792064e9
VS
339 {
340#if wxUSE_FILESYSTEM
ab708d5d 341 m_curFileSystem.ChangePathTo(m_data[f].File);
792064e9 342#endif
56d2f750 343 return node;
792064e9 344 }
56d2f750
VS
345 }
346
e066e256
VS
347 wxLogError(_("XML resource '%s' (class '%s') not found!"),
348 name.c_str(), classname.c_str());
56d2f750
VS
349 return NULL;
350}
351
352
353
354wxObject *wxXmlResource::CreateResFromNode(wxXmlNode *node, wxObject *parent, wxObject *instance)
355{
356 if (node == NULL) return NULL;
357
358 wxXmlResourceHandler *handler;
359 wxObject *ret;
ab708d5d 360 wxNode * ND = m_handlers.GetFirst();
56d2f750
VS
361 while (ND)
362 {
363 handler = (wxXmlResourceHandler*)ND->GetData();
a559d708 364 if (node->GetName() == wxT("object") && handler->CanHandle(node))
56d2f750
VS
365 {
366 ret = handler->CreateResource(node, parent, instance);
367 if (ret) return ret;
368 }
369 ND = ND->GetNext();
370 }
371
e066e256
VS
372 wxLogError(_("No handler found for XML node '%s', class '%s'!"),
373 node->GetName().c_str(),
a559d708 374 node->GetPropVal(wxT("class"), wxEmptyString).c_str());
56d2f750
VS
375 return NULL;
376}
377
378
379
380
381
382
383
384
385
386wxXmlResourceHandler::wxXmlResourceHandler()
ab708d5d
VS
387 : m_node(NULL), m_parent(NULL), m_instance(NULL),
388 m_parentAsWindow(NULL), m_instanceAsWindow(NULL)
56d2f750
VS
389{}
390
391
392
393wxObject *wxXmlResourceHandler::CreateResource(wxXmlNode *node, wxObject *parent, wxObject *instance)
394{
ab708d5d
VS
395 wxXmlNode *myNode = m_node;
396 wxString myClass = m_class;
397 wxObject *myParent = m_parent, *myInstance = m_instance;
398 wxWindow *myParentAW = m_parentAsWindow, *myInstanceAW = m_instanceAsWindow;
56d2f750 399
ab708d5d
VS
400 m_node = node;
401 m_class = node->GetPropVal(wxT("class"), wxEmptyString);
402 m_parent = parent;
403 m_instance = instance;
404 m_parentAsWindow = wxDynamicCast(m_parent, wxWindow);
405 m_instanceAsWindow = wxDynamicCast(m_instance, wxWindow);
56d2f750
VS
406
407 wxObject *returned = DoCreateResource();
408
ab708d5d
VS
409 m_node = myNode;
410 m_class = myClass;
411 m_parent = myParent; m_parentAsWindow = myParentAW;
412 m_instance = myInstance; m_instanceAsWindow = myInstanceAW;
56d2f750
VS
413
414 return returned;
415}
416
417
56d2f750
VS
418void wxXmlResourceHandler::AddStyle(const wxString& name, int value)
419{
ab708d5d
VS
420 m_styleNames.Add(name);
421 m_styleValues.Add(value);
56d2f750
VS
422}
423
424
09dc1241
VS
425
426void wxXmlResourceHandler::AddWindowStyles()
427{
428 ADD_STYLE(wxSIMPLE_BORDER);
429 ADD_STYLE(wxSUNKEN_BORDER);
430 ADD_STYLE(wxDOUBLE_BORDER);
431 ADD_STYLE(wxRAISED_BORDER);
432 ADD_STYLE(wxSTATIC_BORDER);
433 ADD_STYLE(wxTRANSPARENT_WINDOW);
434 ADD_STYLE(wxWANTS_CHARS);
435 ADD_STYLE(wxNO_FULL_REPAINT_ON_RESIZE);
436}
437
438
439
56d2f750
VS
440bool wxXmlResourceHandler::HasParam(const wxString& param)
441{
442 return (GetParamNode(param) != NULL);
443}
444
445
446int wxXmlResourceHandler::GetStyle(const wxString& param, int defaults)
447{
448 wxString s = GetParamValue(param);
449
450 if (!s) return defaults;
451
a559d708 452 wxStringTokenizer tkn(s, wxT("| "), wxTOKEN_STRTOK);
56d2f750
VS
453 int style = 0;
454 int index;
455 wxString fl;
456 while (tkn.HasMoreTokens())
457 {
458 fl = tkn.GetNextToken();
ab708d5d 459 index = m_styleNames.Index(fl);
56d2f750 460 if (index != wxNOT_FOUND)
ab708d5d 461 style |= m_styleValues[index];
56d2f750
VS
462 else
463 wxLogError(_("Unknown style flag ") + fl);
464 }
465 return style;
466}
467
468
469
470wxString wxXmlResourceHandler::GetText(const wxString& param)
471{
472 wxString str1 = GetParamValue(param);
473 wxString str2;
474 const wxChar *dt;
475
476 for (dt = str1.c_str(); *dt; dt++)
477 {
478 // Remap $ to &, map $$ to $ (for things like "&File..." --
479 // this is illegal in XML, so we use "$File..."):
480 if (*dt == '$')
481 switch (*(++dt))
482 {
483 case '$' : str2 << '$'; break;
484 default : str2 << '&' << *dt; break;
485 }
486 // Remap \n to CR, \r LF, \t to TAB:
487 else if (*dt == '\\')
488 switch (*(++dt))
489 {
490 case 'n' : str2 << '\n'; break;
491 case 't' : str2 << '\t'; break;
492 case 'r' : str2 << '\r'; break;
493 default : str2 << '\\' << *dt; break;
494 }
495 else str2 << *dt;
496 }
d33a1e8b 497
ab708d5d 498 if (m_resource->GetUseLocale())
d33a1e8b
VS
499 return wxGetTranslation(str2);
500 else
501 return str2;
56d2f750
VS
502}
503
504
505
506long wxXmlResourceHandler::GetLong(const wxString& param, long defaultv)
507{
508 long value;
509 wxString str1 = GetParamValue(param);
510
511 if (!str1.ToLong(&value))
512 value = defaultv;
513
514 return value;
515}
516
517
518int wxXmlResourceHandler::GetID()
519{
520 wxString sid = GetName();
521 long num;
522
a559d708 523 if (sid == wxT("-1")) return -1;
56d2f750 524 else if (sid.IsNumber() && sid.ToLong(&num)) return num;
a559d708 525#define stdID(id) else if (sid == wxT(#id)) return id
56d2f750
VS
526 stdID(wxID_OPEN); stdID(wxID_CLOSE); stdID(wxID_NEW);
527 stdID(wxID_SAVE); stdID(wxID_SAVEAS); stdID(wxID_REVERT);
528 stdID(wxID_EXIT); stdID(wxID_UNDO); stdID(wxID_REDO);
529 stdID(wxID_HELP); stdID(wxID_PRINT); stdID(wxID_PRINT_SETUP);
530 stdID(wxID_PREVIEW); stdID(wxID_ABOUT); stdID(wxID_HELP_CONTENTS);
531 stdID(wxID_HELP_COMMANDS); stdID(wxID_HELP_PROCEDURES);
532 stdID(wxID_CUT); stdID(wxID_COPY); stdID(wxID_PASTE);
533 stdID(wxID_CLEAR); stdID(wxID_FIND); stdID(wxID_DUPLICATE);
534 stdID(wxID_SELECTALL); stdID(wxID_OK); stdID(wxID_CANCEL);
535 stdID(wxID_APPLY); stdID(wxID_YES); stdID(wxID_NO);
536 stdID(wxID_STATIC); stdID(wxID_FORWARD); stdID(wxID_BACKWARD);
537 stdID(wxID_DEFAULT); stdID(wxID_MORE); stdID(wxID_SETUP);
538 stdID(wxID_RESET); stdID(wxID_HELP_CONTEXT);
539#undef stdID
540 else return XMLID(sid.c_str());
541}
542
543
544wxString wxXmlResourceHandler::GetName()
545{
ab708d5d 546 return m_node->GetPropVal(wxT("name"), wxT("-1"));
56d2f750
VS
547}
548
549
550
551bool wxXmlResourceHandler::GetBool(const wxString& param, bool defaultv)
552{
553 wxString v = GetParamValue(param);
554 v.MakeLower();
555 if (!v) return defaultv;
a559d708 556 else return (v == wxT("1"));
56d2f750
VS
557}
558
559
560
561wxColour wxXmlResourceHandler::GetColour(const wxString& param)
562{
563 wxString v = GetParamValue(param);
564 unsigned long tmp = 0;
565
fafa5632 566 if (v.Length() != 7 || v[0u] != wxT('#') ||
a559d708 567 wxSscanf(v.c_str(), wxT("#%lX"), &tmp) != 1)
56d2f750
VS
568 {
569 wxLogError(_("XML resource: Incorrect colour specification '%s' for property '%s'."),
570 v.c_str(), param.c_str());
571 return wxNullColour;
572 }
573
574 return wxColour((tmp & 0xFF0000) >> 16 ,
575 (tmp & 0x00FF00) >> 8,
576 (tmp & 0x0000FF));
577}
578
579
792064e9
VS
580
581wxBitmap wxXmlResourceHandler::GetBitmap(const wxString& param, wxSize size)
582{
583 wxString name = GetParamValue(param);
584 if (name.IsEmpty()) return wxNullBitmap;
585#if wxUSE_FILESYSTEM
586 wxFSFile *fsfile = GetCurFileSystem().OpenFile(name);
587 if (fsfile == NULL)
588 {
589 wxLogError(_("XML resource: Cannot create bitmap from '%s'."), param.mb_str());
590 return wxNullBitmap;
591 }
592 wxImage img(*(fsfile->GetStream()));
593 delete fsfile;
594#else
a559d708 595 wxImage img(GetParamValue(wxT("bitmap")));
792064e9
VS
596#endif
597 if (!img.Ok())
598 {
599 wxLogError(_("XML resource: Cannot create bitmap from '%s'."), param.mb_str());
600 return wxNullBitmap;
601 }
602 if (!(size == wxDefaultSize)) img.Rescale(size.x, size.y);
603 return img.ConvertToBitmap();
604}
605
606
607
608wxIcon wxXmlResourceHandler::GetIcon(const wxString& param, wxSize size)
609{
bebb14d5 610#if wxCHECK_VERSION(2,3,0) || defined(__WXMSW__)
792064e9
VS
611 wxIcon icon;
612 icon.CopyFromBitmap(GetBitmap(param, size));
613#else
614 wxIcon *iconpt;
615 wxBitmap bmppt = GetBitmap(param, size);
616 iconpt = (wxIcon*)(&bmppt);
617 wxIcon icon(*iconpt);
618#endif
619 return icon;
620}
621
622
623
56d2f750
VS
624wxXmlNode *wxXmlResourceHandler::GetParamNode(const wxString& param)
625{
ab708d5d 626 wxXmlNode *n = m_node->GetChildren();
56d2f750
VS
627
628 while (n)
629 {
630 if (n->GetType() == wxXML_ELEMENT_NODE && n->GetName() == param)
631 return n;
632 n = n->GetNext();
633 }
634 return NULL;
635}
636
637
638wxString wxXmlResourceHandler::GetNodeContent(wxXmlNode *node)
639{
640 wxXmlNode *n = node;
641 if (n == NULL) return wxEmptyString;
642 n = n->GetChildren();
643
644 while (n)
645 {
646 if (n->GetType() == wxXML_TEXT_NODE ||
647 n->GetType() == wxXML_CDATA_SECTION_NODE)
648 return n->GetContent();
649 n = n->GetNext();
650 }
651 return wxEmptyString;
652}
653
654
655
656wxString wxXmlResourceHandler::GetParamValue(const wxString& param)
657{
d33a1e8b 658 if (param.IsEmpty())
ab708d5d 659 return GetNodeContent(m_node);
d33a1e8b
VS
660 else
661 return GetNodeContent(GetParamNode(param));
56d2f750
VS
662}
663
664
665
666wxSize wxXmlResourceHandler::GetSize(const wxString& param)
667{
668 wxString s = GetParamValue(param);
a559d708 669 if (s.IsEmpty()) s = wxT("-1,-1");
56d2f750
VS
670 bool is_dlg;
671 long sx, sy;
672
a559d708 673 is_dlg = s[s.Length()-1] == wxT('d');
56d2f750
VS
674 if (is_dlg) s.RemoveLast();
675
a559d708
VS
676 if (!s.BeforeFirst(wxT(',')).ToLong(&sx) ||
677 !s.AfterLast(wxT(',')).ToLong(&sy))
56d2f750
VS
678 {
679 wxLogError(_("Cannot parse coordinates from '%s'."), s.mb_str());
680 return wxDefaultSize;
681 }
682
683 if (is_dlg)
684 {
ab708d5d
VS
685 if (m_instanceAsWindow)
686 return wxDLG_UNIT(m_instanceAsWindow, wxSize(sx, sy));
687 else if (m_parentAsWindow)
688 return wxDLG_UNIT(m_parentAsWindow, wxSize(sx, sy));
56d2f750
VS
689 else
690 {
691 wxLogError(_("Cannot convert dialog units: dialog unknown."));
692 return wxDefaultSize;
693 }
694 }
695 else return wxSize(sx, sy);
696}
697
698
699
700wxPoint wxXmlResourceHandler::GetPosition(const wxString& param)
701{
702 wxSize sz = GetSize(param);
703 return wxPoint(sz.x, sz.y);
704}
705
706
707
bebb14d5
VS
708wxCoord wxXmlResourceHandler::GetDimension(const wxString& param, wxCoord defaultv)
709{
710 wxString s = GetParamValue(param);
711 if (s.IsEmpty()) return defaultv;
712 bool is_dlg;
713 long sx;
714
a559d708 715 is_dlg = s[s.Length()-1] == wxT('d');
bebb14d5
VS
716 if (is_dlg) s.RemoveLast();
717
718 if (!s.ToLong(&sx))
719 {
720 wxLogError(_("Cannot parse dimension from '%s'."), s.mb_str());
721 return defaultv;
722 }
723
724 if (is_dlg)
725 {
ab708d5d
VS
726 if (m_instanceAsWindow)
727 return wxDLG_UNIT(m_instanceAsWindow, wxSize(sx, 0)).x;
728 else if (m_parentAsWindow)
729 return wxDLG_UNIT(m_parentAsWindow, wxSize(sx, 0)).x;
bebb14d5
VS
730 else
731 {
732 wxLogError(_("Cannot convert dialog units: dialog unknown."));
733 return defaultv;
734 }
735 }
736 else return sx;
737}
738
739
740
d33a1e8b
VS
741wxFont wxXmlResourceHandler::GetFont(const wxString& param)
742{
743 wxXmlNode *font_node = GetParamNode(param);
744 if (font_node == NULL)
745 {
dc743689 746 wxLogError(_("Cannot find font node '%s'."), param.mb_str());
d33a1e8b
VS
747 return wxNullFont;
748 }
749
ab708d5d
VS
750 wxXmlNode *oldnode = m_node;
751 m_node = font_node;
d33a1e8b 752
a559d708 753 long size = GetLong(wxT("size"), 12);
d33a1e8b 754
a559d708
VS
755 wxString style = GetParamValue(wxT("style"));
756 wxString weight = GetParamValue(wxT("weight"));
d33a1e8b 757 int istyle = wxNORMAL, iweight = wxNORMAL;
a559d708
VS
758 if (style == wxT("italic")) istyle = wxITALIC;
759 else if (style == wxT("slant")) istyle = wxSLANT;
760 if (weight == wxT("bold")) iweight = wxBOLD;
761 else if (weight == wxT("light")) iweight = wxLIGHT;
dc743689 762
a559d708 763 wxString family = GetParamValue(wxT("family"));
dc743689 764 int ifamily = wxDEFAULT;
a559d708
VS
765 if (family == wxT("decorative")) ifamily = wxDECORATIVE;
766 else if (family == wxT("roman")) ifamily = wxROMAN;
767 else if (family == wxT("script")) ifamily = wxSCRIPT;
768 else if (family == wxT("swiss")) ifamily = wxSWISS;
769 else if (family == wxT("modern")) ifamily = wxMODERN;
dc743689 770
a559d708 771 bool underlined = GetBool(wxT("underlined"), FALSE);
dc743689 772
a559d708 773 wxString encoding = GetParamValue(wxT("encoding"));
dc743689
VS
774 wxFontMapper mapper;
775 wxFontEncoding enc = wxFONTENCODING_DEFAULT;
776 if (!encoding.IsEmpty()) enc = mapper.CharsetToEncoding(encoding);
777 if (enc == wxFONTENCODING_SYSTEM) enc = wxFONTENCODING_SYSTEM;
778
a559d708 779 wxString faces = GetParamValue(wxT("face"));
d33a1e8b
VS
780 wxString facename = wxEmptyString;
781 wxFontEnumerator enu;
782 enu.EnumerateFacenames();
a559d708 783 wxStringTokenizer tk(faces, wxT(","));
d33a1e8b
VS
784 while (tk.HasMoreTokens())
785 {
786 int index = enu.GetFacenames()->Index(tk.GetNextToken(), FALSE);
787 if (index != wxNOT_FOUND)
788 {
789 facename = (*enu.GetFacenames())[index];
790 break;
791 }
792 }
793
ab708d5d 794 m_node = oldnode;
d33a1e8b 795
dc743689 796 wxFont font(size, ifamily, istyle, iweight, underlined, facename, enc);
d33a1e8b
VS
797 return font;
798}
799
800
56d2f750
VS
801void wxXmlResourceHandler::SetupWindow(wxWindow *wnd)
802{
d33a1e8b 803 //FIXME : add cursor
56d2f750 804
a559d708
VS
805 if (HasParam(wxT("exstyle")))
806 wnd->SetExtraStyle(GetStyle(wxT("exstyle")));
807 if (HasParam(wxT("bg")))
808 wnd->SetBackgroundColour(GetColour(wxT("bg")));
809 if (HasParam(wxT("fg")))
810 wnd->SetForegroundColour(GetColour(wxT("fg")));
811 if (GetBool(wxT("enabled"), 1) == 0)
56d2f750 812 wnd->Enable(FALSE);
a559d708 813 if (GetBool(wxT("focused"), 0) == 1)
56d2f750 814 wnd->SetFocus();
a559d708 815 if (GetBool(wxT("hidden"), 0) == 1)
56d2f750
VS
816 wnd->Show(FALSE);
817#if wxUSE_TOOLTIPS
a559d708
VS
818 if (HasParam(wxT("tooltip")))
819 wnd->SetToolTip(GetText(wxT("tooltip")));
56d2f750 820#endif
a559d708 821 if (HasParam(wxT("font")))
d33a1e8b 822 wnd->SetFont(GetFont());
56d2f750
VS
823}
824
825
e066e256 826void wxXmlResourceHandler::CreateChildren(wxObject *parent, bool this_hnd_only)
56d2f750 827{
ab708d5d 828 wxXmlNode *n = m_node->GetChildren();
792064e9 829
56d2f750
VS
830 while (n)
831 {
e066e256 832 if (n->GetType() == wxXML_ELEMENT_NODE &&
a559d708 833 n->GetName() == wxT("object"))
56d2f750 834 {
e066e256
VS
835 if (this_hnd_only && CanHandle(n))
836 CreateResource(n, parent, NULL);
56d2f750 837 else
ab708d5d 838 m_resource->CreateResFromNode(n, parent, NULL);
56d2f750
VS
839 }
840 n = n->GetNext();
841 }
842}
843
844
f485492a 845void wxXmlResourceHandler::CreateChildrenPrivately(wxObject *parent, wxXmlNode *rootnode)
e066e256
VS
846{
847 wxXmlNode *root;
ab708d5d 848 if (rootnode == NULL) root = m_node; else root = rootnode;
e066e256
VS
849 wxXmlNode *n = root->GetChildren();
850
851 while (n)
852 {
853 if (n->GetType() == wxXML_ELEMENT_NODE && CanHandle(n))
854 {
855 CreateResource(n, parent, NULL);
856 }
857 n = n->GetNext();
858 }
859}
860
861
56d2f750
VS
862
863
864
865
866
867
868
869// --------------- XMLID implementation -----------------------------
870
56d2f750
VS
871#define XMLID_TABLE_SIZE 1024
872
29b5f2cc 873
56d2f750
VS
874struct XMLID_record
875{
876 int id;
29b5f2cc 877 char *key;
56d2f750
VS
878 XMLID_record *next;
879};
880
881static XMLID_record *XMLID_Records[XMLID_TABLE_SIZE] = {NULL};
56d2f750
VS
882
883/*static*/ int wxXmlResource::GetXMLID(const char *str_id)
884{
429fdefc
VS
885 static int XMLID_LastID = wxID_HIGHEST;
886
56d2f750
VS
887 int index = 0;
888
889 for (const char *c = str_id; *c != '\0'; c++) index += (int)*c;
890 index %= XMLID_TABLE_SIZE;
891
892 XMLID_record *oldrec = NULL;
29b5f2cc 893 int matchcnt = 0;
56d2f750
VS
894 for (XMLID_record *rec = XMLID_Records[index]; rec; rec = rec->next)
895 {
29b5f2cc
VS
896 if (strcmp(rec->key, str_id) == 0)
897 {
29b5f2cc
VS
898 return rec->id;
899 }
900 matchcnt++;
56d2f750
VS
901 oldrec = rec;
902 }
903
904 XMLID_record **rec_var = (oldrec == NULL) ?
905 &XMLID_Records[index] : &oldrec->next;
906 *rec_var = new XMLID_record;
907 (*rec_var)->id = ++XMLID_LastID;
29b5f2cc 908 (*rec_var)->key = strdup(str_id);
56d2f750
VS
909 (*rec_var)->next = NULL;
910
911 return (*rec_var)->id;
912}
913
914
915static void CleanXMLID_Record(XMLID_record *rec)
916{
917 if (rec)
918 {
919 CleanXMLID_Record(rec->next);
29b5f2cc 920 free (rec->key);
56d2f750
VS
921 delete rec;
922 }
923}
924
925static void CleanXMLID_Records()
926{
927 for (int i = 0; i < XMLID_TABLE_SIZE; i++)
928 CleanXMLID_Record(XMLID_Records[i]);
929}
930
931
932
933
934
935
936
937
938// --------------- module and globals -----------------------------
939
940
941static wxXmlResource gs_XmlResource;
942
943wxXmlResource *wxTheXmlResource = &gs_XmlResource;
944
945
946class wxXmlResourceModule: public wxModule
947{
948DECLARE_DYNAMIC_CLASS(wxXmlResourceModule)
949public:
950 wxXmlResourceModule() {}
951 bool OnInit() {return TRUE;}
952 void OnExit()
953 {
954 wxTheXmlResource->ClearHandlers();
955 CleanXMLID_Records();
956 }
957};
958
959IMPLEMENT_DYNAMIC_CLASS(wxXmlResourceModule, wxModule)