X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/8516a98b5456f39052b0eccfbb550fb00f23da60..3ab296d9eb6d351eb1d2238f3e6ff2f5e6123861:/src/xrc/xmlres.cpp diff --git a/src/xrc/xmlres.cpp b/src/xrc/xmlres.cpp index 0e1b2943ab..17ee409812 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 ///////////////////////////////////////////////////////////////////////////// -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) -#pragma implementation "xmlres.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -21,32 +17,36 @@ #if wxUSE_XRC +#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" +#endif + #ifndef __WXWINCE__ -#include + #include #endif -#include "wx/dialog.h" -#include "wx/panel.h" -#include "wx/frame.h" #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/settings.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; @@ -65,24 +65,81 @@ wxXmlResource *wxXmlResource::ms_instance = NULL; return old; } -wxXmlResource::wxXmlResource(int flags) +wxXmlResource::wxXmlResource(int flags, const wxString& domain) { m_flags = flags; m_version = -1; + m_domain = NULL; + if (! domain.empty() ) + 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; + m_domain = NULL; + if (! domain.empty() ) + SetDomain(domain); Load(filemask); } wxXmlResource::~wxXmlResource() { + if (m_domain) + free(m_domain); ClearHandlers(); } +void wxXmlResource::SetDomain(const wxChar* domain) +{ + if (m_domain) + free(m_domain); + m_domain = NULL; + if (domain && wxStrlen(domain)) + m_domain = wxStrdup(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) { @@ -105,34 +162,15 @@ bool wxXmlResource::Load(const wxString& filemask) fnd = filemask; 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; @@ -149,6 +187,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) @@ -354,7 +432,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()); @@ -362,9 +444,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) @@ -420,11 +506,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 @@ -558,10 +646,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->GetPropVal(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()); } @@ -622,7 +721,7 @@ wxObject *wxXmlResource::CreateResFromNode(wxXmlNode *node, wxObject *parent, #include "wx/listimpl.cpp" WX_DECLARE_LIST(wxXmlSubclassFactory, wxXmlSubclassFactoriesList); -WX_DEFINE_LIST(wxXmlSubclassFactoriesList); +WX_DEFINE_LIST(wxXmlSubclassFactoriesList) wxXmlSubclassFactoriesList *wxXmlResource::ms_subclassFactories = NULL; @@ -719,17 +818,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); } @@ -828,7 +933,7 @@ wxString wxXmlResourceHandler::GetText(const wxString& param, bool translate) if (translate && parNode && parNode->GetPropVal(wxT("translate"), wxEmptyString) != wxT("0")) { - return wxGetTranslation(str2); + return wxGetTranslation(str2, m_resource->GetDomain()); } else { @@ -877,7 +982,7 @@ float wxXmlResourceHandler::GetFloat(const wxString& param, float defaultv) setlocale(LC_NUMERIC, prevlocale); #endif - return value; + return wx_truncate_cast(float, value); } @@ -954,19 +1059,21 @@ static wxColour GetSystemColour(const wxString& name) return wxNullColour; } -wxColour wxXmlResourceHandler::GetColour(const wxString& param) +wxColour wxXmlResourceHandler::GetColour(const wxString& param, const wxColour& defaultv) { wxString v = GetParamValue(param); - // find colour using HTML syntax (#RRGGBB) - unsigned long tmp = 0; + if ( v.empty() ) + return defaultv; + + wxColour clr; - if (v.Length() != 7 || v[0u] != wxT('#') || - wxSscanf(v.c_str(), wxT("#%lX"), &tmp) != 1) + // wxString -> wxColour conversion + if (!clr.Set(v)) { // the colour doesn't use #RRGGBB format, check if it is symbolic // colour name: - wxColour clr = GetSystemColour(v); + clr = GetSystemColour(v); if (clr.Ok()) return clr; @@ -975,9 +1082,7 @@ wxColour wxXmlResourceHandler::GetColour(const wxString& param) return wxNullColour; } - return wxColour((unsigned char) ((tmp & 0xFF0000) >> 16) , - (unsigned char) ((tmp & 0x00FF00) >> 8), - (unsigned char) ((tmp & 0x0000FF))); + return clr; } @@ -1021,18 +1126,17 @@ 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()); + name.c_str()); return wxNullBitmap; } if (!(size == wxDefaultSize)) img.Rescale(size.x, size.y); return wxBitmap(img); - } @@ -1064,6 +1168,14 @@ wxXmlNode *wxXmlResourceHandler::GetParamNode(const wxString& param) } + +bool wxXmlResourceHandler::IsOfClass(wxXmlNode *node, const wxString& classname) +{ + return node->GetPropVal(wxT("class"), wxEmptyString) == classname; +} + + + wxString wxXmlResourceHandler::GetNodeContent(wxXmlNode *node) { wxXmlNode *n = node; @@ -1092,14 +1204,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.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) || @@ -1111,8 +1224,14 @@ 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.")); @@ -1133,14 +1252,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.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)) @@ -1151,8 +1272,14 @@ 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.")); @@ -1200,10 +1327,10 @@ wxFont wxXmlResourceHandler::GetFont(const wxString& param) // font attributes: // size - int isize = wxDEFAULT; + int isize = -1; bool hasSize = HasParam(wxT("size")); if (hasSize) - isize = GetLong(wxT("size"), wxDEFAULT); + isize = GetLong(wxT("size"), -1); // style int istyle = wxNORMAL; @@ -1253,15 +1380,14 @@ wxFont wxXmlResourceHandler::GetFont(const wxString& param) if (hasFacename) { wxString faces = GetParamValue(wxT("face")); - wxFontEnumerator enu; - enu.EnumerateFacenames(); + wxArrayString facenames(wxFontEnumerator::GetFacenames()); wxStringTokenizer tk(faces, wxT(",")); while (tk.HasMoreTokens()) { - int index = enu.GetFacenames()->Index(tk.GetNextToken(), false); + int index = facenames.Index(tk.GetNextToken(), false); if (index != wxNOT_FOUND) { - facename = (*enu.GetFacenames())[index]; + facename = facenames[index]; break; } } @@ -1281,36 +1407,38 @@ wxFont wxXmlResourceHandler::GetFont(const wxString& param) } // is this font based on a system font? - wxFont sysfont = GetSystemFont(GetParamValue(wxT("sysfont"))); + wxFont font = GetSystemFont(GetParamValue(wxT("sysfont"))); - if (sysfont.Ok()) + if (font.Ok()) { - if (hasSize) - sysfont.SetPointSize(isize); + if (hasSize && isize != -1) + font.SetPointSize(isize); else if (HasParam(wxT("relativesize"))) - sysfont.SetPointSize(int(sysfont.GetPointSize() * + font.SetPointSize(int(font.GetPointSize() * GetFloat(wxT("relativesize")))); if (hasStyle) - sysfont.SetStyle(istyle); + font.SetStyle(istyle); if (hasWeight) - sysfont.SetWeight(iweight); + font.SetWeight(iweight); if (hasUnderlined) - sysfont.SetUnderlined(underlined); + font.SetUnderlined(underlined); if (hasFamily) - sysfont.SetFamily(ifamily); + font.SetFamily(ifamily); if (hasFacename) - sysfont.SetFaceName(facename); + font.SetFaceName(facename); if (hasEncoding) - sysfont.SetDefaultEncoding(enc); - - m_node = oldnode; - return sysfont; + 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 wxFont(isize, ifamily, istyle, iweight, - underlined, facename, enc); + return font; } @@ -1339,6 +1467,8 @@ void wxXmlResourceHandler::SetupWindow(wxWindow *wnd) #endif if (HasParam(wxT("font"))) wnd->SetFont(GetFont()); + if (HasParam(wxT("help"))) + wnd->SetHelpText(GetText(wxT("help"))); } @@ -1395,7 +1525,7 @@ struct XRCID_record 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 wxChar *str_id, int value_if_not_found = wxID_NONE) { int index = 0; @@ -1419,7 +1549,7 @@ static int XRCID_Lookup(const wxChar *str_id, int value_if_not_found = -2) (*rec_var)->next = NULL; wxChar *end; - if (value_if_not_found != -2) + if (value_if_not_found != wxID_NONE) (*rec_var)->id = value_if_not_found; else { @@ -1438,9 +1568,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::GetXRCID(const wxChar *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); } @@ -1483,6 +1624,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); @@ -1584,7 +1726,6 @@ public: wxXmlResourceModule() {} bool OnInit() { - AddStdXRCID_Records(); wxXmlResource::AddSubclassFactory(new wxXmlSubclassFactoryCXX); return true; }