Exemplo n.º 1
0
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;
    tkn.SetString(GetParamValue(param), wxT(","));

    while (tkn.HasMoreTokens())
    {
        unsigned long l;
        if (!tkn.GetNextToken().ToULong(&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);
    }
}
Exemplo n.º 2
0
wxObject *wxCollapsiblePaneXmlHandler::DoCreateResource()
{
    if (m_class == wxT("panewindow"))   // read the XRC for the pane window
    {
        wxXmlNode *n = GetParamNode(wxT("object"));

        if ( !n )
            n = GetParamNode(wxT("object_ref"));

        if (n)
        {
            bool old_ins = m_isInside;
            m_isInside = false;
            wxObject *item = CreateResFromNode(n, m_collpane->GetPane(), NULL);
            m_isInside = old_ins;

            return item;
        }
        else
        {
            ReportError("no control within panewindow");
            return NULL;
        }
    }
    else
    {
        XRC_MAKE_INSTANCE(ctrl, wxCollapsiblePane)

        wxString label = GetText(wxT("label"));
        if (label.empty())
        {
            ReportParamError("label", "label cannot be empty");
            return NULL;
        }

        ctrl->Create(m_parentAsWindow,
                    GetID(),
                    label,
                    GetPosition(), GetSize(),
                    GetStyle(wxT("style"), wxCP_DEFAULT_STYLE),
                    wxDefaultValidator,
                    GetName());

        ctrl->Collapse(GetBool(wxT("collapsed")));
        SetupWindow(ctrl);

        wxCollapsiblePane *old_par = m_collpane;
        m_collpane = ctrl;
        bool old_ins = m_isInside;
        m_isInside = true;
        CreateChildren(m_collpane, true/*only this handler*/);
        m_isInside = old_ins;
        m_collpane = old_par;

        return ctrl;
    }
}
Exemplo n.º 3
0
void wxSizerXmlHandler::SetFlexibleMode(wxFlexGridSizer* fsizer)
{
    if (HasParam(wxT("flexibledirection")))
    {
        wxString dir = GetParamValue(wxT("flexibledirection"));

        if (dir == wxT("wxVERTICAL"))
            fsizer->SetFlexibleDirection(wxVERTICAL);
        else if (dir == wxT("wxHORIZONTAL"))
            fsizer->SetFlexibleDirection(wxHORIZONTAL);
        else if (dir == wxT("wxBOTH"))
            fsizer->SetFlexibleDirection(wxBOTH);
        else
        {
            ReportParamError
            (
                wxT("flexibledirection"),
                wxString::Format("unknown direction \"%s\"", dir)
            );
        }
    }

    if (HasParam(wxT("nonflexiblegrowmode")))
    {
        wxString mode = GetParamValue(wxT("nonflexiblegrowmode"));

        if (mode == wxT("wxFLEX_GROWMODE_NONE"))
            fsizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_NONE);
        else if (mode == wxT("wxFLEX_GROWMODE_SPECIFIED"))
            fsizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
        else if (mode == wxT("wxFLEX_GROWMODE_ALL"))
            fsizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_ALL);
        else
        {
            ReportParamError
            (
                wxT("nonflexiblegrowmode"),
                wxString::Format("unknown grow mode \"%s\"", mode)
            );
        }
    }
}
Exemplo n.º 4
0
wxObject *wxMenuXmlHandler::DoCreateResource()
{
    if (m_class == wxT("wxMenu"))
    {
        wxMenu *menu = m_instance ? wxStaticCast(m_instance, wxMenu)
                                  : new wxMenu(GetStyle());

        wxString title = GetText(wxT("label"));
        wxString help = GetText(wxT("help"));

        bool oldins = m_insideMenu;
        m_insideMenu = true;
        CreateChildren(menu, true/*only this handler*/);
        m_insideMenu = oldins;

        wxMenuBar *p_bar = wxDynamicCast(m_parent, wxMenuBar);
        if (p_bar)
        {
            p_bar->Append(menu, title);
        }
        else
        {
            wxMenu *p_menu = wxDynamicCast(m_parent, wxMenu);
            if (p_menu)
            {
                p_menu->Append(GetID(), title, menu, help);
                if (HasParam(wxT("enabled")))
                    p_menu->Enable(GetID(), GetBool(wxT("enabled")));
            }
        }

        return menu;
    }

    else
    {
        wxMenu *p_menu = wxDynamicCast(m_parent, wxMenu);

        if (m_class == wxT("separator"))
            p_menu->AppendSeparator();
        else if (m_class == wxT("break"))
            p_menu->Break();
        else /*wxMenuItem*/
        {
            int id = GetID();
            wxString label = GetText(wxT("label"));
            wxString accel = GetText(wxT("accel"), false);
            wxString fullLabel = label;
            if (!accel.empty())
                fullLabel << wxT("\t") << accel;

            wxItemKind kind = wxITEM_NORMAL;
            if (GetBool(wxT("radio")))
                kind = wxITEM_RADIO;
            if (GetBool(wxT("checkable")))
            {
                if ( kind != wxITEM_NORMAL )
                {
                    ReportParamError
                    (
                        "checkable",
                        "menu item can't have both <radio> and <checkable> properties"
                    );
                }

                kind = wxITEM_CHECK;
            }

            wxMenuItem *mitem = new wxMenuItem(p_menu, id, fullLabel,
                                               GetText(wxT("help")), kind);

#if (!defined(__WXMSW__) && !defined(__WXPM__)) || wxUSE_OWNER_DRAWN
            if (HasParam(wxT("bitmap")))
            {
                // currently only wxMSW has support for using different checked
                // and unchecked bitmaps for menu items
#ifdef __WXMSW__
                if (HasParam(wxT("bitmap2")))
                    mitem->SetBitmaps(GetBitmap(wxT("bitmap2"), wxART_MENU),
                                      GetBitmap(wxT("bitmap"), wxART_MENU));
                else
#endif // __WXMSW__
                    mitem->SetBitmap(GetBitmap(wxT("bitmap"), wxART_MENU));
            }
#endif
            p_menu->Append(mitem);
            mitem->Enable(GetBool(wxT("enabled"), true));
            if (kind == wxITEM_CHECK)
                mitem->Check(GetBool(wxT("checked")));
        }
        return NULL;
    }
}
Exemplo n.º 5
0
wxObject *wxToolBarXmlHandlerEx::DoCreateResource()
{
	if (m_class == wxT("tool"))
	{
		if (!m_toolbar)
		{
			ReportError("tool only allowed inside a wxToolBar");
			return NULL;
		}

		wxItemKind kind = wxITEM_NORMAL;
		if (GetBool(wxT("radio")))
			kind = wxITEM_RADIO;

		if (GetBool(wxT("toggle")))
		{
			if (kind != wxITEM_NORMAL)
			{
				ReportParamError
					(
					"toggle",
					"tool can't have both <radio> and <toggle> properties"
					);
			}

			kind = wxITEM_CHECK;
		}

#if wxUSE_MENUS
		// check whether we have dropdown tag inside
		wxMenu *menu = NULL; // menu for drop down items
		wxXmlNode * const nodeDropdown = GetParamNode("dropdown");
		if (nodeDropdown)
		{
			if (kind != wxITEM_NORMAL)
			{
				ReportParamError
					(
					"dropdown",
					"drop-down tool can't have neither <radio> nor <toggle> properties"
					);
			}

			kind = wxITEM_DROPDOWN;

			// also check for the menu specified inside dropdown (it is
			// optional and may be absent for e.g. dynamically-created
			// menus)
			wxXmlNode * const nodeMenu = nodeDropdown->GetChildren();
			if (nodeMenu)
			{
				wxObject *res = CreateResFromNode(nodeMenu, NULL);
				menu = dynamic_cast<wxMenu*>(res);
				if (!menu)
				{
					ReportError
						(
						nodeMenu,
						"drop-down tool contents can only be a wxMenu"
						);
				}

				if (nodeMenu->GetNext())
				{
					ReportError
						(
						nodeMenu->GetNext(),
						"unexpected extra contents under drop-down tool"
						);
				}
			}
		}
#endif
		wxBitmap bitmap = GetBitmap(wxT("bitmap"), wxART_TOOLBAR, m_iconSize);
		wxBitmap bitmap2 = GetBitmap(wxT("bitmap2"), wxART_TOOLBAR, m_iconSize);
#ifdef __WXMAC__
		if( bitmap.IsOk() ) {
			if( bitmap.GetSize().x < 24 ) {
				bitmap = wxBitmap(bitmap.ConvertToImage().Size(wxSize(24, 24), wxPoint(4, 4)));
			}
		}

		if( bitmap2.IsOk() ) {
			if( bitmap2.GetSize().x < 24 ) {
				bitmap2 = wxBitmap(bitmap2.ConvertToImage().Size(wxSize(24, 24), wxPoint(4, 4)));
			}
		}
#endif
#ifdef __WXGTK3__
		// We need to provide a disabled bitmap.
		if( !bitmap2.IsOk() && bitmap.IsOk() ) {
			bitmap2 = wxBitmap(bitmap.ConvertToImage().ConvertToGreyscale());
		}
#endif
		wxToolBarToolBase * const tool =
			m_toolbar->AddTool
			(
			GetID(),
			GetText(wxT("label")),
			bitmap,
			bitmap2,
			kind,
			GetText(wxT("tooltip")),
			GetText(wxT("longhelp"))
			);

		if (GetBool(wxT("disabled")))
			m_toolbar->EnableTool(tool->GetId(), false);

		if (GetBool(wxS("checked")))
		{
			if (kind == wxITEM_NORMAL)
			{
				ReportParamError
					(
					"checked",
					"only <radio> nor <toggle> tools can be checked"
					);
			}
			else
			{
				m_toolbar->ToggleTool(tool->GetId(), true);
			}
		}

#if wxUSE_MENUS
		if (menu)
			tool->SetDropdownMenu(menu);
#endif

		return m_toolbar; // must return non-NULL
	}

	else if (m_class == wxT("separator") || m_class == wxT("space"))
	{
		if (!m_toolbar)
		{
			ReportError("separators only allowed inside wxToolBar");
			return NULL;
		}

		if (m_class == wxT("separator"))
			m_toolbar->AddSeparator();
		else
			m_toolbar->AddStretchableSpace();

		return m_toolbar; // must return non-NULL
	}

	else /*<object class="wxToolBar">*/
	{
		int style = GetStyle(wxT("style"), wxNO_BORDER | wxTB_HORIZONTAL);
#ifdef __WXMSW__
		if (!(style & wxNO_BORDER)) style |= wxNO_BORDER;
#endif

		XRC_MAKE_INSTANCE(toolbar, wxToolBar)

			toolbar->Create(m_parentAsWindow,
			GetID(),
			GetPosition(),
			GetSize(),
			style,
			GetName());
		SetupWindow(toolbar);

		toolbar->SetToolBitmapSize(m_iconSize);
		wxSize margins = GetSize(wxT("margins"));
		if (!(margins == wxDefaultSize))
			toolbar->SetMargins(margins.x, margins.y);
		long packing = GetLong(wxT("packing"), -1);
		if (packing != -1)
			toolbar->SetToolPacking(packing);
		long separation = GetLong(wxT("separation"), -1);
		if (separation != -1)
			toolbar->SetToolSeparation(separation);

		wxXmlNode *children_node = GetParamNode(wxT("object"));
		if (!children_node)
			children_node = GetParamNode(wxT("object_ref"));

		if (children_node == NULL) return toolbar;

		m_isInside = true;
		m_toolbar = toolbar;

		wxXmlNode *n = children_node;

		while (n)
		{
			if ((n->GetType() == wxXML_ELEMENT_NODE) &&
				(n->GetName() == wxT("object") || n->GetName() == wxT("object_ref")))
			{
				wxObject *created = CreateResFromNode(n, toolbar, NULL);
				wxControl *control = dynamic_cast<wxControl*>(created);
				if (!IsOfClass(n, wxT("tool")) &&
					!IsOfClass(n, wxT("separator")) &&
					!IsOfClass(n, wxT("space")) &&
					control != NULL)
					toolbar->AddControl(control);
			}
			n = n->GetNext();
		}

		m_isInside = false;
		m_toolbar = NULL;

		if (m_parentAsWindow && !GetBool(wxT("dontattachtoframe")))
		{
			wxFrame *parentFrame = dynamic_cast<wxFrame*>(m_parent);
			if (parentFrame)
				parentFrame->SetToolBar(toolbar);
		}

		toolbar->Realize();

		return toolbar;
	}
}
Exemplo n.º 6
0
wxObject *wxAuiToolBarXmlHandler::DoCreateResource()
{
    if (m_class == wxS("tool"))
    {
        if ( !m_toolbar )
        {
            ReportError("tool only allowed inside a wxAuiToolBar");
            return NULL;
        }

        wxItemKind kind = wxITEM_NORMAL;
        if (GetBool(wxS("radio")))
            kind = wxITEM_RADIO;

        if (GetBool(wxS("toggle")))
        {
            if ( kind != wxITEM_NORMAL )
            {
                ReportParamError
                (
                    "toggle",
                    "tool can't have both <radio> and <toggle> properties"
                );
            }

            kind = wxITEM_CHECK;
        }
#if wxUSE_MENUS
        // check whether we have dropdown tag inside
        wxMenu *menu = NULL; // menu for drop down items
        wxXmlNode * const nodeDropdown = GetParamNode("dropdown");
        if ( nodeDropdown )
        {
            // also check for the menu specified inside dropdown (it is
            // optional and may be absent for e.g. dynamically-created
            // menus)
            wxXmlNode * const nodeMenu = GetNodeChildren(nodeDropdown);
            if ( nodeMenu )
            {
                wxObject *res = CreateResFromNode(nodeMenu, NULL);
                menu = wxDynamicCast(res, wxMenu);
                if ( !menu )
                {
                    ReportError
                    (
                        nodeMenu,
                        "drop-down tool contents can only be a wxMenu"
                    );
                }

                if ( GetNodeNext(nodeMenu) )
                {
                    ReportError
                    (
                        GetNodeNext(nodeMenu),
                        "unexpected extra contents under drop-down tool"
                    );
                }
            }
        }
#endif
        wxAuiToolBarItem * const tool =
            m_toolbar->AddTool
                       (
                          GetID(),
                          GetText(wxS("label")),
                          GetBitmap(wxS("bitmap"), wxART_TOOLBAR, m_toolSize),
                          GetBitmap(wxS("bitmap2"), wxART_TOOLBAR, m_toolSize),
                          kind,
                          GetText(wxS("tooltip")),
                          GetText(wxS("longhelp")),
                          NULL
                       );

        if ( GetBool(wxS("disabled")) )
            m_toolbar->EnableTool(GetID(), false);

#if wxUSE_MENUS
        if (menu)
        {
            tool->SetHasDropDown(true);
            tool->SetUserData(m_menuHandler.RegisterMenu(m_toolbar, GetID(), menu));
        }
#endif

        return m_toolbar; // must return non-NULL
    }

    else if (m_class == wxS("separator") || m_class == wxS("space") || m_class == wxS("label"))
    {
        if ( !m_toolbar )
        {
            ReportError("separators only allowed inside wxAuiToolBar");
            return NULL;
        }

        if ( m_class == wxS("separator") )
            m_toolbar->AddSeparator();

        else if (m_class == wxS("space"))
        {
            // This may be a stretch spacer (the default) or a non-stretch one
            bool hasProportion = HasParam(wxS("proportion"));
            bool hasWidth = HasParam(wxS("width"));
            if (hasProportion && hasWidth)
            {
                ReportError("A space can't both stretch and have width");
                return NULL;
            }

            if (hasWidth)
            {
                m_toolbar->AddSpacer
                (
                    GetLong(wxS("width"))
                );
            }
            else
            {
                m_toolbar->AddStretchSpacer
                (
                    GetLong(wxS("proportion"), 1l)
                );
            }
        }

        else if (m_class == wxS("label"))
        {
            m_toolbar->AddLabel
            (
                GetID(),
                GetText(wxS("label")),
                GetLong(wxS("width"), -1l)
            );
        }

        return m_toolbar; // must return non-NULL
    }

    else /*<object class="wxAuiToolBar">*/
    {
        int style = GetStyle(wxS("style"), wxNO_BORDER | wxTB_HORIZONTAL);
#ifdef __WXMSW__
        if (!(style & wxNO_BORDER)) style |= wxNO_BORDER;
#endif

        XRC_MAKE_INSTANCE(toolbar, wxAuiToolBar)

        toolbar->Create(m_parentAsWindow,
                         GetID(),
                         GetPosition(),
                         GetSize(),
                         style);
        toolbar->SetName(GetName());
        SetupWindow(toolbar);

        m_toolSize = GetSize(wxS("bitmapsize"));
        if (!(m_toolSize == wxDefaultSize))
            toolbar->SetToolBitmapSize(m_toolSize);
        wxSize margins = GetSize(wxS("margins"));
        if (!(margins == wxDefaultSize))
            toolbar->SetMargins(margins.x, margins.y);
        long packing = GetLong(wxS("packing"), -1);
        if (packing != -1)
            toolbar->SetToolPacking(packing);
        long separation = GetLong(wxS("separation"), -1);
        if (separation != -1)
            toolbar->SetToolSeparation(separation);

        wxXmlNode *children_node = GetParamNode(wxS("object"));
        if (!children_node)
           children_node = GetParamNode(wxS("object_ref"));

        if (children_node == NULL) return toolbar;

        m_isInside = true;
        m_toolbar = toolbar;

        wxXmlNode *n = children_node;

        while (n)
        {
            if (IsObjectNode(n))
            {
                wxObject *created = CreateResFromNode(n, toolbar, NULL);
                wxControl *control = wxDynamicCast(created, wxControl);
                if (!IsOfClass(n, wxS("tool")) &&
                    !IsOfClass(n, wxS("separator")) &&
                    !IsOfClass(n, wxS("label")) &&
                    !IsOfClass(n, wxS("space")) &&
                    control != NULL)
                    toolbar->AddControl(control);
            }
            n = GetNodeNext(n);
        }

        m_isInside = false;
        m_toolbar = NULL;

        toolbar->Realize();

        return toolbar;
    }
}
Exemplo n.º 7
0
wxObject *wxTreebookXmlHandler::DoCreateResource()
{
    if (m_class == wxT("wxTreebook"))
    {
        XRC_MAKE_INSTANCE(tbk, wxTreebook)

        tbk->Create(m_parentAsWindow,
                    GetID(),
                    GetPosition(), GetSize(),
                    GetStyle(wxT("style")),
                    GetName());

        wxImageList *imagelist = GetImageList();
        if ( imagelist )
            tbk->AssignImageList(imagelist);

        wxTreebook * old_par = m_tbk;
        m_tbk = tbk;

        bool old_ins = m_isInside;
        m_isInside = true;

        wxArrayTbkPageIndexes old_treeContext = m_treeContext;
        m_treeContext.Clear();

        CreateChildren(m_tbk, true/*only this handler*/);

        wxXmlNode *node = GetParamNode("object");
        int pageIndex = 0;
        for (unsigned int i = 0; i < m_tbk->GetPageCount(); i++)
        {
            if ( m_tbk->GetPage(i) )
            {
                wxXmlNode *child = node->GetChildren();
                while (child)
                {
                    if (child->GetName() == "expanded" && child->GetNodeContent() == "1")
                        m_tbk->ExpandNode(pageIndex, true);

                    child = child->GetNext();
                }
                pageIndex++;
            }
        }

        m_treeContext = old_treeContext;
        m_isInside = old_ins;
        m_tbk = old_par;

        return tbk;
    }

//    else ( m_class == wxT("treebookpage") )
    wxXmlNode *n = GetParamNode(wxT("object"));
    wxWindow *wnd = NULL;

    if ( !n )
        n = GetParamNode(wxT("object_ref"));

    if (n)
    {
        bool old_ins = m_isInside;
        m_isInside = false;
        wxObject *item = CreateResFromNode(n, m_tbk, NULL);
        m_isInside = old_ins;
        wnd = wxDynamicCast(item, wxWindow);

        if (wnd == NULL && item != NULL)
        {
            ReportError(n, "treebookpage child must be a window");
        }
    }

    size_t depth = GetLong( wxT("depth") );

    if( depth <= m_treeContext.GetCount() )
    {
        // first prepare the icon
        int imgIndex = wxNOT_FOUND;
        if ( HasParam(wxT("bitmap")) )
        {
            wxBitmap bmp = GetBitmap(wxT("bitmap"), wxART_OTHER);
            wxImageList *imgList = m_tbk->GetImageList();
            if ( imgList == NULL )
            {
                imgList = new wxImageList( bmp.GetWidth(), bmp.GetHeight() );
                m_tbk->AssignImageList( imgList );
            }
            imgIndex = imgList->Add(bmp);
        }
        else if ( HasParam(wxT("image")) )
        {
            if ( m_tbk->GetImageList() )
            {
                imgIndex = GetLong(wxT("image"));
            }
            else // image without image list?
            {
                ReportError(n, "image can only be used in conjunction "
                               "with imagelist");
            }
        }

        // then add the page to the corresponding parent
        if( depth < m_treeContext.GetCount() )
            m_treeContext.RemoveAt(depth, m_treeContext.GetCount() - depth );
        if( depth == 0)
        {
            m_tbk->AddPage(wnd,
                GetText(wxT("label")), GetBool(wxT("selected")), imgIndex);
        }
        else
        {
            m_tbk->InsertSubPage(m_treeContext.Item(depth - 1), wnd,
                GetText(wxT("label")), GetBool(wxT("selected")), imgIndex);
        }

        m_treeContext.Add( m_tbk->GetPageCount() - 1);

    }
    else
    {
        ReportParamError("depth", "invalid depth");
    }

    return wnd;
}
Exemplo n.º 8
0
wxObject *wxStatusBarXmlHandler::DoCreateResource()
{
    XRC_MAKE_INSTANCE(statbar, wxStatusBar)

    statbar->Create(m_parentAsWindow,
                    GetID(),
                    GetStyle(),
                    GetName());

    int fields = GetLong(wxT("fields"), 1);
    wxString widths = GetParamValue(wxT("widths"));
    wxString styles = GetParamValue(wxT("styles"));

    if (fields > 1 && !widths.IsEmpty())
    {
        int *width = new int[fields];

        for (int i = 0; i < fields; ++i)
        {
            width[i] = wxAtoi(widths.BeforeFirst(wxT(',')));
            if(widths.Find(wxT(',')))
                widths.Remove(0, widths.Find(wxT(',')) + 1);
        }
        statbar->SetFieldsCount(fields, width);
        delete[] width;
    }
    else
        statbar->SetFieldsCount(fields);

    if (!styles.empty())
    {
        int *style = new int[fields];
        for (int i = 0; i < fields; ++i)
        {
            style[i] = wxSB_NORMAL;

            wxString first = styles.BeforeFirst(wxT(','));
            if (first == wxT("wxSB_NORMAL"))
                style[i] = wxSB_NORMAL;
            else if (first == wxT("wxSB_FLAT"))
                style[i] = wxSB_FLAT;
            else if (first == wxT("wxSB_RAISED"))
                style[i] = wxSB_RAISED;
            else if (!first.empty())
            {
                ReportParamError
                (
                    "styles",
                    wxString::Format
                    (
                        "unknown status bar field style \"%s\"",
                        first
                    )
                );
            }

            if(styles.Find(wxT(',')))
                styles.Remove(0, styles.Find(wxT(',')) + 1);
        }
        statbar->SetStatusStyles(fields, style);
        delete [] style;
    }

    CreateChildren(statbar);

    if (m_parentAsWindow)
    {
        wxFrame *parentFrame = wxDynamicCast(m_parent, wxFrame);
        if (parentFrame)
            parentFrame->SetStatusBar(statbar);
    }

    return statbar;
}
Exemplo n.º 9
0
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;
    tkn.SetString(GetParamValue(param), wxT(","));

    while (tkn.HasMoreTokens())
    {
        wxString propStr;
        wxString idxStr = tkn.GetNextToken().BeforeFirst(wxT(':'), &propStr);

        unsigned long li;
        if (!idxStr.ToULong(&li))
        {
            ReportParamError
            (
                param,
                "value must be a comma-separated list of numbers"
            );
            break;
        }

        unsigned long lp = 0;
        if (!propStr.empty())
        {
            if (!propStr.ToULong(&lp))
            {
                ReportParamError
                (
                    param,
                    "value must be a comma-separated list of numbers"
                );
                break;
            }
        }

        const int n = static_cast<int>(li);
        if ( n >= nslots )
        {
            ReportParamError
            (
                param,
                wxString::Format
                (
                    "invalid %s index %d: must be less than %d",
                    rows ? "row" : "column",
                    n,
                    nslots
                )
            );

            // ignore incorrect value, still try to process the rest
            continue;
        }

        if (rows)
            sizer->AddGrowableRow(n, static_cast<int>(lp));
        else
            sizer->AddGrowableCol(n, static_cast<int>(lp));
    }
}
Exemplo n.º 10
0
int wxSizerXmlHandler::GetSizerFlags()
{
    const wxString s = GetParamValue(wxS("flag"));
    if ( s.empty() )
        return 0;

    // Parse flags keeping track of invalid combinations. This is somewhat
    // redundant with the checks performed in wxSizer subclasses themselves but
    // doing it here allows us to give the exact line number at which the
    // offending line numbers are given, which is very valuable.
    //
    // We also can detect invalid flags combinations involving wxALIGN_LEFT and
    // wxALIGN_TOP here, while this is impossible at wxSizer level as both of
    // these flags have value of 0.


    // As the logic is exactly the same in horizontal and vertical
    // orientations, use arrays and loops to avoid duplicating the code.

    enum Orient
    {
        Orient_Horz,
        Orient_Vert,
        Orient_Max
    };

    const char* const orientName[] = { "horizontal", "vertical" };

    // The already seen alignment flag in the given orientation or empty if
    // none have been seen yet.
    wxString alignFlagIn[] = { wxString(), wxString() };

    // Either "wxEXPAND" or "wxGROW" depending on the string used in the input,
    // or empty string if none is specified.
    wxString expandFlag;

    // Either "wxALIGN_CENTRE" or "wxALIGN_CENTER" if either flag was found or
    // empty string.
    wxString centreFlag;

    // Indicates whether we can use alignment in the given orientation at all.
    bool alignAllowedIn[] = { true, true };

    // Find out the sizer orientation: it is the principal/major size direction
    // for the 1D sizers and undefined/invalid for the 2D ones.
    Orient orientSizer;
    if ( wxBoxSizer* const boxSizer = wxDynamicCast(m_parentSizer, wxBoxSizer) )
    {
        orientSizer = boxSizer->GetOrientation() == wxHORIZONTAL
                        ? Orient_Horz
                        : Orient_Vert;

        // Alignment can be only used in the transversal/minor direction.
        alignAllowedIn[orientSizer] = false;
    }
    else
    {
        orientSizer = Orient_Max;
    }

    int flags = 0;

    wxStringTokenizer tkn(s, wxS("| \t\n"), wxTOKEN_STRTOK);
    while ( tkn.HasMoreTokens() )
    {
        const wxString flagName = tkn.GetNextToken();
        const int n = m_styleNames.Index(flagName);
        if ( n == wxNOT_FOUND )
        {
            ReportParamError
            (
                "flag",
                wxString::Format("unknown sizer flag \"%s\"", flagName)
            );
            continue;
        }

        // Flag description is the string that appears in the error messages,
        // the main difference from the flag name is that it can indicate that
        // wxALIGN_CENTRE_XXX flag could have been encountered as part of
        // wxALIGN_CENTRE which should make the error message more clear as
        // seeing references to e.g. wxALIGN_CENTRE_VERTICAL when it's never
        // used could be confusing.
        wxString flagDesc = wxS('"') + flagName + wxS('"');

        int flag = m_styleValues[n];

        bool flagSpecifiesAlignIn[] = { false, false };

        switch ( flag )
        {
            case wxALIGN_CENTRE_HORIZONTAL:
            case wxALIGN_RIGHT:
                flagSpecifiesAlignIn[Orient_Horz] = true;
                break;

            case wxALIGN_CENTRE_VERTICAL:
            case wxALIGN_BOTTOM:
                flagSpecifiesAlignIn[Orient_Vert] = true;
                break;

            case wxEXPAND:
                expandFlag = flagName;
                break;

            case wxALIGN_CENTRE:
                // wxALIGN_CENTRE is a combination of wxALIGN_CENTRE_HORIZONTAL
                // and wxALIGN_CENTRE_VERTICAL but we also handle it as just
                // one of those flags if alignment in the other direction is
                // not allowed for both compatibility and convenience reasons.
                switch ( orientSizer )
                {
                    case Orient_Horz:
                        flagSpecifiesAlignIn[Orient_Vert] = true;
                        flagDesc.Printf
                        (
                             "\"wxALIGN_CENTRE_VERTICAL\" (as part of %s)",
                             flagName
                        );
                        flag = wxALIGN_CENTRE_VERTICAL;
                        break;

                    case Orient_Vert:
                        flagSpecifiesAlignIn[Orient_Horz] = true;
                        flagDesc.Printf
                        (
                            "\"wxALIGN_CENTRE_HORIZONTAL\" (as part of %s)",
                            flagName
                        );
                        flag = wxALIGN_CENTRE_HORIZONTAL;
                        break;

                    case Orient_Max:
                        // For 2D sizers we need to deal with this flag at the
                        // end, so just remember that we had it for now.
                        centreFlag = flagName;
                        flag = 0;
                        break;
                }
                break;

            case 0:
                // This is a special case: both wxALIGN_LEFT and wxALIGN_TOP
                // have value of 0, so we need to examine the name of the flag
                // and not just its value.
                if ( flagName == wxS("wxALIGN_LEFT") )
                    flagSpecifiesAlignIn[Orient_Horz] = true;
                else if ( flagName == wxS("wxALIGN_TOP") )
                    flagSpecifiesAlignIn[Orient_Vert] = true;
                break;
        }

        for ( int orient = 0; orient < Orient_Max; orient++ )
        {
            if ( !flagSpecifiesAlignIn[orient] )
                continue;

            if ( !alignAllowedIn[orient] )
            {
                ReportParamError
                (
                    "flag",
                    wxString::Format
                    (
                        "%s alignment flag %s has no effect inside "
                        "a %s box sizer, remove it and consider inserting "
                        "a spacer instead",
                        orientName[orient],
                        flagDesc,
                        orientName[orient]
                    )
                );

                // Notice that we take care to not add this invalid flag to the
                // flags we will actually use with wxSizer: they would just
                // trigger an assert there which wouldn't be very useful as
                // we've already given an error about this.
                flag = 0;
            }
            else if ( alignFlagIn[orient].empty() )
            {
                alignFlagIn[orient] = flagDesc;
            }
            else
            {
                ReportParamError
                (
                    "flag",
                    wxString::Format
                    (
                        "both %s and %s specify %s alignment "
                        "and can't be used together",
                        alignFlagIn[orient],
                        flagDesc,
                        orientName[orient]
                    )
                );

                flag = 0;
            }
        }

        flags |= flag;
    }

    // Now that we know all the alignment flags we can interpret wxALIGN_CENTRE
    // for the 2D sizers ("centreFlag" is only set in the 2D case).
    if ( !centreFlag.empty() )
    {
        if ( !expandFlag.empty() )
        {
            ReportParamError
            (
                "flag",
                wxString::Format
                (
                    "\"%s\" has no effect when combined with \"%s\"",
                    centreFlag,
                    expandFlag
                )
            );
        }
        else // !wxEXPAND
        {
            int flagsCentre = 0;

            if ( alignFlagIn[Orient_Horz].empty() )
                flagsCentre |= wxALIGN_CENTRE_HORIZONTAL;

            if ( alignFlagIn[Orient_Vert].empty() )
                flagsCentre |= wxALIGN_CENTRE_VERTICAL;

            if ( !flagsCentre )
            {
                ReportParamError
                (
                    "flag",
                    wxString::Format
                    (
                        "\"%s\" flag has no effect when combined "
                        "with both %s and %s horizontal and "
                        "vertical alignment flags",
                        centreFlag,
                        alignFlagIn[Orient_Horz],
                        alignFlagIn[Orient_Vert]
                    )
                );
            }

            flags |= flagsCentre;
        }
    }

    // Finally check that the alignment flags are compatible with wxEXPAND.
    if ( !expandFlag.empty() )
    {
        if ( orientSizer != Orient_Max )
        {
            const Orient orientOther = orientSizer == Orient_Horz
                                            ? Orient_Vert
                                            : Orient_Horz;

            if ( !alignFlagIn[orientOther].empty() )
            {
                ReportParamError
                (
                    "flag",
                    wxString::Format
                    (
                        "\"%s\" is incompatible with %s alignment flag "
                        "\"%s\" in a %s box sizer",
                        expandFlag,
                        orientName[orientOther],
                        alignFlagIn[orientOther],
                        orientName[orientSizer]
                    )
                );

                // Just as with the alignment flags above, ignore wxEXPAND
                // completely to avoid asserts from wxSizer code.
                flags &= ~wxEXPAND;
            }
        }
        else // 2D sizer
        {
            if ( !alignFlagIn[Orient_Horz].empty() &&
                    !alignFlagIn[Orient_Vert].empty() )
            {
                ReportParamError
                (
                    "flag",
                    wxString::Format
                    (
                        "\"%s\" flag has no effect when combined "
                        "with both %s and %s horizontal and "
                        "vertical alignment flags",
                        expandFlag,
                        alignFlagIn[Orient_Horz],
                        alignFlagIn[Orient_Vert]
                    )
                );

                flags &= ~wxEXPAND;
            }
        }
    }

    return flags;
}