home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / common / resource.cpp < prev    next >
C/C++ Source or Header  |  2002-11-04  |  105KB  |  3,244 lines

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