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