X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a1eeda0be2074301793e9776898d9c26397424f9..c4fee2531a15c650bfd7f9f1db7ca02551e4cfd8:/src/xrc/xmlres.cpp diff --git a/src/xrc/xmlres.cpp b/src/xrc/xmlres.cpp index 090d7da5f2..5b41a453aa 100644 --- a/src/xrc/xmlres.cpp +++ b/src/xrc/xmlres.cpp @@ -44,6 +44,7 @@ #include "wx/fontenum.h" #include "wx/fontmap.h" #include "wx/artprov.h" +#include "wx/imaglist.h" #include "wx/dir.h" #include "wx/xml/xml.h" @@ -291,13 +292,13 @@ bool wxXmlResource::Load(const wxString& filemask_) bool wxXmlResource::Unload(const wxString& filename) { wxASSERT_MSG( !wxIsWild(filename), - _T("wildcards not supported by wxXmlResource::Unload()") ); + wxT("wildcards not supported by wxXmlResource::Unload()") ); wxString fnd = ConvertFileNameToURL(filename); #if wxUSE_FILESYSTEM const bool isArchive = IsArchive(fnd); if ( isArchive ) - fnd += _T("#zip:"); + fnd += wxT("#zip:"); #endif // wxUSE_FILESYSTEM bool unloaded = false; @@ -430,14 +431,27 @@ wxIcon wxXmlResource::LoadIcon(const wxString& name) } -wxObject *wxXmlResource::LoadObject(wxWindow *parent, const wxString& name, const wxString& classname) +wxObject * +wxXmlResource::DoLoadObject(wxWindow *parent, + const wxString& name, + const wxString& classname, + bool recursive) { - return CreateResFromNode(FindResource(name, classname), parent, NULL); + wxXmlNode * const node = FindResource(name, classname, recursive); + + return node ? DoCreateResFromNode(*node, parent, NULL) : NULL; } -bool wxXmlResource::LoadObject(wxObject *instance, wxWindow *parent, const wxString& name, const wxString& classname) +bool +wxXmlResource::DoLoadObject(wxObject *instance, + wxWindow *parent, + const wxString& name, + const wxString& classname, + bool recursive) { - return CreateResFromNode(FindResource(name, classname), parent, instance) != NULL; + wxXmlNode * const node = FindResource(name, classname, recursive); + + return node && DoCreateResFromNode(*node, parent, instance) != NULL; } @@ -563,7 +577,7 @@ bool wxXmlResource::UpdateResources() if (modif) { - wxLogTrace(_T("xrc"), _T("opening file '%s'"), rec->File); + wxLogTrace(wxT("xrc"), wxT("opening file '%s'"), rec->File); wxInputStream *stream = NULL; @@ -818,23 +832,23 @@ static void MergeNodesOver(wxXmlNode& dest, wxXmlNode& overwriteWith, dest.SetContent(overwriteWith.GetContent()); } -wxObject *wxXmlResource::CreateResFromNode(wxXmlNode *node, wxObject *parent, - wxObject *instance, - wxXmlResourceHandler *handlerToUse) +wxObject * +wxXmlResource::DoCreateResFromNode(wxXmlNode& node, + wxObject *parent, + wxObject *instance, + wxXmlResourceHandler *handlerToUse) { - if (node == NULL) return NULL; - // handling of referenced resource - if ( node->GetName() == wxT("object_ref") ) + if ( node.GetName() == wxT("object_ref") ) { - wxString refName = node->GetAttribute(wxT("ref"), wxEmptyString); + wxString refName = node.GetAttribute(wxT("ref"), wxEmptyString); wxXmlNode* refNode = FindResource(refName, wxEmptyString, true); if ( !refNode ) { ReportError ( - node, + &node, wxString::Format ( "referenced object node with ref=\"%s\" not found", @@ -844,42 +858,59 @@ wxObject *wxXmlResource::CreateResFromNode(wxXmlNode *node, wxObject *parent, return NULL; } - wxXmlNode copy(*refNode); - MergeNodesOver(copy, *node, GetFileNameFromNode(node, Data())); + if ( !node.GetChildren() ) + { + // In the typical, simple case, is used to link + // to another node and doesn't have any content of its own that + // would overwrite linked object's properties. In this case, + // we can simply create the resource from linked node. + + return DoCreateResFromNode(*refNode, parent, instance); + } + else + { + // In the more complicated (but rare) case, has + // subnodes that partially overwrite content of the referenced + // object. In this case, we need to merge both XML trees and + // load the resource from result of the merge. + + wxXmlNode copy(*refNode); + MergeNodesOver(copy, node, GetFileNameFromNode(&node, Data())); - // remember referenced object's file, see GetFileNameFromNode() - copy.AddAttribute(ATTR_INPUT_FILENAME, - GetFileNameFromNode(refNode, Data())); + // remember referenced object's file, see GetFileNameFromNode() + copy.AddAttribute(ATTR_INPUT_FILENAME, + GetFileNameFromNode(refNode, Data())); - return CreateResFromNode(©, parent, instance); + return DoCreateResFromNode(copy, parent, instance); + } } if (handlerToUse) { - if (handlerToUse->CanHandle(node)) + if (handlerToUse->CanHandle(&node)) { - return handlerToUse->CreateResource(node, parent, instance); + return handlerToUse->CreateResource(&node, parent, instance); } } - else if (node->GetName() == wxT("object")) + else if (node.GetName() == wxT("object")) { for ( wxVector::iterator h = m_handlers.begin(); h != m_handlers.end(); ++h ) { wxXmlResourceHandler *handler = *h; - if (handler->CanHandle(node)) - return handler->CreateResource(node, parent, instance); + if (handler->CanHandle(&node)) + return handler->CreateResource(&node, parent, instance); } } ReportError ( - node, + &node, wxString::Format ( "no handler found for XML node \"%s\" (class \"%s\")", - node->GetName(), - node->GetAttribute("class", wxEmptyString) + node.GetName(), + node.GetAttribute("class", wxEmptyString) ) ); return NULL; @@ -997,7 +1028,8 @@ void wxXmlResourceHandler::AddWindowStyles() // 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(wxDOUBLE_BORDER); XRC_ADD_STYLE(wxBORDER_DOUBLE); // deprecated + XRC_ADD_STYLE(wxBORDER_THEME); 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); @@ -1208,7 +1240,7 @@ static wxColour GetSystemColour(const wxString& name) if (!name.empty()) { #define SYSCLR(clr) \ - if (name == _T(#clr)) return wxSystemSettings::GetColour(clr); + if (name == wxT(#clr)) return wxSystemSettings::GetColour(clr); SYSCLR(wxSYS_COLOUR_SCROLLBAR) SYSCLR(wxSYS_COLOUR_BACKGROUND) SYSCLR(wxSYS_COLOUR_DESKTOP) @@ -1316,9 +1348,32 @@ wxBitmap wxXmlResourceHandler::GetBitmap(const wxString& param, const wxArtClient& defaultArtClient, wxSize size) { + // it used to be possible to pass an empty string here to indicate that the + // bitmap name should be read from this node itself but this is not + // supported any more because GetBitmap(m_node) can be used directly + // instead + wxASSERT_MSG( !param.empty(), "bitmap parameter name can't be empty" ); + + const wxXmlNode* const node = GetParamNode(param); + + if ( !node ) + { + // this is not an error as bitmap parameter could be optional + return wxNullBitmap; + } + + return GetBitmap(node, defaultArtClient, size); +} + +wxBitmap wxXmlResourceHandler::GetBitmap(const wxXmlNode* node, + const wxArtClient& defaultArtClient, + wxSize size) +{ + wxCHECK_MSG( node, wxNullBitmap, "bitmap node can't be NULL" ); + /* If the bitmap is specified as stock item, query wxArtProvider for it: */ wxString art_id, art_client; - if ( GetStockArtAttrs(GetParamNode(param), defaultArtClient, + if ( GetStockArtAttrs(node, defaultArtClient, art_id, art_client) ) { wxBitmap stockArt(wxArtProvider::GetBitmap(art_id, art_client, size)); @@ -1327,7 +1382,7 @@ wxBitmap wxXmlResourceHandler::GetBitmap(const wxString& param, } /* ...or load the bitmap from file: */ - wxString name = GetParamValue(param); + wxString name = GetParamValue(node); if (name.empty()) return wxNullBitmap; #if wxUSE_FILESYSTEM wxFSFile *fsfile = GetCurFileSystem().OpenFile(name, wxFS_READ | wxFS_SEEKABLE); @@ -1335,7 +1390,7 @@ wxBitmap wxXmlResourceHandler::GetBitmap(const wxString& param, { ReportParamError ( - param, + node->GetName(), wxString::Format("cannot open bitmap resource \"%s\"", name) ); return wxNullBitmap; @@ -1350,7 +1405,7 @@ wxBitmap wxXmlResourceHandler::GetBitmap(const wxString& param, { ReportParamError ( - param, + node->GetName(), wxString::Format("cannot create bitmap from \"%s\"", name) ); return wxNullBitmap; @@ -1363,12 +1418,31 @@ wxBitmap wxXmlResourceHandler::GetBitmap(const wxString& param, wxIcon wxXmlResourceHandler::GetIcon(const wxString& param, const wxArtClient& defaultArtClient, wxSize size) +{ + // see comment in GetBitmap(wxString) overload + wxASSERT_MSG( !param.empty(), "icon parameter name can't be empty" ); + + const wxXmlNode* const node = GetParamNode(param); + + if ( !node ) + { + // this is not an error as icon parameter could be optional + return wxIcon(); + } + + return GetIcon(node, defaultArtClient, size); +} + +wxIcon wxXmlResourceHandler::GetIcon(const wxXmlNode* node, + const wxArtClient& defaultArtClient, + wxSize size) { wxIcon icon; - icon.CopyFromBitmap(GetBitmap(param, defaultArtClient, size)); + icon.CopyFromBitmap(GetBitmap(node, defaultArtClient, size)); return icon; } + wxIconBundle wxXmlResourceHandler::GetIconBundle(const wxString& param, const wxArtClient& defaultArtClient) { @@ -1417,6 +1491,46 @@ wxIconBundle wxXmlResourceHandler::GetIconBundle(const wxString& param, } +wxImageList *wxXmlResourceHandler::GetImageList(const wxString& param) +{ + wxXmlNode * const imagelist_node = GetParamNode(param); + if ( !imagelist_node ) + return NULL; + + wxXmlNode * const oldnode = m_node; + m_node = imagelist_node; + + // size + wxSize size = GetSize(); + size.SetDefaults(wxSize(wxSystemSettings::GetMetric(wxSYS_ICON_X), + wxSystemSettings::GetMetric(wxSYS_ICON_Y))); + + // mask: true by default + bool mask = HasParam(wxT("mask")) ? GetBool(wxT("mask"), true) : true; + + // now we have everything we need to create the image list + wxImageList *imagelist = new wxImageList(size.x, size.y, mask); + + // add images + wxString parambitmap = wxT("bitmap"); + if ( HasParam(parambitmap) ) + { + wxXmlNode *n = m_node->GetChildren(); + while (n) + { + if (n->GetType() == wxXML_ELEMENT_NODE && n->GetName() == parambitmap) + { + // add icon instead of bitmap to keep the bitmap mask + imagelist->Add(GetIcon(n)); + } + n = n->GetNext(); + } + } + + m_node = oldnode; + return imagelist; +} + wxXmlNode *wxXmlResourceHandler::GetParamNode(const wxString& param) { wxCHECK_MSG(m_node, NULL, wxT("You can't access handler data before it was initialized!")); @@ -1447,9 +1561,9 @@ bool wxXmlResourceHandler::IsOfClass(wxXmlNode *node, const wxString& classname) -wxString wxXmlResourceHandler::GetNodeContent(wxXmlNode *node) +wxString wxXmlResourceHandler::GetNodeContent(const wxXmlNode *node) { - wxXmlNode *n = node; + const wxXmlNode *n = node; if (n == NULL) return wxEmptyString; n = n->GetChildren(); @@ -1473,6 +1587,10 @@ wxString wxXmlResourceHandler::GetParamValue(const wxString& param) return GetNodeContent(GetParamNode(param)); } +wxString wxXmlResourceHandler::GetParamValue(const wxXmlNode* node) +{ + return GetNodeContent(node); +} wxSize wxXmlResourceHandler::GetSize(const wxString& param, @@ -1584,7 +1702,7 @@ static wxFont GetSystemFont(const wxString& name) if (!name.empty()) { #define SYSFNT(fnt) \ - if (name == _T(#fnt)) return wxSystemSettings::GetFont(fnt); + if (name == wxT(#fnt)) return wxSystemSettings::GetFont(fnt); SYSFNT(wxSYS_OEM_FIXED_FONT) SYSFNT(wxSYS_ANSI_FIXED_FONT) SYSFNT(wxSYS_ANSI_VAR_FONT) @@ -1689,6 +1807,7 @@ wxFont wxXmlResourceHandler::GetFont(const wxString& param) // encoding wxFontEncoding enc = wxFONTENCODING_DEFAULT; bool hasEncoding = HasParam(wxT("encoding")); +#if wxUSE_FONTMAP if (hasEncoding) { wxString encoding = GetParamValue(wxT("encoding")); @@ -1698,6 +1817,7 @@ wxFont wxXmlResourceHandler::GetFont(const wxString& param) if (enc == wxFONTENCODING_SYSTEM) enc = wxFONTENCODING_DEFAULT; } +#endif // wxUSE_FONTMAP // is this font based on a system font? wxFont font = GetSystemFont(GetParamValue(wxT("sysfont"))); @@ -1746,8 +1866,12 @@ void wxXmlResourceHandler::SetupWindow(wxWindow *wnd) wnd->SetExtraStyle(wnd->GetExtraStyle() | GetStyle(wxT("exstyle"))); if (HasParam(wxT("bg"))) wnd->SetBackgroundColour(GetColour(wxT("bg"))); + if (HasParam(wxT("ownbg"))) + wnd->SetOwnBackgroundColour(GetColour(wxT("ownbg"))); if (HasParam(wxT("fg"))) wnd->SetForegroundColour(GetColour(wxT("fg"))); + if (HasParam(wxT("ownfg"))) + wnd->SetOwnForegroundColour(GetColour(wxT("ownfg"))); if (GetBool(wxT("enabled"), 1) == 0) wnd->Enable(false); if (GetBool(wxT("focused"), 0) == 1) @@ -1759,7 +1883,9 @@ void wxXmlResourceHandler::SetupWindow(wxWindow *wnd) wnd->SetToolTip(GetText(wxT("tooltip"))); #endif if (HasParam(wxT("font"))) - wnd->SetFont(GetFont()); + wnd->SetFont(GetFont(wxT("font"))); + if (HasParam(wxT("ownfont"))) + wnd->SetOwnFont(GetFont(wxT("ownfont"))); if (HasParam(wxT("help"))) wnd->SetHelpText(GetText(wxT("help"))); } @@ -1771,8 +1897,8 @@ void wxXmlResourceHandler::CreateChildren(wxObject *parent, bool this_hnd_only) { if ( IsObjectNode(n) ) { - m_resource->CreateResFromNode(n, parent, NULL, - this_hnd_only ? this : NULL); + m_resource->DoCreateResFromNode(*n, parent, NULL, + this_hnd_only ? this : NULL); } } } @@ -1911,58 +2037,13 @@ static int XRCID_Lookup(const char *str_id, int value_if_not_found = wxID_NONE) return (*rec_var)->id; } -static void AddStdXRCID_Records(); - -/*static*/ -int wxXmlResource::DoGetXRCID(const char *str_id, int value_if_not_found) -{ - static bool s_stdIDsAdded = false; - - if ( !s_stdIDsAdded ) - { - s_stdIDsAdded = true; - AddStdXRCID_Records(); - } - - return XRCID_Lookup(str_id, value_if_not_found); -} - -/* static */ -wxString wxXmlResource::FindXRCIDById(int numId) -{ - for ( int i = 0; i < XRCID_TABLE_SIZE; i++ ) - { - for ( XRCID_record *rec = XRCID_Records[i]; rec; rec = rec->next ) - { - if ( rec->id == numId ) - return wxString(rec->key); - } - } - - return wxString(); -} - -static void CleanXRCID_Record(XRCID_record *rec) +namespace { - if (rec) - { - CleanXRCID_Record(rec->next); - - free(rec->key); - delete rec; - } -} -static void CleanXRCID_Records() -{ - for (int i = 0; i < XRCID_TABLE_SIZE; i++) - { - CleanXRCID_Record(XRCID_Records[i]); - XRCID_Records[i] = NULL; - } -} +// flag indicating whether standard XRC ids were already initialized +static bool gs_stdIDsAdded = false; -static void AddStdXRCID_Records() +void AddStdXRCID_Records() { #define stdID(id) XRCID_Lookup(#id, id) stdID(-1); @@ -2090,8 +2171,57 @@ static void AddStdXRCID_Records() #undef stdID } +} // anonymous namespace + + +/*static*/ +int wxXmlResource::DoGetXRCID(const char *str_id, int value_if_not_found) +{ + if ( !gs_stdIDsAdded ) + { + gs_stdIDsAdded = true; + AddStdXRCID_Records(); + } + + return XRCID_Lookup(str_id, value_if_not_found); +} + +/* static */ +wxString wxXmlResource::FindXRCIDById(int numId) +{ + for ( int i = 0; i < XRCID_TABLE_SIZE; i++ ) + { + for ( XRCID_record *rec = XRCID_Records[i]; rec; rec = rec->next ) + { + if ( rec->id == numId ) + return wxString(rec->key); + } + } + + return wxString(); +} + +static void CleanXRCID_Record(XRCID_record *rec) +{ + if (rec) + { + CleanXRCID_Record(rec->next); + free(rec->key); + delete rec; + } +} +static void CleanXRCID_Records() +{ + for (int i = 0; i < XRCID_TABLE_SIZE; i++) + { + CleanXRCID_Record(XRCID_Records[i]); + XRCID_Records[i] = NULL; + } + + gs_stdIDsAdded = false; +} //-----------------------------------------------------------------------------