]> git.saurik.com Git - wxWidgets.git/blobdiff - src/xrc/xmlres.cpp
Set C++ global locale too in wxAppTraitsBase::SetLocale().
[wxWidgets.git] / src / xrc / xmlres.cpp
index 1b62dbc3dcfe6a78e7099f748c5309d2ff1ed48c..06edee5ffc33f8f0d7b654f6893b406475c0c1a4 100644 (file)
@@ -73,6 +73,10 @@ wxDateTime GetXRCFileModTime(const wxString& filename)
 
 } // anonymous namespace
 
+// Assign the given value to the specified entry or add a new value with this
+// name.
+static void XRCID_Assign(const wxString& str_id, int value);
+
 class wxXmlResourceDataRecord
 {
 public:
@@ -103,7 +107,7 @@ class wxXmlResourceDataRecords : public wxVector<wxXmlResourceDataRecord*>
     // this is a class so that it can be forward-declared
 };
 
-WX_DECLARE_HASH_SET(int, wxIntegerHash, wxIntegerEqual, wxHashSetInt);
+WX_DECLARE_HASH_SET_PTR(int, wxIntegerHash, wxIntegerEqual, wxHashSetInt);
 
 class wxIdRange // Holds data for a particular rangename
 {
@@ -152,9 +156,6 @@ public:
     void FinaliseRanges(const wxXmlNode* node) const;
     // Searches for a known IdRange matching 'name', returning its index or -1
     int Find(const wxString& rangename) const;
-    // Removes, if it exists, an entry from the XRCID table. Used in id-ranges
-    // to replace defunct or statically-initialised entries with current values
-    static void RemoveXRCIDEntry(const wxString& idstr);
 
 protected:
     wxIdRange* FindRangeForItem(const wxXmlNode* node,
@@ -983,7 +984,10 @@ wxXmlResource::DoCreateResFromNode(wxXmlNode& node,
             return NULL;
         }
 
-        if ( !node.GetChildren() )
+        const bool hasOnlyRefAttr = node.GetAttributes() != NULL &&
+                                    node.GetAttributes()->GetNext() == NULL;
+
+        if ( hasOnlyRefAttr && !node.GetChildren() )
         {
             // In the typical, simple case, <object_ref> is used to link
             // to another node and doesn't have any content of its own that
@@ -1213,13 +1217,10 @@ void wxIdRange::Finalise(const wxXmlNode* node)
     // Create the XRCIDs
     for (int i=m_start; i <= m_end; ++i)
     {
-        // First clear any pre-existing XRCID
-        // Necessary for wxXmlResource::Unload() followed by Load()
-        wxIdRangeManager::RemoveXRCIDEntry(
-                m_name + wxString::Format("[%i]", i-m_start));
+        // Ensure that we overwrite any existing value as otherwise
+        // wxXmlResource::Unload() followed by Load() wouldn't work correctly.
+        XRCID_Assign(m_name + wxString::Format("[%i]", i-m_start), i);
 
-        // Use the second parameter of GetXRCID to force it to take the value i
-        wxXmlResource::GetXRCID(m_name + wxString::Format("[%i]", i-m_start), i);
         wxLogTrace("xrcrange",
                    "integer = %i %s now returns %i",
                    i,
@@ -1227,10 +1228,8 @@ void wxIdRange::Finalise(const wxXmlNode* node)
                    XRCID((m_name + wxString::Format("[%i]", i-m_start)).mb_str()));
     }
     // and these special ones
-    wxIdRangeManager::RemoveXRCIDEntry(m_name + "[start]");
-    wxXmlResource::GetXRCID(m_name + "[start]", m_start);
-    wxIdRangeManager::RemoveXRCIDEntry(m_name + "[end]");
-    wxXmlResource::GetXRCID(m_name + "[end]", m_end);
+    XRCID_Assign(m_name + "[start]", m_start);
+    XRCID_Assign(m_name + "[end]", m_end);
     wxLogTrace("xrcrange","%s[start] = %i  %s[end] = %i",
             m_name.mb_str(),XRCID(wxString(m_name+"[start]").mb_str()),
                 m_name.mb_str(),XRCID(wxString(m_name+"[end]").mb_str()));
@@ -1483,15 +1482,23 @@ void wxXmlResourceHandler::AddWindowStyles()
     XRC_ADD_STYLE(wxRAISED_BORDER); XRC_ADD_STYLE(wxBORDER_RAISED);
     XRC_ADD_STYLE(wxSTATIC_BORDER); XRC_ADD_STYLE(wxBORDER_STATIC);
     XRC_ADD_STYLE(wxNO_BORDER);     XRC_ADD_STYLE(wxBORDER_NONE);
+    XRC_ADD_STYLE(wxBORDER_DEFAULT);
 
     XRC_ADD_STYLE(wxTRANSPARENT_WINDOW);
     XRC_ADD_STYLE(wxWANTS_CHARS);
     XRC_ADD_STYLE(wxTAB_TRAVERSAL);
     XRC_ADD_STYLE(wxNO_FULL_REPAINT_ON_RESIZE);
     XRC_ADD_STYLE(wxFULL_REPAINT_ON_RESIZE);
+    XRC_ADD_STYLE(wxVSCROLL);
+    XRC_ADD_STYLE(wxHSCROLL);
     XRC_ADD_STYLE(wxALWAYS_SHOW_SB);
+
     XRC_ADD_STYLE(wxWS_EX_BLOCK_EVENTS);
     XRC_ADD_STYLE(wxWS_EX_VALIDATE_RECURSIVELY);
+    XRC_ADD_STYLE(wxWS_EX_TRANSIENT);
+    XRC_ADD_STYLE(wxWS_EX_CONTEXTHELP);
+    XRC_ADD_STYLE(wxWS_EX_PROCESS_IDLE);
+    XRC_ADD_STYLE(wxWS_EX_PROCESS_UI_UPDATES);
 }
 
 
@@ -1555,7 +1562,7 @@ wxString wxXmlResourceHandler::GetText(const wxString& param, bool translate)
         // like "&File..." -- this is illegal in XML, so we use "_File..."):
         if ( *dt == amp_char )
         {
-            if ( *(++dt) == amp_char )
+            if ( dt+1 == str1.end() || *(++dt) == amp_char )
                 str2 << amp_char;
             else
                 str2 << wxT('&') << *dt;
@@ -1626,11 +1633,20 @@ wxString wxXmlResourceHandler::GetText(const wxString& param, bool translate)
 
 long wxXmlResourceHandler::GetLong(const wxString& param, long defaultv)
 {
-    long value;
+    long value = defaultv;
     wxString str1 = GetParamValue(param);
 
-    if (!str1.ToLong(&value))
-        value = defaultv;
+    if (!str1.empty())
+    {
+        if (!str1.ToLong(&value))
+        {
+            ReportParamError
+            (
+                param,
+                wxString::Format("invalid long specification \"%s\"", str1)
+            );
+        }
+    }
 
     return value;
 }
@@ -1642,9 +1658,18 @@ float wxXmlResourceHandler::GetFloat(const wxString& param, float defaultv)
     // strings in XRC always use C locale so make sure to use the
     // locale-independent wxString::ToCDouble() and not ToDouble() which uses
     // the current locale with a potentially different decimal point character
-    double value;
-    if (!str.ToCDouble(&value))
-        value = defaultv;
+    double value = defaultv;
+    if (!str.empty())
+    {
+        if (!str.ToCDouble(&value))
+        {
+            ReportParamError
+            (
+                param,
+                wxString::Format("invalid float specification \"%s\"", str)
+            );
+        }
+    }
 
     return wx_truncate_cast(float, value);
 }
@@ -1742,7 +1767,7 @@ wxColour wxXmlResourceHandler::GetColour(const wxString& param, const wxColour&
         // the colour doesn't use #RRGGBB format, check if it is symbolic
         // colour name:
         clr = GetSystemColour(v);
-        if (clr.Ok())
+        if (clr.IsOk())
             return clr;
 
         ReportParamError
@@ -1820,7 +1845,7 @@ wxBitmap wxXmlResourceHandler::GetBitmap(const wxXmlNode* node,
                           art_id, art_client) )
     {
         wxBitmap stockArt(wxArtProvider::GetBitmap(art_id, art_client, size));
-        if ( stockArt.Ok() )
+        if ( stockArt.IsOk() )
             return stockArt;
     }
 
@@ -1844,7 +1869,7 @@ wxBitmap wxXmlResourceHandler::GetBitmap(const wxXmlNode* node,
     wxImage img(name);
 #endif
 
-    if (!img.Ok())
+    if (!img.IsOk())
     {
         ReportParamError
         (
@@ -1958,7 +1983,7 @@ wxImageList *wxXmlResourceHandler::GetImageList(const wxString& param)
         {
             if (n->GetType() == wxXML_ELEMENT_NODE && n->GetName() == parambitmap)
             {
-                wxIcon icon = GetIcon(n);
+                wxIcon icon = GetIcon(n, wxART_OTHER, size);
                 if ( !imagelist )
                 {
                     // We need the real image list size to create it.
@@ -2147,6 +2172,40 @@ wxCoord wxXmlResourceHandler::GetDimension(const wxString& param,
     return sx;
 }
 
+wxDirection
+wxXmlResourceHandler::GetDirection(const wxString& param, wxDirection dirDefault)
+{
+    wxDirection dir;
+
+    const wxString dirstr = GetParamValue(param);
+    if ( dirstr.empty() )
+        dir = dirDefault;
+    else if ( dirstr == "wxLEFT" )
+        dir = wxLEFT;
+    else if ( dirstr == "wxRIGHT" )
+        dir = wxRIGHT;
+    else if ( dirstr == "wxTOP" )
+        dir = wxTOP;
+    else if ( dirstr == "wxBOTTOM" )
+        dir = wxBOTTOM;
+    else
+    {
+        ReportError
+        (
+            GetParamNode(param),
+            wxString::Format
+            (
+                "Invalid direction \"%s\": must be one of "
+                "wxLEFT|wxRIGHT|wxTOP|wxBOTTOM.",
+                dirstr
+            )
+        );
+
+        dir = dirDefault;
+    }
+
+    return dir;
+}
 
 // Get system font index using indexname
 static wxFont GetSystemFont(const wxString& name)
@@ -2168,7 +2227,7 @@ static wxFont GetSystemFont(const wxString& name)
     return wxNullFont;
 }
 
-wxFont wxXmlResourceHandler::GetFont(const wxString& param)
+wxFont wxXmlResourceHandler::GetFont(const wxString& param, wxWindow* parent)
 {
     wxXmlNode *font_node = GetParamNode(param);
     if (font_node == NULL)
@@ -2199,6 +2258,14 @@ wxFont wxXmlResourceHandler::GetFont(const wxString& param)
             istyle = wxITALIC;
         else if (style == wxT("slant"))
             istyle = wxSLANT;
+        else if (style != wxT("normal"))
+        {
+            ReportParamError
+            (
+                param,
+                wxString::Format("unknown font style \"%s\"", style)
+            );
+        }
     }
 
     // weight
@@ -2211,6 +2278,14 @@ wxFont wxXmlResourceHandler::GetFont(const wxString& param)
             iweight = wxBOLD;
         else if (weight == wxT("light"))
             iweight = wxLIGHT;
+        else if (weight != wxT("normal"))
+        {
+            ReportParamError
+            (
+                param,
+                wxString::Format("unknown font weight \"%s\"", weight)
+            );
+        }
     }
 
     // underline
@@ -2229,6 +2304,14 @@ wxFont wxXmlResourceHandler::GetFont(const wxString& param)
         else if (family == wxT("swiss")) ifamily = wxSWISS;
         else if (family == wxT("modern")) ifamily = wxMODERN;
         else if (family == wxT("teletype")) ifamily = wxTELETYPE;
+        else
+        {
+            ReportParamError
+            (
+                param,
+                wxString::Format("unknown font family \"%s\"", family)
+            );
+        }
     }
 
 
@@ -2271,13 +2354,50 @@ wxFont wxXmlResourceHandler::GetFont(const wxString& param)
     }
 #endif // wxUSE_FONTMAP
 
+    wxFont font;
+
     // is this font based on a system font?
-    wxFont font = GetSystemFont(GetParamValue(wxT("sysfont")));
+    if (HasParam(wxT("sysfont")))
+    {
+        font = GetSystemFont(GetParamValue(wxT("sysfont")));
+        if (HasParam(wxT("inherit")))
+        {
+            ReportParamError
+            (
+                param,
+                "double specification of \"sysfont\" and \"inherit\""
+            );
+        }
+    }
+    // or should the font of the widget be used?
+    else if (GetBool(wxT("inherit"), false))
+    {
+        if (parent)
+            font = parent->GetFont();
+        else
+        {
+            ReportParamError
+            (
+                param,
+                "no parent window specified to derive the font from"
+            );
+        }
+    }
 
-    if (font.Ok())
+    if (font.IsOk())
     {
         if (hasSize && isize != -1)
+        {
             font.SetPointSize(isize);
+            if (HasParam(wxT("relativesize")))
+            {
+                ReportParamError
+                (
+                    param,
+                    "double specification of \"size\" and \"relativesize\""
+                );
+            }
+        }
         else if (HasParam(wxT("relativesize")))
             font.SetPointSize(int(font.GetPointSize() *
                                      GetFloat(wxT("relativesize"))));
@@ -2335,9 +2455,9 @@ void wxXmlResourceHandler::SetupWindow(wxWindow *wnd)
         wnd->SetToolTip(GetText(wxT("tooltip")));
 #endif
     if (HasParam(wxT("font")))
-        wnd->SetFont(GetFont(wxT("font")));
+        wnd->SetFont(GetFont(wxT("font"), wnd));
     if (HasParam(wxT("ownfont")))
-        wnd->SetOwnFont(GetFont(wxT("ownfont")));
+        wnd->SetOwnFont(GetFont(wxT("ownfont"), wnd));
     if (HasParam(wxT("help")))
         wnd->SetHelpText(GetText(wxT("help")));
 }
@@ -2458,6 +2578,31 @@ static inline unsigned XRCIdHash(const char *str_id)
     return index;
 }
 
+static void XRCID_Assign(const wxString& str_id, int value)
+{
+    const wxCharBuffer buf_id(str_id.mb_str());
+    const unsigned index = XRCIdHash(buf_id);
+
+
+    XRCID_record *oldrec = NULL;
+    for (XRCID_record *rec = XRCID_Records[index]; rec; rec = rec->next)
+    {
+        if (wxStrcmp(rec->key, buf_id) == 0)
+        {
+            rec->id = value;
+            return;
+        }
+        oldrec = rec;
+    }
+
+    XRCID_record **rec_var = (oldrec == NULL) ?
+                              &XRCID_Records[index] : &oldrec->next;
+    *rec_var = new XRCID_record;
+    (*rec_var)->key = wxStrdup(str_id);
+    (*rec_var)->id = value;
+    (*rec_var)->next = NULL;
+}
+
 static int XRCID_Lookup(const char *str_id, int value_if_not_found = wxID_NONE)
 {
     const unsigned index = XRCIdHash(str_id);
@@ -2529,11 +2674,14 @@ void AddStdXRCID_Records()
     stdID(wxID_PREVIEW);
     stdID(wxID_ABOUT);
     stdID(wxID_HELP_CONTENTS);
+    stdID(wxID_HELP_INDEX),
+    stdID(wxID_HELP_SEARCH),
     stdID(wxID_HELP_COMMANDS);
     stdID(wxID_HELP_PROCEDURES);
     stdID(wxID_HELP_CONTEXT);
     stdID(wxID_CLOSE_ALL);
     stdID(wxID_PREFERENCES);
+
     stdID(wxID_EDIT);
     stdID(wxID_CUT);
     stdID(wxID_COPY);
@@ -2546,6 +2694,7 @@ void AddStdXRCID_Records()
     stdID(wxID_REPLACE);
     stdID(wxID_REPLACE_ALL);
     stdID(wxID_PROPERTIES);
+
     stdID(wxID_VIEW_DETAILS);
     stdID(wxID_VIEW_LARGEICONS);
     stdID(wxID_VIEW_SMALLICONS);
@@ -2554,6 +2703,8 @@ void AddStdXRCID_Records()
     stdID(wxID_VIEW_SORTNAME);
     stdID(wxID_VIEW_SORTSIZE);
     stdID(wxID_VIEW_SORTTYPE);
+
+
     stdID(wxID_FILE1);
     stdID(wxID_FILE2);
     stdID(wxID_FILE3);
@@ -2563,6 +2714,8 @@ void AddStdXRCID_Records()
     stdID(wxID_FILE7);
     stdID(wxID_FILE8);
     stdID(wxID_FILE9);
+
+
     stdID(wxID_OK);
     stdID(wxID_CANCEL);
     stdID(wxID_APPLY);
@@ -2583,12 +2736,14 @@ void AddStdXRCID_Records()
     stdID(wxID_IGNORE);
     stdID(wxID_ADD);
     stdID(wxID_REMOVE);
+
     stdID(wxID_UP);
     stdID(wxID_DOWN);
     stdID(wxID_HOME);
     stdID(wxID_REFRESH);
     stdID(wxID_STOP);
     stdID(wxID_INDEX);
+
     stdID(wxID_BOLD);
     stdID(wxID_ITALIC);
     stdID(wxID_JUSTIFY_CENTER);
@@ -2604,13 +2759,6 @@ void AddStdXRCID_Records()
     stdID(wxID_ZOOM_OUT);
     stdID(wxID_UNDELETE);
     stdID(wxID_REVERT_TO_SAVED);
-    stdID(wxID_SYSTEM_MENU);
-    stdID(wxID_CLOSE_FRAME);
-    stdID(wxID_MOVE_FRAME);
-    stdID(wxID_RESIZE_FRAME);
-    stdID(wxID_MAXIMIZE_FRAME);
-    stdID(wxID_ICONIZE_FRAME);
-    stdID(wxID_RESTORE_FRAME);
     stdID(wxID_CDROM);
     stdID(wxID_CONVERT);
     stdID(wxID_EXECUTE);
@@ -2630,6 +2778,23 @@ void AddStdXRCID_Records()
     stdID(wxID_SPELL_CHECK);
     stdID(wxID_STRIKETHROUGH);
 
+
+    stdID(wxID_SYSTEM_MENU);
+    stdID(wxID_CLOSE_FRAME);
+    stdID(wxID_MOVE_FRAME);
+    stdID(wxID_RESIZE_FRAME);
+    stdID(wxID_MAXIMIZE_FRAME);
+    stdID(wxID_ICONIZE_FRAME);
+    stdID(wxID_RESTORE_FRAME);
+
+
+
+    stdID(wxID_MDI_WINDOW_CASCADE);
+    stdID(wxID_MDI_WINDOW_TILE_HORZ);
+    stdID(wxID_MDI_WINDOW_TILE_VERT);
+    stdID(wxID_MDI_WINDOW_ARRANGE_ICONS);
+    stdID(wxID_MDI_WINDOW_PREV);
+    stdID(wxID_MDI_WINDOW_NEXT);
 #undef stdID
 }
 
@@ -2663,30 +2828,6 @@ wxString wxXmlResource::FindXRCIDById(int numId)
     return wxString();
 }
 
-/* static */
-void wxIdRangeManager::RemoveXRCIDEntry(const wxString& idstr)
-{
-    const char *str_id = idstr.mb_str();
-
-    const unsigned index = XRCIdHash(str_id);
-
-    XRCID_record **p_previousrec = &XRCID_Records[index];
-    for (XRCID_record *rec = XRCID_Records[index]; rec; rec = rec->next)
-    {
-        if (wxStrcmp(rec->key, str_id) == 0)
-        {
-            // Found the item to be removed so delete its record; but first
-            // remove it from the linked list.
-            *p_previousrec = rec->next;
-            free(rec->key);
-            delete rec;
-            return;
-        }
-
-        p_previousrec = &rec->next;
-    }
-}
-
 static void CleanXRCID_Record(XRCID_record *rec)
 {
     if (rec)