From 4df7057302915da9a0e0a3db5bb43873f2692e9b Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 20 Apr 2015 19:37:47 +0200 Subject: [PATCH] Refactor: extract XRC code handling conversion from dialog units. Factor out this code to a reusable ParseValueInPixels() function instead of repeating it in GetSize() and GetDimension() (and using a hack to reuse it from GetPosition()). No real changes, just made some error messages more precise. --- include/wx/xrc/xmlres.h | 2 + src/xrc/xmlres.cpp | 178 +++++++++++++++++++++------------------- 2 files changed, 97 insertions(+), 83 deletions(-) diff --git a/include/wx/xrc/xmlres.h b/include/wx/xrc/xmlres.h index e58f1c0551..5d05005de1 100644 --- a/include/wx/xrc/xmlres.h +++ b/include/wx/xrc/xmlres.h @@ -585,6 +585,8 @@ public: // Gets the value of a boolean attribute (only "0" and "1" are valid values) bool GetBoolAttr(const wxString& attr, bool defaultv); + // Returns the window associated with the handler (may be NULL). + wxWindow* GetParentAsWindow() const { return m_handler->GetParentAsWindow(); } // Sets common window options. void SetupWindow(wxWindow *wnd); diff --git a/src/xrc/xmlres.cpp b/src/xrc/xmlres.cpp index 3c5e991371..88b280025c 100644 --- a/src/xrc/xmlres.cpp +++ b/src/xrc/xmlres.cpp @@ -49,6 +49,8 @@ #include "wx/hashset.h" #include "wx/scopedptr.h" +#include + namespace { @@ -2056,59 +2058,108 @@ wxString wxXmlResourceHandlerImpl::GetParamValue(const wxXmlNode* node) return GetNodeContent(node); } +namespace +{ + +// Dimensions (linear or sizes/positions) can be expressed as absolute values +// or as dialog units in XRC, define functions for parsing both of them. + +bool XRCConvertFromAbsValue(const wxString& s, int& value) +{ + long l; + if ( !s.ToLong(&l) ) + return false; + + if ( l > INT_MAX ) + return false; + + value = static_cast(l); + return true; +} + +template +inline +bool XRCConvertFromAbsValue(const wxString& s, T& value) +{ + return XRCConvertFromAbsValue(s.BeforeFirst(','), value.x) && + XRCConvertFromAbsValue(s.AfterLast(wxS(',')), value.y); +} + +inline +void XRCConvertFromDLU(wxWindow* w, int& value) +{ + value = w->ConvertDialogToPixels(wxPoint(value, 0)).x; +} + +template +inline +void XRCConvertFromDLU(wxWindow* w, T& value) +{ + value = w->ConvertDialogToPixels(value); +} + +// Helper for parsing values (of type T, for which XRCConvertFromAbsValue() and +// XRCConvertFromDLU() functions must be defined) which can be expressed either +// in pixels or dialog units. +template +T +ParseValueInPixels(wxXmlResourceHandlerImpl* impl, + const wxString& param, + const T& defaultValue, + wxWindow *windowToUse = NULL) +{ + const wxString s = impl->GetParamValue(param); + if ( s.empty() ) + return defaultValue; + + const bool inDLU = s.Last() == 'd'; + + T value; + if ( !XRCConvertFromAbsValue(inDLU ? wxString(s).RemoveLast() : s, value) ) + { + impl->ReportParamError + ( + param, + wxString::Format("cannot parse dimension value \"%s\"", s) + ); + return defaultValue; + } + + if ( inDLU ) + { + if ( !windowToUse ) + windowToUse = impl->GetParentAsWindow(); + + if ( !windowToUse ) + { + impl->ReportParamError + ( + param, + wxString::Format("cannot interpret dimension value \"%s\" " + "in dialog units without a window", s) + ); + return defaultValue; + } + + XRCConvertFromDLU(windowToUse, value); + } + + return value; +} + +} // anonymous namespace wxSize wxXmlResourceHandlerImpl::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'); - if (is_dlg) s.RemoveLast(); - - if (!s.BeforeFirst(wxT(',')).ToLong(&sx) || - !s.AfterLast(wxT(',')).ToLong(&sy)) - { - ReportParamError - ( - param, - wxString::Format("cannot parse coordinates value \"%s\"", s) - ); - return wxDefaultSize; - } - - if (is_dlg) - { - if (windowToUse) - { - return wxDLG_UNIT(windowToUse, wxSize(sx, sy)); - } - else if (m_handler->m_parentAsWindow) - { - return wxDLG_UNIT(m_handler->m_parentAsWindow, wxSize(sx, sy)); - } - else - { - ReportParamError - ( - param, - "cannot convert dialog units: dialog unknown" - ); - return wxDefaultSize; - } - } - - return wxSize(sx, sy); + return ParseValueInPixels(this, param, wxDefaultSize, windowToUse); } wxPoint wxXmlResourceHandlerImpl::GetPosition(const wxString& param) { - wxSize sz = GetSize(param); - return wxPoint(sz.x, sz.y); + return ParseValueInPixels(this, param, wxDefaultPosition); } @@ -2117,46 +2168,7 @@ wxCoord wxXmlResourceHandlerImpl::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'); - if (is_dlg) s.RemoveLast(); - - if (!s.ToLong(&sx)) - { - ReportParamError - ( - param, - wxString::Format("cannot parse dimension value \"%s\"", s) - ); - return defaultv; - } - - if (is_dlg) - { - if (windowToUse) - { - return wxDLG_UNIT(windowToUse, wxSize(sx, 0)).x; - } - else if (m_handler->m_parentAsWindow) - { - return wxDLG_UNIT(m_handler->m_parentAsWindow, wxSize(sx, 0)).x; - } - else - { - ReportParamError - ( - param, - "cannot convert dialog units: dialog unknown" - ); - return defaultv; - } - } - - return sx; + return ParseValueInPixels(this, param, defaultv, windowToUse); } wxDirection