X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/cf2810aa394d47a43489d6138edf0497c389a22c..302c73511a6819c5a56269ba95cb18eb11e994f0:/src/xrc/xmlres.cpp diff --git a/src/xrc/xmlres.cpp b/src/xrc/xmlres.cpp index 365a721f1d..ae88b74358 100644 --- a/src/xrc/xmlres.cpp +++ b/src/xrc/xmlres.cpp @@ -164,10 +164,6 @@ bool wxXmlResource::IsArchive(const wxString& filename) bool wxXmlResource::Load(const wxString& filemask) { - wxString fnd; - bool iswild = wxIsWild(filemask); - bool rt = true; - #if wxUSE_FILESYSTEM wxFileSystem fsys; # define wxXmlFindFirst fsys.FindFirst(filemask, wxFILE) @@ -176,10 +172,13 @@ bool wxXmlResource::Load(const wxString& filemask) # define wxXmlFindFirst wxFindFirstFile(filemask, wxFILE) # define wxXmlFindNext wxFindNextFile() #endif - if (iswild) - fnd = wxXmlFindFirst; - else - fnd = filemask; + wxString fnd = wxXmlFindFirst; + if ( fnd.empty() ) + { + wxLogError(_("Cannot load resources from '%s'."), filemask); + return false; + } + while (!fnd.empty()) { fnd = ConvertFileNameToURL(fnd); @@ -187,7 +186,8 @@ bool wxXmlResource::Load(const wxString& filemask) #if wxUSE_FILESYSTEM if ( IsArchive(fnd) ) { - rt = rt && Load(fnd + wxT("#zip:*.xrc")); + if ( !Load(fnd + wxT("#zip:*.xrc")) ) + return false; } else // a single resource URL #endif // wxUSE_FILESYSTEM @@ -197,14 +197,12 @@ bool wxXmlResource::Load(const wxString& filemask) Data().push_back(drec); } - if (iswild) - fnd = wxXmlFindNext; - else - fnd = wxEmptyString; + fnd = wxXmlFindNext; } # undef wxXmlFindFirst # undef wxXmlFindNext - return rt && UpdateResources(); + + return UpdateResources(); } bool wxXmlResource::Unload(const wxString& filename) @@ -235,6 +233,7 @@ bool wxXmlResource::Unload(const wxString& filename) { if ( (*i)->File == fnd ) { + delete *i; Data().erase(i); unloaded = true; @@ -498,7 +497,7 @@ bool wxXmlResource::UpdateResources() delete rec->Doc; rec->Doc = new wxXmlDocument; } - if (!stream || !rec->Doc->Load(*stream, encoding)) + if (!stream || !stream->IsOk() || !rec->Doc->Load(*stream, encoding)) { wxLogError(_("Cannot load resources from file '%s'."), rec->File); @@ -898,22 +897,21 @@ wxString wxXmlResourceHandler::GetText(const wxString& param, bool translate) wxXmlNode *parNode = GetParamNode(param); wxString str1(GetNodeContent(parNode)); wxString str2; - const wxChar *dt; - wxChar amp_char; + + // "\\" wasn't translated to "\" prior to 2.5.3.0: + const bool escapeBackslash = (m_resource->CompareVersion(2,5,3,0) >= 0); // 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) - amp_char = wxT('$'); - else - amp_char = wxT('_'); + const wxChar amp_char = (m_resource->CompareVersion(2,3,0,1) < 0) + ? '$' : '_'; - for (dt = str1.c_str(); *dt; dt++) + for ( wxString::const_iterator dt = str1.begin(); dt != str1.end(); ++dt ) { // Remap amp_char to &, map double amp_char to amp_char (for things // like "&File..." -- this is illegal in XML, so we use "_File..."): - if (*dt == amp_char) + if ( *dt == amp_char ) { if ( *(++dt) == amp_char ) str2 << amp_char; @@ -921,8 +919,9 @@ wxString wxXmlResourceHandler::GetText(const wxString& param, bool translate) str2 << wxT('&') << *dt; } // Remap \n to CR, \r to LF, \t to TAB, \\ to \: - else if (*dt == wxT('\\')) - switch (*(++dt)) + else if ( *dt == wxT('\\') ) + { + switch ( (*(++dt)).GetValue() ) { case wxT('n'): str2 << wxT('\n'); @@ -938,7 +937,7 @@ wxString wxXmlResourceHandler::GetText(const wxString& param, bool translate) case wxT('\\') : // "\\" wasn't translated to "\" prior to 2.5.3.0: - if (m_resource->CompareVersion(2,5,3,0) >= 0) + if ( escapeBackslash ) { str2 << wxT('\\'); break; @@ -949,7 +948,11 @@ wxString wxXmlResourceHandler::GetText(const wxString& param, bool translate) str2 << wxT('\\') << *dt; break; } - else str2 << *dt; + } + else + { + str2 << *dt; + } } if (m_resource->GetFlags() & wxXRC_USE_LOCALE) @@ -966,7 +969,7 @@ wxString wxXmlResourceHandler::GetText(const wxString& param, bool translate) #else // The string is internally stored as UTF-8, we have to convert // it into system's default encoding so that it can be displayed: - return wxString(str2.mb_str(wxConvUTF8), wxConvLocal); + return wxString(str2.wc_str(wxConvUTF8), wxConvLocal); #endif } } @@ -994,6 +997,7 @@ float wxXmlResourceHandler::GetFloat(const wxString& param, float defaultv) { wxString str = GetParamValue(param); +#if wxUSE_INTL // strings in XRC always use C locale but wxString::ToDouble() uses the // current one, so transform the string to it supposing that the only // difference between them is the decimal separator @@ -1001,6 +1005,7 @@ float wxXmlResourceHandler::GetFloat(const wxString& param, float defaultv) // TODO: use wxString::ToCDouble() when we have it str.Replace(wxT("."), wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT, wxLOCALE_CAT_NUMBER)); +#endif // wxUSE_INTL double value; if (!str.ToDouble(&value)) @@ -1024,13 +1029,17 @@ wxString wxXmlResourceHandler::GetName() +bool wxXmlResourceHandler::GetBoolAttr(const wxString& attr, bool defaultv) +{ + wxString v; + return m_node->GetAttribute(attr, &v) ? v == '1' : defaultv; +} + bool wxXmlResourceHandler::GetBool(const wxString& param, bool defaultv) { - wxString v = GetParamValue(param); - v.MakeLower(); - if (!v) return defaultv; + const wxString v = GetParamValue(param); - return (v == wxT("1")); + return v.empty() ? defaultv : (v == '1'); } @@ -1163,40 +1172,6 @@ wxBitmap wxXmlResourceHandler::GetBitmap(const wxString& param, 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 - - wxIcon wxXmlResourceHandler::GetIcon(const wxString& param, const wxArtClient& defaultArtClient, @@ -1218,14 +1193,20 @@ wxXmlNode *wxXmlResourceHandler::GetParamNode(const wxString& param) while (n) { if (n->GetType() == wxXML_ELEMENT_NODE && n->GetName() == param) + { + // TODO: check that there are no other properties/parameters with + // the same name and log an error if there are (can't do this + // right now as I'm not sure if it's not going to break code + // using this function in unintentional way (i.e. for + // accessing other things than properties), for example + // wxBitmapComboBoxXmlHandler almost surely does return n; + } n = n->GetNext(); } return NULL; } - - bool wxXmlResourceHandler::IsOfClass(wxXmlNode *node, const wxString& classname) { return node->GetAttribute(wxT("class"), wxEmptyString) == classname; @@ -1437,8 +1418,9 @@ wxFont wxXmlResourceHandler::GetFont(const wxString& param) if (hasFacename) { wxString faces = GetParamValue(wxT("face")); - wxArrayString facenames(wxFontEnumerator::GetFacenames()); wxStringTokenizer tk(faces, wxT(",")); +#if wxUSE_FONTENUM + wxArrayString facenames(wxFontEnumerator::GetFacenames()); while (tk.HasMoreTokens()) { int index = facenames.Index(tk.GetNextToken(), false); @@ -1448,6 +1430,11 @@ wxFont wxXmlResourceHandler::GetFont(const wxString& param) break; } } +#else // !wxUSE_FONTENUM + // just use the first face name if we can't check its availability: + if (tk.HasMoreTokens()) + facename = tk.GetNextToken(); +#endif // wxUSE_FONTENUM/!wxUSE_FONTENUM } // encoding @@ -1644,6 +1631,20 @@ int wxXmlResource::DoGetXRCID(const char *str_id, int value_if_not_found) 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) { @@ -1771,6 +1772,24 @@ static void AddStdXRCID_Records() stdID(wxID_MAXIMIZE_FRAME); stdID(wxID_ICONIZE_FRAME); stdID(wxID_RESTORE_FRAME); + stdID(wxID_CDROM); + stdID(wxID_CONVERT); + stdID(wxID_EXECUTE); + stdID(wxID_FLOPPY); + stdID(wxID_HARDDISK); + stdID(wxID_BOTTOM); + stdID(wxID_FIRST); + stdID(wxID_LAST); + stdID(wxID_TOP); + stdID(wxID_INFO); + stdID(wxID_JUMP_TO); + stdID(wxID_NETWORK); + stdID(wxID_SELECT_COLOR); + stdID(wxID_SELECT_FONT); + stdID(wxID_SORT_ASCENDING); + stdID(wxID_SORT_DESCENDING); + stdID(wxID_SPELL_CHECK); + stdID(wxID_STRIKETHROUGH); #undef stdID } @@ -1781,6 +1800,17 @@ static void AddStdXRCID_Records() // --------------- module and globals ----------------------------- +// normally we would do the cleanup from wxXmlResourceModule::OnExit() but it +// can happen that some XRC records have been created because of the use of +// XRCID() in event tables, which happens during static objects initialization, +// but then the application initialization failed and so the wx modules were +// neither initialized nor cleaned up -- this static object does the cleanup in +// this case +static struct wxXRCStaticCleanup +{ + ~wxXRCStaticCleanup() { CleanXRCID_Records(); } +} s_staticCleanup; + class wxXmlResourceModule: public wxModule { DECLARE_DYNAMIC_CLASS(wxXmlResourceModule)