From d4a724d4075418ccaea166925c33242a338249c7 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Mon, 21 Aug 2006 18:27:15 +0000 Subject: [PATCH] Make it possible to tell wxXmlResource which domain to pull translatable strings from. Make the wxLocale::GetString methods virtual so they can be overridden in derived classes. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@40728 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/function.tex | 10 ++- docs/latex/wx/xmlres.tex | 33 +++++++- include/wx/intl.h | 22 +++--- include/wx/xrc/xmlres.h | 15 +++- src/xrc/xh_chckl.cpp | 2 +- src/xrc/xh_choic.cpp | 2 +- src/xrc/xh_combo.cpp | 2 +- src/xrc/xh_listb.cpp | 2 +- src/xrc/xh_odcombo.cpp | 2 +- src/xrc/xh_radbx.cpp | 6 +- src/xrc/xmlres.cpp | 23 +++++- wxPython/src/_intl.i | 158 +++++++++++++++++++++++++++++++++++++ wxPython/src/_xmlres.i | 16 +++- 13 files changed, 260 insertions(+), 33 deletions(-) diff --git a/docs/latex/wx/function.tex b/docs/latex/wx/function.tex index f3565f5b8e..377d434f96 100644 --- a/docs/latex/wx/function.tex +++ b/docs/latex/wx/function.tex @@ -1536,15 +1536,19 @@ This function is deprecated, use \helpref{wxString}{wxstring} class instead. \membersection{::wxGetTranslation}\label{wxgettranslation} -\func{const char *}{wxGetTranslation}{\param{const char * }{str}} +\func{const wxChar *}{wxGetTranslation}{\param{const wxChar* }{str}, + \param{const wxChar* }{domain = NULL}} -\func{const char *}{wxGetTranslation}{\param{const char * }{str}, \param{const char * }{strPlural}, \param{size\_t }{n}} +\func{const wxChar *}{wxGetTranslation}{\param{const wxChar* }{str}, \param{const wxChar* }{strPlural}, \param{size\_t }{n}, + \param{const wxChar* }{domain = NULL}}} This function returns the translation of string {\it str} in the current \helpref{locale}{wxlocale}. If the string is not found in any of the loaded message catalogs (see \helpref{internationalization overview}{internationalization}), the original string is returned. In debug build, an error message is logged -- this -should help to find the strings which were not yet translated. As this function +should help to find the strings which were not yet translated. If +{\it domain} is specified then only that domain/catalog is searched +for a matching string. As this function is used very often, an alternative (and also common in Unix world) syntax is provided: the \helpref{\_()}{underscore} macro is defined to do the same thing as wxGetTranslation. diff --git a/docs/latex/wx/xmlres.tex b/docs/latex/wx/xmlres.tex index 05e6b72dfd..c4f6b75730 100644 --- a/docs/latex/wx/xmlres.tex +++ b/docs/latex/wx/xmlres.tex @@ -35,7 +35,9 @@ enum wxXmlResourceFlags \membersection{wxXmlResource::wxXmlResource}\label{wxxmlresourcector} -\func{}{wxXmlResource}{\param{const wxString\& }{filemask}, \param{int }{flags = wxXRC\_USE\_LOCALE}} +\func{}{wxXmlResource}{\param{const wxString\& }{filemask}, + \param{int }{flags = wxXRC\_USE\_LOCALE}, + \param{const wxString& }{domain = wxEmptyString}} Constructor. @@ -46,7 +48,13 @@ load all resource files inside a zip archive.} wxXRC\_NO\_SUBCLASSING: subclass property of object nodes will be ignored (useful for previews in XRC editors).} -\func{}{wxXmlResource}{\param{int }{flags = wxXRC\_USE\_LOCALE}} +\docparam{domain}{The name of the gettext catalog to search for + translatable strings. By default all loaded catalogs will be + searched. This provides a way to allow the strings to only come + from a specific catalog.} + +\func{}{wxXmlResource}{\param{int }{flags = wxXRC\_USE\_LOCALE}, + \param{const wxString& }{domain = wxEmptyString}} Constructor. @@ -56,6 +64,11 @@ wxXRC\_NO\_SUBCLASSING: subclass property of object nodes will be ignored XRC files from being reloaded from disk in case they have been modified there since being last loaded (may slightly speed up loading them).} +\docparam{domain}{The name of the gettext catalog to search for + translatable strings. By default all loaded catalogs will be + searched. This provides a way to allow the strings to only come + from a specific catalog.} + \membersection{wxXmlResource::\destruct{wxXmlResource}}\label{wxxmlresourcedtor} @@ -254,3 +267,19 @@ This function unloads a resource previously loaded by Returns \true if the resource was successfully unloaded and \false if it hasn't been found in the list of loaded resources. + + +\membersection{wxXmlResource::GetDomain}\label{wxxmlresourcegetdomain} + +\func{wxChar*}{GetDomain}{} + +Returns the domain (message catalog) that will be used to load +translatable strings in the XRC. + + +\membersection{wxXmlResource::SetDomain}\label{wxxmlresourcesetdomain} + +\func{wxChar*}{SetDomain}{\param{const wxChar* }{domain}} + +Sets the domain (message catalog) that will be used to load +translatable strings in the XRC. diff --git a/include/wx/intl.h b/include/wx/intl.h index 3e523ec95f..1518905484 100644 --- a/include/wx/intl.h +++ b/include/wx/intl.h @@ -402,7 +402,7 @@ public: int flags = wxLOCALE_LOAD_DEFAULT | wxLOCALE_CONV_ENCODING); // restores old locale - ~wxLocale(); + virtual ~wxLocale(); // Try to get user's (or OS's) preferred language setting. // Return wxLANGUAGE_UNKNOWN if language-guessing algorithm failed @@ -490,13 +490,13 @@ public: // // domains are searched in the last to first order, i.e. catalogs // added later override those added before. - const wxChar *GetString(const wxChar *szOrigString, - const wxChar *szDomain = NULL) const; + virtual const wxChar *GetString(const wxChar *szOrigString, + const wxChar *szDomain = NULL) const; // plural form version of the same: - const wxChar *GetString(const wxChar *szOrigString, - const wxChar *szOrigString2, - size_t n, - const wxChar *szDomain = NULL) const; + virtual const wxChar *GetString(const wxChar *szOrigString, + const wxChar *szOrigString2, + size_t n, + const wxChar *szDomain = NULL) const; // Returns the current short name for the locale const wxString& GetName() const { return m_strShort; } @@ -548,20 +548,20 @@ private: extern WXDLLIMPEXP_BASE wxLocale* wxGetLocale(); // get the translation of the string in the current locale -inline const wxChar *wxGetTranslation(const wxChar *sz) +inline const wxChar *wxGetTranslation(const wxChar *sz, const wxChar* domain=NULL) { wxLocale *pLoc = wxGetLocale(); if (pLoc) - return pLoc->GetString(sz); + return pLoc->GetString(sz, domain); else return sz; } inline const wxChar *wxGetTranslation(const wxChar *sz1, const wxChar *sz2, - size_t n) + size_t n, const wxChar* domain=NULL) { wxLocale *pLoc = wxGetLocale(); if (pLoc) - return pLoc->GetString(sz1, sz2, n); + return pLoc->GetString(sz1, sz2, n, domain); else return n == 1 ? sz1 : sz2; } diff --git a/include/wx/xrc/xmlres.h b/include/wx/xrc/xmlres.h index 2644c6e86a..715133b2cb 100644 --- a/include/wx/xrc/xmlres.h +++ b/include/wx/xrc/xmlres.h @@ -104,21 +104,25 @@ public: // Constructor. // Flags: wxXRC_USE_LOCALE // translatable strings will be translated via _() + // using the given domain if specified // wxXRC_NO_SUBCLASSING // subclass property of object nodes will be ignored // (useful for previews in XRC editors) // wxXRC_NO_RELOADING // don't check the modification time of the XRC files and // reload them if they have changed on disk - wxXmlResource(int flags = wxXRC_USE_LOCALE); + wxXmlResource(int flags = wxXRC_USE_LOCALE, + const wxString& domain=wxEmptyString); // Constructor. // Flags: wxXRC_USE_LOCALE // translatable strings will be translated via _() + // using the given domain if specified // wxXRC_NO_SUBCLASSING // subclass property of object nodes will be ignored // (useful for previews in XRC editors) - wxXmlResource(const wxString& filemask, int flags = wxXRC_USE_LOCALE); + wxXmlResource(const wxString& filemask, int flags = wxXRC_USE_LOCALE, + const wxString& domain=wxEmptyString); // Destructor. ~wxXmlResource(); @@ -242,6 +246,10 @@ public: // Set flags after construction. void SetFlags(int flags) { m_flags = flags; } + // Get/Set the domain to be passed to the translation functions, defaults to NULL. + wxChar* GetDomain() const { return m_domain; } + void SetDomain(const wxChar* domain); + protected: // Scans the resources list for unloaded files and loads them. Also reloads // files that have been modified since last loading. @@ -281,6 +289,9 @@ private: wxFileSystem& GetCurFileSystem() { return m_curFileSystem; } #endif + // domain to pass to translation functions, if any. + wxChar* m_domain; + friend class wxXmlResourceHandler; friend class wxXmlResourceModule; diff --git a/src/xrc/xh_chckl.cpp b/src/xrc/xh_chckl.cpp index d3a8257cd3..04fb3b78da 100644 --- a/src/xrc/xh_chckl.cpp +++ b/src/xrc/xh_chckl.cpp @@ -113,7 +113,7 @@ wxObject *wxCheckListBoxXmlHandler::DoCreateResource() // add to the list wxString str = GetNodeContent(m_node); if (m_resource->GetFlags() & wxXRC_USE_LOCALE) - str = wxGetTranslation(str); + str = wxGetTranslation(str, m_resource->GetDomain()); strList.Add(str); return NULL; } diff --git a/src/xrc/xh_choic.cpp b/src/xrc/xh_choic.cpp index c26bf71eea..04b726e7c0 100644 --- a/src/xrc/xh_choic.cpp +++ b/src/xrc/xh_choic.cpp @@ -82,7 +82,7 @@ wxObject *wxChoiceXmlHandler::DoCreateResource() // add to the list wxString str = GetNodeContent(m_node); if (m_resource->GetFlags() & wxXRC_USE_LOCALE) - str = wxGetTranslation(str); + str = wxGetTranslation(str, m_resource->GetDomain()); strList.Add(str); return NULL; diff --git a/src/xrc/xh_combo.cpp b/src/xrc/xh_combo.cpp index 6950cfc198..99c0370559 100644 --- a/src/xrc/xh_combo.cpp +++ b/src/xrc/xh_combo.cpp @@ -87,7 +87,7 @@ wxObject *wxComboBoxXmlHandler::DoCreateResource() // add to the list wxString str = GetNodeContent(m_node); if (m_resource->GetFlags() & wxXRC_USE_LOCALE) - str = wxGetTranslation(str); + str = wxGetTranslation(str, m_resource->GetDomain()); strList.Add(str); return NULL; diff --git a/src/xrc/xh_listb.cpp b/src/xrc/xh_listb.cpp index 0deaa03bed..a319449d20 100644 --- a/src/xrc/xh_listb.cpp +++ b/src/xrc/xh_listb.cpp @@ -88,7 +88,7 @@ wxObject *wxListBoxXmlHandler::DoCreateResource() // add to the list wxString str = GetNodeContent(m_node); if (m_resource->GetFlags() & wxXRC_USE_LOCALE) - str = wxGetTranslation(str); + str = wxGetTranslation(str, m_resource->GetDomain()); strList.Add(str); return NULL; diff --git a/src/xrc/xh_odcombo.cpp b/src/xrc/xh_odcombo.cpp index f5108204a4..8f5d6d2705 100644 --- a/src/xrc/xh_odcombo.cpp +++ b/src/xrc/xh_odcombo.cpp @@ -97,7 +97,7 @@ wxObject *wxOwnerDrawnComboBoxXmlHandler::DoCreateResource() // add to the list wxString str = GetNodeContent(m_node); if (m_resource->GetFlags() & wxXRC_USE_LOCALE) - str = wxGetTranslation(str); + str = wxGetTranslation(str, m_resource->GetDomain()); strList.Add(str); return NULL; diff --git a/src/xrc/xh_radbx.cpp b/src/xrc/xh_radbx.cpp index 2b5a066b1d..5cf6472c5b 100644 --- a/src/xrc/xh_radbx.cpp +++ b/src/xrc/xh_radbx.cpp @@ -116,11 +116,11 @@ wxObject *wxRadioBoxXmlHandler::DoCreateResource() if (m_resource->GetFlags() & wxXRC_USE_LOCALE) { - str = wxGetTranslation(str); + str = wxGetTranslation(str, m_resource->GetDomain()); if ( !tooltip.empty() ) - tooltip = wxGetTranslation(tooltip); + tooltip = wxGetTranslation(tooltip, m_resource->GetDomain()); if ( hasHelptext ) - helptext = wxGetTranslation(helptext); + helptext = wxGetTranslation(helptext, m_resource->GetDomain()); } labels.push_back(str); diff --git a/src/xrc/xmlres.cpp b/src/xrc/xmlres.cpp index 20b402dc64..9a55df5861 100644 --- a/src/xrc/xmlres.cpp +++ b/src/xrc/xmlres.cpp @@ -65,24 +65,41 @@ 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) @@ -916,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 { diff --git a/wxPython/src/_intl.i b/wxPython/src/_intl.i index 5901e839a5..32b102bad9 100644 --- a/wxPython/src/_intl.i +++ b/wxPython/src/_intl.i @@ -461,7 +461,163 @@ public: }; +//--------------------------------------------------------------------------- + +%{ +class wxPyLocale : public wxLocale +{ +public: + wxPyLocale(); + + wxPyLocale(const wxChar *szName, // name (for messages) + const wxChar *szShort = (const wxChar *) NULL, // dir prefix (for msg files) + const wxChar *szLocale = (const wxChar *) NULL, // locale (for setlocale) + bool bLoadDefault = true, // preload wxstd.mo? + bool bConvertEncoding = false); // convert Win<->Unix if necessary? + + wxPyLocale(int language, // wxLanguage id or custom language + int flags = wxLOCALE_LOAD_DEFAULT | wxLOCALE_CONV_ENCODING); + + ~wxPyLocale(); + + virtual const wxChar *GetString(const wxChar *szOrigString, + const wxChar *szDomain = NULL) const; + virtual const wxChar *GetString(const wxChar *szOrigString, + const wxChar *szOrigString2, size_t n, + const wxChar *szDomain = NULL) const; + + virtual wxChar *GetSingularString(const wxChar *szOrigString, + const wxChar *szDomain = NULL) const; + virtual wxChar *GetPluralString(const wxChar *szOrigString, + const wxChar *szOrigString2, size_t n, + const wxChar *szDomain = NULL) const; + + PYPRIVATE; +private: + DECLARE_NO_COPY_CLASS(wxPyLocale) +}; + +wxPyLocale::wxPyLocale() : wxLocale() +{ +} + +wxPyLocale::wxPyLocale(const wxChar *szName, // name (for messages) + const wxChar *szShort, // dir prefix (for msg files) + const wxChar *szLocale, // locale (for setlocale) + bool bLoadDefault, // preload wxstd.mo? + bool bConvertEncoding) // convert Win<->Unix if necessary? + : wxLocale(szName, szShort, szLocale, bLoadDefault, bConvertEncoding) +{ +} + +wxPyLocale::wxPyLocale(int language, // wxLanguage id or custom language + int flags) : wxLocale(language, flags) +{ +} + +wxPyLocale::~wxPyLocale() +{ +} + +const wxChar *wxPyLocale::GetString(const wxChar *szOrigString, + const wxChar *szDomain) const +{ + wxChar *str = GetSingularString(szOrigString, szDomain); + return (str != NULL) ? str : wxLocale::GetString(szOrigString, szDomain); +} + +const wxChar *wxPyLocale::GetString(const wxChar *szOrigString, + const wxChar *szOrigString2, size_t n, + const wxChar *szDomain) const +{ + wxChar *str = GetPluralString(szOrigString, szOrigString2, n, szDomain); + return (str != NULL) ? str : wxLocale::GetString(szOrigString, szOrigString2, n, szDomain); +} + +wxChar *wxPyLocale::GetSingularString(const wxChar *szOrigString, + const wxChar *szDomain) const +{ + bool found; + static wxString str; + str = _T("error in translation"); // when the first if condition is true but the second if condition is not we do not want to return the previously queried string. + wxPyBlock_t blocked = wxPyBeginBlockThreads(); + if((found=wxPyCBH_findCallback(m_myInst, "GetSingularString"))) { + PyObject* param1 = wx2PyString(szOrigString); + PyObject* param2 = wx2PyString(szDomain); + PyObject* ret = wxPyCBH_callCallbackObj(m_myInst, Py_BuildValue("(OO)", param1, param2)); + Py_DECREF(param1); + Py_DECREF(param2); + if (ret) { + str = Py2wxString(ret); + Py_DECREF(ret); + } + } + wxPyEndBlockThreads(blocked); + return (found ? (wxChar*)str.c_str() : NULL); +} +wxChar *wxPyLocale::GetPluralString(const wxChar *szOrigString, + const wxChar *szOrigString2, size_t n, + const wxChar *szDomain) const +{ + bool found; + static wxString str; + str = _T("error in translation"); // when the first if condition is true but the second if condition is not we do not want to return the previously queried string. + wxPyBlock_t blocked = wxPyBeginBlockThreads(); + if((found=wxPyCBH_findCallback(m_myInst, "GetPluralString"))) { + PyObject* param1 = wx2PyString(szOrigString); + PyObject* param2 = wx2PyString(szOrigString2); + PyObject* param4 = wx2PyString(szDomain); + PyObject* ret = wxPyCBH_callCallbackObj(m_myInst, Py_BuildValue("(OOiO)", param1, param2, (int)n, param4)); + Py_DECREF(param1); + Py_DECREF(param2); + Py_DECREF(param4); + if( ret) { + str = Py2wxString(ret); + Py_DECREF(ret); + } + } + wxPyEndBlockThreads(blocked); + return (found ? (wxChar*)str.c_str() : NULL); +} +%} + + +class wxPyLocale : public wxLocale +{ +public: + %pythonAppend wxPyLocale "self._setCallbackInfo(self, PyLocale)" + + // ctor & dtor + // ----------- + %extend { + wxPyLocale(int language = -1, + int flags = wxLOCALE_LOAD_DEFAULT | wxLOCALE_CONV_ENCODING) { + wxPyLocale* loc; + if (language == -1) + loc = new wxPyLocale(); + else + loc = new wxPyLocale(language, flags); + // Python before 2.4 needs to have LC_NUMERIC set to "C" in order + // for the floating point conversions and such to work right. +%#if PY_VERSION_HEX < 0x02040000 + setlocale(LC_NUMERIC, "C"); +%#endif + return loc; + } + } + ~wxPyLocale(); + + void _setCallbackInfo(PyObject* self, PyObject* _class); + + virtual const wxChar *GetSingularString(const wxChar *szOrigString, + const wxChar *szDomain = NULL) const; + virtual const wxChar *GetPluralString(const wxChar *szOrigString, + const wxChar *szOrigString2, size_t n, + const wxChar *szDomain = NULL) const; +}; + +//--------------------------------------------------------------------------- // get the current locale object (note that it may be NULL!) wxLocale* wxGetLocale(); @@ -469,7 +625,9 @@ wxLocale* wxGetLocale(); // get the translation of the string in the current locale %nokwargs wxGetTranslation; wxString wxGetTranslation(const wxString& str); +wxString wxGetTranslation(const wxString& str, const wxString& domain); wxString wxGetTranslation(const wxString& str, const wxString& strPlural, size_t n); +wxString wxGetTranslation(const wxString& str, const wxString& strPlural, size_t n, const wxString& domain); //--------------------------------------------------------------------------- %newgroup diff --git a/wxPython/src/_xmlres.i b/wxPython/src/_xmlres.i index d313e342ec..87310ca821 100644 --- a/wxPython/src/_xmlres.i +++ b/wxPython/src/_xmlres.i @@ -45,8 +45,10 @@ class wxXmlResource : public wxObject { public: - %pythonAppend wxXmlResource(const wxString& filemask, int flags) "self.InitAllHandlers()" - %pythonAppend wxXmlResource(int flags) "val.InitAllHandlers()" + %pythonAppend wxXmlResource(const wxString& filemask, int flags, + const wxString& domain=wxEmptyString) "self.InitAllHandlers()" + %pythonAppend wxXmlResource(int flags, + const wxString& domain=wxEmptyString) "val.InitAllHandlers()" // Ctors. // Flags: wxXRC_USE_LOCALE @@ -54,8 +56,11 @@ public: // wxXRC_NO_SUBCLASSING // subclass property of object nodes will be ignored // (useful for previews in XRC editors) - wxXmlResource(const wxString& filemask, int flags = wxXRC_USE_LOCALE); - %RenameCtor(EmptyXmlResource, wxXmlResource(int flags = wxXRC_USE_LOCALE)); + wxXmlResource(const wxString& filemask, int flags = wxXRC_USE_LOCALE, + const wxString& domain=wxEmptyString); + %RenameCtor(EmptyXmlResource, wxXmlResource(int flags = wxXRC_USE_LOCALE, + const wxString& domain=wxEmptyString)); + ~wxXmlResource(); @@ -195,6 +200,9 @@ public: // Set flags after construction. void SetFlags(int flags) { m_flags = flags; } + // Get/Set the domain to be passed to the translation functions, defaults to NULL. + wxString GetDomain() const; + void SetDomain(const wxString& domain); }; //---------------------------------------------------------------------- -- 2.45.2