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