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