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 // Copyright:   (c) 2000 Vaclav Slavik
7 // Licence:     wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9 
10 // For compilers that support precompilation, includes "wx.h".
11 #include "wx/wxprec.h"
12 
13 #ifdef __BORLANDC__
14     #pragma hdrstop
15 #endif
16 
17 #if wxUSE_XRC && wxUSE_MENUS
18 
19 #include "wx/xrc/xh_menu.h"
20 
21 #ifndef WX_PRECOMP
22     #include "wx/frame.h"
23     #include "wx/log.h"
24     #include "wx/menu.h"
25 #endif
26 
IMPLEMENT_DYNAMIC_CLASS(wxMenuXmlHandler,wxXmlResourceHandler)27 IMPLEMENT_DYNAMIC_CLASS(wxMenuXmlHandler, wxXmlResourceHandler)
28 
29 wxMenuXmlHandler::wxMenuXmlHandler() :
30         wxXmlResourceHandler(), m_insideMenu(false)
31 {
32     XRC_ADD_STYLE(wxMENU_TEAROFF);
33 }
34 
DoCreateResource()35 wxObject *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 
83             wxItemKind kind = wxITEM_NORMAL;
84             if (GetBool(wxT("radio")))
85                 kind = wxITEM_RADIO;
86             if (GetBool(wxT("checkable")))
87             {
88                 if ( kind != wxITEM_NORMAL )
89                 {
90                     ReportParamError
91                     (
92                         "checkable",
93                         "menu item can't have both <radio> and <checkable> properties"
94                     );
95                 }
96 
97                 kind = wxITEM_CHECK;
98             }
99 
100             wxMenuItem *mitem = new wxMenuItem(p_menu, id, label,
101                                                GetText(wxT("help")), kind);
102             if (!accel.empty())
103             {
104                 wxAcceleratorEntry entry;
105                 if (entry.FromString(accel))
106                     mitem->SetAccel(&entry);
107             }
108 
109 #if (!defined(__WXMSW__) && !defined(__WXPM__)) || wxUSE_OWNER_DRAWN
110             if (HasParam(wxT("bitmap")))
111             {
112                 // currently only wxMSW has support for using different checked
113                 // and unchecked bitmaps for menu items
114 #ifdef __WXMSW__
115                 if (HasParam(wxT("bitmap2")))
116                     mitem->SetBitmaps(GetBitmap(wxT("bitmap2"), wxART_MENU),
117                                       GetBitmap(wxT("bitmap"), wxART_MENU));
118                 else
119 #endif // __WXMSW__
120                     mitem->SetBitmap(GetBitmap(wxT("bitmap"), wxART_MENU));
121             }
122 #endif
123             p_menu->Append(mitem);
124             mitem->Enable(GetBool(wxT("enabled"), true));
125             if (kind == wxITEM_CHECK)
126                 mitem->Check(GetBool(wxT("checked")));
127         }
128         return NULL;
129     }
130 }
131 
132 
133 
CanHandle(wxXmlNode * node)134 bool wxMenuXmlHandler::CanHandle(wxXmlNode *node)
135 {
136     return IsOfClass(node, wxT("wxMenu")) ||
137            (m_insideMenu &&
138                (IsOfClass(node, wxT("wxMenuItem")) ||
139                 IsOfClass(node, wxT("break")) ||
140                 IsOfClass(node, wxT("separator")))
141            );
142 }
143 
IMPLEMENT_DYNAMIC_CLASS(wxMenuBarXmlHandler,wxXmlResourceHandler)144 IMPLEMENT_DYNAMIC_CLASS(wxMenuBarXmlHandler, wxXmlResourceHandler)
145 
146 wxMenuBarXmlHandler::wxMenuBarXmlHandler() : wxXmlResourceHandler()
147 {
148     XRC_ADD_STYLE(wxMB_DOCKABLE);
149 }
150 
DoCreateResource()151 wxObject *wxMenuBarXmlHandler::DoCreateResource()
152 {
153     wxMenuBar *menubar = NULL;
154 
155     const int style = GetStyle();
156     wxASSERT_MSG(!style || !m_instance,
157                  "cannot use <style> with pre-created menubar");
158 
159     if ( m_instance )
160         menubar = wxDynamicCast(m_instance, wxMenuBar);
161     if ( !menubar )
162         menubar = new wxMenuBar(style);
163 
164     CreateChildren(menubar);
165 
166     if (m_parentAsWindow)
167     {
168         wxFrame *parentFrame = wxDynamicCast(m_parent, wxFrame);
169         if (parentFrame)
170             parentFrame->SetMenuBar(menubar);
171     }
172 
173     return menubar;
174 }
175 
176 
177 
CanHandle(wxXmlNode * node)178 bool wxMenuBarXmlHandler::CanHandle(wxXmlNode *node)
179 {
180     return IsOfClass(node, wxT("wxMenuBar"));
181 }
182 
183 #endif // wxUSE_XRC && wxUSE_MENUS
184