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