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