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