detect and report errors in XRC specification of grid sizers

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@59572 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Václav Slavík
2009-03-16 13:33:39 +00:00
parent 159852aeae
commit afc0db8ca0
3 changed files with 82 additions and 7 deletions

View File

@@ -741,15 +741,16 @@ public:
int GetVGap() const { return m_vgap; }
int GetHGap() const { return m_hgap; }
// return the number of total items and the number of columns and rows
// (for internal use only)
int CalcRowsCols(int& rows, int& cols) const;
protected:
int m_rows;
int m_cols;
int m_vgap;
int m_hgap;
// return the number of total items and the number of columns and rows
int CalcRowsCols(int& rows, int& cols) const;
void SetItemBounds( wxSizerItem *item, int x, int y, int w, int h );
private:

View File

@@ -47,6 +47,7 @@ private:
wxGridBagSizer* Handle_wxGridBagSizer();
wxSizer* Handle_wxWrapSizer();
bool ValidateGridSizerChildren();
void SetGrowables(wxFlexGridSizer* fsizer, const wxChar* param, bool rows);
wxGBPosition GetGBPos(const wxString& param);
wxGBSpan GetGBSpan(const wxString& param);

View File

@@ -215,7 +215,11 @@ wxObject* wxSizerXmlHandler::Handle_sizer()
sizer = Handle_wxStaticBoxSizer();
#endif
else if (m_class == wxT("wxGridSizer"))
{
if ( !ValidateGridSizerChildren() )
return NULL;
sizer = Handle_wxGridSizer();
}
else if (m_class == wxT("wxFlexGridSizer"))
{
flexsizer = Handle_wxFlexGridSizer();
@@ -227,14 +231,18 @@ wxObject* wxSizerXmlHandler::Handle_sizer()
sizer = flexsizer;
}
else if (m_class == wxT("wxWrapSizer"))
{
sizer = Handle_wxWrapSizer();
if ( !sizer )
}
else
{
ReportError(wxString::Format("unknown sizer class \"%s\"", m_class));
return NULL;
}
// creation of sizer failed for some (already reported) reason, so exit:
if ( !sizer )
return NULL;
wxSize minsize = GetSize(wxT("minsize"));
if (!(minsize == wxDefaultSize))
sizer->SetMinSize(minsize);
@@ -318,6 +326,8 @@ wxSizer* wxSizerXmlHandler::Handle_wxGridSizer()
wxFlexGridSizer* wxSizerXmlHandler::Handle_wxFlexGridSizer()
{
if ( !ValidateGridSizerChildren() )
return NULL;
return new wxFlexGridSizer(GetLong(wxT("rows")), GetLong(wxT("cols")),
GetDimension(wxT("vgap")), GetDimension(wxT("hgap")));
}
@@ -325,6 +335,8 @@ wxFlexGridSizer* wxSizerXmlHandler::Handle_wxFlexGridSizer()
wxGridBagSizer* wxSizerXmlHandler::Handle_wxGridBagSizer()
{
if ( !ValidateGridSizerChildren() )
return NULL;
return new wxGridBagSizer(GetDimension(wxT("vgap")), GetDimension(wxT("hgap")));
}
@@ -335,16 +347,59 @@ 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))
{
ReportParamError
@@ -355,6 +410,24 @@ void wxSizerXmlHandler::SetGrowables(wxFlexGridSizer* sizer,
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