From 689704119a3a12110bf8842c76c6298c5e4d9d1d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 11 Jan 2018 00:27:08 +0100 Subject: [PATCH 1/4] Fix handling of underscores in tags in "wxrc -g" output Unlike all the other nodes containing translatable text, the contents of the tags, used for wxChoice, wxListBox etc items, is not escaped (because it can't contain mnemonics), so don't unescape it when outputting it from "wxrc --gettext" neither. See #18033. --- utils/wxrc/wxrc.cpp | 89 +++++++++++++++++++++++++++++---------------- 1 file changed, 57 insertions(+), 32 deletions(-) diff --git a/utils/wxrc/wxrc.cpp b/utils/wxrc/wxrc.cpp index 56f4c9799f..fb06278d07 100644 --- a/utils/wxrc/wxrc.cpp +++ b/utils/wxrc/wxrc.cpp @@ -949,6 +949,46 @@ static wxString ConvertText(const wxString& str) } +enum ContentsKind +{ + Contents_NotTrans, // Not a translatable text at all. + Contents_TransOnly, // Translatable but not escaped text. + Contents_Text // Text, i.e. both translatable and escaped. +}; + +// Check if the given node contains translatable text and, if it does, whether +// it's escaped (i.e. parsed using GetText()) or not. +ContentsKind +GetNodeContentsKind(wxXmlNode& node, const wxString& contents) +{ + if ( node.GetName() == wxT("label") || + (node.GetName() == wxT("value") && !contents.IsNumber()) || + node.GetName() == wxT("help") || + node.GetName() == wxT("hint") || + node.GetName() == wxT("longhelp") || + node.GetName() == wxT("tooltip") || + node.GetName() == wxT("htmlcode") || + node.GetName() == wxT("title") || + node.GetName() == wxT("message") || + node.GetName() == wxT("note") || + node.GetName() == wxT("defaultdirectory") || + node.GetName() == wxT("defaultfilename") || + node.GetName() == wxT("defaultfolder") || + node.GetName() == wxT("filter") || + node.GetName() == wxT("caption") ) + { + return Contents_Text; + } + + // This one is special: it is translated in XRC, but its contents is not + // escaped. + if ( node.GetName() == wxT("item") ) + return Contents_TransOnly; + + return Contents_NotTrans; +} + + ExtractedStrings XmlResApp::FindStrings(const wxString& filename, wxXmlNode *node) { @@ -963,41 +1003,26 @@ XmlResApp::FindStrings(const wxString& filename, wxXmlNode *node) if ((node->GetType() == wxXML_ELEMENT_NODE) && // parent is an element, i.e. has subnodes... (n->GetType() == wxXML_TEXT_NODE || - n->GetType() == wxXML_CDATA_SECTION_NODE) && + n->GetType() == wxXML_CDATA_SECTION_NODE)) // ...it is textnode... - ( - node/*not n!*/->GetName() == wxT("label") || - (node/*not n!*/->GetName() == wxT("value") && - !n->GetContent().IsNumber()) || - node/*not n!*/->GetName() == wxT("help") || - node/*not n!*/->GetName() == wxT("hint") || - node/*not n!*/->GetName() == wxT("longhelp") || - node/*not n!*/->GetName() == wxT("tooltip") || - node/*not n!*/->GetName() == wxT("htmlcode") || - node/*not n!*/->GetName() == wxT("title") || - node/*not n!*/->GetName() == wxT("item") || - node/*not n!*/->GetName() == wxT("message") || - node/*not n!*/->GetName() == wxT("note") || - node/*not n!*/->GetName() == wxT("defaultdirectory") || - node/*not n!*/->GetName() == wxT("defaultfilename") || - node/*not n!*/->GetName() == wxT("defaultfolder") || - node/*not n!*/->GetName() == wxT("filter") || - node/*not n!*/->GetName() == wxT("caption") - )) - // ...and known to contain translatable string { - if (!flagGettext || - node->GetAttribute(wxT("translate"), wxT("1")) != wxT("0")) + wxString s = n->GetContent(); + switch ( GetNodeContentsKind(*node, s) ) { - arr.push_back - ( - ExtractedString - ( - ConvertText(n->GetContent()), - filename, - n->GetLineNumber() - ) - ); + case Contents_NotTrans: + break; + + case Contents_Text: + s = ConvertText(s); + wxFALLTHROUGH; + + case Contents_TransOnly: + if (!flagGettext || + node->GetAttribute(wxT("translate"), wxT("1")) != wxT("0")) + { + arr.push_back(ExtractedString(s, filename, n->GetLineNumber())); + } + break; } } From 52635cfc100380e7d182a771ad070c663afc8e0d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 11 Jan 2018 00:57:02 +0100 Subject: [PATCH 2/4] Reuse the same XRC function for all translations Translate all strings in the new GetNodeText() function replacing the old GetText() which was mostly used for translatable strings before -- except that tag contents didn't use it because it also performed string unescaping, not wanted for the control items, in addition to translation. Replace the old GetText() (while still keeping it for compatibility, i.e. to avoid breaking any custom XRC handlers using it) with the new function which is more flexible and can be used for all tags. No real changes, this is just a refactoring. --- include/wx/xrc/xmlres.h | 5 +- include/wx/xrc/xmlreshandler.h | 16 ++++- src/xrc/xh_chckl.cpp | 5 +- src/xrc/xh_choic.cpp | 5 +- src/xrc/xh_combo.cpp | 5 +- src/xrc/xh_editlbox.cpp | 5 +- src/xrc/xh_htmllbox.cpp | 5 +- src/xrc/xh_listb.cpp | 5 +- src/xrc/xh_odcombo.cpp | 5 +- src/xrc/xh_radbx.cpp | 27 ++------ src/xrc/xmlres.cpp | 120 ++++++++++++++++++--------------- 11 files changed, 96 insertions(+), 107 deletions(-) diff --git a/include/wx/xrc/xmlres.h b/include/wx/xrc/xmlres.h index de31ea27a4..bde64138a5 100644 --- a/include/wx/xrc/xmlres.h +++ b/include/wx/xrc/xmlres.h @@ -513,7 +513,10 @@ public: // - replaces \n, \r, \t by respective chars (according to C syntax) // - replaces _ by & and __ by _ (needed for _File => &File because of XML) // - calls wxGetTranslations (unless disabled in wxXmlResource) - wxString GetText(const wxString& param, bool translate = true) wxOVERRIDE; + // + // The first two conversions can be disabled by using wxXRC_TEXT_NO_ESCAPE + // in flags and the last one -- by using wxXRC_TEXT_NO_TRANSLATE. + wxString GetNodeText(const wxXmlNode *node, int flags = 0) wxOVERRIDE; // Returns the XRCID. int GetID() wxOVERRIDE; diff --git a/include/wx/xrc/xmlreshandler.h b/include/wx/xrc/xmlreshandler.h index 5c2f6b4be1..cdf7f0ab17 100644 --- a/include/wx/xrc/xmlreshandler.h +++ b/include/wx/xrc/xmlreshandler.h @@ -32,6 +32,13 @@ class WXDLLIMPEXP_FWD_CORE wxXmlResourceHandler; // by wxXmlResourceHandler implementation itself. #define XRC_ADD_STYLE(style) AddStyle(wxT(#style), style) +// Flags for GetNodeText(). +enum +{ + wxXRC_TEXT_NO_TRANSLATE = 1, + wxXRC_TEXT_NO_ESCAPE = 2 +}; + // Abstract base class for the implementation object used by // wxXmlResourceHandlerImpl. The real implementation is in // wxXmlResourceHandlerImpl class in the "xrc" library while this class is in @@ -61,7 +68,7 @@ public: virtual wxString GetParamValue(const wxString& param) = 0; virtual wxString GetParamValue(const wxXmlNode* node) = 0; virtual int GetStyle(const wxString& param = wxT("style"), int defaults = 0) = 0; - virtual wxString GetText(const wxString& param, bool translate = true) = 0; + virtual wxString GetNodeText(const wxXmlNode *node, int flags = 0) = 0; virtual int GetID() = 0; virtual wxString GetName() = 0; virtual bool GetBool(const wxString& param, bool defaultv = false) = 0; @@ -254,9 +261,14 @@ protected: { return GetImpl()->GetStyle(param, defaults); } + wxString GetNodeText(const wxXmlNode *node, int flags = 0) + { + return GetImpl()->GetNodeText(node, flags); + } wxString GetText(const wxString& param, bool translate = true) { - return GetImpl()->GetText(param, translate); + return GetImpl()->GetNodeText(GetImpl()->GetParamNode(param), + translate ? 0 : wxXRC_TEXT_NO_TRANSLATE); } int GetID() const { diff --git a/src/xrc/xh_chckl.cpp b/src/xrc/xh_chckl.cpp index fddfcf97c2..61675db8f4 100644 --- a/src/xrc/xh_chckl.cpp +++ b/src/xrc/xh_chckl.cpp @@ -94,10 +94,7 @@ wxObject *wxCheckListBoxXmlHandler::DoCreateResource() // handle Label // add to the list - wxString str = GetNodeContent(m_node); - if (m_resource->GetFlags() & wxXRC_USE_LOCALE) - str = wxGetTranslation(str, m_resource->GetDomain()); - strList.Add(str); + strList.Add(GetNodeText(m_node, wxXRC_TEXT_NO_ESCAPE)); return NULL; } } diff --git a/src/xrc/xh_choic.cpp b/src/xrc/xh_choic.cpp index 445ec6b43a..52a3358cac 100644 --- a/src/xrc/xh_choic.cpp +++ b/src/xrc/xh_choic.cpp @@ -70,10 +70,7 @@ wxObject *wxChoiceXmlHandler::DoCreateResource() // handle Label // add to the list - wxString str = GetNodeContent(m_node); - if (m_resource->GetFlags() & wxXRC_USE_LOCALE) - str = wxGetTranslation(str, m_resource->GetDomain()); - strList.Add(str); + strList.Add(GetNodeText(m_node, wxXRC_TEXT_NO_ESCAPE)); return NULL; } diff --git a/src/xrc/xh_combo.cpp b/src/xrc/xh_combo.cpp index a11d24bef9..e0f672ebe4 100644 --- a/src/xrc/xh_combo.cpp +++ b/src/xrc/xh_combo.cpp @@ -77,10 +77,7 @@ wxObject *wxComboBoxXmlHandler::DoCreateResource() // handle Label // add to the list - wxString str = GetNodeContent(m_node); - if (m_resource->GetFlags() & wxXRC_USE_LOCALE) - str = wxGetTranslation(str, m_resource->GetDomain()); - strList.Add(str); + strList.Add(GetNodeText(m_node, wxXRC_TEXT_NO_ESCAPE)); return NULL; } diff --git a/src/xrc/xh_editlbox.cpp b/src/xrc/xh_editlbox.cpp index 32ab05f525..48a57847d4 100644 --- a/src/xrc/xh_editlbox.cpp +++ b/src/xrc/xh_editlbox.cpp @@ -99,10 +99,7 @@ wxObject *wxEditableListBoxXmlHandler::DoCreateResource() } else if ( m_insideBox && m_node->GetName() == EDITLBOX_ITEM_NAME ) { - wxString str = GetNodeContent(m_node); - if ( m_resource->GetFlags() & wxXRC_USE_LOCALE ) - str = wxGetTranslation(str, m_resource->GetDomain()); - m_items.push_back(str); + m_items.push_back(GetNodeText(m_node, wxXRC_TEXT_NO_ESCAPE)); return NULL; } diff --git a/src/xrc/xh_htmllbox.cpp b/src/xrc/xh_htmllbox.cpp index 2b310e4c4e..82c01f10ad 100644 --- a/src/xrc/xh_htmllbox.cpp +++ b/src/xrc/xh_htmllbox.cpp @@ -69,10 +69,7 @@ wxObject *wxSimpleHtmlListBoxXmlHandler::DoCreateResource() // handle Label // add to the list - wxString str = GetNodeContent(m_node); - if (m_resource->GetFlags() & wxXRC_USE_LOCALE) - str = wxGetTranslation(str, m_resource->GetDomain()); - strList.Add(str); + strList.Add(GetNodeText(m_node, wxXRC_TEXT_NO_ESCAPE)); return NULL; } diff --git a/src/xrc/xh_listb.cpp b/src/xrc/xh_listb.cpp index f496023095..e74eb99e2c 100644 --- a/src/xrc/xh_listb.cpp +++ b/src/xrc/xh_listb.cpp @@ -77,10 +77,7 @@ wxObject *wxListBoxXmlHandler::DoCreateResource() // handle Label // add to the list - wxString str = GetNodeContent(m_node); - if (m_resource->GetFlags() & wxXRC_USE_LOCALE) - str = wxGetTranslation(str, m_resource->GetDomain()); - strList.Add(str); + strList.Add(GetNodeText(m_node, wxXRC_TEXT_NO_ESCAPE)); return NULL; } diff --git a/src/xrc/xh_odcombo.cpp b/src/xrc/xh_odcombo.cpp index 955ac1d826..293e7c5d30 100644 --- a/src/xrc/xh_odcombo.cpp +++ b/src/xrc/xh_odcombo.cpp @@ -85,10 +85,7 @@ wxObject *wxOwnerDrawnComboBoxXmlHandler::DoCreateResource() // handle Label // add to the list - wxString str = GetNodeContent(m_node); - if (m_resource->GetFlags() & wxXRC_USE_LOCALE) - str = wxGetTranslation(str, m_resource->GetDomain()); - strList.Add(str); + strList.Add(GetNodeText(m_node, wxXRC_TEXT_NO_ESCAPE)); return NULL; } diff --git a/src/xrc/xh_radbx.cpp b/src/xrc/xh_radbx.cpp index 12c9e02a25..762f31b2e0 100644 --- a/src/xrc/xh_radbx.cpp +++ b/src/xrc/xh_radbx.cpp @@ -107,30 +107,15 @@ wxObject *wxRadioBoxXmlHandler::DoCreateResource() // we handle handle Label constructs here, and the item // tag can have tooltip, helptext, enabled and hidden attributes - wxString label = GetNodeContent(m_node); - - wxString tooltip; - m_node->GetAttribute(wxT("tooltip"), &tooltip); - - wxString helptext; - bool hasHelptext = m_node->GetAttribute(wxT("helptext"), &helptext); - - if (m_resource->GetFlags() & wxXRC_USE_LOCALE) - { - label = wxGetTranslation(label, m_resource->GetDomain()); - if ( !tooltip.empty() ) - tooltip = wxGetTranslation(tooltip, m_resource->GetDomain()); - if ( hasHelptext ) - helptext = wxGetTranslation(helptext, m_resource->GetDomain()); - } - - m_labels.push_back(label); + m_labels.push_back(GetNodeText(m_node, wxXRC_TEXT_NO_ESCAPE)); #if wxUSE_TOOLTIPS - m_tooltips.push_back(tooltip); + m_tooltips.push_back(GetNodeText(GetParamNode(wxT("tooltip")), + wxXRC_TEXT_NO_ESCAPE)); #endif // wxUSE_TOOLTIPS #if wxUSE_HELP - m_helptexts.push_back(helptext); - m_helptextSpecified.push_back(hasHelptext); + const wxXmlNode* const nodeHelp = GetParamNode(wxT("helptext")); + m_helptexts.push_back(GetNodeText(nodeHelp, wxXRC_TEXT_NO_ESCAPE)); + m_helptextSpecified.push_back(nodeHelp != NULL); #endif // wxUSE_HELP m_isEnabled.push_back(GetBoolAttr("enabled", 1)); m_isShown.push_back(!GetBoolAttr("hidden", 0)); diff --git a/src/xrc/xmlres.cpp b/src/xrc/xmlres.cpp index 6a1e813c26..1963ba9d73 100644 --- a/src/xrc/xmlres.cpp +++ b/src/xrc/xmlres.cpp @@ -1506,73 +1506,83 @@ int wxXmlResourceHandlerImpl::GetStyle(const wxString& param, int defaults) -wxString wxXmlResourceHandlerImpl::GetText(const wxString& param, bool translate) +wxString wxXmlResourceHandlerImpl::GetNodeText(const wxXmlNode* node, int flags) { - wxXmlNode *parNode = GetParamNode(param); - wxString str1(GetNodeContent(parNode)); + wxString str1(GetNodeContent(node)); + if ( str1.empty() ) + return str1; + wxString str2; - // "\\" wasn't translated to "\" prior to 2.5.3.0: - const bool escapeBackslash = (m_handler->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"). - const wxChar amp_char = (m_handler->m_resource->CompareVersion(2,3,0,1) < 0) - ? '$' : '_'; - - for ( wxString::const_iterator dt = str1.begin(); dt != str1.end(); ++dt ) + if ( !(flags & wxXRC_TEXT_NO_ESCAPE) ) { - // 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 ) + // "\\" wasn't translated to "\" prior to 2.5.3.0: + const bool escapeBackslash = (m_handler->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"). + const wxChar amp_char = (m_handler->m_resource->CompareVersion(2,3,0,1) < 0) + ? '$' : '_'; + + for ( wxString::const_iterator dt = str1.begin(); dt != str1.end(); ++dt ) { - if ( dt+1 == str1.end() || *(++dt) == amp_char ) - str2 << amp_char; - else - str2 << wxT('&') << *dt; - } - // Remap \n to CR, \r to LF, \t to TAB, \\ to \: - else if ( *dt == wxT('\\') ) - { - switch ( (*(++dt)).GetValue() ) + // 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 ) { - case wxT('n'): - str2 << wxT('\n'); - break; - - case wxT('t'): - str2 << wxT('\t'); - break; - - case wxT('r'): - str2 << wxT('\r'); - break; - - case wxT('\\') : - // "\\" wasn't translated to "\" prior to 2.5.3.0: - if ( escapeBackslash ) - { - str2 << wxT('\\'); + if ( dt+1 == str1.end() || *(++dt) == amp_char ) + str2 << amp_char; + else + str2 << wxT('&') << *dt; + } + // Remap \n to CR, \r to LF, \t to TAB, \\ to \: + else if ( *dt == wxT('\\') ) + { + switch ( (*(++dt)).GetValue() ) + { + case wxT('n'): + str2 << wxT('\n'); break; - } - wxFALLTHROUGH;// else fall-through to default: branch below - default: - str2 << wxT('\\') << *dt; - break; + case wxT('t'): + str2 << wxT('\t'); + break; + + case wxT('r'): + str2 << wxT('\r'); + break; + + case wxT('\\') : + // "\\" wasn't translated to "\" prior to 2.5.3.0: + if ( escapeBackslash ) + { + str2 << wxT('\\'); + break; + } + wxFALLTHROUGH;// else fall-through to default: branch below + + default: + str2 << wxT('\\') << *dt; + break; + } + } + else + { + str2 << *dt; } } - else - { - str2 << *dt; - } + } + else // Don't escape anything in this string. + { + // We won't use str1 at all, so move its contents to str2. + str2.swap(str1); } if (m_handler->m_resource->GetFlags() & wxXRC_USE_LOCALE) { - if (translate && parNode && - parNode->GetAttribute(wxT("translate"), wxEmptyString) != wxT("0")) + if (!(flags & wxXRC_TEXT_NO_TRANSLATE) && node && + node->GetAttribute(wxT("translate"), wxEmptyString) != wxT("0")) { return wxGetTranslation(str2, m_handler->m_resource->GetDomain()); } @@ -2508,14 +2518,14 @@ void wxXmlResourceHandlerImpl::SetupWindow(wxWindow *wnd) wnd->SetFocus(); #if wxUSE_TOOLTIPS if (HasParam(wxT("tooltip"))) - wnd->SetToolTip(GetText(wxT("tooltip"))); + wnd->SetToolTip(GetNodeText(GetParamNode(wxT("tooltip")))); #endif if (HasParam(wxT("font"))) wnd->SetFont(GetFont(wxT("font"), wnd)); if (HasParam(wxT("ownfont"))) wnd->SetOwnFont(GetFont(wxT("ownfont"), wnd)); if (HasParam(wxT("help"))) - wnd->SetHelpText(GetText(wxT("help"))); + wnd->SetHelpText(GetNodeText(GetParamNode(wxT("help")))); } From bc2c9ce2a3565cd774cbb56bc770833e6530cb11 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 11 Jan 2018 01:03:01 +0100 Subject: [PATCH 3/4] Fix misspelling of a label in XRC docs and example It was spelt in 2 different ways, neither of which was actually correct. --- docs/doxygen/overviews/xrc_format.h | 2 +- samples/xrc/rc/controls.xrc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/doxygen/overviews/xrc_format.h b/docs/doxygen/overviews/xrc_format.h index abffacb471..de2c1e0a27 100644 --- a/docs/doxygen/overviews/xrc_format.h +++ b/docs/doxygen/overviews/xrc_format.h @@ -1611,7 +1611,7 @@ Example: Energy 98.3 CHUM FM 92FM - + @endcode diff --git a/samples/xrc/rc/controls.xrc b/samples/xrc/rc/controls.xrc index bac4812e5e..a6c4406570 100644 --- a/samples/xrc/rc/controls.xrc +++ b/samples/xrc/rc/controls.xrc @@ -779,7 +779,7 @@ lay them out using wxSizers, absolute positioning, everything you like! Energy 98.3 CHUM FM 92FM - + From 3357d46ccc8c53233b7089a042cbfe22d5417ca2 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 11 Jan 2018 01:14:47 +0100 Subject: [PATCH 4/4] Make it simpler to use mnemonics for wxRadioBox items in XRC Allow specifying label="1" attribute in wxRadioBox tags to indicate that the usual translation of "_" to "&" should be done, as for all the other labels. This is still not the default behaviour to avoid breaking any existing XRC files using "_", even though using labels="1" by default would make more sense. --- docs/doxygen/overviews/xrc_format.h | 5 +++++ misc/schema/xrc_schema.rnc | 1 + src/xrc/xh_radbx.cpp | 8 +++++++- utils/wxrc/wxrc.cpp | 9 +++++++-- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/docs/doxygen/overviews/xrc_format.h b/docs/doxygen/overviews/xrc_format.h index de2c1e0a27..ebc25b1513 100644 --- a/docs/doxygen/overviews/xrc_format.h +++ b/docs/doxygen/overviews/xrc_format.h @@ -1595,6 +1595,11 @@ can also have some optional XML @em attributes (not properties!): Is the button enabled (default: 1)?} @row3col{hidden, @ref overview_xrcformat_type_bool, Is the button hidden initially (default: 0)?} +@row3col{label, @ref overview_xrcformat_type_bool, + Should this item text be interpreted as a label, i.e. escaping underscores + in it as done for the label properties of other controls? This attribute + exists since wxWidgets 3.1.1 and was always treated as having the value of + 0, which still remains its default, until then.} @endTable Example: diff --git a/misc/schema/xrc_schema.rnc b/misc/schema/xrc_schema.rnc index e4617452f6..ada4360591 100644 --- a/misc/schema/xrc_schema.rnc +++ b/misc/schema/xrc_schema.rnc @@ -1225,6 +1225,7 @@ wxRadioBox = attribute helptext { t_string }?, attribute enabled { t_bool }?, attribute hidden { t_bool }?, + attribute label { t_bool }?, t_text }* }? diff --git a/src/xrc/xh_radbx.cpp b/src/xrc/xh_radbx.cpp index 762f31b2e0..5fd8a84287 100644 --- a/src/xrc/xh_radbx.cpp +++ b/src/xrc/xh_radbx.cpp @@ -107,7 +107,13 @@ wxObject *wxRadioBoxXmlHandler::DoCreateResource() // we handle handle Label constructs here, and the item // tag can have tooltip, helptext, enabled and hidden attributes - m_labels.push_back(GetNodeText(m_node, wxXRC_TEXT_NO_ESCAPE)); + // For compatibility, labels are not escaped in XRC by default and + // label="1" attribute needs to be explicitly specified to handle them + // consistently with the other labels. + m_labels.push_back(GetNodeText(m_node, + GetBoolAttr("label", 0) + ? 0 + : wxXRC_TEXT_NO_ESCAPE)); #if wxUSE_TOOLTIPS m_tooltips.push_back(GetNodeText(GetParamNode(wxT("tooltip")), wxXRC_TEXT_NO_ESCAPE)); diff --git a/utils/wxrc/wxrc.cpp b/utils/wxrc/wxrc.cpp index fb06278d07..72bfd49738 100644 --- a/utils/wxrc/wxrc.cpp +++ b/utils/wxrc/wxrc.cpp @@ -981,9 +981,14 @@ GetNodeContentsKind(wxXmlNode& node, const wxString& contents) } // This one is special: it is translated in XRC, but its contents is not - // escaped. + // escaped, except for the special case of wxRadioBox when it can be, if + // "label" attribute is supplied. if ( node.GetName() == wxT("item") ) - return Contents_TransOnly; + { + return node.GetAttribute(wxT("label"), wxT("0")) == wxT("1") + ? Contents_Text + : Contents_TransOnly; + } return Contents_NotTrans; }