X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d7b1d73c92067c3bad49cc19b2da514046c69f65..218f97d382565ecc70ef12bfdeaa3495680fc60d:/src/xrc/xmlres.cpp diff --git a/src/xrc/xmlres.cpp b/src/xrc/xmlres.cpp index ef1e2f2761..ade30b6039 100644 --- a/src/xrc/xmlres.cpp +++ b/src/xrc/xmlres.cpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // Name: xmlres.cpp -// Purpose: XML resources +// Purpose: XRC resources // Author: Vaclav Slavik // Created: 2000/03/05 // RCS-ID: $Id$ @@ -40,16 +40,32 @@ WX_DEFINE_OBJARRAY(wxXmlResourceDataRecords); -wxXmlResource::wxXmlResource(bool use_locale) +wxXmlResource *wxXmlResource::ms_instance = NULL; + +/*static*/ wxXmlResource *wxXmlResource::Get() +{ + if ( !ms_instance ) + ms_instance = new wxXmlResource; + return ms_instance; +} + +/*static*/ wxXmlResource *wxXmlResource::Set(wxXmlResource *res) +{ + wxXmlResource *old = ms_instance; + ms_instance = res; + return old; +} + +wxXmlResource::wxXmlResource(int flags) { m_handlers.DeleteContents(TRUE); - m_useLocale = use_locale; + m_flags = flags; m_version = -1; } -wxXmlResource::wxXmlResource(const wxString& filemask, bool use_locale) +wxXmlResource::wxXmlResource(const wxString& filemask, int flags) { - m_useLocale = use_locale; + m_flags = flags; m_version = -1; m_handlers.DeleteContents(TRUE); Load(filemask); @@ -131,18 +147,19 @@ wxMenu *wxXmlResource::LoadMenu(const wxString& name) -wxMenuBar *wxXmlResource::LoadMenuBar(const wxString& name) +wxMenuBar *wxXmlResource::LoadMenuBar(wxWindow *parent, const wxString& name) { - return (wxMenuBar*)CreateResFromNode(FindResource(name, wxT("wxMenuBar")), NULL, NULL); + return (wxMenuBar*)CreateResFromNode(FindResource(name, wxT("wxMenuBar")), parent, NULL); } +#if wxUSE_TOOLBAR wxToolBar *wxXmlResource::LoadToolBar(wxWindow *parent, const wxString& name) { return (wxToolBar*)CreateResFromNode(FindResource(name, wxT("wxToolBar")), parent, NULL); } - +#endif wxDialog *wxXmlResource::LoadDialog(wxWindow *parent, const wxString& name) @@ -310,7 +327,7 @@ void wxXmlResource::UpdateResources() } else if (m_data[i].Doc->GetRoot()->GetName() != wxT("resource")) { - wxLogError(_("Invalid XML resource '%s': doesn't have root node 'resource'."), m_data[i].File.c_str()); + wxLogError(_("Invalid XRC resource '%s': doesn't have root node 'resource'."), m_data[i].File.c_str()); wxDELETE(m_data[i].Doc); } else @@ -343,42 +360,139 @@ void wxXmlResource::UpdateResources() } +wxXmlNode *wxXmlResource::DoFindResource(wxXmlNode *parent, + const wxString& name, + const wxString& classname, + bool recursive) +{ + wxString dummy; + wxXmlNode *node; + + // first search for match at the top-level nodes (as this is + // where the resource is most commonly looked for): + for (node = parent->GetChildren(); node; node = node->GetNext()) + { + if ( node->GetType() == wxXML_ELEMENT_NODE && + (node->GetName() == wxT("object") || + node->GetName() == wxT("object_ref")) && + (!classname || + node->GetPropVal(wxT("class"), wxEmptyString) == classname) && + node->GetPropVal(wxT("name"), &dummy) && dummy == name ) + return node; + } + + if ( recursive ) + for (node = parent->GetChildren(); node; node = node->GetNext()) + { + if ( node->GetType() == wxXML_ELEMENT_NODE && + (node->GetName() == wxT("object") || + node->GetName() == wxT("object_ref")) ) + { + wxXmlNode* found = DoFindResource(node, name, classname, TRUE); + if ( found ) + return found; + } + } + + return NULL; +} -wxXmlNode *wxXmlResource::FindResource(const wxString& name, const wxString& classname) +wxXmlNode *wxXmlResource::FindResource(const wxString& name, + const wxString& classname, + bool recursive) { UpdateResources(); //ensure everything is up-to-date wxString dummy; for (size_t f = 0; f < m_data.GetCount(); f++) { - if (m_data[f].Doc == NULL || m_data[f].Doc->GetRoot() == NULL) continue; - for (wxXmlNode *node = m_data[f].Doc->GetRoot()->GetChildren(); - node; node = node->GetNext()) - if (node->GetType() == wxXML_ELEMENT_NODE && - (!classname || - node->GetPropVal(wxT("class"), wxEmptyString) == classname) && - node->GetName() == wxT("object") && - node->GetPropVal(wxT("name"), &dummy) && - dummy == name) - { + if ( m_data[f].Doc == NULL || m_data[f].Doc->GetRoot() == NULL ) + continue; + + wxXmlNode* found = DoFindResource(m_data[f].Doc->GetRoot(), + name, classname, recursive); + if ( found ) + { #if wxUSE_FILESYSTEM - m_curFileSystem.ChangePathTo(m_data[f].File); + m_curFileSystem.ChangePathTo(m_data[f].File); #endif - return node; - } + return found; + } } - wxLogError(_("XML resource '%s' (class '%s') not found!"), + wxLogError(_("XRC resource '%s' (class '%s') not found!"), name.c_str(), classname.c_str()); return NULL; } +static void MergeNodes(wxXmlNode& dest, wxXmlNode& with) +{ + // Merge properties: + for (wxXmlProperty *prop = with.GetProperties(); prop; prop = prop->GetNext()) + { + wxXmlProperty *dprop; + for (dprop = dest.GetProperties(); dprop; dprop = dprop->GetNext()) + { + + if ( dprop->GetName() == prop->GetName() ) + { + dprop->SetValue(prop->GetValue()); + break; + } + } + + if ( !dprop ) + dest.AddProperty(prop->GetName(), prop->GetValue()); + } + + // Merge child nodes: + for (wxXmlNode* node = with.GetChildren(); node; node = node->GetNext()) + { + wxString name = node->GetPropVal(wxT("name"), wxEmptyString); + wxXmlNode *dnode; + + for (dnode = dest.GetChildren(); dnode; dnode = dnode->GetNext() ) + { + if ( dnode->GetName() == node->GetName() && + dnode->GetPropVal("name", wxEmptyString) == name && + dnode->GetType() == node->GetType() ) + { + MergeNodes(*dnode, *node); + break; + } + } + + if ( !dnode ) + dest.AddChild(new wxXmlNode(*node)); + } + if ( dest.GetType() == wxXML_TEXT_NODE && with.GetContent().Length() ) + dest.SetContent(with.GetContent()); +} wxObject *wxXmlResource::CreateResFromNode(wxXmlNode *node, wxObject *parent, wxObject *instance) { if (node == NULL) return NULL; + // handling of referenced resource + if ( node->GetName() == wxT("object_ref") ) + { + wxString refName = node->GetPropVal(wxT("ref"), wxEmptyString); + wxXmlNode* refNode = FindResource(refName, wxEmptyString, TRUE); + + if ( !refNode ) + { + wxLogError(_("Referenced object node with ref=\"%s\" not found!"), + refName.c_str()); + return NULL; + } + + wxXmlNode copy(*refNode); + MergeNodes(copy, *node); + + return CreateResFromNode(©, parent, instance); + } + wxXmlResourceHandler *handler; wxObject *ret; wxNode * ND = m_handlers.GetFirst(); @@ -402,11 +516,6 @@ wxObject *wxXmlResource::CreateResFromNode(wxXmlNode *node, wxObject *parent, wx - - - - - wxXmlResourceHandler::wxXmlResourceHandler() : m_node(NULL), m_parent(NULL), m_instance(NULL), m_parentAsWindow(NULL), m_instanceAsWindow(NULL) @@ -421,10 +530,28 @@ wxObject *wxXmlResourceHandler::CreateResource(wxXmlNode *node, wxObject *parent wxObject *myParent = m_parent, *myInstance = m_instance; wxWindow *myParentAW = m_parentAsWindow, *myInstanceAW = m_instanceAsWindow; + m_instance = instance; + if (!m_instance && node->HasProp(wxT("subclass")) && + !(m_resource->GetFlags() & wxXRC_NO_SUBCLASSING)) + { + wxString subclass = node->GetPropVal(wxT("subclass"), wxEmptyString); + wxClassInfo* classInfo = wxClassInfo::FindClass(subclass); + + if (classInfo) + m_instance = classInfo->CreateObject(); + + if (!m_instance) + { + wxLogError(_("Subclass '%s' not found for resource '%s', not subclassing!"), + subclass.c_str(), node->GetPropVal(wxT("name"), wxEmptyString).c_str()); + } + + m_instance = classInfo->CreateObject(); + } + m_node = node; m_class = node->GetPropVal(wxT("class"), wxEmptyString); m_parent = parent; - m_instance = instance; m_parentAsWindow = wxDynamicCast(m_parent, wxWindow); m_instanceAsWindow = wxDynamicCast(m_instance, wxWindow); @@ -449,15 +576,15 @@ void wxXmlResourceHandler::AddStyle(const wxString& name, int value) void wxXmlResourceHandler::AddWindowStyles() { - ADD_STYLE(wxSIMPLE_BORDER); - ADD_STYLE(wxSUNKEN_BORDER); - ADD_STYLE(wxDOUBLE_BORDER); - ADD_STYLE(wxRAISED_BORDER); - ADD_STYLE(wxSTATIC_BORDER); - ADD_STYLE(wxNO_BORDER); - ADD_STYLE(wxTRANSPARENT_WINDOW); - ADD_STYLE(wxWANTS_CHARS); - ADD_STYLE(wxNO_FULL_REPAINT_ON_RESIZE); + 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); + XRC_ADD_STYLE(wxTRANSPARENT_WINDOW); + XRC_ADD_STYLE(wxWANTS_CHARS); + XRC_ADD_STYLE(wxNO_FULL_REPAINT_ON_RESIZE); } @@ -494,12 +621,17 @@ int wxXmlResourceHandler::GetStyle(const wxString& param, int defaults) wxString wxXmlResourceHandler::GetText(const wxString& param) { - wxString str1 = GetParamValue(param); + wxString str1; wxString str2; const wxChar *dt; wxChar amp_char; - // VS: First version of XML resources used $ instead of & (which is illegal in XML), + if (m_resource->GetFlags() & wxXRC_USE_LOCALE) + str1 = wxGetTranslation(GetParamValue(param)); + else + str1 = GetParamValue(param); + + // VS: First version of XRC resources used $ instead of & (which is illegal in XML), // but later I realized that '_' fits this purpose much better (because // &File means "File with F underlined"). if (m_resource->CompareVersion(2,3,0,1) < 0) @@ -529,11 +661,8 @@ wxString wxXmlResourceHandler::GetText(const wxString& param) } else str2 << *dt; } - - if (m_resource->GetUseLocale()) - return wxGetTranslation(str2); - else - return str2; + + return str2; } @@ -601,7 +730,7 @@ wxColour wxXmlResourceHandler::GetColour(const wxString& param) if (v.Length() != 7 || v[0u] != wxT('#') || wxSscanf(v.c_str(), wxT("#%lX"), &tmp) != 1) { - wxLogError(_("XML resource: Incorrect colour specification '%s' for property '%s'."), + wxLogError(_("XRC resource: Incorrect colour specification '%s' for property '%s'."), v.c_str(), param.c_str()); return wxNullColour; } @@ -621,7 +750,7 @@ wxBitmap wxXmlResourceHandler::GetBitmap(const wxString& param, wxSize size) wxFSFile *fsfile = GetCurFileSystem().OpenFile(name); if (fsfile == NULL) { - wxLogError(_("XML resource: Cannot create bitmap from '%s'."), param.c_str()); + wxLogError(_("XRC resource: Cannot create bitmap from '%s'."), param.c_str()); return wxNullBitmap; } wxImage img(*(fsfile->GetStream())); @@ -631,7 +760,7 @@ wxBitmap wxXmlResourceHandler::GetBitmap(const wxString& param, wxSize size) #endif if (!img.Ok()) { - wxLogError(_("XML resource: Cannot create bitmap from '%s'."), param.c_str()); + wxLogError(_("XRC resource: Cannot create bitmap from '%s'."), param.c_str()); return wxNullBitmap; } if (!(size == wxDefaultSize)) img.Rescale(size.x, size.y); @@ -808,8 +937,10 @@ wxFont wxXmlResourceHandler::GetFont(const wxString& param) wxString encoding = GetParamValue(wxT("encoding")); wxFontMapper mapper; wxFontEncoding enc = wxFONTENCODING_DEFAULT; - if (!encoding.IsEmpty()) enc = mapper.CharsetToEncoding(encoding); - if (enc == wxFONTENCODING_SYSTEM) enc = wxFONTENCODING_SYSTEM; + if (!encoding.IsEmpty()) + enc = mapper.CharsetToEncoding(encoding); + if (enc == wxFONTENCODING_SYSTEM) + enc = wxFONTENCODING_DEFAULT; wxString faces = GetParamValue(wxT("face")); wxString facename = wxEmptyString; @@ -970,21 +1101,18 @@ static void CleanXMLID_Records() // --------------- module and globals ----------------------------- - -static wxXmlResource gs_XmlResource; - -wxXmlResource *wxTheXmlResource = &gs_XmlResource; - - class wxXmlResourceModule: public wxModule { DECLARE_DYNAMIC_CLASS(wxXmlResourceModule) public: wxXmlResourceModule() {} - bool OnInit() {return TRUE;} + bool OnInit() + { + return TRUE; + } void OnExit() { - wxTheXmlResource->ClearHandlers(); + delete wxXmlResource::Set(NULL); CleanXMLID_Records(); } };