]> git.saurik.com Git - wxWidgets.git/blob - contrib/src/xml/xmlres.cpp
b34261062949f75d950ee3fb1140204d35a21c71
[wxWidgets.git] / contrib / src / xml / xmlres.cpp
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"
24 #include "wx/wfstream.h"
25 #include "wx/filesys.h"
26 #include "wx/log.h"
27 #include "wx/intl.h"
28 #include "wx/tokenzr.h"
29 #include "wx/fontenum.h"
30 #include "wx/module.h"
31 #include "wx/bitmap.h"
32 #include "wx/image.h"
33 #include "wx/fontmap.h"
34
35 #include "wx/xml/xml.h"
36 #include "wx/xml/xmlres.h"
37
38 #include "wx/arrimpl.cpp"
39 WX_DEFINE_OBJARRAY(wxXmlResourceDataRecords);
40
41
42 wxXmlResource::wxXmlResource(bool use_locale = TRUE)
43 {
44 m_Handlers.DeleteContents(TRUE);
45 m_UseLocale = use_locale;
46 }
47
48 wxXmlResource::wxXmlResource(const wxString& filemask, bool use_locale = TRUE)
49 {
50 m_UseLocale = use_locale;
51 m_Handlers.DeleteContents(TRUE);
52 Load(filemask);
53 }
54
55 wxXmlResource::~wxXmlResource()
56 {
57 for (size_t i = 0; i < m_Data.GetCount(); i++)
58 {
59 if (!m_Data[i].DocOwned) m_Data[i].Doc = NULL;
60 // we don't want it to be deleted
61 }
62
63 ClearHandlers();
64 }
65
66
67 bool wxXmlResource::Load(const wxString& filemask)
68 {
69 wxString fnd;
70 wxXmlResourceDataRecord *drec;
71 bool iswild = wxIsWild(filemask);
72
73 #if wxUSE_FILESYSTEM
74 wxFileSystem fsys;
75 # define wxXmlFindFirst fsys.FindFirst(filemask, wxFILE)
76 # define wxXmlFindNext fsys.FindNext()
77 #else
78 # define wxXmlFindFirst wxFindFirstFile(filemask, wxFILE)
79 # define wxXmlFindNext wxFindNextFile()
80 #endif
81 if (iswild)
82 fnd = wxXmlFindFirst;
83 else
84 fnd = filemask;
85 while (!!fnd)
86 {
87 #if wxUSE_FILESYSTEM
88 if (filemask.Lower().Matches("*.zip") ||
89 filemask.Lower().Matches("*.rsc"))
90 {
91 wxFileSystem fs2;
92 wxString fnd2;
93
94 fnd2 = fs2.FindFirst(fnd + wxT("#zip:*.xmb"), wxFILE);
95 while (!!fnd2)
96 {
97 drec = new wxXmlResourceDataRecord;
98 drec->File = fnd2;
99 m_Data.Add(drec);
100 drec->DocOwned = TRUE;
101 fnd2 = fs2.FindNext();
102 }
103 }
104 else
105 #endif
106 {
107 drec = new wxXmlResourceDataRecord;
108 drec->File = fnd;
109 drec->DocOwned = TRUE;
110 m_Data.Add(drec);
111 }
112
113 if (iswild)
114 fnd = wxXmlFindNext;
115 else
116 fnd = wxEmptyString;
117 }
118 # undef wxXmlFindFirst
119 # undef wxXmlFindNext
120 return TRUE;
121 }
122
123
124
125 void wxXmlResource::AddHandler(wxXmlResourceHandler *handler)
126 {
127 m_Handlers.Append(handler);
128 handler->SetParentResource(this);
129 }
130
131
132
133 void wxXmlResource::ClearHandlers()
134 {
135 m_Handlers.Clear();
136 }
137
138
139
140 wxMenu *wxXmlResource::LoadMenu(const wxString& name)
141 {
142 return (wxMenu*)CreateResFromNode(FindResource(name, wxT("menu")), NULL, NULL);
143 }
144
145
146
147 wxMenuBar *wxXmlResource::LoadMenuBar(const wxString& name)
148 {
149 return (wxMenuBar*)CreateResFromNode(FindResource(name, wxT("menubar")), NULL, NULL);
150 }
151
152
153
154 wxToolBar *wxXmlResource::LoadToolBar(wxWindow *parent, const wxString& name)
155 {
156 return (wxToolBar*)CreateResFromNode(FindResource(name, wxT("toolbar")), parent, NULL);
157 }
158
159
160
161 wxDialog *wxXmlResource::LoadDialog(wxWindow *parent, const wxString& name)
162 {
163 wxDialog *dialog = new wxDialog;
164 if (!LoadDialog(dialog, parent, name))
165 { delete dialog; return NULL; }
166 else return dialog;
167 }
168
169 bool wxXmlResource::LoadDialog(wxDialog *dlg, wxWindow *parent, const wxString& name)
170 {
171 return CreateResFromNode(FindResource(name, wxT("dialog")), parent, dlg) != NULL;
172 }
173
174
175
176 wxPanel *wxXmlResource::LoadPanel(wxWindow *parent, const wxString& name)
177 {
178 wxPanel *panel = new wxPanel;
179 if (!LoadPanel(panel, parent, name))
180 { delete panel; return NULL; }
181 else return panel;
182 }
183
184 bool wxXmlResource::LoadPanel(wxPanel *panel, wxWindow *parent, const wxString& name)
185 {
186 return CreateResFromNode(FindResource(name, wxT("panel")), parent, panel) != NULL;
187 }
188
189
190
191 wxBitmap wxXmlResource::LoadBitmap(const wxString& name)
192 {
193 wxBitmap *bmp = (wxBitmap*)CreateResFromNode(
194 FindResource(name, wxT("bitmap")), NULL, NULL);
195 wxBitmap rt;
196
197 if (bmp) { rt = *bmp; delete bmp; }
198 return rt;
199 }
200
201 wxIcon wxXmlResource::LoadIcon(const wxString& name)
202 {
203 wxIcon *icon = (wxIcon*)CreateResFromNode(
204 FindResource(name, wxT("icon")), NULL, NULL);
205 wxIcon rt;
206
207 if (icon) { rt = *icon; delete icon; }
208 return rt;
209 }
210
211
212
213 void wxXmlResource::ProcessPlatformProperty(wxXmlNode *node)
214 {
215 wxString s;
216 bool isok;
217
218 wxXmlNode *c = node->GetChildren();
219 while (c)
220 {
221 isok = FALSE;
222 if (!c->GetPropVal(_T("platform"), &s))
223 isok = TRUE;
224 else
225 {
226 wxStringTokenizer tkn(s, " |");
227
228 while (tkn.HasMoreTokens())
229 {
230 s = tkn.GetNextToken();
231 if (
232 #ifdef __WXMSW__
233 s == wxString(_T("win"))
234 #elif defined(__UNIX__)
235 s == wxString(_T("unix"))
236 #elif defined(__MAC__)
237 s == wxString(_T("mac"))
238 #elif defined(__OS2__)
239 s == wxString(_T("os2"))
240 #else
241 FALSE
242 #endif
243 ) isok = TRUE;
244 }
245 }
246
247 if (isok)
248 ProcessPlatformProperty(c);
249 else
250 {
251 node->RemoveChild(c);
252 delete c;
253 }
254
255 c = c->GetNext();
256 }
257 }
258
259
260
261 void wxXmlResource::UpdateResources()
262 {
263 bool modif;
264 # if wxUSE_FILESYSTEM
265 wxFSFile *file;
266 wxFileSystem fsys;
267 # endif
268
269 for (size_t i = 0; i < m_Data.GetCount(); i++)
270 {
271 if (!m_Data[i].DocOwned) continue;
272
273 modif = (m_Data[i].Doc == NULL);
274
275 if (!modif)
276 {
277 # if wxUSE_FILESYSTEM
278 file = fsys.OpenFile(m_Data[i].File);
279 modif = file && file->GetModificationTime() > m_Data[i].Time;
280 if (!file)
281 wxLogError(_("Cannot open file '%s'."), m_Data[i].File.c_str());
282 delete file;
283 # else
284 modif = wxDateTime(wxFileModificationTime(m_Data[i].File)) > m_Data[i].Time;
285 # endif
286 }
287
288 if (modif)
289 {
290 wxInputStream *stream;
291
292 # if wxUSE_FILESYSTEM
293 file = fsys.OpenFile(m_Data[i].File);
294 stream = file->GetStream();
295 # else
296 stream = new wxFileInputStream(m_Data[i].File);
297 # endif
298
299 if (stream)
300 {
301 delete m_Data[i].Doc;
302 m_Data[i].Doc = new wxXmlDocument;
303 }
304 if (!stream || !m_Data[i].Doc->Load(*stream))
305 {
306 wxLogError(_("Cannot load resources from file '%s'."), m_Data[i].File.c_str());
307 delete m_Data[i].Doc;
308 m_Data[i].Doc = NULL;
309 }
310 else if (m_Data[i].Doc->GetRoot()->GetName() != _T("resource"))
311 {
312 wxLogError(_("Invalid XML resource '%s': doesn't have root node 'resource'."), m_Data[i].File.c_str());
313 delete m_Data[i].Doc;
314 m_Data[i].Doc = NULL;
315 }
316 else
317 ProcessPlatformProperty(m_Data[i].Doc->GetRoot());
318
319 # if wxUSE_FILESYSTEM
320 delete file;
321 # else
322 delete stream;
323 # endif
324 }
325 }
326 }
327
328
329
330 wxXmlNode *wxXmlResource::FindResource(const wxString& name, const wxString& type)
331 {
332 UpdateResources(); //ensure everything is up-to-date
333
334 wxString dummy;
335 for (size_t f = 0; f < m_Data.GetCount(); f++)
336 {
337 if (m_Data[f].Doc == NULL || m_Data[f].Doc->GetRoot() == NULL) continue;
338 for (wxXmlNode *node = m_Data[f].Doc->GetRoot()->GetChildren();
339 node; node = node->GetNext())
340 if ( node->GetType() == wxXML_ELEMENT_NODE &&
341 (!type || node->GetName() == type) &&
342 node->GetPropVal(wxT("name"), &dummy) &&
343 dummy == name)
344 {
345 #if wxUSE_FILESYSTEM
346 m_CurFileSystem.ChangePathTo(m_Data[f].File);
347 #endif
348 return node;
349 }
350 }
351
352 wxLogError(_("XML resource '%s' (type '%s') not found!"),
353 name.c_str(), type.c_str());
354 return NULL;
355 }
356
357
358
359 wxObject *wxXmlResource::CreateResFromNode(wxXmlNode *node, wxObject *parent, wxObject *instance)
360 {
361 if (node == NULL) return NULL;
362
363 wxXmlResourceHandler *handler;
364 wxObject *ret;
365 wxNode * ND = m_Handlers.GetFirst();
366 while (ND)
367 {
368 handler = (wxXmlResourceHandler*)ND->GetData();
369 if (handler->CanHandle(node))
370 {
371 ret = handler->CreateResource(node, parent, instance);
372 if (ret) return ret;
373 }
374 ND = ND->GetNext();
375 }
376
377 wxLogError(_("No handler found for XML node '%s'!"), node->GetName().c_str());
378 return NULL;
379 }
380
381
382
383
384
385
386
387
388
389 wxXmlResourceHandler::wxXmlResourceHandler()
390 : m_Node(NULL), m_Parent(NULL), m_Instance(NULL),
391 m_ParentAsWindow(NULL), m_InstanceAsWindow(NULL)
392 {}
393
394
395
396 wxObject *wxXmlResourceHandler::CreateResource(wxXmlNode *node, wxObject *parent, wxObject *instance)
397 {
398 wxXmlNode *myNode = m_Node;
399 wxObject *myParent = m_Parent, *myInstance = m_Instance;
400 wxWindow *myParentAW = m_ParentAsWindow, *myInstanceAW = m_InstanceAsWindow;
401
402 m_Node = node;
403 m_Parent = parent;
404 m_Instance = instance;
405 m_ParentAsWindow = wxDynamicCast(m_Parent, wxWindow);
406 m_InstanceAsWindow = wxDynamicCast(m_Instance, wxWindow);
407
408 wxObject *returned = DoCreateResource();
409
410 m_Node = myNode;
411 m_Parent = myParent; m_ParentAsWindow = myParentAW;
412 m_Instance = myInstance; m_InstanceAsWindow = myInstanceAW;
413
414 return returned;
415 }
416
417
418 void wxXmlResourceHandler::AddStyle(const wxString& name, int value)
419 {
420 m_StyleNames.Add(name);
421 m_StyleValues.Add(value);
422 }
423
424
425
426 void 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
440 bool wxXmlResourceHandler::HasParam(const wxString& param)
441 {
442 return (GetParamNode(param) != NULL);
443 }
444
445
446 int wxXmlResourceHandler::GetStyle(const wxString& param, int defaults)
447 {
448 wxString s = GetParamValue(param);
449
450 if (!s) return defaults;
451
452 wxStringTokenizer tkn(s, _T("| "), wxTOKEN_STRTOK);
453 int style = 0;
454 int index;
455 wxString fl;
456 while (tkn.HasMoreTokens())
457 {
458 fl = tkn.GetNextToken();
459 index = m_StyleNames.Index(fl);
460 if (index != wxNOT_FOUND)
461 style |= m_StyleValues[index];
462 else
463 wxLogError(_("Unknown style flag ") + fl);
464 }
465 return style;
466 }
467
468
469
470 wxString 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 }
497
498 if (m_Resource->GetUseLocale())
499 return wxGetTranslation(str2);
500 else
501 return str2;
502 }
503
504
505
506 long 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
518 int wxXmlResourceHandler::GetID()
519 {
520 wxString sid = GetName();
521 long num;
522
523 if (sid == _T("-1")) return -1;
524 else if (sid.IsNumber() && sid.ToLong(&num)) return num;
525 #define stdID(id) else if (sid == _T(#id)) return id
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
544 wxString wxXmlResourceHandler::GetName()
545 {
546 return m_Node->GetPropVal(_T("name"), _T("-1"));
547 }
548
549
550
551 bool wxXmlResourceHandler::GetBool(const wxString& param, bool defaultv)
552 {
553 wxString v = GetParamValue(param);
554 v.MakeLower();
555 if (!v) return defaultv;
556 else return (v == _T("1"));
557 }
558
559
560
561 wxColour wxXmlResourceHandler::GetColour(const wxString& param)
562 {
563 wxString v = GetParamValue(param);
564 unsigned long tmp = 0;
565
566 if (v.Length() != 7 || v[0] != _T('#') ||
567 wxSscanf(v.c_str(), _T("#%lX"), &tmp) != 1)
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
580
581 wxBitmap 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
595 wxImage img(GetParamValue(_T("bitmap")));
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
608 wxIcon wxXmlResourceHandler::GetIcon(const wxString& param, wxSize size)
609 {
610 #if wxCHECK_VERSION(2,3,0) || defined(__WXMSW__)
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
624 wxXmlNode *wxXmlResourceHandler::GetParamNode(const wxString& param)
625 {
626 wxXmlNode *n = m_Node->GetChildren();
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
638 wxString 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
656 wxString wxXmlResourceHandler::GetParamValue(const wxString& param)
657 {
658 if (param.IsEmpty())
659 return GetNodeContent(m_Node);
660 else
661 return GetNodeContent(GetParamNode(param));
662 }
663
664
665
666 wxSize wxXmlResourceHandler::GetSize(const wxString& param)
667 {
668 wxString s = GetParamValue(param);
669 if (s.IsEmpty()) s = _T("-1,-1");
670 bool is_dlg;
671 long sx, sy;
672
673 is_dlg = s[s.Length()-1] == _T('d');
674 if (is_dlg) s.RemoveLast();
675
676 if (!s.BeforeFirst(_T(',')).ToLong(&sx) ||
677 !s.AfterLast(_T(',')).ToLong(&sy))
678 {
679 wxLogError(_("Cannot parse coordinates from '%s'."), s.mb_str());
680 return wxDefaultSize;
681 }
682
683 if (is_dlg)
684 {
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));
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
700 wxPoint wxXmlResourceHandler::GetPosition(const wxString& param)
701 {
702 wxSize sz = GetSize(param);
703 return wxPoint(sz.x, sz.y);
704 }
705
706
707
708 wxCoord 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
715 is_dlg = s[s.Length()-1] == _T('d');
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 {
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;
730 else
731 {
732 wxLogError(_("Cannot convert dialog units: dialog unknown."));
733 return defaultv;
734 }
735 }
736 else return sx;
737 }
738
739
740
741 wxFont wxXmlResourceHandler::GetFont(const wxString& param)
742 {
743 wxXmlNode *font_node = GetParamNode(param);
744 if (font_node == NULL)
745 {
746 wxLogError(_("Cannot find font node '%s'."), param.mb_str());
747 return wxNullFont;
748 }
749
750 wxXmlNode *oldnode = m_Node;
751 m_Node = font_node;
752
753 long size = GetLong(_T("size"), 12);
754
755 wxString style = GetParamValue(_T("style"));
756 wxString weight = GetParamValue(_T("weight"));
757 int istyle = wxNORMAL, iweight = wxNORMAL;
758 if (style == _T("italic")) istyle = wxITALIC;
759 else if (style == _T("slant")) istyle = wxSLANT;
760 if (weight == _T("bold")) iweight = wxBOLD;
761 else if (weight == _T("light")) iweight = wxLIGHT;
762
763 wxString family = GetParamValue(_T("family"));
764 int ifamily = wxDEFAULT;
765 if (family == _T("decorative")) ifamily = wxDECORATIVE;
766 else if (family == _T("roman")) ifamily = wxROMAN;
767 else if (family == _T("script")) ifamily = wxSCRIPT;
768 else if (family == _T("swiss")) ifamily = wxSWISS;
769 else if (family == _T("modern")) ifamily = wxMODERN;
770
771 bool underlined = GetBool(_T("underlined"), FALSE);
772
773 wxString encoding = GetParamValue(_T("encoding"));
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
779 wxString faces = GetParamValue(_T("face"));
780 wxString facename = wxEmptyString;
781 wxFontEnumerator enu;
782 enu.EnumerateFacenames();
783 wxStringTokenizer tk(faces, _T(","));
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
794 m_Node = oldnode;
795
796 wxFont font(size, ifamily, istyle, iweight, underlined, facename, enc);
797 return font;
798 }
799
800
801 void wxXmlResourceHandler::SetupWindow(wxWindow *wnd)
802 {
803 //FIXME : add cursor
804
805 if (HasParam(_T("exstyle")))
806 wnd->SetExtraStyle(GetStyle(_T("exstyle")));
807 if (HasParam(_T("bg")))
808 wnd->SetBackgroundColour(GetColour(_T("bg")));
809 if (HasParam(_T("fg")))
810 wnd->SetForegroundColour(GetColour(_T("fg")));
811 if (GetBool(_T("enabled"), 1) == 0)
812 wnd->Enable(FALSE);
813 if (GetBool(_T("focused"), 0) == 1)
814 wnd->SetFocus();
815 if (GetBool(_T("hidden"), 0) == 1)
816 wnd->Show(FALSE);
817 #if wxUSE_TOOLTIPS
818 if (HasParam(_T("tooltip")))
819 wnd->SetToolTip(GetText(_T("tooltip")));
820 #endif
821 if (HasParam(_T("font")))
822 wnd->SetFont(GetFont());
823 }
824
825
826 void wxXmlResourceHandler::CreateChildren(wxObject *parent,
827 bool only_this_handler, wxXmlNode *children_node)
828 {
829 if (children_node == NULL) children_node = GetParamNode(_T("children"));
830 if (children_node == NULL) return;
831
832 wxXmlNode *n = children_node->GetChildren();
833
834 while (n)
835 {
836 if (n->GetType() == wxXML_ELEMENT_NODE)
837 {
838 if (only_this_handler)
839 {
840 if (CanHandle(n))
841 CreateResource(n, parent, NULL);
842 }
843 else
844 m_Resource->CreateResFromNode(n, parent, NULL);
845 }
846 n = n->GetNext();
847 }
848 }
849
850
851
852
853
854
855
856
857
858 // --------------- XMLID implementation -----------------------------
859
860 #define XMLID_TABLE_SIZE 1024
861
862
863 struct XMLID_record
864 {
865 int id;
866 char *key;
867 XMLID_record *next;
868 };
869
870 static XMLID_record *XMLID_Records[XMLID_TABLE_SIZE] = {NULL};
871 static int XMLID_LastID = wxID_HIGHEST;
872
873 /*static*/ int wxXmlResource::GetXMLID(const char *str_id)
874 {
875 int index = 0;
876
877 for (const char *c = str_id; *c != '\0'; c++) index += (int)*c;
878 index %= XMLID_TABLE_SIZE;
879
880 XMLID_record *oldrec = NULL;
881 int matchcnt = 0;
882 for (XMLID_record *rec = XMLID_Records[index]; rec; rec = rec->next)
883 {
884 if (strcmp(rec->key, str_id) == 0)
885 {
886 return rec->id;
887 }
888 matchcnt++;
889 oldrec = rec;
890 }
891
892 XMLID_record **rec_var = (oldrec == NULL) ?
893 &XMLID_Records[index] : &oldrec->next;
894 *rec_var = new XMLID_record;
895 (*rec_var)->id = ++XMLID_LastID;
896 (*rec_var)->key = strdup(str_id);
897 (*rec_var)->next = NULL;
898
899 return (*rec_var)->id;
900 }
901
902
903 static void CleanXMLID_Record(XMLID_record *rec)
904 {
905 if (rec)
906 {
907 CleanXMLID_Record(rec->next);
908 free (rec->key);
909 delete rec;
910 }
911 }
912
913 static void CleanXMLID_Records()
914 {
915 for (int i = 0; i < XMLID_TABLE_SIZE; i++)
916 CleanXMLID_Record(XMLID_Records[i]);
917 }
918
919
920
921
922
923
924
925
926 // --------------- module and globals -----------------------------
927
928
929 static wxXmlResource gs_XmlResource;
930
931 wxXmlResource *wxTheXmlResource = &gs_XmlResource;
932
933
934 class wxXmlResourceModule: public wxModule
935 {
936 DECLARE_DYNAMIC_CLASS(wxXmlResourceModule)
937 public:
938 wxXmlResourceModule() {}
939 bool OnInit() {return TRUE;}
940 void OnExit()
941 {
942 wxTheXmlResource->ClearHandlers();
943 CleanXMLID_Records();
944 }
945 };
946
947 IMPLEMENT_DYNAMIC_CLASS(wxXmlResourceModule, wxModule)