]> git.saurik.com Git - wxWidgets.git/blame - tests/menu/menu.cpp
Don't include Common-Controls manifest in wxBase apps.
[wxWidgets.git] / tests / menu / menu.cpp
CommitLineData
65571ec7
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: tests/menu/menu.cpp
3// Purpose: wxMenu unit test
4// Author: wxWidgets team
5// Created: 2010-11-10
6// RCS-ID: $Id$
7// Copyright: (c) 2010 wxWidgets team
8///////////////////////////////////////////////////////////////////////////////
9
10// ----------------------------------------------------------------------------
11// headers
12// ----------------------------------------------------------------------------
13
14#include "testprec.h"
15
16#ifdef __BORLANDC__
17 #pragma hdrstop
18#endif
19
20#ifndef WX_PRECOMP
21 #include "wx/wx.h"
22#endif // WX_PRECOMP
23
24#include "wx/menu.h"
6eca840c
VZ
25#include "wx/uiaction.h"
26
65571ec7
VZ
27#include <stdarg.h>
28
29// ----------------------------------------------------------------------------
30// helper
31// ----------------------------------------------------------------------------
32
33namespace
34{
35
36enum
37{
f8314f3c
VZ
38 MenuTestCase_Foo = 10000,
39 MenuTestCase_Bar,
40 MenuTestCase_First
65571ec7
VZ
41};
42
43void PopulateMenu(wxMenu* menu, const wxString& name, size_t& itemcount)
44{
45 // Start at item 1 to make it human-readable ;)
46 for (int n=1; n<6; ++n, ++itemcount)
47 {
48 wxString label = name; label << n;
49 menu->Append(MenuTestCase_First + itemcount, label, label + " help string");
50 }
51}
52
53void RecursivelyCountMenuItems(const wxMenu* menu, size_t& count)
54{
55 CPPUNIT_ASSERT( menu );
56
57 count += menu->GetMenuItemCount();
58 for (size_t n=0; n < menu->GetMenuItemCount(); ++n)
59 {
60 wxMenuItem* item = menu->FindItemByPosition(n);
61 if (item->IsSubMenu())
62 {
63 RecursivelyCountMenuItems(item->GetSubMenu(), count);
64 }
65 }
66}
67
68} // anon namespace
69
70
71// ----------------------------------------------------------------------------
72// test class
73// ----------------------------------------------------------------------------
74
75class MenuTestCase : public CppUnit::TestCase
76{
77public:
78 MenuTestCase() {}
79
80 virtual void setUp() { CreateFrame(); }
81 virtual void tearDown() { m_frame->Destroy(); }
82
83private:
84 CPPUNIT_TEST_SUITE( MenuTestCase );
85 CPPUNIT_TEST( FindInMenubar );
86 CPPUNIT_TEST( FindInMenu );
e4a23857 87 CPPUNIT_TEST( EnableTop );
65571ec7 88 CPPUNIT_TEST( Count );
7bc0ff86 89 CPPUNIT_TEST( Labels );
89511b42 90 CPPUNIT_TEST( RadioItems );
61263343 91 CPPUNIT_TEST( RemoveAdd );
6eca840c 92 WXUISIM_TEST( Events );
65571ec7
VZ
93 CPPUNIT_TEST_SUITE_END();
94
95 void CreateFrame();
96
97 void FindInMenubar();
98 void FindInMenu();
e4a23857 99 void EnableTop();
65571ec7 100 void Count();
7bc0ff86 101 void Labels();
89511b42 102 void RadioItems();
61263343 103 void RemoveAdd();
6eca840c 104 void Events();
65571ec7
VZ
105
106 wxFrame* m_frame;
107
108 // Holds the number of menuitems contained in all the menus
109 size_t m_itemCount;
110
111 // Store here the id of a known submenu item, to be searched for later
112 int m_submenuItemId;
113
114 // and a sub-submenu item
115 int m_subsubmenuItemId;
116
117 wxArrayString m_menuLabels;
118
4936c099
VZ
119 // The menu containing the item with MenuTestCase_Bar id.
120 wxMenu* m_menuWithBar;
121
65571ec7
VZ
122 DECLARE_NO_COPY_CLASS(MenuTestCase)
123};
124
125// register in the unnamed registry so that these tests are run by default
126CPPUNIT_TEST_SUITE_REGISTRATION( MenuTestCase );
127
e3778b4d 128// also include in its own registry so that these tests can be run alone
65571ec7
VZ
129CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( MenuTestCase, "MenuTestCase" );
130
131void MenuTestCase::CreateFrame()
132{
133 m_frame = new wxFrame(NULL, wxID_ANY, "test frame");
134
135 wxMenu *fileMenu = new wxMenu;
136 wxMenu *helpMenu = new wxMenu;
137 wxMenu *subMenu = new wxMenu;
138 wxMenu *subsubMenu = new wxMenu;
139
140 size_t itemcount = 0;
141
142 PopulateMenu(subsubMenu, "Subsubmenu item ", itemcount);
143
144 // Store one of its IDs for later
145 m_subsubmenuItemId = MenuTestCase_First + itemcount - 2;
146
147 PopulateMenu(subMenu, "Submenu item ", itemcount);
148
149 // Store one of its IDs for later
150 m_submenuItemId = MenuTestCase_First + itemcount - 2;
151
152 subMenu->AppendSubMenu(subsubMenu, "Subsubmen&u", "Test a subsubmenu");
153
154 PopulateMenu(fileMenu, "Filemenu item ", itemcount);
f8314f3c
VZ
155
156 fileMenu->Append(MenuTestCase_Foo, "&Foo\tCtrl-F", "Test item to be found");
65571ec7
VZ
157
158
159 PopulateMenu(helpMenu, "Helpmenu item ", itemcount);
6eca840c 160 helpMenu->Append(MenuTestCase_Bar, "Bar\tF1");
4936c099 161 m_menuWithBar = helpMenu;
65571ec7
VZ
162 helpMenu->AppendSubMenu(subMenu, "Sub&menu", "Test a submenu");
163
f8314f3c 164 // +2 for "Foo" and "Bar", +2 for the 2 submenus
65571ec7
VZ
165 m_itemCount = itemcount + 4;
166
167 // Use an arraystring here, to help with future tests
168 m_menuLabels.Add("&File");
169 m_menuLabels.Add("&Help");
170
171 wxMenuBar *menuBar = new wxMenuBar();
172 menuBar->Append(fileMenu, m_menuLabels[0]);
173 menuBar->Append(helpMenu, m_menuLabels[1]);
174 m_frame->SetMenuBar(menuBar);
175}
176
177void MenuTestCase::FindInMenubar()
178{
179 wxMenuBar* bar = m_frame->GetMenuBar();
180
181 // Find by name:
182 CPPUNIT_ASSERT( bar->FindMenu("File") != wxNOT_FOUND );
183 CPPUNIT_ASSERT( bar->FindMenu("&File") != wxNOT_FOUND );
184 CPPUNIT_ASSERT( bar->FindMenu("&Fail") == wxNOT_FOUND );
185
186 // Find by menu name plus item name:
f8314f3c
VZ
187 CPPUNIT_ASSERT( bar->FindMenuItem("File", "Foo") != wxNOT_FOUND );
188 CPPUNIT_ASSERT( bar->FindMenuItem("&File", "&Foo") != wxNOT_FOUND );
7bc0ff86 189 // and using the menu label
65571ec7
VZ
190 int index = bar->FindMenu("&File");
191 CPPUNIT_ASSERT( index != wxNOT_FOUND );
7bc0ff86
VZ
192 wxString menulabel = bar->GetMenuLabel(index);
193 CPPUNIT_ASSERT( bar->FindMenuItem(menulabel, "&Foo") != wxNOT_FOUND );
194 // and title
195 wxString menutitle = bar->GetMenu(index)->GetTitle();
f8314f3c 196 CPPUNIT_ASSERT( bar->FindMenuItem(menutitle, "&Foo") != wxNOT_FOUND );
65571ec7
VZ
197
198 // Find by position:
199 for (size_t n=0; n < bar->GetMenuCount(); ++n)
200 {
201 CPPUNIT_ASSERT( bar->GetMenu(n) );
202 }
203
204 // Find by id:
205 wxMenu* menu = NULL;
206 wxMenuItem* item = NULL;
f8314f3c 207 item = bar->FindItem(MenuTestCase_Foo, &menu);
65571ec7
VZ
208 CPPUNIT_ASSERT( item );
209 CPPUNIT_ASSERT( menu );
210 // Check that the correct menu was found
f8314f3c 211 CPPUNIT_ASSERT( menu->FindChildItem(MenuTestCase_Foo) );
65571ec7
VZ
212
213 // Find submenu item:
214 item = bar->FindItem(m_submenuItemId, &menu);
215 CPPUNIT_ASSERT( item );
216 CPPUNIT_ASSERT( menu );
7bc0ff86 217 // and, for completeness, a subsubmenu one:
65571ec7
VZ
218 item = bar->FindItem(m_subsubmenuItemId, &menu);
219 CPPUNIT_ASSERT( item );
220 CPPUNIT_ASSERT( menu );
221}
222
223void MenuTestCase::FindInMenu()
224{
225 wxMenuBar* bar = m_frame->GetMenuBar();
226
227 // Find by name:
228 wxMenu* menuFind = bar->GetMenu(0);
f8314f3c
VZ
229 CPPUNIT_ASSERT( menuFind->FindItem("Foo") != wxNOT_FOUND );
230 CPPUNIT_ASSERT( menuFind->FindItem("&Foo") != wxNOT_FOUND );
65571ec7
VZ
231 // and for submenus
232 wxMenu* menuHelp = bar->GetMenu(1);
233 CPPUNIT_ASSERT( menuHelp->FindItem("Submenu") != wxNOT_FOUND );
234 CPPUNIT_ASSERT( menuHelp->FindItem("Sub&menu") != wxNOT_FOUND );
235
236 // Find by position:
6ab66823
VZ
237 size_t n;
238 for (n=0; n < menuHelp->GetMenuItemCount(); ++n)
65571ec7
VZ
239 {
240 CPPUNIT_ASSERT( menuHelp->FindItemByPosition(n) );
241 }
242
243 // Find by id:
f8314f3c
VZ
244 CPPUNIT_ASSERT( menuHelp->FindItem(MenuTestCase_Bar) );
245 CPPUNIT_ASSERT( menuHelp->FindItem(MenuTestCase_Foo) == NULL );
65571ec7 246
6ab66823 247 for (n=0; n < menuHelp->GetMenuItemCount(); ++n)
65571ec7
VZ
248 {
249 size_t locatedAt;
250 wxMenuItem* itemByPos = menuHelp->FindItemByPosition(n);
251 CPPUNIT_ASSERT( itemByPos );
252 wxMenuItem* itemById = menuHelp->FindChildItem(itemByPos->GetId(), &locatedAt);
253 CPPUNIT_ASSERT_EQUAL( itemByPos, itemById );
254 CPPUNIT_ASSERT_EQUAL( locatedAt, n );
255 }
256
257 // Find submenu item:
6ab66823 258 for (n=0; n < menuHelp->GetMenuItemCount(); ++n)
65571ec7
VZ
259 {
260 wxMenuItem* item = menuHelp->FindItemByPosition(n);
261 if (item->IsSubMenu())
262 {
263 wxMenu* submenu;
264 wxMenuItem* submenuItem = menuHelp->FindItem(m_submenuItemId, &submenu);
265 CPPUNIT_ASSERT( submenuItem );
266 CPPUNIT_ASSERT( item->GetSubMenu() == submenu );
267 }
268 }
269}
270
e4a23857
VZ
271void MenuTestCase::EnableTop()
272{
273 wxMenuBar* const bar = m_frame->GetMenuBar();
274 CPPUNIT_ASSERT( bar->IsEnabledTop(0) );
275 bar->EnableTop( 0, false );
276 CPPUNIT_ASSERT( !bar->IsEnabledTop(0) );
277 bar->EnableTop( 0, true );
278 CPPUNIT_ASSERT( bar->IsEnabledTop(0) );
279}
280
65571ec7
VZ
281void MenuTestCase::Count()
282{
283 wxMenuBar* bar = m_frame->GetMenuBar();
284 // I suppose you could call this "counting menubars" :)
285 CPPUNIT_ASSERT( bar );
286
287 CPPUNIT_ASSERT_EQUAL( bar->GetMenuCount(), 2 );
288
289 size_t count = 0;
290 for (size_t n=0; n < bar->GetMenuCount(); ++n)
291 {
292 RecursivelyCountMenuItems(bar->GetMenu(n), count);
293 }
294 CPPUNIT_ASSERT_EQUAL( count, m_itemCount );
295}
7bc0ff86
VZ
296
297void MenuTestCase::Labels()
298{
299 wxMenuBar* bar = m_frame->GetMenuBar();
300 CPPUNIT_ASSERT( bar );
301 wxMenu* filemenu;
302 wxMenuItem* itemFoo = bar->FindItem(MenuTestCase_Foo, &filemenu);
303 CPPUNIT_ASSERT( itemFoo );
304 CPPUNIT_ASSERT( filemenu );
305
306 // These return labels including mnemonics/accelerators:
307
308 // wxMenuBar
309 CPPUNIT_ASSERT_EQUAL( "&File", bar->GetMenuLabel(0) );
310 CPPUNIT_ASSERT_EQUAL( "&Foo\tCtrl-F", bar->GetLabel(MenuTestCase_Foo) );
311
312 // wxMenu
313 CPPUNIT_ASSERT_EQUAL( "&File", filemenu->GetTitle() );
314 CPPUNIT_ASSERT_EQUAL( "&Foo\tCtrl-F", filemenu->GetLabel(MenuTestCase_Foo) );
315
316 // wxMenuItem
317 CPPUNIT_ASSERT_EQUAL( "&Foo\tCtrl-F", itemFoo->GetItemLabel() );
318
319 // These return labels stripped of mnemonics/accelerators:
320
321 // wxMenuBar
322 CPPUNIT_ASSERT_EQUAL( "File", bar->GetMenuLabelText(0) );
323
324 // wxMenu
325 CPPUNIT_ASSERT_EQUAL( "Foo", filemenu->GetLabelText(MenuTestCase_Foo) );
326
327 // wxMenuItem
328 CPPUNIT_ASSERT_EQUAL( "Foo", itemFoo->GetItemLabelText() );
329 CPPUNIT_ASSERT_EQUAL( "Foo", wxMenuItem::GetLabelText("&Foo\tCtrl-F") );
330}
89511b42
VZ
331
332void MenuTestCase::RadioItems()
333{
334 wxMenuBar * const bar = m_frame->GetMenuBar();
335 wxMenu * const menu = new wxMenu;
336 bar->Append(menu, "&Radio");
337
338 // Adding consecutive radio items creates a radio group.
339 menu->AppendRadioItem(MenuTestCase_First, "Radio 0");
340 menu->AppendRadioItem(MenuTestCase_First + 1, "Radio 1");
341
342 // First item of a radio group is checked by default.
343 CPPUNIT_ASSERT( menu->IsChecked(MenuTestCase_First) );
344
345 // Checking the second one make the first one unchecked however.
346 menu->Check(MenuTestCase_First + 1, true);
347 CPPUNIT_ASSERT( !menu->IsChecked(MenuTestCase_First) );
348 CPPUNIT_ASSERT( menu->IsChecked(MenuTestCase_First + 1) );
349
350 // Adding more radio items after a separator creates another radio group...
351 menu->AppendSeparator();
352 menu->AppendRadioItem(MenuTestCase_First + 2, "Radio 2");
353 menu->AppendRadioItem(MenuTestCase_First + 3, "Radio 3");
354 menu->AppendRadioItem(MenuTestCase_First + 4, "Radio 4");
355
356 // ... which is independent from the first one.
357 CPPUNIT_ASSERT( menu->IsChecked(MenuTestCase_First + 2) );
358
359 menu->Check(MenuTestCase_First + 3, true);
360 CPPUNIT_ASSERT( menu->IsChecked(MenuTestCase_First + 3) );
361 CPPUNIT_ASSERT( !menu->IsChecked(MenuTestCase_First + 2) );
362 CPPUNIT_ASSERT( menu->IsChecked(MenuTestCase_First + 1) );
363
364
365 // Insert an item in the middle of an existing radio group.
366 menu->InsertRadioItem(4, MenuTestCase_First + 5, "Radio 5");
367 CPPUNIT_ASSERT( menu->IsChecked(MenuTestCase_First + 3) );
368
369 menu->Check( MenuTestCase_First + 5, true );
370 CPPUNIT_ASSERT( !menu->IsChecked(MenuTestCase_First + 3) );
371
372
373 // Prepend a couple of items before the first group.
374 menu->PrependRadioItem(MenuTestCase_First + 6, "Radio 6");
375 menu->PrependRadioItem(MenuTestCase_First + 7, "Radio 7");
376 menu->Check(MenuTestCase_First + 7, true);
377 CPPUNIT_ASSERT( !menu->IsChecked(MenuTestCase_First + 1) );
378
379
380 // Check that the last radio group still works as expected.
381 menu->Check(MenuTestCase_First + 4, true);
382 CPPUNIT_ASSERT( !menu->IsChecked(MenuTestCase_First + 5) );
383}
61263343
PC
384
385void MenuTestCase::RemoveAdd()
386{
387 wxMenuBar* bar = m_frame->GetMenuBar();
388
389 wxMenu* menu0 = bar->GetMenu(0);
390 wxMenu* menu1 = bar->GetMenu(1);
391 wxMenuItem* item = new wxMenuItem(menu0, MenuTestCase_Foo + 100, "t&ext\tCtrl-E");
392 menu0->Insert(0, item);
393 CPPUNIT_ASSERT( menu0->FindItemByPosition(0) == item );
394 menu0->Remove(item);
395 CPPUNIT_ASSERT( menu0->FindItemByPosition(0) != item );
396 menu1->Insert(0, item);
397 CPPUNIT_ASSERT( menu1->FindItemByPosition(0) == item );
398 menu1->Remove(item);
399 CPPUNIT_ASSERT( menu1->FindItemByPosition(0) != item );
400 menu0->Insert(0, item);
401 CPPUNIT_ASSERT( menu0->FindItemByPosition(0) == item );
402 menu0->Delete(item);
403}
6eca840c
VZ
404
405void MenuTestCase::Events()
406{
407#if wxUSE_UIACTIONSIMULATOR
408 class MenuEventHandler : public wxEvtHandler
409 {
410 public:
411 MenuEventHandler(wxWindow* win)
412 : m_win(win)
413 {
414 m_win->Connect(wxEVT_COMMAND_MENU_SELECTED,
415 wxCommandEventHandler(MenuEventHandler::OnMenu),
416 NULL,
417 this);
418
419 m_gotEvent = false;
420 m_event = NULL;
421 }
422
423 virtual ~MenuEventHandler()
424 {
425 m_win->Disconnect(wxEVT_COMMAND_MENU_SELECTED,
426 wxCommandEventHandler(MenuEventHandler::OnMenu),
427 NULL,
428 this);
429
430 delete m_event;
431 }
432
433 const wxCommandEvent& GetEvent()
434 {
435 CPPUNIT_ASSERT( m_gotEvent );
436
437 m_gotEvent = false;
438
439 return *m_event;
440 }
441
442 private:
443 void OnMenu(wxCommandEvent& event)
444 {
445 CPPUNIT_ASSERT( !m_gotEvent );
446
447 delete m_event;
448 m_event = static_cast<wxCommandEvent*>(event.Clone());
449 m_gotEvent = true;
450 }
451
452 wxWindow* const m_win;
453 wxCommandEvent* m_event;
454 bool m_gotEvent;
455 };
456
457 MenuEventHandler handler(m_frame);
458
459 // Invoke the accelerator.
460 m_frame->Show();
461 m_frame->SetFocus();
462 wxYield();
463
464 wxUIActionSimulator sim;
465 sim.KeyDown(WXK_F1);
466 sim.KeyUp(WXK_F1);
467 wxYield();
468
469 const wxCommandEvent& ev = handler.GetEvent();
470 CPPUNIT_ASSERT_EQUAL( static_cast<int>(MenuTestCase_Bar), ev.GetId() );
4936c099
VZ
471
472 wxObject* const src = ev.GetEventObject();
473 CPPUNIT_ASSERT( src );
474
475 CPPUNIT_ASSERT_EQUAL( "wxMenu",
476 wxString(src->GetClassInfo()->GetClassName()) );
477 CPPUNIT_ASSERT_EQUAL( static_cast<wxObject*>(m_menuWithBar),
478 src );
6eca840c
VZ
479#endif // wxUSE_UIACTIONSIMULATOR
480}