]> git.saurik.com Git - wxWidgets.git/blame - contrib/src/xml/xmlres.cpp
added timestamping to wxLogStream
[wxWidgets.git] / contrib / src / xml / xmlres.cpp
CommitLineData
56d2f750
VS
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"
d33a1e8b 29#include "wx/fontenum.h"
56d2f750 30#include "wx/module.h"
792064e9
VS
31#include "wx/bitmap.h"
32#include "wx/image.h"
dc743689 33#include "wx/fontmap.h"
56d2f750
VS
34
35#include "wx/xml/xml.h"
36#include "wx/xml/xmlres.h"
37
38#include "wx/arrimpl.cpp"
39WX_DEFINE_OBJARRAY(wxXmlResourceDataRecords);
40
41
f485492a 42wxXmlResource::wxXmlResource(bool use_locale)
56d2f750
VS
43{
44 m_Handlers.DeleteContents(TRUE);
d33a1e8b 45 m_UseLocale = use_locale;
56d2f750
VS
46}
47
f485492a 48wxXmlResource::wxXmlResource(const wxString& filemask, bool use_locale)
56d2f750 49{
d33a1e8b 50 m_UseLocale = use_locale;
56d2f750 51 m_Handlers.DeleteContents(TRUE);
0ceae932 52 Load(filemask);
56d2f750
VS
53}
54
55wxXmlResource::~wxXmlResource()
56{
57 ClearHandlers();
58}
59
60
0ceae932 61bool wxXmlResource::Load(const wxString& filemask)
56d2f750
VS
62{
63 wxString fnd;
64 wxXmlResourceDataRecord *drec;
0ceae932 65 bool iswild = wxIsWild(filemask);
56d2f750
VS
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()
56d2f750 74#endif
0ceae932
VS
75 if (iswild)
76 fnd = wxXmlFindFirst;
77 else
78 fnd = filemask;
56d2f750
VS
79 while (!!fnd)
80 {
81#if wxUSE_FILESYSTEM
0ceae932
VS
82 if (filemask.Lower().Matches("*.zip") ||
83 filemask.Lower().Matches("*.rsc"))
56d2f750
VS
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 }
0ceae932
VS
104
105 if (iswild)
106 fnd = wxXmlFindNext;
107 else
108 fnd = wxEmptyString;
56d2f750
VS
109 }
110# undef wxXmlFindFirst
111# undef wxXmlFindNext
112 return TRUE;
113}
114
115
116
117void wxXmlResource::AddHandler(wxXmlResourceHandler *handler)
118{
119 m_Handlers.Append(handler);
120 handler->SetParentResource(this);
121}
122
123
124
125void wxXmlResource::ClearHandlers()
126{
127 m_Handlers.Clear();
128}
129
130
131
132wxMenu *wxXmlResource::LoadMenu(const wxString& name)
133{
e066e256 134 return (wxMenu*)CreateResFromNode(FindResource(name, wxT("wxMenu")), NULL, NULL);
56d2f750
VS
135}
136
137
138
139wxMenuBar *wxXmlResource::LoadMenuBar(const wxString& name)
140{
e066e256 141 return (wxMenuBar*)CreateResFromNode(FindResource(name, wxT("wxMenuBar")), NULL, NULL);
56d2f750
VS
142}
143
144
145
792064e9
VS
146wxToolBar *wxXmlResource::LoadToolBar(wxWindow *parent, const wxString& name)
147{
e066e256 148 return (wxToolBar*)CreateResFromNode(FindResource(name, wxT("wxToolBar")), parent, NULL);
792064e9
VS
149}
150
151
152
56d2f750
VS
153wxDialog *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
161bool wxXmlResource::LoadDialog(wxDialog *dlg, wxWindow *parent, const wxString& name)
162{
e066e256 163 return CreateResFromNode(FindResource(name, wxT("wxDialog")), parent, dlg) != NULL;
56d2f750
VS
164}
165
166
167
168wxPanel *wxXmlResource::LoadPanel(wxWindow *parent, const wxString& name)
169{
e066e256 170 return (wxPanel*)CreateResFromNode(FindResource(name, wxT("wxPanel")), parent, NULL);
56d2f750
VS
171}
172
173bool wxXmlResource::LoadPanel(wxPanel *panel, wxWindow *parent, const wxString& name)
174{
e066e256 175 return CreateResFromNode(FindResource(name, wxT("wxPanel")), parent, panel) != NULL;
56d2f750
VS
176}
177
178
179
d33a1e8b
VS
180wxBitmap wxXmlResource::LoadBitmap(const wxString& name)
181{
182 wxBitmap *bmp = (wxBitmap*)CreateResFromNode(
e066e256 183 FindResource(name, wxT("wxBitmap")), NULL, NULL);
d33a1e8b
VS
184 wxBitmap rt;
185
186 if (bmp) { rt = *bmp; delete bmp; }
187 return rt;
188}
189
190wxIcon wxXmlResource::LoadIcon(const wxString& name)
191{
192 wxIcon *icon = (wxIcon*)CreateResFromNode(
e066e256 193 FindResource(name, wxT("wxIcon")), NULL, NULL);
d33a1e8b
VS
194 wxIcon rt;
195
196 if (icon) { rt = *icon; delete icon; }
197 return rt;
198}
199
200
201
29b5f2cc
VS
202void 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
56d2f750
VS
250void 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))
0ceae932 292 {
56d2f750 293 wxLogError(_("Cannot load resources from file '%s'."), m_Data[i].File.c_str());
0ceae932
VS
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 {
56d2f750 299 wxLogError(_("Invalid XML resource '%s': doesn't have root node 'resource'."), m_Data[i].File.c_str());
0ceae932
VS
300 delete m_Data[i].Doc;
301 m_Data[i].Doc = NULL;
302 }
303 else
304 ProcessPlatformProperty(m_Data[i].Doc->GetRoot());
29b5f2cc 305
56d2f750
VS
306# if wxUSE_FILESYSTEM
307 delete file;
308# else
309 delete stream;
310# endif
311 }
312 }
313}
314
315
316
e066e256 317wxXmlNode *wxXmlResource::FindResource(const wxString& name, const wxString& classname)
56d2f750
VS
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 {
0ceae932 324 if (m_Data[f].Doc == NULL || m_Data[f].Doc->GetRoot() == NULL) continue;
56d2f750
VS
325 for (wxXmlNode *node = m_Data[f].Doc->GetRoot()->GetChildren();
326 node; node = node->GetNext())
e066e256
VS
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)
792064e9
VS
333 {
334#if wxUSE_FILESYSTEM
335 m_CurFileSystem.ChangePathTo(m_Data[f].File);
336#endif
56d2f750 337 return node;
792064e9 338 }
56d2f750
VS
339 }
340
e066e256
VS
341 wxLogError(_("XML resource '%s' (class '%s') not found!"),
342 name.c_str(), classname.c_str());
56d2f750
VS
343 return NULL;
344}
345
346
347
348wxObject *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();
e066e256 358 if (node->GetName() == _T("object") && handler->CanHandle(node))
56d2f750
VS
359 {
360 ret = handler->CreateResource(node, parent, instance);
361 if (ret) return ret;
362 }
363 ND = ND->GetNext();
364 }
365
e066e256
VS
366 wxLogError(_("No handler found for XML node '%s', class '%s'!"),
367 node->GetName().c_str(),
368 node->GetPropVal(_T("class"), wxEmptyString).c_str());
56d2f750
VS
369 return NULL;
370}
371
372
373
374
375
376
377
378
379
380wxXmlResourceHandler::wxXmlResourceHandler()
381 : m_Node(NULL), m_Parent(NULL), m_Instance(NULL),
382 m_ParentAsWindow(NULL), m_InstanceAsWindow(NULL)
383{}
384
385
386
387wxObject *wxXmlResourceHandler::CreateResource(wxXmlNode *node, wxObject *parent, wxObject *instance)
388{
56d2f750 389 wxXmlNode *myNode = m_Node;
e066e256 390 wxString myClass = m_Class;
56d2f750
VS
391 wxObject *myParent = m_Parent, *myInstance = m_Instance;
392 wxWindow *myParentAW = m_ParentAsWindow, *myInstanceAW = m_InstanceAsWindow;
393
394 m_Node = node;
e066e256 395 m_Class = node->GetPropVal(_T("class"), wxEmptyString);
56d2f750
VS
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;
e066e256 404 m_Class = myClass;
56d2f750
VS
405 m_Parent = myParent; m_ParentAsWindow = myParentAW;
406 m_Instance = myInstance; m_InstanceAsWindow = myInstanceAW;
407
408 return returned;
409}
410
411
56d2f750
VS
412void wxXmlResourceHandler::AddStyle(const wxString& name, int value)
413{
414 m_StyleNames.Add(name);
415 m_StyleValues.Add(value);
416}
417
418
09dc1241
VS
419
420void 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
56d2f750
VS
434bool wxXmlResourceHandler::HasParam(const wxString& param)
435{
436 return (GetParamNode(param) != NULL);
437}
438
439
440int 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
464wxString 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 }
d33a1e8b
VS
491
492 if (m_Resource->GetUseLocale())
493 return wxGetTranslation(str2);
494 else
495 return str2;
56d2f750
VS
496}
497
498
499
500long 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
512int 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
538wxString wxXmlResourceHandler::GetName()
539{
540 return m_Node->GetPropVal(_T("name"), _T("-1"));
541}
542
543
544
545bool wxXmlResourceHandler::GetBool(const wxString& param, bool defaultv)
546{
547 wxString v = GetParamValue(param);
548 v.MakeLower();
549 if (!v) return defaultv;
10461e19 550 else return (v == _T("1"));
56d2f750
VS
551}
552
553
554
555wxColour 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
792064e9
VS
574
575wxBitmap 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
602wxIcon wxXmlResourceHandler::GetIcon(const wxString& param, wxSize size)
603{
bebb14d5 604#if wxCHECK_VERSION(2,3,0) || defined(__WXMSW__)
792064e9
VS
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
56d2f750
VS
618wxXmlNode *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
632wxString 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
650wxString wxXmlResourceHandler::GetParamValue(const wxString& param)
651{
d33a1e8b
VS
652 if (param.IsEmpty())
653 return GetNodeContent(m_Node);
654 else
655 return GetNodeContent(GetParamNode(param));
56d2f750
VS
656}
657
658
659
660wxSize wxXmlResourceHandler::GetSize(const wxString& param)
661{
662 wxString s = GetParamValue(param);
29b5f2cc 663 if (s.IsEmpty()) s = _T("-1,-1");
56d2f750
VS
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
694wxPoint wxXmlResourceHandler::GetPosition(const wxString& param)
695{
696 wxSize sz = GetSize(param);
697 return wxPoint(sz.x, sz.y);
698}
699
700
701
bebb14d5
VS
702wxCoord 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
d33a1e8b
VS
735wxFont wxXmlResourceHandler::GetFont(const wxString& param)
736{
737 wxXmlNode *font_node = GetParamNode(param);
738 if (font_node == NULL)
739 {
dc743689 740 wxLogError(_("Cannot find font node '%s'."), param.mb_str());
d33a1e8b
VS
741 return wxNullFont;
742 }
743
744 wxXmlNode *oldnode = m_Node;
745 m_Node = font_node;
746
dc743689 747 long size = GetLong(_T("size"), 12);
d33a1e8b 748
dc743689
VS
749 wxString style = GetParamValue(_T("style"));
750 wxString weight = GetParamValue(_T("weight"));
d33a1e8b 751 int istyle = wxNORMAL, iweight = wxNORMAL;
dc743689
VS
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"));
d33a1e8b
VS
774 wxString facename = wxEmptyString;
775 wxFontEnumerator enu;
776 enu.EnumerateFacenames();
dc743689 777 wxStringTokenizer tk(faces, _T(","));
d33a1e8b
VS
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
dc743689 790 wxFont font(size, ifamily, istyle, iweight, underlined, facename, enc);
d33a1e8b
VS
791 return font;
792}
793
794
56d2f750
VS
795void wxXmlResourceHandler::SetupWindow(wxWindow *wnd)
796{
d33a1e8b 797 //FIXME : add cursor
56d2f750
VS
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
d33a1e8b
VS
815 if (HasParam(_T("font")))
816 wnd->SetFont(GetFont());
56d2f750
VS
817}
818
819
e066e256 820void wxXmlResourceHandler::CreateChildren(wxObject *parent, bool this_hnd_only)
56d2f750 821{
e066e256 822 wxXmlNode *n = m_Node->GetChildren();
792064e9 823
56d2f750
VS
824 while (n)
825 {
e066e256
VS
826 if (n->GetType() == wxXML_ELEMENT_NODE &&
827 n->GetName() == _T("object"))
56d2f750 828 {
e066e256
VS
829 if (this_hnd_only && CanHandle(n))
830 CreateResource(n, parent, NULL);
56d2f750
VS
831 else
832 m_Resource->CreateResFromNode(n, parent, NULL);
833 }
834 n = n->GetNext();
835 }
836}
837
838
f485492a 839void wxXmlResourceHandler::CreateChildrenPrivately(wxObject *parent, wxXmlNode *rootnode)
e066e256
VS
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
56d2f750
VS
856
857
858
859
860
861
862
863// --------------- XMLID implementation -----------------------------
864
56d2f750
VS
865#define XMLID_TABLE_SIZE 1024
866
29b5f2cc 867
56d2f750
VS
868struct XMLID_record
869{
870 int id;
29b5f2cc 871 char *key;
56d2f750
VS
872 XMLID_record *next;
873};
874
875static XMLID_record *XMLID_Records[XMLID_TABLE_SIZE] = {NULL};
876static 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;
29b5f2cc 886 int matchcnt = 0;
56d2f750
VS
887 for (XMLID_record *rec = XMLID_Records[index]; rec; rec = rec->next)
888 {
29b5f2cc
VS
889 if (strcmp(rec->key, str_id) == 0)
890 {
29b5f2cc
VS
891 return rec->id;
892 }
893 matchcnt++;
56d2f750
VS
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;
29b5f2cc 901 (*rec_var)->key = strdup(str_id);
56d2f750
VS
902 (*rec_var)->next = NULL;
903
904 return (*rec_var)->id;
905}
906
907
908static void CleanXMLID_Record(XMLID_record *rec)
909{
910 if (rec)
911 {
912 CleanXMLID_Record(rec->next);
29b5f2cc 913 free (rec->key);
56d2f750
VS
914 delete rec;
915 }
916}
917
918static 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
934static wxXmlResource gs_XmlResource;
935
936wxXmlResource *wxTheXmlResource = &gs_XmlResource;
937
938
939class wxXmlResourceModule: public wxModule
940{
941DECLARE_DYNAMIC_CLASS(wxXmlResourceModule)
942public:
943 wxXmlResourceModule() {}
944 bool OnInit() {return TRUE;}
945 void OnExit()
946 {
947 wxTheXmlResource->ClearHandlers();
948 CleanXMLID_Records();
949 }
950};
951
952IMPLEMENT_DYNAMIC_CLASS(wxXmlResourceModule, wxModule)