1/////////////////////////////////////////////////////////////////////////////
2// Name:        src/xrc/xh_menu.cpp
3// Purpose:     XRC resource for menus and menubars
4// Author:      Vaclav Slavik
5// Created:     2000/03/05
6// RCS-ID:      $Id: xh_menu.cpp 63466 2010-02-11 12:47:17Z VS $
7// Copyright:   (c) 2000 Vaclav Slavik
8// Licence:     wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11// For compilers that support precompilation, includes "wx.h".
12#include "wx/wxprec.h"
13
14#ifdef __BORLANDC__
15    #pragma hdrstop
16#endif
17
18#if wxUSE_XRC && wxUSE_MENUS
19
20#include "wx/xrc/xh_menu.h"
21
22#ifndef WX_PRECOMP
23    #include "wx/frame.h"
24    #include "wx/menu.h"
25#endif
26
27IMPLEMENT_DYNAMIC_CLASS(wxMenuXmlHandler, wxXmlResourceHandler)
28
29wxMenuXmlHandler::wxMenuXmlHandler() :
30        wxXmlResourceHandler(), m_insideMenu(false)
31{
32    XRC_ADD_STYLE(wxMENU_TEAROFF);
33}
34
35wxObject *wxMenuXmlHandler::DoCreateResource()
36{
37    if (m_class == wxT("wxMenu"))
38    {
39        wxMenu *menu = m_instance ? wxStaticCast(m_instance, wxMenu)
40                                  : new wxMenu(GetStyle());
41
42        wxString title = GetText(wxT("label"));
43        wxString help = GetText(wxT("help"));
44
45        bool oldins = m_insideMenu;
46        m_insideMenu = true;
47        CreateChildren(menu, true/*only this handler*/);
48        m_insideMenu = oldins;
49
50        wxMenuBar *p_bar = wxDynamicCast(m_parent, wxMenuBar);
51        if (p_bar)
52        {
53            p_bar->Append(menu, title);
54        }
55        else
56        {
57            wxMenu *p_menu = wxDynamicCast(m_parent, wxMenu);
58            if (p_menu)
59            {
60                p_menu->Append(GetID(), title, menu, help);
61                if (HasParam(wxT("enabled")))
62                    p_menu->Enable(GetID(), GetBool(wxT("enabled")));
63            }
64        }
65
66        return menu;
67    }
68
69    else
70    {
71        wxMenu *p_menu = wxDynamicCast(m_parent, wxMenu);
72
73        if (m_class == wxT("separator"))
74            p_menu->AppendSeparator();
75        else if (m_class == wxT("break"))
76            p_menu->Break();
77        else /*wxMenuItem*/
78        {
79            int id = GetID();
80            wxString label = GetText(wxT("label"));
81            wxString accel = GetText(wxT("accel"), false);
82            wxString fullLabel = label;
83            if (!accel.empty())
84                fullLabel << wxT("\t") << accel;
85
86            wxItemKind kind = wxITEM_NORMAL;
87            if (GetBool(wxT("radio")))
88                kind = wxITEM_RADIO;
89            if (GetBool(wxT("checkable")))
90            {
91                wxASSERT_MSG( kind == wxITEM_NORMAL, _T("can't have both checkable and radion button at once") );
92                kind = wxITEM_CHECK;
93            }
94
95            wxMenuItem *mitem = new wxMenuItem(p_menu, id, fullLabel,
96                                               GetText(wxT("help")), kind);
97
98#if (!defined(__WXMSW__) && !defined(__WXPM__)) || wxUSE_OWNER_DRAWN
99            if (HasParam(wxT("bitmap")))
100                mitem->SetBitmap(GetBitmap(wxT("bitmap"), wxART_MENU));
101#endif
102            p_menu->Append(mitem);
103            mitem->Enable(GetBool(wxT("enabled"), true));
104            if (kind == wxITEM_CHECK)
105                mitem->Check(GetBool(wxT("checked")));
106        }
107        return NULL;
108    }
109}
110
111
112
113bool wxMenuXmlHandler::CanHandle(wxXmlNode *node)
114{
115    return IsOfClass(node, wxT("wxMenu")) ||
116           (m_insideMenu &&
117               (IsOfClass(node, wxT("wxMenuItem")) ||
118                IsOfClass(node, wxT("break")) ||
119                IsOfClass(node, wxT("separator")))
120           );
121}
122
123IMPLEMENT_DYNAMIC_CLASS(wxMenuBarXmlHandler, wxXmlResourceHandler)
124
125wxMenuBarXmlHandler::wxMenuBarXmlHandler() : wxXmlResourceHandler()
126{
127    XRC_ADD_STYLE(wxMB_DOCKABLE);
128}
129
130wxObject *wxMenuBarXmlHandler::DoCreateResource()
131{
132    wxMenuBar *menubar = NULL;
133
134    const int style = GetStyle();
135    wxASSERT_MSG(!style || !m_instance,
136                 wxT("cannot use <style> with pre-created menubar"));
137
138    if ( m_instance )
139        menubar = wxDynamicCast(m_instance, wxMenuBar);
140    if ( !menubar )
141        menubar = new wxMenuBar(style);
142
143    CreateChildren(menubar);
144
145    if (m_parentAsWindow)
146    {
147        wxFrame *parentFrame = wxDynamicCast(m_parent, wxFrame);
148        if (parentFrame)
149            parentFrame->SetMenuBar(menubar);
150    }
151
152    return menubar;
153}
154
155
156
157bool wxMenuBarXmlHandler::CanHandle(wxXmlNode *node)
158{
159    return IsOfClass(node, wxT("wxMenuBar"));
160}
161
162#endif // wxUSE_XRC && wxUSE_MENUS
163