X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/3a3013019a93ae68757a501fd0b732290bc62ade..9d8fe14a97d1092989eecbe43c4e1f730fba17ad:/src/xrc/xmlres.cpp?ds=sidebyside diff --git a/src/xrc/xmlres.cpp b/src/xrc/xmlres.cpp index 90aba8c06e..5a024457b6 100644 --- a/src/xrc/xmlres.cpp +++ b/src/xrc/xmlres.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: xmlres.cpp +// Name: src/xrc/xmlres.cpp // Purpose: XRC resources // Author: Vaclav Slavik // Created: 2000/03/05 @@ -8,10 +8,6 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ -#pragma implementation "xmlres.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -21,27 +17,37 @@ #if wxUSE_XRC -#include "wx/dialog.h" -#include "wx/panel.h" -#include "wx/frame.h" +#include "wx/xrc/xmlres.h" + +#ifndef WX_PRECOMP + #include "wx/intl.h" + #include "wx/log.h" + #include "wx/panel.h" + #include "wx/frame.h" + #include "wx/dialog.h" + #include "wx/settings.h" + #include "wx/bitmap.h" + #include "wx/image.h" + #include "wx/module.h" + #include "wx/wxcrtvararg.h" +#endif + +#ifndef __WXWINCE__ + #include +#endif + #include "wx/wfstream.h" #include "wx/filesys.h" #include "wx/filename.h" -#include "wx/log.h" -#include "wx/intl.h" #include "wx/tokenzr.h" #include "wx/fontenum.h" -#include "wx/module.h" -#include "wx/bitmap.h" -#include "wx/image.h" #include "wx/fontmap.h" #include "wx/artprov.h" #include "wx/xml/xml.h" -#include "wx/xrc/xmlres.h" #include "wx/arrimpl.cpp" -WX_DEFINE_OBJARRAY(wxXmlResourceDataRecords); +WX_DEFINE_OBJARRAY(wxXmlResourceDataRecords) wxXmlResource *wxXmlResource::ms_instance = NULL; @@ -60,16 +66,18 @@ wxXmlResource *wxXmlResource::ms_instance = NULL; return old; } -wxXmlResource::wxXmlResource(int flags) +wxXmlResource::wxXmlResource(int flags, const wxString& domain) { m_flags = flags; m_version = -1; + SetDomain(domain); } -wxXmlResource::wxXmlResource(const wxString& filemask, int flags) +wxXmlResource::wxXmlResource(const wxString& filemask, int flags, const wxString& domain) { m_flags = flags; m_version = -1; + SetDomain(domain); Load(filemask); } @@ -78,6 +86,51 @@ wxXmlResource::~wxXmlResource() ClearHandlers(); } +void wxXmlResource::SetDomain(const wxString& domain) +{ + m_domain = domain; +} + + +/* static */ +wxString wxXmlResource::ConvertFileNameToURL(const wxString& filename) +{ + wxString fnd(filename); + + // NB: as Load() and Unload() accept both filenames and URLs (should + // probably be changed to filenames only, but embedded resources + // currently rely on its ability to handle URLs - FIXME) we need to + // determine whether found name is filename and not URL and this is the + // fastest/simplest way to do it + if (wxFileName::FileExists(fnd)) + { + // Make the name absolute filename, because the app may + // change working directory later: + wxFileName fn(fnd); + if (fn.IsRelative()) + { + fn.MakeAbsolute(); + fnd = fn.GetFullPath(); + } +#if wxUSE_FILESYSTEM + fnd = wxFileSystem::FileNameToURL(fnd); +#endif + } + + return fnd; +} + +#if wxUSE_FILESYSTEM + +/* static */ +bool wxXmlResource::IsArchive(const wxString& filename) +{ + const wxString fnd = filename.Lower(); + + return fnd.Matches(wxT("*.zip")) || fnd.Matches(wxT("*.xrs")); +} + +#endif // wxUSE_FILESYSTEM bool wxXmlResource::Load(const wxString& filemask) { @@ -98,36 +151,17 @@ bool wxXmlResource::Load(const wxString& filemask) fnd = wxXmlFindFirst; else fnd = filemask; - while (!!fnd) + while (!fnd.empty()) { - // NB: Load() accepts both filenames and URLs (should probably be - // changed to filenames only, but embedded resources currently - // rely on its ability to handle URLs - FIXME). This check - // serves as a quick way to determine whether found name is - // filename and not URL: - if (wxFileName::FileExists(fnd)) - { - // Make the name absolute filename, because the app may - // change working directory later: - wxFileName fn(fnd); - if (fn.IsRelative()) - { - fn.MakeAbsolute(); - fnd = fn.GetFullPath(); - } -#if wxUSE_FILESYSTEM - fnd = wxFileSystem::FileNameToURL(fnd); -#endif - } + fnd = ConvertFileNameToURL(fnd); #if wxUSE_FILESYSTEM - if (fnd.Lower().Matches(wxT("*.zip")) || - fnd.Lower().Matches(wxT("*.xrs"))) + if ( IsArchive(fnd) ) { rt = rt && Load(fnd + wxT("#zip:*.xrc")); } - else -#endif + else // a single resource URL +#endif // wxUSE_FILESYSTEM { drec = new wxXmlResourceDataRecord; drec->File = fnd; @@ -144,6 +178,46 @@ bool wxXmlResource::Load(const wxString& filemask) return rt && UpdateResources(); } +bool wxXmlResource::Unload(const wxString& filename) +{ + wxASSERT_MSG( !wxIsWild(filename), + _T("wildcards not supported by wxXmlResource::Unload()") ); + + wxString fnd = ConvertFileNameToURL(filename); +#if wxUSE_FILESYSTEM + const bool isArchive = IsArchive(fnd); + if ( isArchive ) + fnd += _T("#zip:"); +#endif // wxUSE_FILESYSTEM + + bool unloaded = false; + const size_t count = m_data.GetCount(); + for ( size_t i = 0; i < count; i++ ) + { +#if wxUSE_FILESYSTEM + if ( isArchive ) + { + if ( m_data[i].File.StartsWith(fnd) ) + unloaded = true; + // don't break from the loop, we can have other matching files + } + else // a single resource URL +#endif // wxUSE_FILESYSTEM + { + if ( m_data[i].File == fnd ) + { + m_data.RemoveAt(i); + unloaded = true; + + // no sense in continuing, there is only one file with this URL + break; + } + } + } + + return unloaded; +} + IMPLEMENT_ABSTRACT_CLASS(wxXmlResourceHandler, wxObject) @@ -277,7 +351,7 @@ static void ProcessPlatformProperty(wxXmlNode *node) while (c) { isok = false; - if (!c->GetPropVal(wxT("platform"), &s)) + if (!c->GetAttribute(wxT("platform"), &s)) isok = true; else { @@ -349,7 +423,11 @@ bool wxXmlResource::UpdateResources() { # if wxUSE_FILESYSTEM file = fsys.OpenFile(m_data[i].File); +# if wxUSE_DATETIME modif = file && file->GetModificationTime() > m_data[i].Time; +# else // wxUSE_DATETIME + modif = true; +# endif // wxUSE_DATETIME if (!file) { wxLogError(_("Cannot open file '%s'."), m_data[i].File.c_str()); @@ -357,9 +435,13 @@ bool wxXmlResource::UpdateResources() } wxDELETE(file); wxUnusedVar(file); -# else +# else // wxUSE_FILESYSTEM +# if wxUSE_DATETIME modif = wxDateTime(wxFileModificationTime(m_data[i].File)) > m_data[i].Time; -# endif +# else // wxUSE_DATETIME + modif = true; +# endif // wxUSE_DATETIME +# endif // wxUSE_FILESYSTEM } if (modif) @@ -399,7 +481,7 @@ bool wxXmlResource::UpdateResources() { long version; int v1, v2, v3, v4; - wxString verstr = m_data[i].Doc->GetRoot()->GetPropVal( + wxString verstr = m_data[i].Doc->GetRoot()->GetAttribute( wxT("version"), wxT("0.0.0.0")); if (wxSscanf(verstr.c_str(), wxT("%i.%i.%i.%i"), &v1, &v2, &v3, &v4) == 4) @@ -415,11 +497,13 @@ bool wxXmlResource::UpdateResources() } ProcessPlatformProperty(m_data[i].Doc->GetRoot()); +#if wxUSE_DATETIME #if wxUSE_FILESYSTEM m_data[i].Time = file->GetModificationTime(); -#else +#else // wxUSE_FILESYSTEM m_data[i].Time = wxDateTime(wxFileModificationTime(m_data[i].File)); -#endif +#endif // wxUSE_FILESYSTEM +#endif // wxUSE_DATETIME } # if wxUSE_FILESYSTEM @@ -450,20 +534,20 @@ wxXmlNode *wxXmlResource::DoFindResource(wxXmlNode *parent, if ( node->GetType() == wxXML_ELEMENT_NODE && (node->GetName() == wxT("object") || node->GetName() == wxT("object_ref")) && - node->GetPropVal(wxT("name"), &dummy) && dummy == name ) + node->GetAttribute(wxT("name"), &dummy) && dummy == name ) { - wxString cls(node->GetPropVal(wxT("class"), wxEmptyString)); + wxString cls(node->GetAttribute(wxT("class"), wxEmptyString)); if (!classname || cls == classname) return node; - // object_ref may not have 'class' property: + // object_ref may not have 'class' attribute: if (cls.empty() && node->GetName() == wxT("object_ref")) { - wxString refName = node->GetPropVal(wxT("ref"), wxEmptyString); + wxString refName = node->GetAttribute(wxT("ref"), wxEmptyString); if (refName.empty()) continue; wxXmlNode* refNode = FindResource(refName, wxEmptyString, true); if (refNode && - refNode->GetPropVal(wxT("class"), wxEmptyString) == classname) + refNode->GetAttribute(wxT("class"), wxEmptyString) == classname) { return node; } @@ -517,34 +601,35 @@ wxXmlNode *wxXmlResource::FindResource(const wxString& name, static void MergeNodes(wxXmlNode& dest, wxXmlNode& with) { - // Merge properties: - for (wxXmlProperty *prop = with.GetProperties(); prop; prop = prop->GetNext()) + // Merge attributes: + for ( wxXmlAttribute *attr = with.GetAttributes(); + attr; attr = attr->GetNext() ) { - wxXmlProperty *dprop; - for (dprop = dest.GetProperties(); dprop; dprop = dprop->GetNext()) + wxXmlAttribute *dattr; + for (dattr = dest.GetAttributes(); dattr; dattr = dattr->GetNext()) { - if ( dprop->GetName() == prop->GetName() ) + if ( dattr->GetName() == attr->GetName() ) { - dprop->SetValue(prop->GetValue()); + dattr->SetValue(attr->GetValue()); break; } } - if ( !dprop ) - dest.AddProperty(prop->GetName(), prop->GetValue()); + if ( !dattr ) + dest.AddAttribute(attr->GetName(), attr->GetValue()); } // Merge child nodes: for (wxXmlNode* node = with.GetChildren(); node; node = node->GetNext()) { - wxString name = node->GetPropVal(wxT("name"), wxEmptyString); + wxString name = node->GetAttribute(wxT("name"), wxEmptyString); wxXmlNode *dnode; for (dnode = dest.GetChildren(); dnode; dnode = dnode->GetNext() ) { if ( dnode->GetName() == node->GetName() && - dnode->GetPropVal(wxT("name"), wxEmptyString) == name && + dnode->GetAttribute(wxT("name"), wxEmptyString) == name && dnode->GetType() == node->GetType() ) { MergeNodes(*dnode, *node); @@ -553,10 +638,21 @@ static void MergeNodes(wxXmlNode& dest, wxXmlNode& with) } if ( !dnode ) - dest.AddChild(new wxXmlNode(*node)); + { + static const wxChar *AT_END = wxT("end"); + wxString insert_pos = node->GetAttribute(wxT("insert_at"), AT_END); + if ( insert_pos == AT_END ) + { + dest.AddChild(new wxXmlNode(*node)); + } + else if ( insert_pos == wxT("begin") ) + { + dest.InsertChild(new wxXmlNode(*node), dest.GetChildren()); + } + } } - if ( dest.GetType() == wxXML_TEXT_NODE && with.GetContent().Length() ) + if ( dest.GetType() == wxXML_TEXT_NODE && with.GetContent().length() ) dest.SetContent(with.GetContent()); } @@ -569,7 +665,7 @@ wxObject *wxXmlResource::CreateResFromNode(wxXmlNode *node, wxObject *parent, // handling of referenced resource if ( node->GetName() == wxT("object_ref") ) { - wxString refName = node->GetPropVal(wxT("ref"), wxEmptyString); + wxString refName = node->GetAttribute(wxT("ref"), wxEmptyString); wxXmlNode* refNode = FindResource(refName, wxEmptyString, true); if ( !refNode ) @@ -610,14 +706,14 @@ wxObject *wxXmlResource::CreateResFromNode(wxXmlNode *node, wxObject *parent, wxLogError(_("No handler found for XML node '%s', class '%s'!"), node->GetName().c_str(), - node->GetPropVal(wxT("class"), wxEmptyString).c_str()); + node->GetAttribute(wxT("class"), wxEmptyString).c_str()); return NULL; } #include "wx/listimpl.cpp" WX_DECLARE_LIST(wxXmlSubclassFactory, wxXmlSubclassFactoriesList); -WX_DEFINE_LIST(wxXmlSubclassFactoriesList); +WX_DEFINE_LIST(wxXmlSubclassFactoriesList) wxXmlSubclassFactoriesList *wxXmlResource::ms_subclassFactories = NULL; @@ -649,7 +745,6 @@ public: - wxXmlResourceHandler::wxXmlResourceHandler() : m_node(NULL), m_parent(NULL), m_instance(NULL), m_parentAsWindow(NULL) @@ -665,10 +760,10 @@ wxObject *wxXmlResourceHandler::CreateResource(wxXmlNode *node, wxObject *parent wxWindow *myParentAW = m_parentAsWindow; m_instance = instance; - if (!m_instance && node->HasProp(wxT("subclass")) && + if (!m_instance && node->HasAttribute(wxT("subclass")) && !(m_resource->GetFlags() & wxXRC_NO_SUBCLASSING)) { - wxString subclass = node->GetPropVal(wxT("subclass"), wxEmptyString); + wxString subclass = node->GetAttribute(wxT("subclass"), wxEmptyString); if (!subclass.empty()) { for (wxXmlSubclassFactoriesList::compatibility_iterator i = wxXmlResource::ms_subclassFactories->GetFirst(); @@ -681,7 +776,7 @@ wxObject *wxXmlResourceHandler::CreateResource(wxXmlNode *node, wxObject *parent if (!m_instance) { - wxString name = node->GetPropVal(wxT("name"), wxEmptyString); + wxString name = node->GetAttribute(wxT("name"), wxEmptyString); wxLogError(_("Subclass '%s' not found for resource '%s', not subclassing!"), subclass.c_str(), name.c_str()); } @@ -689,7 +784,7 @@ wxObject *wxXmlResourceHandler::CreateResource(wxXmlNode *node, wxObject *parent } m_node = node; - m_class = node->GetPropVal(wxT("class"), wxEmptyString); + m_class = node->GetAttribute(wxT("class"), wxEmptyString); m_parent = parent; m_parentAsWindow = wxDynamicCast(m_parent, wxWindow); @@ -715,17 +810,23 @@ void wxXmlResourceHandler::AddStyle(const wxString& name, int value) void wxXmlResourceHandler::AddWindowStyles() { XRC_ADD_STYLE(wxCLIP_CHILDREN); - XRC_ADD_STYLE(wxSIMPLE_BORDER); - XRC_ADD_STYLE(wxSUNKEN_BORDER); - XRC_ADD_STYLE(wxDOUBLE_BORDER); - XRC_ADD_STYLE(wxRAISED_BORDER); - XRC_ADD_STYLE(wxSTATIC_BORDER); - XRC_ADD_STYLE(wxNO_BORDER); + + // the border styles all have the old and new names, recognize both for now + XRC_ADD_STYLE(wxSIMPLE_BORDER); XRC_ADD_STYLE(wxBORDER_SIMPLE); + XRC_ADD_STYLE(wxSUNKEN_BORDER); XRC_ADD_STYLE(wxBORDER_SUNKEN); + XRC_ADD_STYLE(wxDOUBLE_BORDER); XRC_ADD_STYLE(wxBORDER_DOUBLE); + 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(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(wxALWAYS_SHOW_SB); XRC_ADD_STYLE(wxWS_EX_BLOCK_EVENTS); + XRC_ADD_STYLE(wxWS_EX_VALIDATE_RECURSIVELY); } @@ -794,11 +895,11 @@ wxString wxXmlResourceHandler::GetText(const wxString& param, bool translate) case wxT('n'): str2 << wxT('\n'); break; - + case wxT('t'): str2 << wxT('\t'); break; - + case wxT('r'): str2 << wxT('\r'); break; @@ -811,7 +912,7 @@ wxString wxXmlResourceHandler::GetText(const wxString& param, bool translate) break; } // else fall-through to default: branch below - + default: str2 << wxT('\\') << *dt; break; @@ -822,9 +923,9 @@ wxString wxXmlResourceHandler::GetText(const wxString& param, bool translate) if (m_resource->GetFlags() & wxXRC_USE_LOCALE) { if (translate && parNode && - parNode->GetPropVal(wxT("translate"), wxEmptyString) != wxT("0")) + parNode->GetAttribute(wxT("translate"), wxEmptyString) != wxT("0")) { - return wxGetTranslation(str2); + return wxGetTranslation(str2, m_resource->GetDomain()); } else { @@ -837,13 +938,11 @@ wxString wxXmlResourceHandler::GetText(const wxString& param, bool translate) #endif } } - else - { - // If wxXRC_USE_LOCALE is not set, then the string is already in - // system's default encoding in ANSI build, so we don't have to - // do anything special here. - return str2; - } + + // If wxXRC_USE_LOCALE is not set, then the string is already in + // system's default encoding in ANSI build, so we don't have to + // do anything special here. + return str2; } @@ -859,6 +958,24 @@ long wxXmlResourceHandler::GetLong(const wxString& param, long defaultv) return value; } +float wxXmlResourceHandler::GetFloat(const wxString& param, float defaultv) +{ + double value; + wxString str1 = GetParamValue(param); + +#ifndef __WXWINCE__ + const char *prevlocale = setlocale(LC_NUMERIC, "C"); +#endif + + if (!str1.ToDouble(&value)) + value = defaultv; + +#ifndef __WXWINCE__ + setlocale(LC_NUMERIC, prevlocale); +#endif + + return wx_truncate_cast(float, value); +} int wxXmlResourceHandler::GetID() @@ -870,7 +987,7 @@ int wxXmlResourceHandler::GetID() wxString wxXmlResourceHandler::GetName() { - return m_node->GetPropVal(wxT("name"), wxT("-1")); + return m_node->GetAttribute(wxT("name"), wxT("-1")); } @@ -880,27 +997,84 @@ bool wxXmlResourceHandler::GetBool(const wxString& param, bool defaultv) wxString v = GetParamValue(param); v.MakeLower(); if (!v) return defaultv; - else return (v == wxT("1")); + + return (v == wxT("1")); } +static wxColour GetSystemColour(const wxString& name) +{ + if (!name.empty()) + { + #define SYSCLR(clr) \ + if (name == _T(#clr)) return wxSystemSettings::GetColour(clr); + SYSCLR(wxSYS_COLOUR_SCROLLBAR) + SYSCLR(wxSYS_COLOUR_BACKGROUND) + SYSCLR(wxSYS_COLOUR_DESKTOP) + SYSCLR(wxSYS_COLOUR_ACTIVECAPTION) + SYSCLR(wxSYS_COLOUR_INACTIVECAPTION) + SYSCLR(wxSYS_COLOUR_MENU) + SYSCLR(wxSYS_COLOUR_WINDOW) + SYSCLR(wxSYS_COLOUR_WINDOWFRAME) + SYSCLR(wxSYS_COLOUR_MENUTEXT) + SYSCLR(wxSYS_COLOUR_WINDOWTEXT) + SYSCLR(wxSYS_COLOUR_CAPTIONTEXT) + SYSCLR(wxSYS_COLOUR_ACTIVEBORDER) + SYSCLR(wxSYS_COLOUR_INACTIVEBORDER) + SYSCLR(wxSYS_COLOUR_APPWORKSPACE) + SYSCLR(wxSYS_COLOUR_HIGHLIGHT) + SYSCLR(wxSYS_COLOUR_HIGHLIGHTTEXT) + SYSCLR(wxSYS_COLOUR_BTNFACE) + SYSCLR(wxSYS_COLOUR_3DFACE) + SYSCLR(wxSYS_COLOUR_BTNSHADOW) + SYSCLR(wxSYS_COLOUR_3DSHADOW) + SYSCLR(wxSYS_COLOUR_GRAYTEXT) + SYSCLR(wxSYS_COLOUR_BTNTEXT) + SYSCLR(wxSYS_COLOUR_INACTIVECAPTIONTEXT) + SYSCLR(wxSYS_COLOUR_BTNHIGHLIGHT) + SYSCLR(wxSYS_COLOUR_BTNHILIGHT) + SYSCLR(wxSYS_COLOUR_3DHIGHLIGHT) + SYSCLR(wxSYS_COLOUR_3DHILIGHT) + SYSCLR(wxSYS_COLOUR_3DDKSHADOW) + SYSCLR(wxSYS_COLOUR_3DLIGHT) + SYSCLR(wxSYS_COLOUR_INFOTEXT) + SYSCLR(wxSYS_COLOUR_INFOBK) + SYSCLR(wxSYS_COLOUR_LISTBOX) + SYSCLR(wxSYS_COLOUR_HOTLIGHT) + SYSCLR(wxSYS_COLOUR_GRADIENTACTIVECAPTION) + SYSCLR(wxSYS_COLOUR_GRADIENTINACTIVECAPTION) + SYSCLR(wxSYS_COLOUR_MENUHILIGHT) + SYSCLR(wxSYS_COLOUR_MENUBAR) + #undef SYSCLR + } + + return wxNullColour; +} -wxColour wxXmlResourceHandler::GetColour(const wxString& param) +wxColour wxXmlResourceHandler::GetColour(const wxString& param, const wxColour& defaultv) { wxString v = GetParamValue(param); - unsigned long tmp = 0; - if (v.Length() != 7 || v[0u] != wxT('#') || - wxSscanf(v.c_str(), wxT("#%lX"), &tmp) != 1) + if ( v.empty() ) + return defaultv; + + wxColour clr; + + // wxString -> wxColour conversion + if (!clr.Set(v)) { - wxLogError(_("XRC resource: Incorrect colour specification '%s' for property '%s'."), + // the colour doesn't use #RRGGBB format, check if it is symbolic + // colour name: + clr = GetSystemColour(v); + if (clr.Ok()) + return clr; + + wxLogError(_("XRC resource: Incorrect colour specification '%s' for attribute '%s'."), v.c_str(), param.c_str()); return wxNullColour; } - return wxColour((unsigned char) ((tmp & 0xFF0000) >> 16) , - (unsigned char) ((tmp & 0x00FF00) >> 8), - (unsigned char) ((tmp & 0x0000FF))); + return clr; } @@ -913,15 +1087,15 @@ wxBitmap wxXmlResourceHandler::GetBitmap(const wxString& param, wxXmlNode *bmpNode = GetParamNode(param); if ( bmpNode ) { - wxString sid = bmpNode->GetPropVal(wxT("stock_id"), wxEmptyString); + wxString sid = bmpNode->GetAttribute(wxT("stock_id"), wxEmptyString); if ( !sid.empty() ) { - wxString scl = bmpNode->GetPropVal(wxT("stock_client"), wxEmptyString); + wxString scl = bmpNode->GetAttribute(wxT("stock_client"), wxEmptyString); if (scl.empty()) scl = defaultArtClient; else scl = wxART_MAKE_CLIENT_ID_FROM_STR(scl); - + wxBitmap stockArt = wxArtProvider::GetBitmap(wxART_MAKE_ART_ID_FROM_STR(sid), scl, size); @@ -932,9 +1106,9 @@ wxBitmap wxXmlResourceHandler::GetBitmap(const wxString& param, /* ...or load the bitmap from file: */ wxString name = GetParamValue(param); - if (name.IsEmpty()) return wxNullBitmap; + if (name.empty()) return wxNullBitmap; #if wxUSE_FILESYSTEM - wxFSFile *fsfile = GetCurFileSystem().OpenFile(name); + wxFSFile *fsfile = GetCurFileSystem().OpenFile(name, wxFS_READ | wxFS_SEEKABLE); if (fsfile == NULL) { wxLogError(_("XRC resource: Cannot create bitmap from '%s'."), @@ -944,18 +1118,51 @@ wxBitmap wxXmlResourceHandler::GetBitmap(const wxString& param, wxImage img(*(fsfile->GetStream())); delete fsfile; #else - wxImage img(GetParamValue(wxT("bitmap"))); + wxImage img(name); #endif if (!img.Ok()) { - wxLogError(_("XRC resource: Cannot create bitmap from '%s'."), param.c_str()); + wxLogError(_("XRC resource: Cannot create bitmap from '%s'."), + name.c_str()); return wxNullBitmap; } if (!(size == wxDefaultSize)) img.Rescale(size.x, size.y); return wxBitmap(img); +} + +#if wxUSE_ANIMATIONCTRL +wxAnimation wxXmlResourceHandler::GetAnimation(const wxString& param) +{ + wxAnimation ani; + + /* load the animation from file: */ + wxString name = GetParamValue(param); + if (name.empty()) return wxNullAnimation; +#if wxUSE_FILESYSTEM + wxFSFile *fsfile = GetCurFileSystem().OpenFile(name, wxFS_READ | wxFS_SEEKABLE); + if (fsfile == NULL) + { + wxLogError(_("XRC resource: Cannot create animation from '%s'."), + name.c_str()); + return wxNullAnimation; + } + ani.Load(*(fsfile->GetStream())); + delete fsfile; +#else + ani.LoadFile(name); +#endif + if (!ani.IsOk()) + { + wxLogError(_("XRC resource: Cannot create animation from '%s'."), + name.c_str()); + return wxNullAnimation; + } + + return ani; } +#endif // wxUSE_ANIMATIONCTRL @@ -986,6 +1193,14 @@ wxXmlNode *wxXmlResourceHandler::GetParamNode(const wxString& param) } + +bool wxXmlResourceHandler::IsOfClass(wxXmlNode *node, const wxString& classname) +{ + return node->GetAttribute(wxT("class"), wxEmptyString) == classname; +} + + + wxString wxXmlResourceHandler::GetNodeContent(wxXmlNode *node) { wxXmlNode *n = node; @@ -1006,7 +1221,7 @@ wxString wxXmlResourceHandler::GetNodeContent(wxXmlNode *node) wxString wxXmlResourceHandler::GetParamValue(const wxString& param) { - if (param.IsEmpty()) + if (param.empty()) return GetNodeContent(m_node); else return GetNodeContent(GetParamNode(param)); @@ -1014,14 +1229,15 @@ wxString wxXmlResourceHandler::GetParamValue(const wxString& param) -wxSize wxXmlResourceHandler::GetSize(const wxString& param) +wxSize wxXmlResourceHandler::GetSize(const wxString& param, + wxWindow *windowToUse) { wxString s = GetParamValue(param); - if (s.IsEmpty()) s = wxT("-1,-1"); + if (s.empty()) s = wxT("-1,-1"); bool is_dlg; long sx, sy = 0; - is_dlg = s[s.Length()-1] == wxT('d'); + is_dlg = s[s.length()-1] == wxT('d'); if (is_dlg) s.RemoveLast(); if (!s.BeforeFirst(wxT(',')).ToLong(&sx) || @@ -1033,15 +1249,22 @@ wxSize wxXmlResourceHandler::GetSize(const wxString& param) if (is_dlg) { - if (m_parentAsWindow) + if (windowToUse) + { + return wxDLG_UNIT(windowToUse, wxSize(sx, sy)); + } + else if (m_parentAsWindow) + { return wxDLG_UNIT(m_parentAsWindow, wxSize(sx, sy)); + } else { wxLogError(_("Cannot convert dialog units: dialog unknown.")); return wxDefaultSize; } } - else return wxSize(sx, sy); + + return wxSize(sx, sy); } @@ -1054,14 +1277,16 @@ wxPoint wxXmlResourceHandler::GetPosition(const wxString& param) -wxCoord wxXmlResourceHandler::GetDimension(const wxString& param, wxCoord defaultv) +wxCoord wxXmlResourceHandler::GetDimension(const wxString& param, + wxCoord defaultv, + wxWindow *windowToUse) { wxString s = GetParamValue(param); - if (s.IsEmpty()) return defaultv; + if (s.empty()) return defaultv; bool is_dlg; long sx; - is_dlg = s[s.Length()-1] == wxT('d'); + is_dlg = s[s.length()-1] == wxT('d'); if (is_dlg) s.RemoveLast(); if (!s.ToLong(&sx)) @@ -1072,18 +1297,45 @@ wxCoord wxXmlResourceHandler::GetDimension(const wxString& param, wxCoord defaul if (is_dlg) { - if (m_parentAsWindow) + if (windowToUse) + { + return wxDLG_UNIT(windowToUse, wxSize(sx, 0)).x; + } + else if (m_parentAsWindow) + { return wxDLG_UNIT(m_parentAsWindow, wxSize(sx, 0)).x; + } else { wxLogError(_("Cannot convert dialog units: dialog unknown.")); return defaultv; } } - else return sx; + + return sx; } +// Get system font index using indexname +static wxFont GetSystemFont(const wxString& name) +{ + if (!name.empty()) + { + #define SYSFNT(fnt) \ + if (name == _T(#fnt)) return wxSystemSettings::GetFont(fnt); + SYSFNT(wxSYS_OEM_FIXED_FONT) + SYSFNT(wxSYS_ANSI_FIXED_FONT) + SYSFNT(wxSYS_ANSI_VAR_FONT) + SYSFNT(wxSYS_SYSTEM_FONT) + SYSFNT(wxSYS_DEVICE_DEFAULT_FONT) + SYSFNT(wxSYS_DEFAULT_PALETTE) + SYSFNT(wxSYS_SYSTEM_FIXED_FONT) + SYSFNT(wxSYS_DEFAULT_GUI_FONT) + #undef SYSFNT + } + + return wxNullFont; +} wxFont wxXmlResourceHandler::GetFont(const wxString& param) { @@ -1097,52 +1349,120 @@ wxFont wxXmlResourceHandler::GetFont(const wxString& param) wxXmlNode *oldnode = m_node; m_node = font_node; - long size = GetLong(wxT("size"), 12); + // font attributes: - wxString style = GetParamValue(wxT("style")); - wxString weight = GetParamValue(wxT("weight")); - int istyle = wxNORMAL, iweight = wxNORMAL; - if (style == wxT("italic")) istyle = wxITALIC; - else if (style == wxT("slant")) istyle = wxSLANT; - if (weight == wxT("bold")) iweight = wxBOLD; - else if (weight == wxT("light")) iweight = wxLIGHT; + // size + int isize = -1; + bool hasSize = HasParam(wxT("size")); + if (hasSize) + isize = GetLong(wxT("size"), -1); - wxString family = GetParamValue(wxT("family")); + // style + int istyle = wxNORMAL; + bool hasStyle = HasParam(wxT("style")); + if (hasStyle) + { + wxString style = GetParamValue(wxT("style")); + if (style == wxT("italic")) + istyle = wxITALIC; + else if (style == wxT("slant")) + istyle = wxSLANT; + } + + // weight + int iweight = wxNORMAL; + bool hasWeight = HasParam(wxT("weight")); + if (hasWeight) + { + wxString weight = GetParamValue(wxT("weight")); + if (weight == wxT("bold")) + iweight = wxBOLD; + else if (weight == wxT("light")) + iweight = wxLIGHT; + } + + // underline + bool hasUnderlined = HasParam(wxT("underlined")); + bool underlined = hasUnderlined ? GetBool(wxT("underlined"), false) : false; + + // family and facename int ifamily = wxDEFAULT; - if (family == wxT("decorative")) ifamily = wxDECORATIVE; - else if (family == wxT("roman")) ifamily = wxROMAN; - else if (family == wxT("script")) ifamily = wxSCRIPT; - else if (family == wxT("swiss")) ifamily = wxSWISS; - else if (family == wxT("modern")) ifamily = wxMODERN; + bool hasFamily = HasParam(wxT("family")); + if (hasFamily) + { + wxString family = GetParamValue(wxT("family")); + if (family == wxT("decorative")) ifamily = wxDECORATIVE; + else if (family == wxT("roman")) ifamily = wxROMAN; + else if (family == wxT("script")) ifamily = wxSCRIPT; + else if (family == wxT("swiss")) ifamily = wxSWISS; + else if (family == wxT("modern")) ifamily = wxMODERN; + else if (family == wxT("teletype")) ifamily = wxTELETYPE; + } - bool underlined = GetBool(wxT("underlined"), false); - wxString encoding = GetParamValue(wxT("encoding")); - wxFontMapper mapper; - wxFontEncoding enc = wxFONTENCODING_DEFAULT; - if (!encoding.IsEmpty()) - enc = mapper.CharsetToEncoding(encoding); - if (enc == wxFONTENCODING_SYSTEM) - enc = wxFONTENCODING_DEFAULT; - - wxString faces = GetParamValue(wxT("face")); - wxString facename = wxEmptyString; - wxFontEnumerator enu; - enu.EnumerateFacenames(); - wxStringTokenizer tk(faces, wxT(",")); - while (tk.HasMoreTokens()) + wxString facename; + bool hasFacename = HasParam(wxT("face")); + if (hasFacename) { - int index = enu.GetFacenames()->Index(tk.GetNextToken(), false); - if (index != wxNOT_FOUND) + wxString faces = GetParamValue(wxT("face")); + wxArrayString facenames(wxFontEnumerator::GetFacenames()); + wxStringTokenizer tk(faces, wxT(",")); + while (tk.HasMoreTokens()) { - facename = (*enu.GetFacenames())[index]; - break; + int index = facenames.Index(tk.GetNextToken(), false); + if (index != wxNOT_FOUND) + { + facename = facenames[index]; + break; + } } } - m_node = oldnode; + // encoding + wxFontEncoding enc = wxFONTENCODING_DEFAULT; + bool hasEncoding = HasParam(wxT("encoding")); + if (hasEncoding) + { + wxString encoding = GetParamValue(wxT("encoding")); + wxFontMapper mapper; + if (!encoding.empty()) + enc = mapper.CharsetToEncoding(encoding); + if (enc == wxFONTENCODING_SYSTEM) + enc = wxFONTENCODING_DEFAULT; + } - wxFont font(size, ifamily, istyle, iweight, underlined, facename, enc); + // is this font based on a system font? + wxFont font = GetSystemFont(GetParamValue(wxT("sysfont"))); + + if (font.Ok()) + { + if (hasSize && isize != -1) + font.SetPointSize(isize); + else if (HasParam(wxT("relativesize"))) + font.SetPointSize(int(font.GetPointSize() * + GetFloat(wxT("relativesize")))); + + if (hasStyle) + font.SetStyle(istyle); + if (hasWeight) + font.SetWeight(iweight); + if (hasUnderlined) + font.SetUnderlined(underlined); + if (hasFamily) + font.SetFamily(ifamily); + if (hasFacename) + font.SetFaceName(facename); + if (hasEncoding) + font.SetDefaultEncoding(enc); + } + else // not based on system font + { + font = wxFont(isize == -1 ? wxNORMAL_FONT->GetPointSize() : isize, + ifamily, istyle, iweight, + underlined, facename, enc); + } + + m_node = oldnode; return font; } @@ -1172,6 +1492,8 @@ void wxXmlResourceHandler::SetupWindow(wxWindow *wnd) #endif if (HasParam(wxT("font"))) wnd->SetFont(GetFont()); + if (HasParam(wxT("help"))) + wnd->SetHelpText(GetText(wxT("help"))); } @@ -1222,17 +1544,17 @@ void wxXmlResourceHandler::CreateChildrenPrivately(wxObject *parent, wxXmlNode * struct XRCID_record { int id; - wxChar *key; + char *key; XRCID_record *next; }; static XRCID_record *XRCID_Records[XRCID_TABLE_SIZE] = {NULL}; -static int XRCID_Lookup(const wxChar *str_id, int value_if_not_found = -2) +static int XRCID_Lookup(const char *str_id, int value_if_not_found = wxID_NONE) { int index = 0; - for (const wxChar *c = str_id; *c != wxT('\0'); c++) index += (int)*c; + for (const char *c = str_id; *c != '\0'; c++) index += (int)*c; index %= XRCID_TABLE_SIZE; XRCID_record *oldrec = NULL; @@ -1251,8 +1573,8 @@ static int XRCID_Lookup(const wxChar *str_id, int value_if_not_found = -2) (*rec_var)->key = wxStrdup(str_id); (*rec_var)->next = NULL; - wxChar *end; - if (value_if_not_found != -2) + char *end; + if (value_if_not_found != wxID_NONE) (*rec_var)->id = value_if_not_found; else { @@ -1271,9 +1593,20 @@ static int XRCID_Lookup(const wxChar *str_id, int value_if_not_found = -2) return (*rec_var)->id; } -/*static*/ int wxXmlResource::GetXRCID(const wxChar *str_id) +static void AddStdXRCID_Records(); + +/*static*/ +int wxXmlResource::DoGetXRCID(const char *str_id, int value_if_not_found) { - return XRCID_Lookup(str_id); + static bool s_stdIDsAdded = false; + + if ( !s_stdIDsAdded ) + { + s_stdIDsAdded = true; + AddStdXRCID_Records(); + } + + return XRCID_Lookup(str_id, value_if_not_found); } @@ -1298,12 +1631,12 @@ static void CleanXRCID_Records() static void AddStdXRCID_Records() { -#define stdID(id) XRCID_Lookup(wxT(#id), id) +#define stdID(id) XRCID_Lookup(#id, id) stdID(-1); stdID(wxID_ANY); stdID(wxID_SEPARATOR); - + stdID(wxID_OPEN); stdID(wxID_CLOSE); stdID(wxID_NEW); @@ -1316,6 +1649,7 @@ static void AddStdXRCID_Records() stdID(wxID_HELP); stdID(wxID_PRINT); stdID(wxID_PRINT_SETUP); + stdID(wxID_PAGE_SETUP); stdID(wxID_PREVIEW); stdID(wxID_ABOUT); stdID(wxID_HELP_CONTENTS); @@ -1417,7 +1751,6 @@ public: wxXmlResourceModule() {} bool OnInit() { - AddStdXRCID_Records(); wxXmlResource::AddSubclassFactory(new wxXmlSubclassFactoryCXX); return true; }