X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/63b37a4e648320827a5b4a3161be13154370b5c3..d27d59fb91131222207a535b43ef67babfd03ee9:/src/xrc/xh_sizer.cpp diff --git a/src/xrc/xh_sizer.cpp b/src/xrc/xh_sizer.cpp index 2e6bc72c4a..9e3d23d2ff 100644 --- a/src/xrc/xh_sizer.cpp +++ b/src/xrc/xh_sizer.cpp @@ -81,6 +81,11 @@ wxSizerXmlHandler::wxSizerXmlHandler() XRC_ADD_STYLE(wxFIXED_MINSIZE); XRC_ADD_STYLE(wxRESERVE_SPACE_EVEN_IF_HIDDEN); + // this flag doesn't do anything any more but we can just ignore its + // occurrences in the old resource files instead of raising a fuss because + // of it + AddStyle("wxADJUST_MINSIZE", 0); + // wxWrapSizer-specific flags XRC_ADD_STYLE(wxEXTEND_LAST_ON_EACH_LINE); XRC_ADD_STYLE(wxREMOVE_LEADING_SPACES); @@ -110,9 +115,40 @@ wxObject* wxSizerXmlHandler::DoCreateResource() } +wxSizer* wxSizerXmlHandler::DoCreateSizer(const wxString& name) +{ + if (name == wxT("wxBoxSizer")) + return Handle_wxBoxSizer(); +#if wxUSE_STATBOX + else if (name == wxT("wxStaticBoxSizer")) + return Handle_wxStaticBoxSizer(); +#endif + else if (name == wxT("wxGridSizer")) + { + if ( !ValidateGridSizerChildren() ) + return NULL; + return Handle_wxGridSizer(); + } + else if (name == wxT("wxFlexGridSizer")) + { + return Handle_wxFlexGridSizer(); + } + else if (name == wxT("wxGridBagSizer")) + { + return Handle_wxGridBagSizer(); + } + else if (name == wxT("wxWrapSizer")) + { + return Handle_wxWrapSizer(); + } + + ReportError(wxString::Format("unknown sizer class \"%s\"", name)); + return NULL; +} + -bool wxSizerXmlHandler::IsSizerNode(wxXmlNode *node) +bool wxSizerXmlHandler::IsSizerNode(wxXmlNode *node) const { return (IsOfClass(node, wxT("wxBoxSizer"))) || (IsOfClass(node, wxT("wxStaticBoxSizer"))) || @@ -156,7 +192,7 @@ wxObject* wxSizerXmlHandler::Handle_sizeritem() else if (wnd) sitem->AssignWindow(wnd); else - wxLogError(wxT("Error in resource.")); + ReportError(n, "unexpected item in sizer"); // finally, set other wxSizerItem attributes SetSizerItemAttributes(sitem); @@ -166,7 +202,7 @@ wxObject* wxSizerXmlHandler::Handle_sizeritem() } else /*n == NULL*/ { - wxLogError(wxT("Error in resource: no window/sizer/spacer within sizeritem object.")); + ReportError("no window/sizer/spacer within sizeritem object"); return NULL; } } @@ -174,7 +210,11 @@ wxObject* wxSizerXmlHandler::Handle_sizeritem() wxObject* wxSizerXmlHandler::Handle_spacer() { - wxCHECK_MSG(m_parentSizer, NULL, wxT("Incorrect syntax of XRC resource: spacer not within sizer!")); + if ( !m_parentSizer ) + { + ReportError("spacer only allowed inside a sizer"); + return NULL; + } wxSizerItem* sitem = MakeSizerItem(); SetSizerItemAttributes(sitem); @@ -186,40 +226,22 @@ wxObject* wxSizerXmlHandler::Handle_spacer() wxObject* wxSizerXmlHandler::Handle_sizer() { - wxSizer *sizer = NULL; - wxXmlNode *parentNode = m_node->GetParent(); - wxCHECK_MSG(m_parentSizer != NULL || - (parentNode && parentNode->GetType() == wxXML_ELEMENT_NODE && - m_parentAsWindow), NULL, - wxT("Sizer must have a window parent node")); - - if (m_class == wxT("wxBoxSizer")) - sizer = Handle_wxBoxSizer(); - -#if wxUSE_STATBOX - else if (m_class == wxT("wxStaticBoxSizer")) - sizer = Handle_wxStaticBoxSizer(); -#endif - - else if (m_class == wxT("wxGridSizer")) - sizer = Handle_wxGridSizer(); - - else if (m_class == wxT("wxFlexGridSizer")) - sizer = Handle_wxFlexGridSizer(); - - else if (m_class == wxT("wxGridBagSizer")) - sizer = Handle_wxGridBagSizer(); + if ( !m_parentSizer && + (!parentNode || parentNode->GetType() != wxXML_ELEMENT_NODE || + !m_parentAsWindow) ) + { + ReportError("sizer must have a window parent"); + return NULL; + } - else if (m_class == wxT("wxWrapSizer")) - sizer = Handle_wxWrapSizer(); + // Create the sizer of the appropriate class. + wxSizer * const sizer = DoCreateSizer(m_class); + // creation of sizer failed for some (already reported) reason, so exit: if ( !sizer ) - { - wxLogError(_T("Failed to create size of class \"%s\""), m_class.c_str()); return NULL; - } wxSize minsize = GetSize(wxT("minsize")); if (!(minsize == wxDefaultSize)) @@ -236,6 +258,13 @@ wxObject* wxSizerXmlHandler::Handle_sizer() CreateChildren(m_parent, true/*only this handler*/); + // set growable rows and cols for sizers which support this + if ( wxFlexGridSizer *flexsizer = wxDynamicCast(sizer, wxFlexGridSizer) ) + { + SetGrowables(flexsizer, wxT("growablerows"), true); + SetGrowables(flexsizer, wxT("growablecols"), false); + } + // restore state m_isInside = old_ins; m_parentSizer = old_par; @@ -295,24 +324,20 @@ wxSizer* wxSizerXmlHandler::Handle_wxGridSizer() } -wxSizer* wxSizerXmlHandler::Handle_wxFlexGridSizer() +wxFlexGridSizer* wxSizerXmlHandler::Handle_wxFlexGridSizer() { - wxFlexGridSizer *sizer = - new wxFlexGridSizer(GetLong(wxT("rows")), GetLong(wxT("cols")), - GetDimension(wxT("vgap")), GetDimension(wxT("hgap"))); - SetGrowables(sizer, wxT("growablerows"), true); - SetGrowables(sizer, wxT("growablecols"), false); - return sizer; + if ( !ValidateGridSizerChildren() ) + return NULL; + return new wxFlexGridSizer(GetLong(wxT("rows")), GetLong(wxT("cols")), + GetDimension(wxT("vgap")), GetDimension(wxT("hgap"))); } -wxSizer* wxSizerXmlHandler::Handle_wxGridBagSizer() +wxGridBagSizer* wxSizerXmlHandler::Handle_wxGridBagSizer() { - wxGridBagSizer *sizer = - new wxGridBagSizer(GetDimension(wxT("vgap")), GetDimension(wxT("hgap"))); - SetGrowables(sizer, wxT("growablerows"), true); - SetGrowables(sizer, wxT("growablecols"), false); - return sizer; + if ( !ValidateGridSizerChildren() ) + return NULL; + return new wxGridBagSizer(GetDimension(wxT("vgap")), GetDimension(wxT("hgap"))); } wxSizer* wxSizerXmlHandler::Handle_wxWrapSizer() @@ -322,24 +347,91 @@ wxSizer* wxSizerXmlHandler::Handle_wxWrapSizer() } +bool wxSizerXmlHandler::ValidateGridSizerChildren() +{ + int rows = GetLong("rows"); + int cols = GetLong("cols"); + + if ( rows && cols ) + { + // fixed number of cells, need to verify children count + int children = 0; + for ( wxXmlNode *n = m_node->GetChildren(); n; n = n->GetNext() ) + { + if ( n->GetType() == wxXML_ELEMENT_NODE && + (n->GetName() == "object" || n->GetName() == "object_ref") ) + { + children++; + } + } + + if ( children > rows * cols ) + { + ReportError + ( + wxString::Format + ( + "too many children in grid sizer: %d > %d x %d" + " (consider omitting the number of rows or columns)", + children, + cols, + rows + ) + ); + return false; + } + } + + return true; +} + void wxSizerXmlHandler::SetGrowables(wxFlexGridSizer* sizer, const wxChar* param, bool rows) { + int nrows, ncols; + sizer->CalcRowsCols(nrows, ncols); + const int nslots = rows ? nrows : ncols; + wxStringTokenizer tkn; - unsigned long l; tkn.SetString(GetParamValue(param), wxT(",")); + while (tkn.HasMoreTokens()) { + unsigned long l; if (!tkn.GetNextToken().ToULong(&l)) - wxLogError(wxT("growable[rows|cols] must be comma-separated list of row numbers")); - else { - if (rows) - sizer->AddGrowableRow(l); - else - sizer->AddGrowableCol(l); + { + ReportParamError + ( + param, + "value must be comma-separated list of row numbers" + ); + break; } + + if ( (int)l >= nslots ) + { + ReportParamError + ( + param, + wxString::Format + ( + "invalid %s index %d: must be less than %d", + rows ? "row" : "column", + l, + nslots + ) + ); + + // ignore incorrect value, still try to process the rest + continue; + } + + if (rows) + sizer->AddGrowableRow(l); + else + sizer->AddGrowableCol(l); } } @@ -451,13 +543,13 @@ wxObject *wxStdDialogButtonSizerXmlHandler::DoCreateResource() if (button) m_parentSizer->AddButton(button); else - wxLogError(wxT("Error in resource - expected button.")); + ReportError(n, "expected wxButton"); return item; } else /*n == NULL*/ { - wxLogError(wxT("Error in resource: no button within wxStdDialogButtonSizer.")); + ReportError("no button within wxStdDialogButtonSizer"); return NULL; } }