]> git.saurik.com Git - wxWidgets.git/blob - src/common/resource.cpp
don't write the strings to the stream one char at a time, it's *horribly* slow
[wxWidgets.git] / src / common / resource.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: resource.cpp
3 // Purpose: Resource system
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "resource.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #if wxUSE_WX_RESOURCES
24
25 #ifdef __VISUALC__
26 #pragma warning(disable:4706) // assignment within conditional expression
27 #endif // VC++
28
29 #ifndef WX_PRECOMP
30 #include "wx/defs.h"
31 #include "wx/setup.h"
32 #include "wx/list.h"
33 #include "wx/hash.h"
34 #include "wx/gdicmn.h"
35 #include "wx/utils.h"
36 #include "wx/types.h"
37 #include "wx/menu.h"
38 #include "wx/stattext.h"
39 #include "wx/button.h"
40 #include "wx/bmpbuttn.h"
41 #include "wx/radiobox.h"
42 #include "wx/listbox.h"
43 #include "wx/choice.h"
44 #include "wx/checkbox.h"
45 #include "wx/settings.h"
46 #include "wx/slider.h"
47 #include "wx/icon.h"
48 #include "wx/statbox.h"
49 #include "wx/statbmp.h"
50 #include "wx/gauge.h"
51 #include "wx/textctrl.h"
52 #include "wx/msgdlg.h"
53 #include "wx/intl.h"
54 #endif
55
56 #include "wx/treebase.h"
57 #include "wx/listctrl.h"
58
59 #if wxUSE_RADIOBTN
60 #include "wx/radiobut.h"
61 #endif
62
63 #if wxUSE_SCROLLBAR
64 #include "wx/scrolbar.h"
65 #endif
66
67 #if wxUSE_COMBOBOX
68 #include "wx/combobox.h"
69 #endif
70
71 #include "wx/validate.h"
72
73 #include "wx/log.h"
74
75 #include <ctype.h>
76 #include <math.h>
77 #include <stdlib.h>
78 #include <string.h>
79
80 #include "wx/resource.h"
81 #include "wx/string.h"
82 #include "wx/wxexpr.h"
83
84 #include "wx/settings.h"
85 #include "wx/stream.h"
86
87 // Forward (private) declarations
88 bool wxResourceInterpretResources(wxResourceTable& table, wxExprDatabase& db);
89 wxItemResource *wxResourceInterpretDialog(wxResourceTable& table, wxExpr *expr, bool isPanel = FALSE);
90 wxItemResource *wxResourceInterpretControl(wxResourceTable& table, wxExpr *expr);
91 wxItemResource *wxResourceInterpretMenu(wxResourceTable& table, wxExpr *expr);
92 wxItemResource *wxResourceInterpretMenuBar(wxResourceTable& table, wxExpr *expr);
93 wxItemResource *wxResourceInterpretString(wxResourceTable& table, wxExpr *expr);
94 wxItemResource *wxResourceInterpretBitmap(wxResourceTable& table, wxExpr *expr);
95 wxItemResource *wxResourceInterpretIcon(wxResourceTable& table, wxExpr *expr);
96 // Interpret list expression
97 wxFont wxResourceInterpretFontSpec(wxExpr *expr);
98
99 bool wxResourceReadOneResource(FILE *fd, wxExprDatabase& db, bool *eof, wxResourceTable *table = (wxResourceTable *) NULL);
100 bool wxResourceReadOneResource(wxInputStream *fd, wxExprDatabase& db, bool *eof, wxResourceTable *table) ;
101 bool wxResourceParseIncludeFile(const wxString& f, wxResourceTable *table = (wxResourceTable *) NULL);
102
103 wxResourceTable *wxDefaultResourceTable = (wxResourceTable *) NULL;
104
105 char *wxResourceBuffer = (char *) NULL;
106 long wxResourceBufferSize = 0;
107 long wxResourceBufferCount = 0;
108 int wxResourceStringPtr = 0;
109
110 void wxInitializeResourceSystem()
111 {
112 wxDefaultResourceTable = new wxResourceTable;
113 }
114
115 void wxCleanUpResourceSystem()
116 {
117 delete wxDefaultResourceTable;
118 if (wxResourceBuffer)
119 delete[] wxResourceBuffer;
120 }
121
122 void wxLogWarning(char *msg)
123 {
124 wxMessageBox(msg, _("Warning"), wxOK);
125 }
126
127 IMPLEMENT_DYNAMIC_CLASS(wxItemResource, wxObject)
128 IMPLEMENT_DYNAMIC_CLASS(wxResourceTable, wxHashTable)
129
130 wxItemResource::wxItemResource()
131 {
132 m_itemType = "";
133 m_title = "";
134 m_name = "";
135 m_windowStyle = 0;
136 m_x = m_y = m_width = m_height = 0;
137 m_value1 = m_value2 = m_value3 = m_value5 = 0;
138 m_value4 = "";
139 m_windowId = 0;
140 m_exStyle = 0;
141 }
142
143 wxItemResource::~wxItemResource()
144 {
145 wxNode *node = m_children.First();
146 while (node)
147 {
148 wxItemResource *item = (wxItemResource *)node->Data();
149 delete item;
150 delete node;
151 node = m_children.First();
152 }
153 }
154
155 /*
156 * Resource table
157 */
158
159 wxResourceTable::wxResourceTable():wxHashTable(wxKEY_STRING), identifiers(wxKEY_STRING)
160 {
161 }
162
163 wxResourceTable::~wxResourceTable()
164 {
165 ClearTable();
166 }
167
168 wxItemResource *wxResourceTable::FindResource(const wxString& name) const
169 {
170 wxItemResource *item = (wxItemResource *)Get(WXSTRINGCAST name);
171 return item;
172 }
173
174 void wxResourceTable::AddResource(wxItemResource *item)
175 {
176 wxString name = item->GetName();
177 if (name == wxT(""))
178 name = item->GetTitle();
179 if (name == wxT(""))
180 name = wxT("no name");
181
182 // Delete existing resource, if any.
183 Delete(name);
184
185 Put(name, item);
186 }
187
188 bool wxResourceTable::DeleteResource(const wxString& name)
189 {
190 wxItemResource *item = (wxItemResource *)Delete(WXSTRINGCAST name);
191 if (item)
192 {
193 // See if any resource has this as its child; if so, delete from
194 // parent's child list.
195 BeginFind();
196 wxNode *node = (wxNode *) NULL;
197 node = Next();
198 while (node != NULL)
199 {
200 wxItemResource *parent = (wxItemResource *)node->Data();
201 if (parent->GetChildren().Member(item))
202 {
203 parent->GetChildren().DeleteObject(item);
204 break;
205 }
206 node = Next();
207 }
208
209 delete item;
210 return TRUE;
211 }
212 else
213 return FALSE;
214 }
215
216 bool wxResourceTable::ParseResourceFile( wxInputStream *is )
217 {
218 wxExprDatabase db;
219 int len = is->StreamSize() ;
220
221 bool eof = FALSE;
222 while ( is->TellI() + 10 < len) // it's a hack because the streams dont support EOF
223 {
224 wxResourceReadOneResource(is, db, &eof, this) ;
225 }
226 return wxResourceInterpretResources(*this, db);
227 }
228
229 bool wxResourceTable::ParseResourceFile(const wxString& filename)
230 {
231 wxExprDatabase db;
232
233 FILE *fd = wxFopen(filename, _T("r"));
234 if (!fd)
235 return FALSE;
236 bool eof = FALSE;
237 while (wxResourceReadOneResource(fd, db, &eof, this) && !eof)
238 {
239 // Loop
240 }
241 fclose(fd);
242 return wxResourceInterpretResources(*this, db);
243 }
244
245 bool wxResourceTable::ParseResourceData(const wxString& data)
246 {
247 wxExprDatabase db;
248 if (!db.ReadFromString(data))
249 {
250 wxLogWarning(_("Ill-formed resource file syntax."));
251 return FALSE;
252 }
253
254 return wxResourceInterpretResources(*this, db);
255 }
256
257 bool wxResourceTable::RegisterResourceBitmapData(const wxString& name, char bits[], int width, int height)
258 {
259 // Register pre-loaded bitmap data
260 wxItemResource *item = new wxItemResource;
261 // item->SetType(wxRESOURCE_TYPE_XBM_DATA);
262 item->SetType(wxT("wxXBMData"));
263 item->SetName(name);
264 item->SetValue1((long)bits);
265 item->SetValue2((long)width);
266 item->SetValue3((long)height);
267 AddResource(item);
268 return TRUE;
269 }
270
271 bool wxResourceTable::RegisterResourceBitmapData(const wxString& name, char **data)
272 {
273 // Register pre-loaded bitmap data
274 wxItemResource *item = new wxItemResource;
275 // item->SetType(wxRESOURCE_TYPE_XPM_DATA);
276 item->SetType(wxT("wxXPMData"));
277 item->SetName(name);
278 item->SetValue1((long)data);
279 AddResource(item);
280 return TRUE;
281 }
282
283 bool wxResourceTable::SaveResource(const wxString& WXUNUSED(filename))
284 {
285 return FALSE;
286 }
287
288 void wxResourceTable::ClearTable()
289 {
290 BeginFind();
291 wxNode *node = Next();
292 while (node)
293 {
294 wxNode *next = Next();
295 wxItemResource *item = (wxItemResource *)node->Data();
296 delete item;
297 delete node;
298 node = next;
299 }
300 }
301
302 wxControl *wxResourceTable::CreateItem(wxWindow *parent, const wxItemResource* childResource, const wxItemResource* parentResource) const
303 {
304 int id = childResource->GetId();
305 if ( id == 0 )
306 id = -1;
307
308 bool dlgUnits = ((parentResource->GetResourceStyle() & wxRESOURCE_DIALOG_UNITS) != 0);
309
310 wxControl *control = (wxControl *) NULL;
311 wxString itemType(childResource->GetType());
312
313 wxPoint pos;
314 wxSize size;
315 if (dlgUnits)
316 {
317 pos = parent->ConvertDialogToPixels(wxPoint(childResource->GetX(), childResource->GetY()));
318 size = parent->ConvertDialogToPixels(wxSize(childResource->GetWidth(), childResource->GetHeight()));
319 }
320 else
321 {
322 pos = wxPoint(childResource->GetX(), childResource->GetY());
323 size = wxSize(childResource->GetWidth(), childResource->GetHeight());
324 }
325
326 if (itemType == wxString(wxT("wxButton")) || itemType == wxString(wxT("wxBitmapButton")))
327 {
328 if (childResource->GetValue4() != wxT(""))
329 {
330 // Bitmap button
331 wxBitmap bitmap = childResource->GetBitmap();
332 if (!bitmap.Ok())
333 {
334 bitmap = wxResourceCreateBitmap(childResource->GetValue4(), (wxResourceTable *)this);
335 ((wxItemResource*) childResource)->SetBitmap(bitmap);
336 }
337 if (!bitmap.Ok())
338 #if defined(__WXPM__)
339 //
340 // OS/2 uses integer id's to access resources, not file name strings
341 //
342 bitmap.LoadFile(wxCROSS_BITMAP, wxBITMAP_TYPE_BMP_RESOURCE);
343 #else
344 bitmap.LoadFile("cross_bmp", wxBITMAP_TYPE_BMP_RESOURCE);
345 #endif
346 control = new wxBitmapButton(parent, id, bitmap, pos, size,
347 childResource->GetStyle() | wxBU_AUTODRAW, wxDefaultValidator, childResource->GetName());
348 }
349 else
350 // Normal, text button
351 control = new wxButton(parent, id, childResource->GetTitle(), pos, size,
352 childResource->GetStyle(), wxDefaultValidator, childResource->GetName());
353 }
354 else if (itemType == wxString(wxT("wxMessage")) || itemType == wxString(wxT("wxStaticText")) ||
355 itemType == wxString(wxT("wxStaticBitmap")))
356 {
357 if (childResource->GetValue4() != wxT("") || itemType == wxString(wxT("wxStaticBitmap")) )
358 {
359 // Bitmap message
360 wxBitmap bitmap = childResource->GetBitmap();
361 if (!bitmap.Ok())
362 {
363 bitmap = wxResourceCreateBitmap(childResource->GetValue4(), (wxResourceTable *)this);
364 ((wxItemResource*) childResource)->SetBitmap(bitmap);
365 }
366 #if wxUSE_BITMAP_MESSAGE
367 #ifdef __WXMSW__
368 // Use a default bitmap
369 if (!bitmap.Ok())
370 bitmap.LoadFile("cross_bmp", wxBITMAP_TYPE_BMP_RESOURCE);
371 #endif
372
373 if (bitmap.Ok())
374 control = new wxStaticBitmap(parent, id, bitmap, pos, size,
375 childResource->GetStyle(), childResource->GetName());
376 #endif
377 }
378 else
379 {
380 control = new wxStaticText(parent, id, childResource->GetTitle(), pos, size,
381 childResource->GetStyle(), childResource->GetName());
382 }
383 }
384 else if (itemType == wxString(wxT("wxText")) || itemType == wxString(wxT("wxTextCtrl")) || itemType == wxString(wxT("wxMultiText")))
385 {
386 control = new wxTextCtrl(parent, id, childResource->GetValue4(), pos, size,
387 childResource->GetStyle(), wxDefaultValidator, childResource->GetName());
388 }
389 else if (itemType == wxString(wxT("wxCheckBox")))
390 {
391 control = new wxCheckBox(parent, id, childResource->GetTitle(), pos, size,
392 childResource->GetStyle(), wxDefaultValidator, childResource->GetName());
393
394 ((wxCheckBox *)control)->SetValue((childResource->GetValue1() != 0));
395 }
396 #if wxUSE_GAUGE
397 else if (itemType == wxString(wxT("wxGauge")))
398 {
399 control = new wxGauge(parent, id, (int)childResource->GetValue2(), pos, size,
400 childResource->GetStyle(), wxDefaultValidator, childResource->GetName());
401
402 ((wxGauge *)control)->SetValue((int)childResource->GetValue1());
403 }
404 #endif
405 #if wxUSE_RADIOBTN
406 else if (itemType == wxString(wxT("wxRadioButton")))
407 {
408 control = new wxRadioButton(parent, id, childResource->GetTitle(), // (int)childResource->GetValue1(),
409 pos, size,
410 childResource->GetStyle(), wxDefaultValidator, childResource->GetName());
411 }
412 #endif
413 #if wxUSE_SCROLLBAR
414 else if (itemType == wxString(wxT("wxScrollBar")))
415 {
416 control = new wxScrollBar(parent, id, pos, size,
417 childResource->GetStyle(), wxDefaultValidator, childResource->GetName());
418 /*
419 ((wxScrollBar *)control)->SetValue((int)childResource->GetValue1());
420 ((wxScrollBar *)control)->SetPageSize((int)childResource->GetValue2());
421 ((wxScrollBar *)control)->SetObjectLength((int)childResource->GetValue3());
422 ((wxScrollBar *)control)->SetViewLength((int)(long)childResource->GetValue5());
423 */
424 ((wxScrollBar *)control)->SetScrollbar((int)childResource->GetValue1(),(int)childResource->GetValue2(),
425 (int)childResource->GetValue3(),(int)(long)childResource->GetValue5(),FALSE);
426
427 }
428 #endif
429 else if (itemType == wxString(wxT("wxSlider")))
430 {
431 control = new wxSlider(parent, id, (int)childResource->GetValue1(),
432 (int)childResource->GetValue2(), (int)childResource->GetValue3(), pos, size,
433 childResource->GetStyle(), wxDefaultValidator, childResource->GetName());
434 }
435 else if (itemType == wxString(wxT("wxGroupBox")) || itemType == wxString(wxT("wxStaticBox")))
436 {
437 control = new wxStaticBox(parent, id, childResource->GetTitle(), pos, size,
438 childResource->GetStyle(), childResource->GetName());
439 }
440 else if (itemType == wxString(wxT("wxListBox")))
441 {
442 wxStringList& stringList = childResource->GetStringValues();
443 wxString *strings = (wxString *) NULL;
444 int noStrings = 0;
445 if (stringList.Number() > 0)
446 {
447 noStrings = stringList.Number();
448 strings = new wxString[noStrings];
449 wxNode *node = stringList.First();
450 int i = 0;
451 while (node)
452 {
453 strings[i] = (wxChar *)node->Data();
454 i ++;
455 node = node->Next();
456 }
457 }
458 control = new wxListBox(parent, id, pos, size,
459 noStrings, strings, childResource->GetStyle(), wxDefaultValidator, childResource->GetName());
460
461 if (strings)
462 delete[] strings;
463 }
464 else if (itemType == wxString(wxT("wxChoice")))
465 {
466 wxStringList& stringList = childResource->GetStringValues();
467 wxString *strings = (wxString *) NULL;
468 int noStrings = 0;
469 if (stringList.Number() > 0)
470 {
471 noStrings = stringList.Number();
472 strings = new wxString[noStrings];
473 wxNode *node = stringList.First();
474 int i = 0;
475 while (node)
476 {
477 strings[i] = (wxChar *)node->Data();
478 i ++;
479 node = node->Next();
480 }
481 }
482 control = new wxChoice(parent, id, pos, size,
483 noStrings, strings, childResource->GetStyle(), wxDefaultValidator, childResource->GetName());
484
485 if (strings)
486 delete[] strings;
487 }
488 #if wxUSE_COMBOBOX
489 else if (itemType == wxString(wxT("wxComboBox")))
490 {
491 wxStringList& stringList = childResource->GetStringValues();
492 wxString *strings = (wxString *) NULL;
493 int noStrings = 0;
494 if (stringList.Number() > 0)
495 {
496 noStrings = stringList.Number();
497 strings = new wxString[noStrings];
498 wxNode *node = stringList.First();
499 int i = 0;
500 while (node)
501 {
502 strings[i] = (wxChar *)node->Data();
503 i ++;
504 node = node->Next();
505 }
506 }
507 control = new wxComboBox(parent, id, childResource->GetValue4(), pos, size,
508 noStrings, strings, childResource->GetStyle(), wxDefaultValidator, childResource->GetName());
509
510 if (strings)
511 delete[] strings;
512 }
513 #endif
514 else if (itemType == wxString(wxT("wxRadioBox")))
515 {
516 wxStringList& stringList = childResource->GetStringValues();
517 wxString *strings = (wxString *) NULL;
518 int noStrings = 0;
519 if (stringList.Number() > 0)
520 {
521 noStrings = stringList.Number();
522 strings = new wxString[noStrings];
523 wxNode *node = stringList.First();
524 int i = 0;
525 while (node)
526 {
527 strings[i] = (wxChar *)node->Data();
528 i ++;
529 node = node->Next();
530 }
531 }
532 control = new wxRadioBox(parent, (wxWindowID) id, wxString(childResource->GetTitle()), pos, size,
533 noStrings, strings, (int)childResource->GetValue1(), childResource->GetStyle(), wxDefaultValidator,
534 childResource->GetName());
535
536 if (strings)
537 delete[] strings;
538 }
539
540 if ((parentResource->GetResourceStyle() & wxRESOURCE_USE_DEFAULTS) != 0)
541 {
542 // Don't set font; will be inherited from parent.
543 }
544 else
545 {
546 if (control && childResource->GetFont().Ok())
547 {
548 control->SetFont(childResource->GetFont());
549
550 #ifdef __WXMSW__
551 // Force the layout algorithm since the size changes the layout
552 if (control->IsKindOf(CLASSINFO(wxRadioBox)))
553 {
554 control->SetSize(-1, -1, -1, -1, wxSIZE_AUTO_WIDTH|wxSIZE_AUTO_HEIGHT);
555 }
556 #endif
557 }
558 }
559 return control;
560 }
561
562 /*
563 * Interpret database as a series of resources
564 */
565
566 bool wxResourceInterpretResources(wxResourceTable& table, wxExprDatabase& db)
567 {
568 wxNode *node = db.First();
569 while (node)
570 {
571 wxExpr *clause = (wxExpr *)node->Data();
572 wxString functor(clause->Functor());
573
574 wxItemResource *item = (wxItemResource *) NULL;
575 if (functor == wxT("dialog"))
576 item = wxResourceInterpretDialog(table, clause);
577 else if (functor == wxT("panel"))
578 item = wxResourceInterpretDialog(table, clause, TRUE);
579 else if (functor == wxT("menubar"))
580 item = wxResourceInterpretMenuBar(table, clause);
581 else if (functor == wxT("menu"))
582 item = wxResourceInterpretMenu(table, clause);
583 else if (functor == wxT("string"))
584 item = wxResourceInterpretString(table, clause);
585 else if (functor == wxT("bitmap"))
586 item = wxResourceInterpretBitmap(table, clause);
587 else if (functor == wxT("icon"))
588 item = wxResourceInterpretIcon(table, clause);
589
590 if (item)
591 {
592 // Remove any existing resource of same name
593 if (item->GetName() != wxT(""))
594 table.DeleteResource(item->GetName());
595 table.AddResource(item);
596 }
597 node = node->Next();
598 }
599 return TRUE;
600 }
601
602 static const wxChar *g_ValidControlClasses[] =
603 {
604 wxT("wxButton"),
605 wxT("wxBitmapButton"),
606 wxT("wxMessage"),
607 wxT("wxStaticText"),
608 wxT("wxStaticBitmap"),
609 wxT("wxText"),
610 wxT("wxTextCtrl"),
611 wxT("wxMultiText"),
612 wxT("wxListBox"),
613 wxT("wxRadioBox"),
614 wxT("wxRadioButton"),
615 wxT("wxCheckBox"),
616 wxT("wxBitmapCheckBox"),
617 wxT("wxGroupBox"),
618 wxT("wxStaticBox"),
619 wxT("wxSlider"),
620 wxT("wxGauge"),
621 wxT("wxScrollBar"),
622 wxT("wxChoice"),
623 wxT("wxComboBox")
624 };
625
626 static bool wxIsValidControlClass(const wxString& c)
627 {
628 for ( size_t i = 0; i < WXSIZEOF(g_ValidControlClasses); i++ )
629 {
630 if ( c == g_ValidControlClasses[i] )
631 return TRUE;
632 }
633 return FALSE;
634 }
635
636 wxItemResource *wxResourceInterpretDialog(wxResourceTable& table, wxExpr *expr, bool isPanel)
637 {
638 wxItemResource *dialogItem = new wxItemResource;
639 if (isPanel)
640 dialogItem->SetType(wxT("wxPanel"));
641 else
642 dialogItem->SetType(wxT("wxDialog"));
643 wxString style = wxT("");
644 wxString title = wxT("");
645 wxString name = wxT("");
646 wxString backColourHex = wxT("");
647 wxString labelColourHex = wxT("");
648 wxString buttonColourHex = wxT("");
649
650 long windowStyle = wxDEFAULT_DIALOG_STYLE;
651 if (isPanel)
652 windowStyle = 0;
653
654 int x = 0; int y = 0; int width = -1; int height = -1;
655 int isModal = 0;
656 wxExpr *labelFontExpr = (wxExpr *) NULL;
657 wxExpr *buttonFontExpr = (wxExpr *) NULL;
658 wxExpr *fontExpr = (wxExpr *) NULL;
659 expr->GetAttributeValue(wxT("style"), style);
660 expr->GetAttributeValue(wxT("name"), name);
661 expr->GetAttributeValue(wxT("title"), title);
662 expr->GetAttributeValue(wxT("x"), x);
663 expr->GetAttributeValue(wxT("y"), y);
664 expr->GetAttributeValue(wxT("width"), width);
665 expr->GetAttributeValue(wxT("height"), height);
666 expr->GetAttributeValue(wxT("modal"), isModal);
667 expr->GetAttributeValue(wxT("label_font"), &labelFontExpr);
668 expr->GetAttributeValue(wxT("button_font"), &buttonFontExpr);
669 expr->GetAttributeValue(wxT("font"), &fontExpr);
670 expr->GetAttributeValue(wxT("background_colour"), backColourHex);
671 expr->GetAttributeValue(wxT("label_colour"), labelColourHex);
672 expr->GetAttributeValue(wxT("button_colour"), buttonColourHex);
673
674 int useDialogUnits = 0;
675 expr->GetAttributeValue(wxT("use_dialog_units"), useDialogUnits);
676 if (useDialogUnits != 0)
677 dialogItem->SetResourceStyle(dialogItem->GetResourceStyle() | wxRESOURCE_DIALOG_UNITS);
678
679 int useDefaults = 0;
680 expr->GetAttributeValue(wxT("use_system_defaults"), useDefaults);
681 if (useDefaults != 0)
682 dialogItem->SetResourceStyle(dialogItem->GetResourceStyle() | wxRESOURCE_USE_DEFAULTS);
683
684 int id = 0;
685 expr->GetAttributeValue(wxT("id"), id);
686 dialogItem->SetId(id);
687
688 if (style != wxT(""))
689 {
690 windowStyle = wxParseWindowStyle(style);
691 }
692 dialogItem->SetStyle(windowStyle);
693 dialogItem->SetValue1(isModal);
694 if (windowStyle & wxDIALOG_MODAL) // Uses style in wxWin 2
695 dialogItem->SetValue1(TRUE);
696
697 dialogItem->SetName(name);
698 dialogItem->SetTitle(title);
699 dialogItem->SetSize(x, y, width, height);
700
701 // Check for wxWin 1.68-style specifications
702 if (style.Find(wxT("VERTICAL_LABEL")) != -1)
703 dialogItem->SetResourceStyle(dialogItem->GetResourceStyle() | wxRESOURCE_VERTICAL_LABEL);
704 else if (style.Find(wxT("HORIZONTAL_LABEL")) != -1)
705 dialogItem->SetResourceStyle(dialogItem->GetResourceStyle() | wxRESOURCE_HORIZONTAL_LABEL);
706
707 if (backColourHex != wxT(""))
708 {
709 int r = 0;
710 int g = 0;
711 int b = 0;
712 r = wxHexToDec(backColourHex.Mid(0, 2));
713 g = wxHexToDec(backColourHex.Mid(2, 2));
714 b = wxHexToDec(backColourHex.Mid(4, 2));
715 dialogItem->SetBackgroundColour(wxColour((unsigned char)r,(unsigned char)g,(unsigned char)b));
716 }
717 if (labelColourHex != wxT(""))
718 {
719 int r = 0;
720 int g = 0;
721 int b = 0;
722 r = wxHexToDec(labelColourHex.Mid(0, 2));
723 g = wxHexToDec(labelColourHex.Mid(2, 2));
724 b = wxHexToDec(labelColourHex.Mid(4, 2));
725 dialogItem->SetLabelColour(wxColour((unsigned char)r,(unsigned char)g,(unsigned char)b));
726 }
727 if (buttonColourHex != wxT(""))
728 {
729 int r = 0;
730 int g = 0;
731 int b = 0;
732 r = wxHexToDec(buttonColourHex.Mid(0, 2));
733 g = wxHexToDec(buttonColourHex.Mid(2, 2));
734 b = wxHexToDec(buttonColourHex.Mid(4, 2));
735 dialogItem->SetButtonColour(wxColour((unsigned char)r,(unsigned char)g,(unsigned char)b));
736 }
737
738 if (fontExpr)
739 dialogItem->SetFont(wxResourceInterpretFontSpec(fontExpr));
740 else if (buttonFontExpr)
741 dialogItem->SetFont(wxResourceInterpretFontSpec(buttonFontExpr));
742 else if (labelFontExpr)
743 dialogItem->SetFont(wxResourceInterpretFontSpec(labelFontExpr));
744
745 // Now parse all controls
746 wxExpr *controlExpr = expr->GetFirst();
747 while (controlExpr)
748 {
749 if (controlExpr->Number() == 3)
750 {
751 wxString controlKeyword(controlExpr->Nth(1)->StringValue());
752 if (controlKeyword != wxT("") && controlKeyword == wxT("control"))
753 {
754 // The value part: always a list.
755 wxExpr *listExpr = controlExpr->Nth(2);
756 if (listExpr->Type() == PrologList)
757 {
758 wxItemResource *controlItem = wxResourceInterpretControl(table, listExpr);
759 if (controlItem)
760 {
761 dialogItem->GetChildren().Append(controlItem);
762 }
763 }
764 }
765 }
766 controlExpr = controlExpr->GetNext();
767 }
768 return dialogItem;
769 }
770
771 wxItemResource *wxResourceInterpretControl(wxResourceTable& table, wxExpr *expr)
772 {
773 wxItemResource *controlItem = new wxItemResource;
774
775 // First, find the standard features of a control definition:
776 // [optional integer/string id], control name, title, style, name, x, y, width, height
777
778 wxString controlType;
779 wxString style;
780 wxString title;
781 wxString name;
782 int id = 0;
783 long windowStyle = 0;
784 int x = 0; int y = 0; int width = -1; int height = -1;
785 int count = 0;
786
787 wxExpr *expr1 = expr->Nth(0);
788
789 if ( expr1->Type() == PrologString || expr1->Type() == PrologWord )
790 {
791 if ( wxIsValidControlClass(expr1->StringValue()) )
792 {
793 count = 1;
794 controlType = expr1->StringValue();
795 }
796 else
797 {
798 wxString str(expr1->StringValue());
799 id = wxResourceGetIdentifier(str, &table);
800 if (id == 0)
801 {
802 wxLogWarning(_("Could not resolve control class or id '%s'. Use (non-zero) integer instead\n or provide #define (see manual for caveats)"),
803 (const wxChar*) expr1->StringValue());
804 delete controlItem;
805 return (wxItemResource *) NULL;
806 }
807 else
808 {
809 // Success - we have an id, so the 2nd element must be the control class.
810 controlType = expr->Nth(1)->StringValue();
811 count = 2;
812 }
813 }
814 }
815 else if (expr1->Type() == PrologInteger)
816 {
817 id = (int)expr1->IntegerValue();
818 // Success - we have an id, so the 2nd element must be the control class.
819 controlType = expr->Nth(1)->StringValue();
820 count = 2;
821 }
822
823 expr1 = expr->Nth(count);
824 count ++;
825 if ( expr1 )
826 title = expr1->StringValue();
827
828 expr1 = expr->Nth(count);
829 count ++;
830 if (expr1)
831 {
832 style = expr1->StringValue();
833 windowStyle = wxParseWindowStyle(style);
834 }
835
836 expr1 = expr->Nth(count);
837 count ++;
838 if (expr1)
839 name = expr1->StringValue();
840
841 expr1 = expr->Nth(count);
842 count ++;
843 if (expr1)
844 x = (int)expr1->IntegerValue();
845
846 expr1 = expr->Nth(count);
847 count ++;
848 if (expr1)
849 y = (int)expr1->IntegerValue();
850
851 expr1 = expr->Nth(count);
852 count ++;
853 if (expr1)
854 width = (int)expr1->IntegerValue();
855
856 expr1 = expr->Nth(count);
857 count ++;
858 if (expr1)
859 height = (int)expr1->IntegerValue();
860
861 controlItem->SetStyle(windowStyle);
862 controlItem->SetName(name);
863 controlItem->SetTitle(title);
864 controlItem->SetSize(x, y, width, height);
865 controlItem->SetType(controlType);
866 controlItem->SetId(id);
867
868 // Check for wxWin 1.68-style specifications
869 if (style.Find(wxT("VERTICAL_LABEL")) != -1)
870 controlItem->SetResourceStyle(controlItem->GetResourceStyle() | wxRESOURCE_VERTICAL_LABEL);
871 else if (style.Find(wxT("HORIZONTAL_LABEL")) != -1)
872 controlItem->SetResourceStyle(controlItem->GetResourceStyle() | wxRESOURCE_HORIZONTAL_LABEL);
873
874 if (controlType == wxT("wxButton"))
875 {
876 // Check for bitmap resource name (in case loading old-style resource file)
877 if (expr->Nth(count) && ((expr->Nth(count)->Type() == PrologString) || (expr->Nth(count)->Type() == PrologWord)))
878 {
879 wxString str(expr->Nth(count)->StringValue());
880 count ++;
881
882 if (str != wxT(""))
883 {
884 controlItem->SetValue4(str);
885 controlItem->SetType(wxT("wxBitmapButton"));
886 }
887 }
888 if (expr->Nth(count) && expr->Nth(count)->Type() == PrologList)
889 controlItem->SetFont(wxResourceInterpretFontSpec(expr->Nth(count)));
890 }
891 else if (controlType == wxT("wxBitmapButton"))
892 {
893 // Check for bitmap resource name
894 if (expr->Nth(count) && ((expr->Nth(count)->Type() == PrologString) || (expr->Nth(count)->Type() == PrologWord)))
895 {
896 wxString str(expr->Nth(count)->StringValue());
897 controlItem->SetValue4(str);
898 count ++;
899 if (expr->Nth(count) && expr->Nth(count)->Type() == PrologList)
900 controlItem->SetFont(wxResourceInterpretFontSpec(expr->Nth(count)));
901 }
902 }
903 else if (controlType == wxT("wxCheckBox"))
904 {
905 // Check for default value
906 if (expr->Nth(count) && (expr->Nth(count)->Type() == PrologInteger))
907 {
908 controlItem->SetValue1(expr->Nth(count)->IntegerValue());
909 count ++;
910 if (expr->Nth(count) && expr->Nth(count)->Type() == PrologList)
911 controlItem->SetFont(wxResourceInterpretFontSpec(expr->Nth(count)));
912 }
913 }
914 #if wxUSE_RADIOBTN
915 else if (controlType == wxT("wxRadioButton"))
916 {
917 // Check for default value
918 if (expr->Nth(count) && (expr->Nth(count)->Type() == PrologInteger))
919 {
920 controlItem->SetValue1(expr->Nth(count)->IntegerValue());
921 count ++;
922 if (expr->Nth(count) && expr->Nth(count)->Type() == PrologList)
923 controlItem->SetFont(wxResourceInterpretFontSpec(expr->Nth(count)));
924 }
925 }
926 #endif
927 else if (controlType == wxT("wxText") || controlType == wxT("wxTextCtrl") || controlType == wxT("wxMultiText"))
928 {
929 // Check for default value
930 if (expr->Nth(count) && ((expr->Nth(count)->Type() == PrologString) || (expr->Nth(count)->Type() == PrologWord)))
931 {
932 wxString str(expr->Nth(count)->StringValue());
933 controlItem->SetValue4(str);
934 count ++;
935
936 if (expr->Nth(count) && expr->Nth(count)->Type() == PrologList)
937 {
938 // controlItem->SetLabelFont(wxResourceInterpretFontSpec(expr->Nth(count)));
939 // Skip past the obsolete label font spec if there are two consecutive specs
940 if (expr->Nth(count+1) && expr->Nth(count+1)->Type() == PrologList)
941 count ++;
942 controlItem->SetFont(wxResourceInterpretFontSpec(expr->Nth(count)));
943 }
944 }
945 }
946 else if (controlType == wxT("wxMessage") || controlType == wxT("wxStaticText"))
947 {
948 // Check for bitmap resource name (in case it's an old-style .wxr file)
949 if (expr->Nth(count) && ((expr->Nth(count)->Type() == PrologString) || (expr->Nth(count)->Type() == PrologWord)))
950 {
951 wxString str(expr->Nth(count)->StringValue());
952 controlItem->SetValue4(str);
953 count ++;
954 controlItem->SetType(wxT("wxStaticText"));
955 }
956 if (expr->Nth(count) && expr->Nth(count)->Type() == PrologList)
957 controlItem->SetFont(wxResourceInterpretFontSpec(expr->Nth(count)));
958 }
959 else if (controlType == wxT("wxStaticBitmap"))
960 {
961 // Check for bitmap resource name
962 if (expr->Nth(count) && ((expr->Nth(count)->Type() == PrologString) || (expr->Nth(count)->Type() == PrologWord)))
963 {
964 wxString str(expr->Nth(count)->StringValue());
965 controlItem->SetValue4(str);
966 count ++;
967 }
968 if (expr->Nth(count) && expr->Nth(count)->Type() == PrologList)
969 controlItem->SetFont(wxResourceInterpretFontSpec(expr->Nth(count)));
970 }
971 else if (controlType == wxT("wxGroupBox") || controlType == wxT("wxStaticBox"))
972 {
973 if (expr->Nth(count) && expr->Nth(count)->Type() == PrologList)
974 controlItem->SetFont(wxResourceInterpretFontSpec(expr->Nth(count)));
975 }
976 else if (controlType == wxT("wxGauge"))
977 {
978 // Check for default value
979 if (expr->Nth(count) && (expr->Nth(count)->Type() == PrologInteger))
980 {
981 controlItem->SetValue1(expr->Nth(count)->IntegerValue());
982 count ++;
983
984 // Check for range
985 if (expr->Nth(count) && (expr->Nth(count)->Type() == PrologInteger))
986 {
987 controlItem->SetValue2(expr->Nth(count)->IntegerValue());
988 count ++;
989
990 if (expr->Nth(count) && expr->Nth(count)->Type() == PrologList)
991 {
992 // Skip past the obsolete label font spec if there are two consecutive specs
993 if (expr->Nth(count+1) && expr->Nth(count+1)->Type() == PrologList)
994 count ++;
995 controlItem->SetFont(wxResourceInterpretFontSpec(expr->Nth(count)));
996 }
997 }
998 }
999 }
1000 else if (controlType == wxT("wxSlider"))
1001 {
1002 // Check for default value
1003 if (expr->Nth(count) && (expr->Nth(count)->Type() == PrologInteger))
1004 {
1005 controlItem->SetValue1(expr->Nth(count)->IntegerValue());
1006 count ++;
1007
1008 // Check for min
1009 if (expr->Nth(count) && (expr->Nth(count)->Type() == PrologInteger))
1010 {
1011 controlItem->SetValue2(expr->Nth(count)->IntegerValue());
1012 count ++;
1013
1014 // Check for max
1015 if (expr->Nth(count) && (expr->Nth(count)->Type() == PrologInteger))
1016 {
1017 controlItem->SetValue3(expr->Nth(count)->IntegerValue());
1018 count ++;
1019
1020 if (expr->Nth(count) && expr->Nth(count)->Type() == PrologList)
1021 {
1022 // controlItem->SetLabelFont(wxResourceInterpretFontSpec(expr->Nth(count)));
1023 // do nothing
1024 count ++;
1025
1026 if (expr->Nth(count) && expr->Nth(count)->Type() == PrologList)
1027 controlItem->SetFont(wxResourceInterpretFontSpec(expr->Nth(count)));
1028 }
1029 }
1030 }
1031 }
1032 }
1033 else if (controlType == wxT("wxScrollBar"))
1034 {
1035 // DEFAULT VALUE
1036 if (expr->Nth(count) && (expr->Nth(count)->Type() == PrologInteger))
1037 {
1038 controlItem->SetValue1(expr->Nth(count)->IntegerValue());
1039 count ++;
1040
1041 // PAGE LENGTH
1042 if (expr->Nth(count) && (expr->Nth(count)->Type() == PrologInteger))
1043 {
1044 controlItem->SetValue2(expr->Nth(count)->IntegerValue());
1045 count ++;
1046
1047 // OBJECT LENGTH
1048 if (expr->Nth(count) && (expr->Nth(count)->Type() == PrologInteger))
1049 {
1050 controlItem->SetValue3(expr->Nth(count)->IntegerValue());
1051 count ++;
1052
1053 // VIEW LENGTH
1054 if (expr->Nth(count) && (expr->Nth(count)->Type() == PrologInteger))
1055 controlItem->SetValue5(expr->Nth(count)->IntegerValue());
1056 }
1057 }
1058 }
1059 }
1060 else if (controlType == wxT("wxListBox"))
1061 {
1062 wxExpr *valueList = (wxExpr *) NULL;
1063
1064 if (((valueList = expr->Nth(count)) != 0) && (valueList->Type() == PrologList))
1065 {
1066 wxStringList stringList;
1067 wxExpr *stringExpr = valueList->GetFirst();
1068 while (stringExpr)
1069 {
1070 stringList.Add(stringExpr->StringValue());
1071 stringExpr = stringExpr->GetNext();
1072 }
1073 controlItem->SetStringValues(stringList);
1074 count ++;
1075 // This is now obsolete: it's in the window style.
1076 // Check for wxSINGLE/wxMULTIPLE
1077 wxExpr *mult = (wxExpr *) NULL;
1078 /*
1079 controlItem->SetValue1(wxLB_SINGLE);
1080 */
1081 if (((mult = expr->Nth(count)) != 0) && ((mult->Type() == PrologString)||(mult->Type() == PrologWord)))
1082 {
1083 /*
1084 wxString m(mult->StringValue());
1085 if (m == "wxLB_MULTIPLE")
1086 controlItem->SetValue1(wxLB_MULTIPLE);
1087 else if (m == "wxLB_EXTENDED")
1088 controlItem->SetValue1(wxLB_EXTENDED);
1089 */
1090 // Ignore the value
1091 count ++;
1092 }
1093 if (expr->Nth(count) && expr->Nth(count)->Type() == PrologList)
1094 {
1095 // Skip past the obsolete label font spec if there are two consecutive specs
1096 if (expr->Nth(count+1) && expr->Nth(count+1)->Type() == PrologList)
1097 count ++;
1098 controlItem->SetFont(wxResourceInterpretFontSpec(expr->Nth(count)));
1099 }
1100 }
1101 }
1102 else if (controlType == wxT("wxChoice"))
1103 {
1104 wxExpr *valueList = (wxExpr *) NULL;
1105 // Check for default value list
1106 if (((valueList = expr->Nth(count)) != 0) && (valueList->Type() == PrologList))
1107 {
1108 wxStringList stringList;
1109 wxExpr *stringExpr = valueList->GetFirst();
1110 while (stringExpr)
1111 {
1112 stringList.Add(stringExpr->StringValue());
1113 stringExpr = stringExpr->GetNext();
1114 }
1115 controlItem->SetStringValues(stringList);
1116
1117 count ++;
1118
1119 if (expr->Nth(count) && expr->Nth(count)->Type() == PrologList)
1120 {
1121 // Skip past the obsolete label font spec if there are two consecutive specs
1122 if (expr->Nth(count+1) && expr->Nth(count+1)->Type() == PrologList)
1123 count ++;
1124 controlItem->SetFont(wxResourceInterpretFontSpec(expr->Nth(count)));
1125 }
1126 }
1127 }
1128 #if wxUSE_COMBOBOX
1129 else if (controlType == wxT("wxComboBox"))
1130 {
1131 wxExpr *textValue = expr->Nth(count);
1132 if (textValue && (textValue->Type() == PrologString || textValue->Type() == PrologWord))
1133 {
1134 wxString str(textValue->StringValue());
1135 controlItem->SetValue4(str);
1136
1137 count ++;
1138
1139 wxExpr *valueList = (wxExpr *) NULL;
1140 // Check for default value list
1141 if (((valueList = expr->Nth(count)) != 0) && (valueList->Type() == PrologList))
1142 {
1143 wxStringList stringList;
1144 wxExpr *stringExpr = valueList->GetFirst();
1145 while (stringExpr)
1146 {
1147 stringList.Add(stringExpr->StringValue());
1148 stringExpr = stringExpr->GetNext();
1149 }
1150 controlItem->SetStringValues(stringList);
1151
1152 count ++;
1153
1154 if (expr->Nth(count) && expr->Nth(count)->Type() == PrologList)
1155 {
1156 // Skip past the obsolete label font spec if there are two consecutive specs
1157 if (expr->Nth(count+1) && expr->Nth(count+1)->Type() == PrologList)
1158 count ++;
1159 controlItem->SetFont(wxResourceInterpretFontSpec(expr->Nth(count)));
1160 }
1161 }
1162 }
1163 }
1164 #endif
1165 #if 1
1166 else if (controlType == wxT("wxRadioBox"))
1167 {
1168 wxExpr *valueList = (wxExpr *) NULL;
1169 // Check for default value list
1170 if (((valueList = expr->Nth(count)) != 0) && (valueList->Type() == PrologList))
1171 {
1172 wxStringList stringList;
1173 wxExpr *stringExpr = valueList->GetFirst();
1174 while (stringExpr)
1175 {
1176 stringList.Add(stringExpr->StringValue());
1177 stringExpr = stringExpr->GetNext();
1178 }
1179 controlItem->SetStringValues(stringList);
1180 count ++;
1181
1182 // majorDim (number of rows or cols)
1183 if (expr->Nth(count) && (expr->Nth(count)->Type() == PrologInteger))
1184 {
1185 controlItem->SetValue1(expr->Nth(count)->IntegerValue());
1186 count ++;
1187 }
1188 else
1189 controlItem->SetValue1(0);
1190
1191 if (expr->Nth(count) && expr->Nth(count)->Type() == PrologList)
1192 {
1193 // Skip past the obsolete label font spec if there are two consecutive specs
1194 if (expr->Nth(count+1) && expr->Nth(count+1)->Type() == PrologList)
1195 count ++;
1196 controlItem->SetFont(wxResourceInterpretFontSpec(expr->Nth(count)));
1197 }
1198 }
1199 }
1200 #endif
1201 else
1202 {
1203 delete controlItem;
1204 return (wxItemResource *) NULL;
1205 }
1206 return controlItem;
1207 }
1208
1209 // Forward declaration
1210 wxItemResource *wxResourceInterpretMenu1(wxResourceTable& table, wxExpr *expr);
1211
1212 /*
1213 * Interpet a menu item
1214 */
1215
1216 wxItemResource *wxResourceInterpretMenuItem(wxResourceTable& table, wxExpr *expr)
1217 {
1218 wxItemResource *item = new wxItemResource;
1219
1220 wxExpr *labelExpr = expr->Nth(0);
1221 wxExpr *idExpr = expr->Nth(1);
1222 wxExpr *helpExpr = expr->Nth(2);
1223 wxExpr *checkableExpr = expr->Nth(3);
1224
1225 // Further keywords/attributes to follow sometime...
1226 if (expr->Number() == 0)
1227 {
1228 // item->SetType(wxRESOURCE_TYPE_SEPARATOR);
1229 item->SetType(wxT("wxMenuSeparator"));
1230 return item;
1231 }
1232 else
1233 {
1234 // item->SetType(wxTYPE_MENU); // Well, menu item, but doesn't matter.
1235 item->SetType(wxT("wxMenu")); // Well, menu item, but doesn't matter.
1236 if (labelExpr)
1237 {
1238 wxString str(labelExpr->StringValue());
1239 item->SetTitle(str);
1240 }
1241 if (idExpr)
1242 {
1243 int id = 0;
1244 // If a string or word, must look up in identifier table.
1245 if ((idExpr->Type() == PrologString) || (idExpr->Type() == PrologWord))
1246 {
1247 wxString str(idExpr->StringValue());
1248 id = wxResourceGetIdentifier(str, &table);
1249 if (id == 0)
1250 {
1251 wxLogWarning(_("Could not resolve menu id '%s'. Use (non-zero) integer instead\nor provide #define (see manual for caveats)"),
1252 (const wxChar*) idExpr->StringValue());
1253 }
1254 }
1255 else if (idExpr->Type() == PrologInteger)
1256 id = (int)idExpr->IntegerValue();
1257 item->SetValue1(id);
1258 }
1259 if (helpExpr)
1260 {
1261 wxString str(helpExpr->StringValue());
1262 item->SetValue4(str);
1263 }
1264 if (checkableExpr)
1265 item->SetValue2(checkableExpr->IntegerValue());
1266
1267 // Find the first expression that's a list, for submenu
1268 wxExpr *subMenuExpr = expr->GetFirst();
1269 while (subMenuExpr && (subMenuExpr->Type() != PrologList))
1270 subMenuExpr = subMenuExpr->GetNext();
1271
1272 while (subMenuExpr)
1273 {
1274 wxItemResource *child = wxResourceInterpretMenuItem(table, subMenuExpr);
1275 item->GetChildren().Append(child);
1276 subMenuExpr = subMenuExpr->GetNext();
1277 }
1278 }
1279 return item;
1280 }
1281
1282 /*
1283 * Interpret a nested list as a menu
1284 */
1285 /*
1286 wxItemResource *wxResourceInterpretMenu1(wxResourceTable& table, wxExpr *expr)
1287 {
1288 wxItemResource *menu = new wxItemResource;
1289 // menu->SetType(wxTYPE_MENU);
1290 menu->SetType("wxMenu");
1291 wxExpr *element = expr->GetFirst();
1292 while (element)
1293 {
1294 wxItemResource *item = wxResourceInterpretMenuItem(table, element);
1295 if (item)
1296 menu->GetChildren().Append(item);
1297 element = element->GetNext();
1298 }
1299 return menu;
1300 }
1301 */
1302
1303 wxItemResource *wxResourceInterpretMenu(wxResourceTable& table, wxExpr *expr)
1304 {
1305 wxExpr *listExpr = (wxExpr *) NULL;
1306 expr->GetAttributeValue(wxT("menu"), &listExpr);
1307 if (!listExpr)
1308 return (wxItemResource *) NULL;
1309
1310 wxItemResource *menuResource = wxResourceInterpretMenuItem(table, listExpr);
1311
1312 if (!menuResource)
1313 return (wxItemResource *) NULL;
1314
1315 wxString name;
1316 if (expr->GetAttributeValue(wxT("name"), name))
1317 {
1318 menuResource->SetName(name);
1319 }
1320
1321 return menuResource;
1322 }
1323
1324 wxItemResource *wxResourceInterpretMenuBar(wxResourceTable& table, wxExpr *expr)
1325 {
1326 wxExpr *listExpr = (wxExpr *) NULL;
1327 expr->GetAttributeValue(wxT("menu"), &listExpr);
1328 if (!listExpr)
1329 return (wxItemResource *) NULL;
1330
1331 wxItemResource *resource = new wxItemResource;
1332 resource->SetType(wxT("wxMenu"));
1333 // resource->SetType(wxTYPE_MENU);
1334
1335 wxExpr *element = listExpr->GetFirst();
1336 while (element)
1337 {
1338 wxItemResource *menuResource = wxResourceInterpretMenuItem(table, listExpr);
1339 resource->GetChildren().Append(menuResource);
1340 element = element->GetNext();
1341 }
1342
1343 wxString name;
1344 if (expr->GetAttributeValue(wxT("name"), name))
1345 {
1346 resource->SetName(name);
1347 }
1348
1349 return resource;
1350 }
1351
1352 wxItemResource *wxResourceInterpretString(wxResourceTable& WXUNUSED(table), wxExpr *WXUNUSED(expr))
1353 {
1354 return (wxItemResource *) NULL;
1355 }
1356
1357 wxItemResource *wxResourceInterpretBitmap(wxResourceTable& WXUNUSED(table), wxExpr *expr)
1358 {
1359 wxItemResource *bitmapItem = new wxItemResource;
1360 // bitmapItem->SetType(wxTYPE_BITMAP);
1361 bitmapItem->SetType(wxT("wxBitmap"));
1362 wxString name;
1363 if (expr->GetAttributeValue(wxT("name"), name))
1364 {
1365 bitmapItem->SetName(name);
1366 }
1367 // Now parse all bitmap specifications
1368 wxExpr *bitmapExpr = expr->GetFirst();
1369 while (bitmapExpr)
1370 {
1371 if (bitmapExpr->Number() == 3)
1372 {
1373 wxString bitmapKeyword(bitmapExpr->Nth(1)->StringValue());
1374 if (bitmapKeyword == wxT("bitmap") || bitmapKeyword == wxT("icon"))
1375 {
1376 // The value part: always a list.
1377 wxExpr *listExpr = bitmapExpr->Nth(2);
1378 if (listExpr->Type() == PrologList)
1379 {
1380 wxItemResource *bitmapSpec = new wxItemResource;
1381 // bitmapSpec->SetType(wxTYPE_BITMAP);
1382 bitmapSpec->SetType(wxT("wxBitmap"));
1383
1384 // List is of form: [filename, bitmaptype, platform, colours, xresolution, yresolution]
1385 // where everything after 'filename' is optional.
1386 wxExpr *nameExpr = listExpr->Nth(0);
1387 wxExpr *typeExpr = listExpr->Nth(1);
1388 wxExpr *platformExpr = listExpr->Nth(2);
1389 wxExpr *coloursExpr = listExpr->Nth(3);
1390 wxExpr *xresExpr = listExpr->Nth(4);
1391 wxExpr *yresExpr = listExpr->Nth(5);
1392 if (nameExpr && nameExpr->StringValue() != wxT(""))
1393 {
1394 bitmapSpec->SetName(nameExpr->StringValue());
1395 }
1396 if (typeExpr && typeExpr->StringValue() != wxT(""))
1397 {
1398 bitmapSpec->SetValue1(wxParseWindowStyle(typeExpr->StringValue()));
1399 }
1400 else
1401 bitmapSpec->SetValue1(0);
1402
1403 if (platformExpr && platformExpr->StringValue() != wxT(""))
1404 {
1405 wxString plat(platformExpr->StringValue());
1406 if (plat == wxT("windows") || plat == wxT("WINDOWS"))
1407 bitmapSpec->SetValue2(RESOURCE_PLATFORM_WINDOWS);
1408 else if (plat == wxT("x") || plat == wxT("X"))
1409 bitmapSpec->SetValue2(RESOURCE_PLATFORM_X);
1410 else if (plat == wxT("mac") || plat == wxT("MAC"))
1411 bitmapSpec->SetValue2(RESOURCE_PLATFORM_MAC);
1412 else
1413 bitmapSpec->SetValue2(RESOURCE_PLATFORM_ANY);
1414 }
1415 else
1416 bitmapSpec->SetValue2(RESOURCE_PLATFORM_ANY);
1417
1418 if (coloursExpr)
1419 bitmapSpec->SetValue3(coloursExpr->IntegerValue());
1420 int xres = 0;
1421 int yres = 0;
1422 if (xresExpr)
1423 xres = (int)xresExpr->IntegerValue();
1424 if (yresExpr)
1425 yres = (int)yresExpr->IntegerValue();
1426 bitmapSpec->SetSize(0, 0, xres, yres);
1427
1428 bitmapItem->GetChildren().Append(bitmapSpec);
1429 }
1430 }
1431 }
1432 bitmapExpr = bitmapExpr->GetNext();
1433 }
1434
1435 return bitmapItem;
1436 }
1437
1438 wxItemResource *wxResourceInterpretIcon(wxResourceTable& table, wxExpr *expr)
1439 {
1440 wxItemResource *item = wxResourceInterpretBitmap(table, expr);
1441 if (item)
1442 {
1443 // item->SetType(wxTYPE_ICON);
1444 item->SetType(wxT("wxIcon"));
1445 return item;
1446 }
1447 else
1448 return (wxItemResource *) NULL;
1449 }
1450
1451 // Interpret list expression as a font
1452 wxFont wxResourceInterpretFontSpec(wxExpr *expr)
1453 {
1454 if (expr->Type() != PrologList)
1455 return wxNullFont;
1456
1457 int point = 10;
1458 int family = wxSWISS;
1459 int style = wxNORMAL;
1460 int weight = wxNORMAL;
1461 int underline = 0;
1462 wxString faceName(wxT(""));
1463
1464 wxExpr *pointExpr = expr->Nth(0);
1465 wxExpr *familyExpr = expr->Nth(1);
1466 wxExpr *styleExpr = expr->Nth(2);
1467 wxExpr *weightExpr = expr->Nth(3);
1468 wxExpr *underlineExpr = expr->Nth(4);
1469 wxExpr *faceNameExpr = expr->Nth(5);
1470 if (pointExpr)
1471 point = (int)pointExpr->IntegerValue();
1472
1473 wxString str;
1474 if (familyExpr)
1475 {
1476 str = familyExpr->StringValue();
1477 family = (int)wxParseWindowStyle(str);
1478 }
1479 if (styleExpr)
1480 {
1481 str = styleExpr->StringValue();
1482 style = (int)wxParseWindowStyle(str);
1483 }
1484 if (weightExpr)
1485 {
1486 str = weightExpr->StringValue();
1487 weight = (int)wxParseWindowStyle(str);
1488 }
1489 if (underlineExpr)
1490 underline = (int)underlineExpr->IntegerValue();
1491 if (faceNameExpr)
1492 faceName = faceNameExpr->StringValue();
1493
1494 return *wxTheFontList->FindOrCreateFont(point, family, style, weight,
1495 (underline != 0), faceName);
1496 }
1497
1498 // Separate file for the remainder of this, for BC++/Win16
1499
1500 #if !((defined(__BORLANDC__) || defined(__SC__)) && defined(__WIN16__))
1501 /*
1502 * (Re)allocate buffer for reading in from resource file
1503 */
1504
1505 bool wxReallocateResourceBuffer()
1506 {
1507 if (!wxResourceBuffer)
1508 {
1509 wxResourceBufferSize = 1000;
1510 wxResourceBuffer = new char[wxResourceBufferSize];
1511 return TRUE;
1512 }
1513 if (wxResourceBuffer)
1514 {
1515 long newSize = wxResourceBufferSize + 1000;
1516 char *tmp = new char[(int)newSize];
1517 strncpy(tmp, wxResourceBuffer, (int)wxResourceBufferCount);
1518 delete[] wxResourceBuffer;
1519 wxResourceBuffer = tmp;
1520 wxResourceBufferSize = newSize;
1521 }
1522 return TRUE;
1523 }
1524
1525 static bool wxEatWhiteSpace(FILE *fd)
1526 {
1527 int ch = 0;
1528
1529 while ((ch = getc(fd)) != EOF)
1530 {
1531 switch (ch)
1532 {
1533 case ' ':
1534 case 0x0a:
1535 case 0x0d:
1536 case 0x09:
1537 break;
1538 case '/':
1539 {
1540 int prev_ch = ch;
1541 ch = getc(fd);
1542 if (ch == EOF)
1543 {
1544 ungetc(prev_ch, fd);
1545 return TRUE;
1546 }
1547
1548 if (ch == '*')
1549 {
1550 // Eat C comment
1551 prev_ch = 0;
1552 while ((ch = getc(fd)) != EOF)
1553 {
1554 if (ch == '/' && prev_ch == '*')
1555 break;
1556 prev_ch = ch;
1557 }
1558 }
1559 else if (ch == '/')
1560 {
1561 // Eat C++ comment
1562 static char buffer[255];
1563 fgets(buffer, 255, fd);
1564 }
1565 else
1566 {
1567 ungetc(prev_ch, fd);
1568 ungetc(ch, fd);
1569 return TRUE;
1570 }
1571 }
1572 break;
1573 default:
1574 ungetc(ch, fd);
1575 return TRUE;
1576
1577 }
1578 }
1579 return FALSE;
1580 }
1581 static bool wxEatWhiteSpace(wxInputStream *is)
1582 {
1583 int ch = is->GetC() ;
1584 if ((ch != ' ') && (ch != '/') && (ch != ' ') && (ch != 10) && (ch != 13) && (ch != 9))
1585 {
1586 is->Ungetch(ch);
1587 return TRUE;
1588 }
1589
1590 // Eat whitespace
1591 while (ch == ' ' || ch == 10 || ch == 13 || ch == 9)
1592 ch = is->GetC();
1593 // Check for comment
1594 if (ch == '/')
1595 {
1596 ch = is->GetC();
1597 if (ch == '*')
1598 {
1599 bool finished = FALSE;
1600 while (!finished)
1601 {
1602 ch = is->GetC();
1603 if (ch == EOF)
1604 return FALSE;
1605 if (ch == '*')
1606 {
1607 int newCh = is->GetC();
1608 if (newCh == '/')
1609 finished = TRUE;
1610 else
1611 {
1612 is->Ungetch(ch);
1613 }
1614 }
1615 }
1616 }
1617 else // False alarm
1618 return FALSE;
1619 }
1620 else
1621 is->Ungetch(ch);
1622 return wxEatWhiteSpace(is);
1623 }
1624
1625 bool wxGetResourceToken(FILE *fd)
1626 {
1627 if (!wxResourceBuffer)
1628 wxReallocateResourceBuffer();
1629 wxResourceBuffer[0] = 0;
1630 wxEatWhiteSpace(fd);
1631
1632 int ch = getc(fd);
1633 if (ch == '"')
1634 {
1635 // Get string
1636 wxResourceBufferCount = 0;
1637 ch = getc(fd);
1638 while (ch != '"')
1639 {
1640 int actualCh = ch;
1641 if (ch == EOF)
1642 {
1643 wxResourceBuffer[wxResourceBufferCount] = 0;
1644 return FALSE;
1645 }
1646 // Escaped characters
1647 else if (ch == '\\')
1648 {
1649 int newCh = getc(fd);
1650 if (newCh == '"')
1651 actualCh = '"';
1652 else if (newCh == 10)
1653 actualCh = 10;
1654 else
1655 {
1656 ungetc(newCh, fd);
1657 }
1658 }
1659
1660 if (wxResourceBufferCount >= wxResourceBufferSize-1)
1661 wxReallocateResourceBuffer();
1662 wxResourceBuffer[wxResourceBufferCount] = (char)actualCh;
1663 wxResourceBufferCount ++;
1664 ch = getc(fd);
1665 }
1666 wxResourceBuffer[wxResourceBufferCount] = 0;
1667 }
1668 else
1669 {
1670 wxResourceBufferCount = 0;
1671 // Any other token
1672 while (ch != ' ' && ch != EOF && ch != ' ' && ch != 13 && ch != 9 && ch != 10)
1673 {
1674 if (wxResourceBufferCount >= wxResourceBufferSize-1)
1675 wxReallocateResourceBuffer();
1676 wxResourceBuffer[wxResourceBufferCount] = (char)ch;
1677 wxResourceBufferCount ++;
1678
1679 ch = getc(fd);
1680 }
1681 wxResourceBuffer[wxResourceBufferCount] = 0;
1682 if (ch == EOF)
1683 return FALSE;
1684 }
1685 return TRUE;
1686 }
1687
1688 bool wxGetResourceToken(wxInputStream *is)
1689 {
1690 if (!wxResourceBuffer)
1691 wxReallocateResourceBuffer();
1692 wxResourceBuffer[0] = 0;
1693 wxEatWhiteSpace(is);
1694
1695 int ch = is->GetC() ;
1696 if (ch == '"')
1697 {
1698 // Get string
1699 wxResourceBufferCount = 0;
1700 ch = is->GetC();
1701 while (ch != '"')
1702 {
1703 int actualCh = ch;
1704 if (ch == EOF)
1705 {
1706 wxResourceBuffer[wxResourceBufferCount] = 0;
1707 return FALSE;
1708 }
1709 // Escaped characters
1710 else if (ch == '\\')
1711 {
1712 int newCh = is->GetC();
1713 if (newCh == '"')
1714 actualCh = '"';
1715 else if (newCh == 10)
1716 actualCh = 10;
1717 else if (newCh == 13) // mac
1718 actualCh = 10;
1719 else
1720 {
1721 is->Ungetch(newCh);
1722 }
1723 }
1724
1725 if (wxResourceBufferCount >= wxResourceBufferSize-1)
1726 wxReallocateResourceBuffer();
1727 wxResourceBuffer[wxResourceBufferCount] = (char)actualCh;
1728 wxResourceBufferCount ++;
1729 ch = is->GetC();
1730 }
1731 wxResourceBuffer[wxResourceBufferCount] = 0;
1732 }
1733 else
1734 {
1735 wxResourceBufferCount = 0;
1736 // Any other token
1737 while (ch != ' ' && ch != EOF && ch != ' ' && ch != 13 && ch != 9 && ch != 10)
1738 {
1739 if (wxResourceBufferCount >= wxResourceBufferSize-1)
1740 wxReallocateResourceBuffer();
1741 wxResourceBuffer[wxResourceBufferCount] = (char)ch;
1742 wxResourceBufferCount ++;
1743
1744 ch = is->GetC();
1745 }
1746 wxResourceBuffer[wxResourceBufferCount] = 0;
1747 if (ch == EOF)
1748 return FALSE;
1749 }
1750 return TRUE;
1751 }
1752
1753 /*
1754 * Files are in form:
1755 static char *name = "....";
1756 with possible comments.
1757 */
1758
1759 bool wxResourceReadOneResource(FILE *fd, wxExprDatabase& db, bool *eof, wxResourceTable *table)
1760 {
1761 if (!table)
1762 table = wxDefaultResourceTable;
1763
1764 // static or #define
1765 if (!wxGetResourceToken(fd))
1766 {
1767 *eof = TRUE;
1768 return FALSE;
1769 }
1770
1771 if (strcmp(wxResourceBuffer, "#define") == 0)
1772 {
1773 wxGetResourceToken(fd);
1774 wxChar *name = copystring(wxConvCurrent->cMB2WX(wxResourceBuffer));
1775 wxGetResourceToken(fd);
1776 wxChar *value = copystring(wxConvCurrent->cMB2WX(wxResourceBuffer));
1777 if (wxIsdigit(value[0]))
1778 {
1779 int val = (int)wxAtol(value);
1780 wxResourceAddIdentifier(name, val, table);
1781 }
1782 else
1783 {
1784 wxLogWarning(_("#define %s must be an integer."), name);
1785 delete[] name;
1786 delete[] value;
1787 return FALSE;
1788 }
1789 delete[] name;
1790 delete[] value;
1791
1792 return TRUE;
1793 }
1794 else if (strcmp(wxResourceBuffer, "#include") == 0)
1795 {
1796 wxGetResourceToken(fd);
1797 wxChar *name = copystring(wxConvCurrent->cMB2WX(wxResourceBuffer));
1798 wxChar *actualName = name;
1799 if (name[0] == wxT('"'))
1800 actualName = name + 1;
1801 int len = wxStrlen(name);
1802 if ((len > 0) && (name[len-1] == wxT('"')))
1803 name[len-1] = 0;
1804 if (!wxResourceParseIncludeFile(actualName, table))
1805 {
1806 wxLogWarning(_("Could not find resource include file %s."), actualName);
1807 }
1808 delete[] name;
1809 return TRUE;
1810 }
1811 else if (strcmp(wxResourceBuffer, "static") != 0)
1812 {
1813 wxChar buf[300];
1814 wxStrcpy(buf, _("Found "));
1815 wxStrncat(buf, wxConvCurrent->cMB2WX(wxResourceBuffer), 30);
1816 wxStrcat(buf, _(", expected static, #include or #define\nwhilst parsing resource."));
1817 wxLogWarning(buf);
1818 return FALSE;
1819 }
1820
1821 // char
1822 if (!wxGetResourceToken(fd))
1823 {
1824 wxLogWarning(_("Unexpected end of file whilst parsing resource."));
1825 *eof = TRUE;
1826 return FALSE;
1827 }
1828
1829 if (strcmp(wxResourceBuffer, "char") != 0)
1830 {
1831 wxLogWarning(_("Expected 'char' whilst parsing resource."));
1832 return FALSE;
1833 }
1834
1835 // *name
1836 if (!wxGetResourceToken(fd))
1837 {
1838 wxLogWarning(_("Unexpected end of file whilst parsing resource."));
1839 *eof = TRUE;
1840 return FALSE;
1841 }
1842
1843 if (wxResourceBuffer[0] != '*')
1844 {
1845 wxLogWarning(_("Expected '*' whilst parsing resource."));
1846 return FALSE;
1847 }
1848 wxChar nameBuf[100];
1849 wxMB2WX(nameBuf, wxResourceBuffer+1, 99);
1850 nameBuf[99] = 0;
1851
1852 // =
1853 if (!wxGetResourceToken(fd))
1854 {
1855 wxLogWarning(_("Unexpected end of file whilst parsing resource."));
1856 *eof = TRUE;
1857 return FALSE;
1858 }
1859
1860 if (strcmp(wxResourceBuffer, "=") != 0)
1861 {
1862 wxLogWarning(_("Expected '=' whilst parsing resource."));
1863 return FALSE;
1864 }
1865
1866 // String
1867 if (!wxGetResourceToken(fd))
1868 {
1869 wxLogWarning(_("Unexpected end of file whilst parsing resource."));
1870 *eof = TRUE;
1871 return FALSE;
1872 }
1873 else
1874 {
1875 if (!db.ReadPrologFromString(wxResourceBuffer))
1876 {
1877 wxLogWarning(_("%s: ill-formed resource file syntax."), nameBuf);
1878 return FALSE;
1879 }
1880 }
1881 // Semicolon
1882 if (!wxGetResourceToken(fd))
1883 {
1884 *eof = TRUE;
1885 }
1886 return TRUE;
1887 }
1888
1889 bool wxResourceReadOneResource(wxInputStream *fd, wxExprDatabase& db, bool *eof, wxResourceTable *table)
1890 {
1891 if (!table)
1892 table = wxDefaultResourceTable;
1893
1894 // static or #define
1895 if (!wxGetResourceToken(fd))
1896 {
1897 *eof = TRUE;
1898 return FALSE;
1899 }
1900
1901 if (strcmp(wxResourceBuffer, "#define") == 0)
1902 {
1903 wxGetResourceToken(fd);
1904 wxChar *name = copystring(wxConvLibc.cMB2WX(wxResourceBuffer));
1905 wxGetResourceToken(fd);
1906 wxChar *value = copystring(wxConvLibc.cMB2WX(wxResourceBuffer));
1907 if (wxIsalpha(value[0]))
1908 {
1909 int val = (int)wxAtol(value);
1910 wxResourceAddIdentifier(name, val, table);
1911 }
1912 else
1913 {
1914 wxLogWarning(_("#define %s must be an integer."), name);
1915 delete[] name;
1916 delete[] value;
1917 return FALSE;
1918 }
1919 delete[] name;
1920 delete[] value;
1921
1922 return TRUE;
1923 }
1924 else if (strcmp(wxResourceBuffer, "#include") == 0)
1925 {
1926 wxGetResourceToken(fd);
1927 wxChar *name = copystring(wxConvLibc.cMB2WX(wxResourceBuffer));
1928 wxChar *actualName = name;
1929 if (name[0] == wxT('"'))
1930 actualName = name + 1;
1931 int len = wxStrlen(name);
1932 if ((len > 0) && (name[len-1] == wxT('"')))
1933 name[len-1] = 0;
1934 if (!wxResourceParseIncludeFile(actualName, table))
1935 {
1936 wxLogWarning(_("Could not find resource include file %s."), actualName);
1937 }
1938 delete[] name;
1939 return TRUE;
1940 }
1941 else if (strcmp(wxResourceBuffer, "static") != 0)
1942 {
1943 wxChar buf[300];
1944 wxStrcpy(buf, _("Found "));
1945 wxStrncat(buf, wxConvLibc.cMB2WX(wxResourceBuffer), 30);
1946 wxStrcat(buf, _(", expected static, #include or #define\nwhilst parsing resource."));
1947 wxLogWarning(buf);
1948 return FALSE;
1949 }
1950
1951 // char
1952 if (!wxGetResourceToken(fd))
1953 {
1954 wxLogWarning(_("Unexpected end of file whilst parsing resource."));
1955 *eof = TRUE;
1956 return FALSE;
1957 }
1958
1959 if (strcmp(wxResourceBuffer, "char") != 0)
1960 {
1961 wxLogWarning(_("Expected 'char' whilst parsing resource."));
1962 return FALSE;
1963 }
1964
1965 // *name
1966 if (!wxGetResourceToken(fd))
1967 {
1968 wxLogWarning(_("Unexpected end of file whilst parsing resource."));
1969 *eof = TRUE;
1970 return FALSE;
1971 }
1972
1973 if (wxResourceBuffer[0] != '*')
1974 {
1975 wxLogWarning(_("Expected '*' whilst parsing resource."));
1976 return FALSE;
1977 }
1978 char nameBuf[100];
1979 strncpy(nameBuf, wxResourceBuffer+1, 99);
1980
1981 // =
1982 if (!wxGetResourceToken(fd))
1983 {
1984 wxLogWarning(_("Unexpected end of file whilst parsing resource."));
1985 *eof = TRUE;
1986 return FALSE;
1987 }
1988
1989 if (strcmp(wxResourceBuffer, "=") != 0)
1990 {
1991 wxLogWarning(_("Expected '=' whilst parsing resource."));
1992 return FALSE;
1993 }
1994
1995 // String
1996 if (!wxGetResourceToken(fd))
1997 {
1998 wxLogWarning(_("Unexpected end of file whilst parsing resource."));
1999 *eof = TRUE;
2000 return FALSE;
2001 }
2002 else
2003 {
2004 if (!db.ReadPrologFromString(wxResourceBuffer))
2005 {
2006 wxLogWarning(_("%s: ill-formed resource file syntax."), nameBuf);
2007 return FALSE;
2008 }
2009 }
2010 // Semicolon
2011 if (!wxGetResourceToken(fd))
2012 {
2013 *eof = TRUE;
2014 }
2015 return TRUE;
2016 }
2017
2018 /*
2019 * Parses string window style into integer window style
2020 */
2021
2022 /*
2023 * Style flag parsing, e.g.
2024 * "wxSYSTEM_MENU | wxBORDER" -> integer
2025 */
2026
2027 wxChar* wxResourceParseWord(wxChar*s, int *i)
2028 {
2029 if (!s)
2030 return (wxChar*) NULL;
2031
2032 static wxChar buf[150];
2033 int len = wxStrlen(s);
2034 int j = 0;
2035 int ii = *i;
2036 while ((ii < len) && (wxIsalpha(s[ii]) || (s[ii] == wxT('_'))))
2037 {
2038 buf[j] = s[ii];
2039 j ++;
2040 ii ++;
2041 }
2042 buf[j] = 0;
2043
2044 // Eat whitespace and conjunction characters
2045 while ((ii < len) &&
2046 ((s[ii] == wxT(' ')) || (s[ii] == wxT('|')) || (s[ii] == wxT(','))))
2047 {
2048 ii ++;
2049 }
2050 *i = ii;
2051 if (j == 0)
2052 return (wxChar*) NULL;
2053 else
2054 return buf;
2055 }
2056
2057 struct wxResourceBitListStruct
2058 {
2059 const wxChar *word;
2060 long bits;
2061 };
2062
2063 static wxResourceBitListStruct wxResourceBitListTable[] =
2064 {
2065 /* wxListBox */
2066 { wxT("wxSINGLE"), wxLB_SINGLE },
2067 { wxT("wxMULTIPLE"), wxLB_MULTIPLE },
2068 { wxT("wxEXTENDED"), wxLB_EXTENDED },
2069 { wxT("wxLB_SINGLE"), wxLB_SINGLE },
2070 { wxT("wxLB_MULTIPLE"), wxLB_MULTIPLE },
2071 { wxT("wxLB_EXTENDED"), wxLB_EXTENDED },
2072 { wxT("wxLB_NEEDED_SB"), wxLB_NEEDED_SB },
2073 { wxT("wxLB_ALWAYS_SB"), wxLB_ALWAYS_SB },
2074 { wxT("wxLB_SORT"), wxLB_SORT },
2075 { wxT("wxLB_OWNERDRAW"), wxLB_OWNERDRAW },
2076 { wxT("wxLB_HSCROLL"), wxLB_HSCROLL },
2077
2078 /* wxComboxBox */
2079 { wxT("wxCB_SIMPLE"), wxCB_SIMPLE },
2080 { wxT("wxCB_DROPDOWN"), wxCB_DROPDOWN },
2081 { wxT("wxCB_READONLY"), wxCB_READONLY },
2082 { wxT("wxCB_SORT"), wxCB_SORT },
2083
2084 /* wxGauge */
2085 { wxT("wxGA_PROGRESSBAR"), wxGA_PROGRESSBAR },
2086 { wxT("wxGA_HORIZONTAL"), wxGA_HORIZONTAL },
2087 { wxT("wxGA_VERTICAL"), wxGA_VERTICAL },
2088
2089 /* wxTextCtrl */
2090 { wxT("wxPASSWORD"), wxPASSWORD},
2091 { wxT("wxPROCESS_ENTER"), wxPROCESS_ENTER},
2092 { wxT("wxTE_PASSWORD"), wxTE_PASSWORD},
2093 { wxT("wxTE_READONLY"), wxTE_READONLY},
2094 { wxT("wxTE_PROCESS_ENTER"), wxTE_PROCESS_ENTER},
2095 { wxT("wxTE_MULTILINE"), wxTE_MULTILINE},
2096 { wxT("wxTE_NO_VSCROLL"), wxTE_NO_VSCROLL},
2097
2098 /* wxRadioBox/wxRadioButton */
2099 { wxT("wxRB_GROUP"), wxRB_GROUP },
2100 { wxT("wxRA_SPECIFY_COLS"), wxRA_SPECIFY_COLS },
2101 { wxT("wxRA_SPECIFY_ROWS"), wxRA_SPECIFY_ROWS },
2102 { wxT("wxRA_HORIZONTAL"), wxRA_HORIZONTAL },
2103 { wxT("wxRA_VERTICAL"), wxRA_VERTICAL },
2104
2105 /* wxSlider */
2106 { wxT("wxSL_HORIZONTAL"), wxSL_HORIZONTAL },
2107 { wxT("wxSL_VERTICAL"), wxSL_VERTICAL },
2108 { wxT("wxSL_AUTOTICKS"), wxSL_AUTOTICKS },
2109 { wxT("wxSL_LABELS"), wxSL_LABELS },
2110 { wxT("wxSL_LEFT"), wxSL_LEFT },
2111 { wxT("wxSL_TOP"), wxSL_TOP },
2112 { wxT("wxSL_RIGHT"), wxSL_RIGHT },
2113 { wxT("wxSL_BOTTOM"), wxSL_BOTTOM },
2114 { wxT("wxSL_BOTH"), wxSL_BOTH },
2115 { wxT("wxSL_SELRANGE"), wxSL_SELRANGE },
2116
2117 /* wxScrollBar */
2118 { wxT("wxSB_HORIZONTAL"), wxSB_HORIZONTAL },
2119 { wxT("wxSB_VERTICAL"), wxSB_VERTICAL },
2120
2121 /* wxButton */
2122 { wxT("wxBU_AUTODRAW"), wxBU_AUTODRAW },
2123 { wxT("wxBU_NOAUTODRAW"), wxBU_NOAUTODRAW },
2124
2125 /* wxTreeCtrl */
2126 { wxT("wxTR_HAS_BUTTONS"), wxTR_HAS_BUTTONS },
2127 { wxT("wxTR_EDIT_LABELS"), wxTR_EDIT_LABELS },
2128 { wxT("wxTR_LINES_AT_ROOT"), wxTR_LINES_AT_ROOT },
2129
2130 /* wxListCtrl */
2131 { wxT("wxLC_ICON"), wxLC_ICON },
2132 { wxT("wxLC_SMALL_ICON"), wxLC_SMALL_ICON },
2133 { wxT("wxLC_LIST"), wxLC_LIST },
2134 { wxT("wxLC_REPORT"), wxLC_REPORT },
2135 { wxT("wxLC_ALIGN_TOP"), wxLC_ALIGN_TOP },
2136 { wxT("wxLC_ALIGN_LEFT"), wxLC_ALIGN_LEFT },
2137 { wxT("wxLC_AUTOARRANGE"), wxLC_AUTOARRANGE },
2138 { wxT("wxLC_USER_TEXT"), wxLC_USER_TEXT },
2139 { wxT("wxLC_EDIT_LABELS"), wxLC_EDIT_LABELS },
2140 { wxT("wxLC_NO_HEADER"), wxLC_NO_HEADER },
2141 { wxT("wxLC_NO_SORT_HEADER"), wxLC_NO_SORT_HEADER },
2142 { wxT("wxLC_SINGLE_SEL"), wxLC_SINGLE_SEL },
2143 { wxT("wxLC_SORT_ASCENDING"), wxLC_SORT_ASCENDING },
2144 { wxT("wxLC_SORT_DESCENDING"), wxLC_SORT_DESCENDING },
2145
2146 /* wxSpinButton */
2147 { wxT("wxSP_VERTICAL"), wxSP_VERTICAL},
2148 { wxT("wxSP_HORIZONTAL"), wxSP_HORIZONTAL},
2149 { wxT("wxSP_ARROW_KEYS"), wxSP_ARROW_KEYS},
2150 { wxT("wxSP_WRAP"), wxSP_WRAP},
2151
2152 /* wxSplitterWnd */
2153 { wxT("wxSP_NOBORDER"), wxSP_NOBORDER},
2154 { wxT("wxSP_3D"), wxSP_3D},
2155 { wxT("wxSP_BORDER"), wxSP_BORDER},
2156
2157 /* wxTabCtrl */
2158 { wxT("wxTC_MULTILINE"), wxTC_MULTILINE},
2159 { wxT("wxTC_RIGHTJUSTIFY"), wxTC_RIGHTJUSTIFY},
2160 { wxT("wxTC_FIXEDWIDTH"), wxTC_FIXEDWIDTH},
2161 { wxT("wxTC_OWNERDRAW"), wxTC_OWNERDRAW},
2162
2163 /* wxStatusBar95 */
2164 { wxT("wxST_SIZEGRIP"), wxST_SIZEGRIP},
2165
2166 /* wxControl */
2167 { wxT("wxFIXED_LENGTH"), wxFIXED_LENGTH},
2168 { wxT("wxALIGN_LEFT"), wxALIGN_LEFT},
2169 { wxT("wxALIGN_CENTER"), wxALIGN_CENTER},
2170 { wxT("wxALIGN_CENTRE"), wxALIGN_CENTRE},
2171 { wxT("wxALIGN_RIGHT"), wxALIGN_RIGHT},
2172 { wxT("wxCOLOURED"), wxCOLOURED},
2173
2174 /* wxToolBar */
2175 { wxT("wxTB_3DBUTTONS"), wxTB_3DBUTTONS},
2176 { wxT("wxTB_HORIZONTAL"), wxTB_HORIZONTAL},
2177 { wxT("wxTB_VERTICAL"), wxTB_VERTICAL},
2178 { wxT("wxTB_FLAT"), wxTB_FLAT},
2179
2180 /* wxDialog */
2181 { wxT("wxDIALOG_MODAL"), wxDIALOG_MODAL },
2182
2183 /* Generic */
2184 { wxT("wxVSCROLL"), wxVSCROLL },
2185 { wxT("wxHSCROLL"), wxHSCROLL },
2186 { wxT("wxCAPTION"), wxCAPTION },
2187 { wxT("wxSTAY_ON_TOP"), wxSTAY_ON_TOP},
2188 { wxT("wxICONIZE"), wxICONIZE},
2189 { wxT("wxMINIMIZE"), wxICONIZE},
2190 { wxT("wxMAXIMIZE"), wxMAXIMIZE},
2191 { wxT("wxSDI"), 0},
2192 { wxT("wxMDI_PARENT"), 0},
2193 { wxT("wxMDI_CHILD"), 0},
2194 { wxT("wxTHICK_FRAME"), wxTHICK_FRAME},
2195 { wxT("wxRESIZE_BORDER"), wxRESIZE_BORDER},
2196 { wxT("wxSYSTEM_MENU"), wxSYSTEM_MENU},
2197 { wxT("wxMINIMIZE_BOX"), wxMINIMIZE_BOX},
2198 { wxT("wxMAXIMIZE_BOX"), wxMAXIMIZE_BOX},
2199 { wxT("wxRESIZE_BOX"), wxRESIZE_BOX},
2200 { wxT("wxDEFAULT_FRAME_STYLE"), wxDEFAULT_FRAME_STYLE},
2201 { wxT("wxDEFAULT_FRAME"), wxDEFAULT_FRAME_STYLE},
2202 { wxT("wxDEFAULT_DIALOG_STYLE"), wxDEFAULT_DIALOG_STYLE},
2203 { wxT("wxBORDER"), wxBORDER},
2204 { wxT("wxRETAINED"), wxRETAINED},
2205 { wxT("wxNATIVE_IMPL"), 0},
2206 { wxT("wxEXTENDED_IMPL"), 0},
2207 { wxT("wxBACKINGSTORE"), wxBACKINGSTORE},
2208 // { wxT("wxFLAT"), wxFLAT},
2209 // { wxT("wxMOTIF_RESIZE"), wxMOTIF_RESIZE},
2210 { wxT("wxFIXED_LENGTH"), 0},
2211 { wxT("wxDOUBLE_BORDER"), wxDOUBLE_BORDER},
2212 { wxT("wxSUNKEN_BORDER"), wxSUNKEN_BORDER},
2213 { wxT("wxRAISED_BORDER"), wxRAISED_BORDER},
2214 { wxT("wxSIMPLE_BORDER"), wxSIMPLE_BORDER},
2215 { wxT("wxSTATIC_BORDER"), wxSTATIC_BORDER},
2216 { wxT("wxTRANSPARENT_WINDOW"), wxTRANSPARENT_WINDOW},
2217 { wxT("wxNO_BORDER"), wxNO_BORDER},
2218 { wxT("wxCLIP_CHILDREN"), wxCLIP_CHILDREN},
2219 { wxT("wxCLIP_SIBLINGS"), wxCLIP_SIBLINGS},
2220 { wxT("wxTAB_TRAVERSAL"), 0}, // Compatibility only
2221
2222 { wxT("wxTINY_CAPTION_HORIZ"), wxTINY_CAPTION_HORIZ},
2223 { wxT("wxTINY_CAPTION_VERT"), wxTINY_CAPTION_VERT},
2224
2225 // Text font families
2226 { wxT("wxDEFAULT"), wxDEFAULT},
2227 { wxT("wxDECORATIVE"), wxDECORATIVE},
2228 { wxT("wxROMAN"), wxROMAN},
2229 { wxT("wxSCRIPT"), wxSCRIPT},
2230 { wxT("wxSWISS"), wxSWISS},
2231 { wxT("wxMODERN"), wxMODERN},
2232 { wxT("wxTELETYPE"), wxTELETYPE},
2233 { wxT("wxVARIABLE"), wxVARIABLE},
2234 { wxT("wxFIXED"), wxFIXED},
2235 { wxT("wxNORMAL"), wxNORMAL},
2236 { wxT("wxLIGHT"), wxLIGHT},
2237 { wxT("wxBOLD"), wxBOLD},
2238 { wxT("wxITALIC"), wxITALIC},
2239 { wxT("wxSLANT"), wxSLANT},
2240 { wxT("wxSOLID"), wxSOLID},
2241 { wxT("wxDOT"), wxDOT},
2242 { wxT("wxLONG_DASH"), wxLONG_DASH},
2243 { wxT("wxSHORT_DASH"), wxSHORT_DASH},
2244 { wxT("wxDOT_DASH"), wxDOT_DASH},
2245 { wxT("wxUSER_DASH"), wxUSER_DASH},
2246 { wxT("wxTRANSPARENT"), wxTRANSPARENT},
2247 { wxT("wxSTIPPLE"), wxSTIPPLE},
2248 { wxT("wxBDIAGONAL_HATCH"), wxBDIAGONAL_HATCH},
2249 { wxT("wxCROSSDIAG_HATCH"), wxCROSSDIAG_HATCH},
2250 { wxT("wxFDIAGONAL_HATCH"), wxFDIAGONAL_HATCH},
2251 { wxT("wxCROSS_HATCH"), wxCROSS_HATCH},
2252 { wxT("wxHORIZONTAL_HATCH"), wxHORIZONTAL_HATCH},
2253 { wxT("wxVERTICAL_HATCH"), wxVERTICAL_HATCH},
2254 { wxT("wxJOIN_BEVEL"), wxJOIN_BEVEL},
2255 { wxT("wxJOIN_MITER"), wxJOIN_MITER},
2256 { wxT("wxJOIN_ROUND"), wxJOIN_ROUND},
2257 { wxT("wxCAP_ROUND"), wxCAP_ROUND},
2258 { wxT("wxCAP_PROJECTING"), wxCAP_PROJECTING},
2259 { wxT("wxCAP_BUTT"), wxCAP_BUTT},
2260
2261 // Logical ops
2262 { wxT("wxCLEAR"), wxCLEAR},
2263 { wxT("wxXOR"), wxXOR},
2264 { wxT("wxINVERT"), wxINVERT},
2265 { wxT("wxOR_REVERSE"), wxOR_REVERSE},
2266 { wxT("wxAND_REVERSE"), wxAND_REVERSE},
2267 { wxT("wxCOPY"), wxCOPY},
2268 { wxT("wxAND"), wxAND},
2269 { wxT("wxAND_INVERT"), wxAND_INVERT},
2270 { wxT("wxNO_OP"), wxNO_OP},
2271 { wxT("wxNOR"), wxNOR},
2272 { wxT("wxEQUIV"), wxEQUIV},
2273 { wxT("wxSRC_INVERT"), wxSRC_INVERT},
2274 { wxT("wxOR_INVERT"), wxOR_INVERT},
2275 { wxT("wxNAND"), wxNAND},
2276 { wxT("wxOR"), wxOR},
2277 { wxT("wxSET"), wxSET},
2278
2279 { wxT("wxFLOOD_SURFACE"), wxFLOOD_SURFACE},
2280 { wxT("wxFLOOD_BORDER"), wxFLOOD_BORDER},
2281 { wxT("wxODDEVEN_RULE"), wxODDEVEN_RULE},
2282 { wxT("wxWINDING_RULE"), wxWINDING_RULE},
2283 { wxT("wxHORIZONTAL"), wxHORIZONTAL},
2284 { wxT("wxVERTICAL"), wxVERTICAL},
2285 { wxT("wxBOTH"), wxBOTH},
2286 { wxT("wxCENTER_FRAME"), wxCENTER_FRAME},
2287 { wxT("wxOK"), wxOK},
2288 { wxT("wxYES_NO"), wxYES_NO},
2289 { wxT("wxCANCEL"), wxCANCEL},
2290 { wxT("wxYES"), wxYES},
2291 { wxT("wxNO"), wxNO},
2292 { wxT("wxICON_EXCLAMATION"), wxICON_EXCLAMATION},
2293 { wxT("wxICON_HAND"), wxICON_HAND},
2294 { wxT("wxICON_QUESTION"), wxICON_QUESTION},
2295 { wxT("wxICON_INFORMATION"), wxICON_INFORMATION},
2296 { wxT("wxICON_STOP"), wxICON_STOP},
2297 { wxT("wxICON_ASTERISK"), wxICON_ASTERISK},
2298 { wxT("wxICON_MASK"), wxICON_MASK},
2299 { wxT("wxCENTRE"), wxCENTRE},
2300 { wxT("wxCENTER"), wxCENTRE},
2301 { wxT("wxUSER_COLOURS"), wxUSER_COLOURS},
2302 { wxT("wxVERTICAL_LABEL"), 0},
2303 { wxT("wxHORIZONTAL_LABEL"), 0},
2304
2305 // Bitmap types (not strictly styles)
2306 { wxT("wxBITMAP_TYPE_XPM"), wxBITMAP_TYPE_XPM},
2307 { wxT("wxBITMAP_TYPE_XBM"), wxBITMAP_TYPE_XBM},
2308 { wxT("wxBITMAP_TYPE_BMP"), wxBITMAP_TYPE_BMP},
2309 { wxT("wxBITMAP_TYPE_RESOURCE"), wxBITMAP_TYPE_BMP_RESOURCE},
2310 { wxT("wxBITMAP_TYPE_BMP_RESOURCE"), wxBITMAP_TYPE_BMP_RESOURCE},
2311 { wxT("wxBITMAP_TYPE_GIF"), wxBITMAP_TYPE_GIF},
2312 { wxT("wxBITMAP_TYPE_TIF"), wxBITMAP_TYPE_TIF},
2313 { wxT("wxBITMAP_TYPE_ICO"), wxBITMAP_TYPE_ICO},
2314 { wxT("wxBITMAP_TYPE_ICO_RESOURCE"), wxBITMAP_TYPE_ICO_RESOURCE},
2315 { wxT("wxBITMAP_TYPE_CUR"), wxBITMAP_TYPE_CUR},
2316 { wxT("wxBITMAP_TYPE_CUR_RESOURCE"), wxBITMAP_TYPE_CUR_RESOURCE},
2317 { wxT("wxBITMAP_TYPE_XBM_DATA"), wxBITMAP_TYPE_XBM_DATA},
2318 { wxT("wxBITMAP_TYPE_XPM_DATA"), wxBITMAP_TYPE_XPM_DATA},
2319 { wxT("wxBITMAP_TYPE_ANY"), wxBITMAP_TYPE_ANY}
2320 };
2321
2322 static int wxResourceBitListCount = (sizeof(wxResourceBitListTable)/sizeof(wxResourceBitListStruct));
2323
2324 long wxParseWindowStyle(const wxString& bitListString)
2325 {
2326 int i = 0;
2327 wxChar *word;
2328 long bitList = 0;
2329 word = wxResourceParseWord(WXSTRINGCAST bitListString, &i);
2330 while (word != NULL)
2331 {
2332 bool found = FALSE;
2333 int j;
2334 for (j = 0; j < wxResourceBitListCount; j++)
2335 if (wxStrcmp(wxResourceBitListTable[j].word, word) == 0)
2336 {
2337 bitList |= wxResourceBitListTable[j].bits;
2338 found = TRUE;
2339 break;
2340 }
2341 if (!found)
2342 {
2343 wxLogWarning(_("Unrecognized style %s whilst parsing resource."), word);
2344 return 0;
2345 }
2346 word = wxResourceParseWord(WXSTRINGCAST bitListString, &i);
2347 }
2348 return bitList;
2349 }
2350
2351 /*
2352 * Load a bitmap from a wxWindows resource, choosing an optimum
2353 * depth and appropriate type.
2354 */
2355
2356 wxBitmap wxResourceCreateBitmap(const wxString& resource, wxResourceTable *table)
2357 {
2358 if (!table)
2359 table = wxDefaultResourceTable;
2360
2361 wxItemResource *item = table->FindResource(resource);
2362 if (item)
2363 {
2364 if ((item->GetType() == wxT("")) || (item->GetType() != wxT("wxBitmap")))
2365 {
2366 wxLogWarning(_("%s not a bitmap resource specification."), (const wxChar*) resource);
2367 return wxNullBitmap;
2368 }
2369 int thisDepth = wxDisplayDepth();
2370 long thisNoColours = (long)pow(2.0, (double)thisDepth);
2371
2372 wxItemResource *optResource = (wxItemResource *) NULL;
2373
2374 // Try to find optimum bitmap for this platform/colour depth
2375 wxNode *node = item->GetChildren().First();
2376 while (node)
2377 {
2378 wxItemResource *child = (wxItemResource *)node->Data();
2379 int platform = (int)child->GetValue2();
2380 int noColours = (int)child->GetValue3();
2381 /*
2382 char *name = child->GetName();
2383 int bitmapType = (int)child->GetValue1();
2384 int xRes = child->GetWidth();
2385 int yRes = child->GetHeight();
2386 */
2387
2388 switch (platform)
2389 {
2390 case RESOURCE_PLATFORM_ANY:
2391 {
2392 if (!optResource && ((noColours == 0) || (noColours <= thisNoColours)))
2393 optResource = child;
2394 else
2395 {
2396 // Maximise the number of colours.
2397 // If noColours is zero (unspecified), then assume this
2398 // is the right one.
2399 if ((noColours == 0) || ((noColours <= thisNoColours) && (noColours > optResource->GetValue3())))
2400 optResource = child;
2401 }
2402 break;
2403 }
2404 #ifdef __WXMSW__
2405 case RESOURCE_PLATFORM_WINDOWS:
2406 {
2407 if (!optResource && ((noColours == 0) || (noColours <= thisNoColours)))
2408 optResource = child;
2409 else
2410 {
2411 // Maximise the number of colours
2412 if ((noColours > 0) || ((noColours <= thisNoColours) && (noColours > optResource->GetValue3())))
2413 optResource = child;
2414 }
2415 break;
2416 }
2417 #endif
2418 #ifdef __WXGTK__
2419 case RESOURCE_PLATFORM_X:
2420 {
2421 if (!optResource && ((noColours == 0) || (noColours <= thisNoColours)))
2422 optResource = child;
2423 else
2424 {
2425 // Maximise the number of colours
2426 if ((noColours == 0) || ((noColours <= thisNoColours) && (noColours > optResource->GetValue3())))
2427 optResource = child;
2428 }
2429 break;
2430 }
2431 #endif
2432 #ifdef wx_max
2433 case RESOURCE_PLATFORM_MAC:
2434 {
2435 if (!optResource && ((noColours == 0) || (noColours <= thisNoColours)))
2436 optResource = child;
2437 else
2438 {
2439 // Maximise the number of colours
2440 if ((noColours == 0) || ((noColours <= thisNoColours) && (noColours > optResource->GetValue3())))
2441 optResource = child;
2442 }
2443 break;
2444 }
2445 #endif
2446 default:
2447 break;
2448 }
2449 node = node->Next();
2450 }
2451 // If no matching resource, fail.
2452 if (!optResource)
2453 return wxNullBitmap;
2454
2455 wxString name = optResource->GetName();
2456 int bitmapType = (int)optResource->GetValue1();
2457 switch (bitmapType)
2458 {
2459 case wxBITMAP_TYPE_XBM_DATA:
2460 {
2461 #ifdef __WXGTK__
2462 wxItemResource *item = table->FindResource(name);
2463 if (!item)
2464 {
2465 wxLogWarning(_("Failed to find XBM resource %s.\n"
2466 "Forgot to use wxResourceLoadBitmapData?"), (const wxChar*) name);
2467 return wxNullBitmap;
2468 }
2469 return wxBitmap(item->GetValue1(), (int)item->GetValue2(), (int)item->GetValue3()) ;
2470 #else
2471 wxLogWarning(_("No XBM facility available!"));
2472 break;
2473 #endif
2474 }
2475 case wxBITMAP_TYPE_XPM_DATA:
2476 {
2477 wxItemResource *item = table->FindResource(name);
2478 if (!item)
2479 {
2480 wxLogWarning(_("Failed to find XPM resource %s.\nForgot to use wxResourceLoadBitmapData?"), (const wxChar*) name);
2481 return wxNullBitmap;
2482 }
2483 return wxBitmap((char **)item->GetValue1());
2484 }
2485 default:
2486 {
2487 #if defined(__WXPM__)
2488 return wxNullBitmap;
2489 #else
2490 return wxBitmap(name, (wxBitmapType)bitmapType);
2491 #endif
2492 }
2493 }
2494 #ifndef __WXGTK__
2495 return wxNullBitmap;
2496 #endif
2497 }
2498 else
2499 {
2500 wxLogWarning(_("Bitmap resource specification %s not found."), (const wxChar*) resource);
2501 return wxNullBitmap;
2502 }
2503 }
2504
2505 /*
2506 * Load an icon from a wxWindows resource, choosing an optimum
2507 * depth and appropriate type.
2508 */
2509
2510 wxIcon wxResourceCreateIcon(const wxString& resource, wxResourceTable *table)
2511 {
2512 if (!table)
2513 table = wxDefaultResourceTable;
2514
2515 wxItemResource *item = table->FindResource(resource);
2516 if (item)
2517 {
2518 if ((item->GetType() == wxT("")) || wxStrcmp(item->GetType(), wxT("wxIcon")) != 0)
2519 {
2520 wxLogWarning(_("%s not an icon resource specification."), (const wxChar*) resource);
2521 return wxNullIcon;
2522 }
2523 int thisDepth = wxDisplayDepth();
2524 long thisNoColours = (long)pow(2.0, (double)thisDepth);
2525
2526 wxItemResource *optResource = (wxItemResource *) NULL;
2527
2528 // Try to find optimum icon for this platform/colour depth
2529 wxNode *node = item->GetChildren().First();
2530 while (node)
2531 {
2532 wxItemResource *child = (wxItemResource *)node->Data();
2533 int platform = (int)child->GetValue2();
2534 int noColours = (int)child->GetValue3();
2535 /*
2536 char *name = child->GetName();
2537 int bitmapType = (int)child->GetValue1();
2538 int xRes = child->GetWidth();
2539 int yRes = child->GetHeight();
2540 */
2541
2542 switch (platform)
2543 {
2544 case RESOURCE_PLATFORM_ANY:
2545 {
2546 if (!optResource && ((noColours == 0) || (noColours <= thisNoColours)))
2547 optResource = child;
2548 else
2549 {
2550 // Maximise the number of colours.
2551 // If noColours is zero (unspecified), then assume this
2552 // is the right one.
2553 if ((noColours == 0) || ((noColours <= thisNoColours) && (noColours > optResource->GetValue3())))
2554 optResource = child;
2555 }
2556 break;
2557 }
2558 #ifdef __WXMSW__
2559 case RESOURCE_PLATFORM_WINDOWS:
2560 {
2561 if (!optResource && ((noColours == 0) || (noColours <= thisNoColours)))
2562 optResource = child;
2563 else
2564 {
2565 // Maximise the number of colours
2566 if ((noColours > 0) || ((noColours <= thisNoColours) && (noColours > optResource->GetValue3())))
2567 optResource = child;
2568 }
2569 break;
2570 }
2571 #endif
2572 #ifdef __WXGTK__
2573 case RESOURCE_PLATFORM_X:
2574 {
2575 if (!optResource && ((noColours == 0) || (noColours <= thisNoColours)))
2576 optResource = child;
2577 else
2578 {
2579 // Maximise the number of colours
2580 if ((noColours == 0) || ((noColours <= thisNoColours) && (noColours > optResource->GetValue3())))
2581 optResource = child;
2582 }
2583 break;
2584 }
2585 #endif
2586 #ifdef wx_max
2587 case RESOURCE_PLATFORM_MAC:
2588 {
2589 if (!optResource && ((noColours == 0) || (noColours <= thisNoColours)))
2590 optResource = child;
2591 else
2592 {
2593 // Maximise the number of colours
2594 if ((noColours == 0) || ((noColours <= thisNoColours) && (noColours > optResource->GetValue3())))
2595 optResource = child;
2596 }
2597 break;
2598 }
2599 #endif
2600 default:
2601 break;
2602 }
2603 node = node->Next();
2604 }
2605 // If no matching resource, fail.
2606 if (!optResource)
2607 return wxNullIcon;
2608
2609 wxString name = optResource->GetName();
2610 int bitmapType = (int)optResource->GetValue1();
2611 switch (bitmapType)
2612 {
2613 case wxBITMAP_TYPE_XBM_DATA:
2614 {
2615 #ifdef __WXGTK__
2616 wxItemResource *item = table->FindResource(name);
2617 if (!item)
2618 {
2619 wxLogWarning(_("Failed to find XBM resource %s.\n"
2620 "Forgot to use wxResourceLoadIconData?"), (const wxChar*) name);
2621 return wxNullIcon;
2622 }
2623 return wxIcon((const char **)item->GetValue1(), (int)item->GetValue2(), (int)item->GetValue3());
2624 #else
2625 wxLogWarning(_("No XBM facility available!"));
2626 break;
2627 #endif
2628 }
2629 case wxBITMAP_TYPE_XPM_DATA:
2630 {
2631 // *** XPM ICON NOT YET IMPLEMENTED IN WXWINDOWS ***
2632 /*
2633 wxItemResource *item = table->FindResource(name);
2634 if (!item)
2635 {
2636 char buf[400];
2637 sprintf(buf, _("Failed to find XPM resource %s.\nForgot to use wxResourceLoadIconData?"), name);
2638 wxLogWarning(buf);
2639 return NULL;
2640 }
2641 return wxIcon((char **)item->GetValue1());
2642 */
2643 wxLogWarning(_("No XPM icon facility available!"));
2644 break;
2645 }
2646 default:
2647 {
2648 #ifdef __WXGTK__
2649 wxLogWarning(_("Icon resource specification %s not found."), (const wxChar*) resource);
2650 break;
2651 #else
2652 return wxIcon(name, bitmapType);
2653 #endif
2654 }
2655 }
2656 return wxNullIcon;
2657 }
2658 else
2659 {
2660 wxLogWarning(_("Icon resource specification %s not found."), (const wxChar*) resource);
2661 return wxNullIcon;
2662 }
2663 }
2664
2665 #if wxUSE_MENUS
2666
2667 wxMenu *wxResourceCreateMenu(wxItemResource *item)
2668 {
2669 wxMenu *menu = new wxMenu;
2670 wxNode *node = item->GetChildren().First();
2671 while (node)
2672 {
2673 wxItemResource *child = (wxItemResource *)node->Data();
2674 if ((child->GetType() != wxT("")) && (child->GetType() == wxT("wxMenuSeparator")))
2675 menu->AppendSeparator();
2676 else if (child->GetChildren().Number() > 0)
2677 {
2678 wxMenu *subMenu = wxResourceCreateMenu(child);
2679 if (subMenu)
2680 menu->Append((int)child->GetValue1(), child->GetTitle(), subMenu, child->GetValue4());
2681 }
2682 else
2683 {
2684 menu->Append((int)child->GetValue1(), child->GetTitle(), child->GetValue4(), (child->GetValue2() != 0));
2685 }
2686 node = node->Next();
2687 }
2688 return menu;
2689 }
2690
2691 wxMenuBar *wxResourceCreateMenuBar(const wxString& resource, wxResourceTable *table, wxMenuBar *menuBar)
2692 {
2693 if (!table)
2694 table = wxDefaultResourceTable;
2695
2696 wxItemResource *menuResource = table->FindResource(resource);
2697 if (menuResource && (menuResource->GetType() != wxT("")) && (menuResource->GetType() == wxT("wxMenu")))
2698 {
2699 if (!menuBar)
2700 menuBar = new wxMenuBar;
2701 wxNode *node = menuResource->GetChildren().First();
2702 while (node)
2703 {
2704 wxItemResource *child = (wxItemResource *)node->Data();
2705 wxMenu *menu = wxResourceCreateMenu(child);
2706 if (menu)
2707 menuBar->Append(menu, child->GetTitle());
2708 node = node->Next();
2709 }
2710 return menuBar;
2711 }
2712 return (wxMenuBar *) NULL;
2713 }
2714
2715 wxMenu *wxResourceCreateMenu(const wxString& resource, wxResourceTable *table)
2716 {
2717 if (!table)
2718 table = wxDefaultResourceTable;
2719
2720 wxItemResource *menuResource = table->FindResource(resource);
2721 if (menuResource && (menuResource->GetType() != wxT("")) && (menuResource->GetType() == wxT("wxMenu")))
2722 // if (menuResource && (menuResource->GetType() == wxTYPE_MENU))
2723 return wxResourceCreateMenu(menuResource);
2724 return (wxMenu *) NULL;
2725 }
2726
2727 #endif // wxUSE_MENUS
2728
2729 // Global equivalents (so don't have to refer to default table explicitly)
2730 bool wxResourceParseData(const wxString& resource, wxResourceTable *table)
2731 {
2732 if (!table)
2733 table = wxDefaultResourceTable;
2734
2735 return table->ParseResourceData(resource);
2736 }
2737
2738 bool wxResourceParseFile(const wxString& filename, wxResourceTable *table)
2739 {
2740 if (!table)
2741 table = wxDefaultResourceTable;
2742
2743 return table->ParseResourceFile(filename);
2744 }
2745
2746 // Register XBM/XPM data
2747 bool wxResourceRegisterBitmapData(const wxString& name, char bits[], int width, int height, wxResourceTable *table)
2748 {
2749 if (!table)
2750 table = wxDefaultResourceTable;
2751
2752 return table->RegisterResourceBitmapData(name, bits, width, height);
2753 }
2754
2755 bool wxResourceRegisterBitmapData(const wxString& name, char **data, wxResourceTable *table)
2756 {
2757 if (!table)
2758 table = wxDefaultResourceTable;
2759
2760 return table->RegisterResourceBitmapData(name, data);
2761 }
2762
2763 void wxResourceClear(wxResourceTable *table)
2764 {
2765 if (!table)
2766 table = wxDefaultResourceTable;
2767
2768 table->ClearTable();
2769 }
2770
2771 /*
2772 * Identifiers
2773 */
2774
2775 bool wxResourceAddIdentifier(const wxString& name, int value, wxResourceTable *table)
2776 {
2777 if (!table)
2778 table = wxDefaultResourceTable;
2779
2780 table->identifiers.Put(name, (wxObject *)(long)value);
2781 return TRUE;
2782 }
2783
2784 int wxResourceGetIdentifier(const wxString& name, wxResourceTable *table)
2785 {
2786 if (!table)
2787 table = wxDefaultResourceTable;
2788
2789 return (int)(long)table->identifiers.Get(name);
2790 }
2791
2792 /*
2793 * Parse #include file for #defines (only)
2794 */
2795
2796 bool wxResourceParseIncludeFile(const wxString& f, wxResourceTable *table)
2797 {
2798 if (!table)
2799 table = wxDefaultResourceTable;
2800
2801 FILE *fd = wxFopen(f, _T("r"));
2802 if (!fd)
2803 {
2804 return FALSE;
2805 }
2806 while (wxGetResourceToken(fd))
2807 {
2808 if (strcmp(wxResourceBuffer, "#define") == 0)
2809 {
2810 wxGetResourceToken(fd);
2811 wxChar *name = copystring(wxConvCurrent->cMB2WX(wxResourceBuffer));
2812 wxGetResourceToken(fd);
2813 wxChar *value = copystring(wxConvCurrent->cMB2WX(wxResourceBuffer));
2814 if (wxIsdigit(value[0]))
2815 {
2816 int val = (int)wxAtol(value);
2817 wxResourceAddIdentifier(name, val, table);
2818 }
2819 delete[] name;
2820 delete[] value;
2821 }
2822 }
2823 fclose(fd);
2824 return TRUE;
2825 }
2826
2827 /*
2828 * Reading strings as if they were .wxr files
2829 */
2830
2831 static int getc_string(char *s)
2832 {
2833 int ch = s[wxResourceStringPtr];
2834 if (ch == 0)
2835 return EOF;
2836 else
2837 {
2838 wxResourceStringPtr ++;
2839 return ch;
2840 }
2841 }
2842
2843 static int ungetc_string()
2844 {
2845 wxResourceStringPtr --;
2846 return 0;
2847 }
2848
2849 bool wxEatWhiteSpaceString(char *s)
2850 {
2851 int ch = 0;
2852
2853 while ((ch = getc_string(s)) != EOF)
2854 {
2855 switch (ch)
2856 {
2857 case ' ':
2858 case 0x0a:
2859 case 0x0d:
2860 case 0x09:
2861 break;
2862 case '/':
2863 {
2864 int prev_ch = ch;
2865 ch = getc_string(s);
2866 if (ch == EOF)
2867 {
2868 ungetc_string();
2869 return TRUE;
2870 }
2871
2872 if (ch == '*')
2873 {
2874 // Eat C comment
2875 prev_ch = 0;
2876 while ((ch = getc_string(s)) != EOF)
2877 {
2878 if (ch == '/' && prev_ch == '*')
2879 break;
2880 prev_ch = ch;
2881 }
2882 }
2883 else
2884 {
2885 ungetc_string();
2886 ungetc_string();
2887 return TRUE;
2888 }
2889 }
2890 break;
2891 default:
2892 ungetc_string();
2893 return TRUE;
2894
2895 }
2896 }
2897 return FALSE;
2898 }
2899
2900 bool wxGetResourceTokenString(char *s)
2901 {
2902 if (!wxResourceBuffer)
2903 wxReallocateResourceBuffer();
2904 wxResourceBuffer[0] = 0;
2905 wxEatWhiteSpaceString(s);
2906
2907 int ch = getc_string(s);
2908 if (ch == '"')
2909 {
2910 // Get string
2911 wxResourceBufferCount = 0;
2912 ch = getc_string(s);
2913 while (ch != '"')
2914 {
2915 int actualCh = ch;
2916 if (ch == EOF)
2917 {
2918 wxResourceBuffer[wxResourceBufferCount] = 0;
2919 return FALSE;
2920 }
2921 // Escaped characters
2922 else if (ch == '\\')
2923 {
2924 int newCh = getc_string(s);
2925 if (newCh == '"')
2926 actualCh = '"';
2927 else if (newCh == 10)
2928 actualCh = 10;
2929 else
2930 {
2931 ungetc_string();
2932 }
2933 }
2934
2935 if (wxResourceBufferCount >= wxResourceBufferSize-1)
2936 wxReallocateResourceBuffer();
2937 wxResourceBuffer[wxResourceBufferCount] = (char)actualCh;
2938 wxResourceBufferCount ++;
2939 ch = getc_string(s);
2940 }
2941 wxResourceBuffer[wxResourceBufferCount] = 0;
2942 }
2943 else
2944 {
2945 wxResourceBufferCount = 0;
2946 // Any other token
2947 while (ch != ' ' && ch != EOF && ch != ' ' && ch != 13 && ch != 9 && ch != 10)
2948 {
2949 if (wxResourceBufferCount >= wxResourceBufferSize-1)
2950 wxReallocateResourceBuffer();
2951 wxResourceBuffer[wxResourceBufferCount] = (char)ch;
2952 wxResourceBufferCount ++;
2953
2954 ch = getc_string(s);
2955 }
2956 wxResourceBuffer[wxResourceBufferCount] = 0;
2957 if (ch == EOF)
2958 return FALSE;
2959 }
2960 return TRUE;
2961 }
2962
2963 /*
2964 * Files are in form:
2965 static char *name = "....";
2966 with possible comments.
2967 */
2968
2969 bool wxResourceReadOneResourceString(char *s, wxExprDatabase& db, bool *eof, wxResourceTable *table)
2970 {
2971 if (!table)
2972 table = wxDefaultResourceTable;
2973
2974 // static or #define
2975 if (!wxGetResourceTokenString(s))
2976 {
2977 *eof = TRUE;
2978 return FALSE;
2979 }
2980
2981 if (strcmp(wxResourceBuffer, "#define") == 0)
2982 {
2983 wxGetResourceTokenString(s);
2984 wxChar *name = copystring(wxConvCurrent->cMB2WX(wxResourceBuffer));
2985 wxGetResourceTokenString(s);
2986 wxChar *value = copystring(wxConvCurrent->cMB2WX(wxResourceBuffer));
2987 if (wxIsdigit(value[0]))
2988 {
2989 int val = (int)wxAtol(value);
2990 wxResourceAddIdentifier(name, val, table);
2991 }
2992 else
2993 {
2994 wxLogWarning(_("#define %s must be an integer."), name);
2995 delete[] name;
2996 delete[] value;
2997 return FALSE;
2998 }
2999 delete[] name;
3000 delete[] value;
3001
3002 return TRUE;
3003 }
3004 /*
3005 else if (strcmp(wxResourceBuffer, "#include") == 0)
3006 {
3007 wxGetResourceTokenString(s);
3008 char *name = copystring(wxResourceBuffer);
3009 char *actualName = name;
3010 if (name[0] == '"')
3011 actualName = name + 1;
3012 int len = strlen(name);
3013 if ((len > 0) && (name[len-1] == '"'))
3014 name[len-1] = 0;
3015 if (!wxResourceParseIncludeFile(actualName, table))
3016 {
3017 char buf[400];
3018 sprintf(buf, _("Could not find resource include file %s."), actualName);
3019 wxLogWarning(buf);
3020 }
3021 delete[] name;
3022 return TRUE;
3023 }
3024 */
3025 else if (strcmp(wxResourceBuffer, "static") != 0)
3026 {
3027 wxChar buf[300];
3028 wxStrcpy(buf, _("Found "));
3029 wxStrncat(buf, wxConvCurrent->cMB2WX(wxResourceBuffer), 30);
3030 wxStrcat(buf, _(", expected static, #include or #define\nwhilst parsing resource."));
3031 wxLogWarning(buf);
3032 return FALSE;
3033 }
3034
3035 // char
3036 if (!wxGetResourceTokenString(s))
3037 {
3038 wxLogWarning(_("Unexpected end of file whilst parsing resource."));
3039 *eof = TRUE;
3040 return FALSE;
3041 }
3042
3043 if (strcmp(wxResourceBuffer, "char") != 0)
3044 {
3045 wxLogWarning(_("Expected 'char' whilst parsing resource."));
3046 return FALSE;
3047 }
3048
3049 // *name
3050 if (!wxGetResourceTokenString(s))
3051 {
3052 wxLogWarning(_("Unexpected end of file whilst parsing resource."));
3053 *eof = TRUE;
3054 return FALSE;
3055 }
3056
3057 if (wxResourceBuffer[0] != '*')
3058 {
3059 wxLogWarning(_("Expected '*' whilst parsing resource."));
3060 return FALSE;
3061 }
3062 wxChar nameBuf[100];
3063 wxMB2WX(nameBuf, wxResourceBuffer+1, 99);
3064 nameBuf[99] = 0;
3065
3066 // =
3067 if (!wxGetResourceTokenString(s))
3068 {
3069 wxLogWarning(_("Unexpected end of file whilst parsing resource."));
3070 *eof = TRUE;
3071 return FALSE;
3072 }
3073
3074 if (strcmp(wxResourceBuffer, "=") != 0)
3075 {
3076 wxLogWarning(_("Expected '=' whilst parsing resource."));
3077 return FALSE;
3078 }
3079
3080 // String
3081 if (!wxGetResourceTokenString(s))
3082 {
3083 wxLogWarning(_("Unexpected end of file whilst parsing resource."));
3084 *eof = TRUE;
3085 return FALSE;
3086 }
3087 else
3088 {
3089 if (!db.ReadPrologFromString(wxResourceBuffer))
3090 {
3091 wxLogWarning(_("%s: ill-formed resource file syntax."), nameBuf);
3092 return FALSE;
3093 }
3094 }
3095 // Semicolon
3096 if (!wxGetResourceTokenString(s))
3097 {
3098 *eof = TRUE;
3099 }
3100 return TRUE;
3101 }
3102
3103 bool wxResourceParseString(char *s, wxResourceTable *table)
3104 {
3105 if (!table)
3106 table = wxDefaultResourceTable;
3107
3108 if (!s)
3109 return FALSE;
3110
3111 // Turn backslashes into spaces
3112 if (s)
3113 {
3114 int len = strlen(s);
3115 int i;
3116 for (i = 0; i < len; i++)
3117 if (s[i] == 92 && s[i+1] == 13)
3118 {
3119 s[i] = ' ';
3120 s[i+1] = ' ';
3121 }
3122 }
3123
3124 wxExprDatabase db;
3125 wxResourceStringPtr = 0;
3126
3127 bool eof = FALSE;
3128 while (wxResourceReadOneResourceString(s, db, &eof, table) && !eof)
3129 {
3130 // Loop
3131 }
3132 return wxResourceInterpretResources(*table, db);
3133 }
3134
3135 /*
3136 * resource loading facility
3137 */
3138
3139 bool wxWindowBase::LoadFromResource(wxWindow *parent, const wxString& resourceName, const wxResourceTable *table)
3140 {
3141 if (!table)
3142 table = wxDefaultResourceTable;
3143
3144 wxItemResource *resource = table->FindResource((const wxChar *)resourceName);
3145 // if (!resource || (resource->GetType() != wxTYPE_DIALOG_BOX))
3146 if (!resource || (resource->GetType() == wxT("")) ||
3147 ! ((resource->GetType() == wxT("wxDialog")) || (resource->GetType() == wxT("wxPanel"))))
3148 return FALSE;
3149
3150 wxString title(resource->GetTitle());
3151 long theWindowStyle = resource->GetStyle();
3152 bool isModal = (resource->GetValue1() != 0) ;
3153 int x = resource->GetX();
3154 int y = resource->GetY();
3155 int width = resource->GetWidth();
3156 int height = resource->GetHeight();
3157 wxString name = resource->GetName();
3158
3159 // this is used for loading wxWizard pages from WXR
3160 if ( parent != this )
3161 {
3162 if (IsKindOf(CLASSINFO(wxDialog)))
3163 {
3164 wxDialog *dialogBox = (wxDialog *)this;
3165 long modalStyle = isModal ? wxDIALOG_MODAL : 0;
3166 if (!dialogBox->Create(parent, -1, title, wxPoint(x, y), wxSize(width, height), theWindowStyle|modalStyle, name))
3167 return FALSE;
3168
3169 // Only reset the client size if we know we're not going to do it again below.
3170 if ((resource->GetResourceStyle() & wxRESOURCE_DIALOG_UNITS) == 0)
3171 dialogBox->SetClientSize(width, height);
3172 }
3173 else if (IsKindOf(CLASSINFO(wxPanel)))
3174 {
3175 wxPanel* panel = (wxPanel *)this;
3176 if (!panel->Create(parent, -1, wxPoint(x, y), wxSize(width, height), theWindowStyle | wxTAB_TRAVERSAL, name))
3177 return FALSE;
3178 }
3179 else
3180 {
3181 if (!((wxWindow *)this)->Create(parent, -1, wxPoint(x, y), wxSize(width, height), theWindowStyle, name))
3182 return FALSE;
3183 }
3184 }
3185
3186 if ((resource->GetResourceStyle() & wxRESOURCE_USE_DEFAULTS) != 0)
3187 {
3188 // No need to do this since it's done in wxPanel or wxDialog constructor.
3189 // SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
3190 }
3191 else
3192 {
3193 if (resource->GetFont().Ok())
3194 SetFont(resource->GetFont());
3195 if (resource->GetBackgroundColour().Ok())
3196 SetBackgroundColour(resource->GetBackgroundColour());
3197 }
3198
3199 // Should have some kind of font at this point
3200 if (!GetFont().Ok())
3201 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
3202 if (!GetBackgroundColour().Ok())
3203 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
3204
3205 // Only when we've created the window and set the font can we set the correct size,
3206 // if based on dialog units.
3207 if ((resource->GetResourceStyle() & wxRESOURCE_DIALOG_UNITS) != 0)
3208 {
3209 wxSize sz = ConvertDialogToPixels(wxSize(width, height));
3210 SetClientSize(sz.x, sz.y);
3211
3212 wxPoint pt = ConvertDialogToPixels(wxPoint(x, y));
3213 Move(pt.x, pt.y);
3214 }
3215
3216 // Now create children
3217 wxNode *node = resource->GetChildren().First();
3218 while (node)
3219 {
3220 wxItemResource *childResource = (wxItemResource *)node->Data();
3221
3222 (void) CreateItem(childResource, resource, table);
3223
3224 node = node->Next();
3225 }
3226 return TRUE;
3227 }
3228
3229 wxControl *wxWindowBase::CreateItem(const wxItemResource *resource, const wxItemResource* parentResource, const wxResourceTable *table)
3230 {
3231 if (!table)
3232 table = wxDefaultResourceTable;
3233 return table->CreateItem((wxWindow *)this, resource, parentResource);
3234 }
3235
3236 #ifdef __VISUALC__
3237 #pragma warning(default:4706) // assignment within conditional expression
3238 #endif // VC++
3239
3240 #endif
3241 // BC++/Win16
3242
3243 #endif // wxUSE_WX_RESOURCES