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