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