]> git.saurik.com Git - wxWidgets.git/blob - tests/controls/treectrltest.cpp
Ensure that the default wxWebView backends are registered.
[wxWidgets.git] / tests / controls / treectrltest.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/controls/treectrltest.cpp
3 // Purpose: wxTreeCtrl unit test
4 // Author: Vadim Zeitlin
5 // Created: 2008-11-26
6 // RCS-ID: $Id$
7 // Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
8 // (c) 2010 Steven Lamerton
9 ///////////////////////////////////////////////////////////////////////////////
10
11 // ----------------------------------------------------------------------------
12 // headers
13 // ----------------------------------------------------------------------------
14
15 #include "testprec.h"
16
17 #if wxUSE_TREECTRL
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include "wx/app.h"
25 #endif // WX_PRECOMP
26
27 #include "wx/artprov.h"
28 #include "wx/imaglist.h"
29 #include "wx/treectrl.h"
30 #include "wx/uiaction.h"
31 #include "testableframe.h"
32
33 // ----------------------------------------------------------------------------
34 // test class
35 // ----------------------------------------------------------------------------
36
37 class TreeCtrlTestCase : public CppUnit::TestCase
38 {
39 public:
40 TreeCtrlTestCase() { }
41
42 virtual void setUp();
43 virtual void tearDown();
44
45 private:
46 CPPUNIT_TEST_SUITE( TreeCtrlTestCase );
47 WXUISIM_TEST( ItemClick );
48 CPPUNIT_TEST( DeleteItem );
49 WXUISIM_TEST( LabelEdit );
50 WXUISIM_TEST( KeyDown );
51 #ifndef __WXGTK__
52 WXUISIM_TEST( CollapseExpandEvents );
53 WXUISIM_TEST( SelectionChange );
54 #endif // !__WXGTK__
55 WXUISIM_TEST( Menu );
56 CPPUNIT_TEST( ItemData );
57 CPPUNIT_TEST( Iteration );
58 CPPUNIT_TEST( Parent );
59 CPPUNIT_TEST( CollapseExpand );
60 CPPUNIT_TEST( AssignImageList );
61 CPPUNIT_TEST( Focus );
62 CPPUNIT_TEST( Bold );
63 CPPUNIT_TEST( Visible );
64 CPPUNIT_TEST( Sort );
65 WXUISIM_TEST( KeyNavigation );
66 CPPUNIT_TEST( HasChildren );
67 CPPUNIT_TEST( SelectItemSingle );
68 CPPUNIT_TEST( PseudoTest_MultiSelect );
69 CPPUNIT_TEST( SelectItemMulti );
70 CPPUNIT_TEST( PseudoTest_SetHiddenRoot );
71 CPPUNIT_TEST( HasChildren );
72 CPPUNIT_TEST_SUITE_END();
73
74 void ItemClick();
75 void DeleteItem();
76 void LabelEdit();
77 void KeyDown();
78 #ifndef __WXGTK__
79 void CollapseExpandEvents();
80 void SelectionChange();
81 #endif // !__WXGTK__
82 void Menu();
83 void ItemData();
84 void Iteration();
85 void Parent();
86 void CollapseExpand();
87 void AssignImageList();
88 void Focus();
89 void Bold();
90 void Visible();
91 void Sort();
92 void KeyNavigation();
93 void HasChildren();
94 void SelectItemSingle();
95 void SelectItemMulti();
96 void PseudoTest_MultiSelect() { ms_multiSelect = true; }
97 void PseudoTest_SetHiddenRoot() { ms_hiddenRoot = true; }
98
99 static bool ms_multiSelect;
100 static bool ms_hiddenRoot;
101
102 // the tree control itself
103 wxTreeCtrl *m_tree;
104
105 // and some of its items
106 wxTreeItemId m_root,
107 m_child1,
108 m_child2,
109 m_grandchild;
110
111 DECLARE_NO_COPY_CLASS(TreeCtrlTestCase)
112 };
113
114 // register in the unnamed registry so that these tests are run by default
115 CPPUNIT_TEST_SUITE_REGISTRATION( TreeCtrlTestCase );
116
117 // also include in its own registry so that these tests can be run alone
118 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( TreeCtrlTestCase, "TreeCtrlTestCase" );
119
120 // ----------------------------------------------------------------------------
121 // test initialization
122 // ----------------------------------------------------------------------------
123
124 bool TreeCtrlTestCase::ms_multiSelect = false;
125 bool TreeCtrlTestCase::ms_hiddenRoot = false;
126
127 void TreeCtrlTestCase::setUp()
128 {
129 m_tree = new wxTreeCtrl(wxTheApp->GetTopWindow(),
130 wxID_ANY,
131 wxDefaultPosition,
132 wxSize(400, 200),
133 wxTR_DEFAULT_STYLE | wxTR_EDIT_LABELS);
134
135 if ( ms_multiSelect )
136 m_tree->ToggleWindowStyle(wxTR_MULTIPLE);
137
138 if ( ms_hiddenRoot )
139 m_tree->ToggleWindowStyle(wxTR_HIDE_ROOT); // actually set it
140
141 m_root = m_tree->AddRoot("root");
142 m_child1 = m_tree->AppendItem(m_root, "child1");
143 m_child2 = m_tree->AppendItem(m_root, "child2");
144 m_grandchild = m_tree->AppendItem(m_child1, "grandchild");
145
146 m_tree->SetSize(400, 200);
147 m_tree->ExpandAll();
148 m_tree->Refresh();
149 m_tree->Update();
150 }
151
152 void TreeCtrlTestCase::tearDown()
153 {
154 delete m_tree;
155 m_tree = NULL;
156
157 m_root =
158 m_child1 =
159 m_child2 =
160 m_grandchild = wxTreeItemId();
161 }
162
163 // ----------------------------------------------------------------------------
164 // the tests themselves
165 // ----------------------------------------------------------------------------
166
167 void TreeCtrlTestCase::HasChildren()
168 {
169 CPPUNIT_ASSERT( m_tree->HasChildren(m_root) );
170 CPPUNIT_ASSERT( m_tree->HasChildren(m_child1) );
171 CPPUNIT_ASSERT( !m_tree->HasChildren(m_child2) );
172 CPPUNIT_ASSERT( !m_tree->HasChildren(m_grandchild) );
173 }
174
175 void TreeCtrlTestCase::SelectItemSingle()
176 {
177 // this test should be only ran in single-selection control
178 CPPUNIT_ASSERT( !m_tree->HasFlag(wxTR_MULTIPLE) );
179
180 // initially nothing is selected
181 CPPUNIT_ASSERT( !m_tree->IsSelected(m_child1) );
182
183 // selecting an item should make it selected
184 m_tree->SelectItem(m_child1);
185 CPPUNIT_ASSERT( m_tree->IsSelected(m_child1) );
186
187 // selecting it again shouldn't change anything
188 m_tree->SelectItem(m_child1);
189 CPPUNIT_ASSERT( m_tree->IsSelected(m_child1) );
190
191 // selecting another item should switch the selection to it
192 m_tree->SelectItem(m_child2);
193 CPPUNIT_ASSERT( !m_tree->IsSelected(m_child1) );
194 CPPUNIT_ASSERT( m_tree->IsSelected(m_child2) );
195
196 // selecting it again still shouldn't change anything
197 m_tree->SelectItem(m_child2);
198 CPPUNIT_ASSERT( !m_tree->IsSelected(m_child1) );
199 CPPUNIT_ASSERT( m_tree->IsSelected(m_child2) );
200
201 // deselecting an item should remove the selection entirely
202 m_tree->UnselectItem(m_child2);
203 CPPUNIT_ASSERT( !m_tree->IsSelected(m_child1) );
204 CPPUNIT_ASSERT( !m_tree->IsSelected(m_child2) );
205 }
206
207 void TreeCtrlTestCase::SelectItemMulti()
208 {
209 // this test should be only ran in multi-selection control
210 CPPUNIT_ASSERT( m_tree->HasFlag(wxTR_MULTIPLE) );
211
212 // initially nothing is selected
213 CPPUNIT_ASSERT( !m_tree->IsSelected(m_child1) );
214
215 // selecting an item should make it selected
216 m_tree->SelectItem(m_child1);
217 CPPUNIT_ASSERT( m_tree->IsSelected(m_child1) );
218
219 // selecting it again shouldn't change anything
220 m_tree->SelectItem(m_child1);
221 CPPUNIT_ASSERT( m_tree->IsSelected(m_child1) );
222
223 // selecting another item shouldn't deselect the previously selected one
224 m_tree->SelectItem(m_child2);
225 CPPUNIT_ASSERT( m_tree->IsSelected(m_child1) );
226 CPPUNIT_ASSERT( m_tree->IsSelected(m_child2) );
227
228 // selecting it again still shouldn't change anything
229 m_tree->SelectItem(m_child2);
230 CPPUNIT_ASSERT( m_tree->IsSelected(m_child1) );
231 CPPUNIT_ASSERT( m_tree->IsSelected(m_child2) );
232
233 // deselecting one of the items should leave the others selected
234 m_tree->UnselectItem(m_child1);
235 CPPUNIT_ASSERT( !m_tree->IsSelected(m_child1) );
236 CPPUNIT_ASSERT( m_tree->IsSelected(m_child2) );
237 }
238
239 void TreeCtrlTestCase::ItemClick()
240 {
241 #if wxUSE_UIACTIONSIMULATOR
242 EventCounter activated(m_tree, wxEVT_TREE_ITEM_ACTIVATED);
243 EventCounter rclick(m_tree, wxEVT_TREE_ITEM_RIGHT_CLICK);
244
245 wxUIActionSimulator sim;
246
247 wxRect pos;
248 m_tree->GetBoundingRect(m_child1, pos, true);
249
250 // We move in slightly so we are not on the edge
251 wxPoint point = m_tree->ClientToScreen(pos.GetPosition()) + wxPoint(4, 4);
252
253 sim.MouseMove(point);
254 wxYield();
255
256 sim.MouseDblClick();
257 wxYield();
258
259 sim.MouseClick(wxMOUSE_BTN_RIGHT);
260 wxYield();
261
262 CPPUNIT_ASSERT_EQUAL(1, activated.GetCount());
263 CPPUNIT_ASSERT_EQUAL(1, rclick.GetCount());
264 #endif // wxUSE_UIACTIONSIMULATOR
265 }
266
267 void TreeCtrlTestCase::DeleteItem()
268 {
269 EventCounter deleteitem(m_tree, wxEVT_TREE_DELETE_ITEM);
270
271 wxTreeItemId todelete = m_tree->AppendItem(m_root, "deleteme");
272 m_tree->Delete(todelete);
273 // We do not test DeleteAllItems() as under some versions of Windows events
274 // are not generated.
275
276 CPPUNIT_ASSERT_EQUAL(1, deleteitem.GetCount());
277 }
278
279 #if wxUSE_UIACTIONSIMULATOR
280
281 void TreeCtrlTestCase::LabelEdit()
282 {
283 EventCounter beginedit(m_tree, wxEVT_TREE_BEGIN_LABEL_EDIT);
284 EventCounter endedit(m_tree, wxEVT_TREE_END_LABEL_EDIT);
285
286 wxUIActionSimulator sim;
287
288 m_tree->SetFocusedItem(m_tree->GetRootItem());
289 m_tree->EditLabel(m_tree->GetRootItem());
290
291 sim.Text("newroottext");
292 wxYield();
293
294 CPPUNIT_ASSERT_EQUAL(1, beginedit.GetCount());
295
296 sim.Char(WXK_RETURN);
297 wxYield();
298
299 CPPUNIT_ASSERT_EQUAL(1, endedit.GetCount());
300 }
301
302 void TreeCtrlTestCase::KeyDown()
303 {
304 EventCounter keydown(m_tree, wxEVT_TREE_KEY_DOWN);
305
306 wxUIActionSimulator sim;
307
308 m_tree->SetFocus();
309 sim.Text("aAbB");
310 wxYield();
311
312 CPPUNIT_ASSERT_EQUAL(6, keydown.GetCount());
313 }
314
315 #if !defined(__WXGTK__)
316
317 void TreeCtrlTestCase::CollapseExpandEvents()
318 {
319 m_tree->CollapseAll();
320
321 EventCounter collapsed(m_tree, wxEVT_TREE_ITEM_COLLAPSED);
322 EventCounter collapsing(m_tree, wxEVT_TREE_ITEM_COLLAPSING);
323 EventCounter expanded(m_tree, wxEVT_TREE_ITEM_EXPANDED);
324 EventCounter expanding(m_tree, wxEVT_TREE_ITEM_EXPANDING);
325
326 wxUIActionSimulator sim;
327
328 wxRect pos;
329 m_tree->GetBoundingRect(m_root, pos, true);
330
331 // We move in slightly so we are not on the edge
332 wxPoint point = m_tree->ClientToScreen(pos.GetPosition()) + wxPoint(4, 4);
333
334 sim.MouseMove(point);
335 wxYield();
336
337 sim.MouseDblClick();
338 wxYield();
339
340 CPPUNIT_ASSERT_EQUAL(1, expanding.GetCount());
341 CPPUNIT_ASSERT_EQUAL(1, expanded.GetCount());
342
343 sim.MouseDblClick();
344 wxYield();
345
346 CPPUNIT_ASSERT_EQUAL(1, collapsing.GetCount());
347 CPPUNIT_ASSERT_EQUAL(1, collapsed.GetCount());
348 }
349
350 void TreeCtrlTestCase::SelectionChange()
351 {
352 m_tree->ExpandAll();
353 m_tree->UnselectAll();
354
355 EventCounter changed(m_tree, wxEVT_TREE_SEL_CHANGED);
356 EventCounter changing(m_tree, wxEVT_TREE_SEL_CHANGING);
357
358 wxUIActionSimulator sim;
359
360 wxRect poschild1, poschild2;
361 m_tree->GetBoundingRect(m_child1, poschild1, true);
362 m_tree->GetBoundingRect(m_child2, poschild2, true);
363
364 // We move in slightly so we are not on the edge
365 wxPoint point1 = m_tree->ClientToScreen(poschild1.GetPosition()) + wxPoint(4, 4);
366 wxPoint point2 = m_tree->ClientToScreen(poschild2.GetPosition()) + wxPoint(4, 4);
367
368 sim.MouseMove(point1);
369 wxYield();
370
371 sim.MouseClick();
372 wxYield();
373
374 sim.MouseMove(point2);
375 wxYield();
376
377 sim.MouseClick();
378 wxYield();
379
380 CPPUNIT_ASSERT_EQUAL(2, changed.GetCount());
381 CPPUNIT_ASSERT_EQUAL(2, changing.GetCount());
382 }
383
384 #endif // !__WXGTK__
385
386 void TreeCtrlTestCase::Menu()
387 {
388 EventCounter menu(m_tree, wxEVT_TREE_ITEM_MENU);
389 wxUIActionSimulator sim;
390
391 wxRect pos;
392 m_tree->GetBoundingRect(m_child1, pos, true);
393
394 // We move in slightly so we are not on the edge
395 wxPoint point = m_tree->ClientToScreen(pos.GetPosition()) + wxPoint(4, 4);
396
397 sim.MouseMove(point);
398 wxYield();
399
400 sim.MouseClick(wxMOUSE_BTN_RIGHT);
401 wxYield();
402
403 CPPUNIT_ASSERT_EQUAL(1, menu.GetCount());
404 }
405
406 #endif // wxUSE_UIACTIONSIMULATOR
407
408 void TreeCtrlTestCase::ItemData()
409 {
410 wxTreeItemData* child1data = new wxTreeItemData();
411 wxTreeItemData* appenddata = new wxTreeItemData();
412 wxTreeItemData* insertdata = new wxTreeItemData();
413
414 m_tree->SetItemData(m_child1, child1data);
415
416 CPPUNIT_ASSERT_EQUAL(child1data, m_tree->GetItemData(m_child1));
417 CPPUNIT_ASSERT_EQUAL(m_child1, child1data->GetId());
418
419 wxTreeItemId append = m_tree->AppendItem(m_root, "new", -1, -1, appenddata);
420
421 CPPUNIT_ASSERT_EQUAL(appenddata, m_tree->GetItemData(append));
422 CPPUNIT_ASSERT_EQUAL(append, appenddata->GetId());
423
424 wxTreeItemId insert = m_tree->InsertItem(m_root, m_child1, "new", -1, -1,
425 insertdata);
426
427 CPPUNIT_ASSERT_EQUAL(insertdata, m_tree->GetItemData(insert));
428 CPPUNIT_ASSERT_EQUAL(insert, insertdata->GetId());
429 }
430
431 void TreeCtrlTestCase::Iteration()
432 {
433 // Get first / next / last child
434 wxTreeItemIdValue cookie;
435 CPPUNIT_ASSERT_EQUAL(m_tree->GetFirstChild(m_root, cookie), m_child1);
436 CPPUNIT_ASSERT_EQUAL(m_tree->GetNextChild(m_root, cookie),
437 m_tree->GetLastChild(m_root));
438 CPPUNIT_ASSERT_EQUAL(m_child2, m_tree->GetLastChild(m_root));
439
440 // Get next / previous sibling
441 CPPUNIT_ASSERT_EQUAL(m_child2, m_tree->GetNextSibling(m_child1));
442 CPPUNIT_ASSERT_EQUAL(m_child1, m_tree->GetPrevSibling(m_child2));
443 }
444
445 void TreeCtrlTestCase::Parent()
446 {
447 CPPUNIT_ASSERT_EQUAL(m_root, m_tree->GetRootItem());
448 CPPUNIT_ASSERT_EQUAL(m_root, m_tree->GetItemParent(m_child1));
449 CPPUNIT_ASSERT_EQUAL(m_root, m_tree->GetItemParent(m_child2));
450 CPPUNIT_ASSERT_EQUAL(m_child1, m_tree->GetItemParent(m_grandchild));
451 }
452
453 void TreeCtrlTestCase::CollapseExpand()
454 {
455 m_tree->ExpandAll();
456
457 CPPUNIT_ASSERT(m_tree->IsExpanded(m_root));
458 CPPUNIT_ASSERT(m_tree->IsExpanded(m_child1));
459
460 m_tree->CollapseAll();
461
462 CPPUNIT_ASSERT(!m_tree->IsExpanded(m_root));
463 CPPUNIT_ASSERT(!m_tree->IsExpanded(m_child1));
464
465 m_tree->ExpandAllChildren(m_root);
466
467 CPPUNIT_ASSERT(m_tree->IsExpanded(m_root));
468 CPPUNIT_ASSERT(m_tree->IsExpanded(m_child1));
469
470 m_tree->CollapseAllChildren(m_child1);
471
472 CPPUNIT_ASSERT(!m_tree->IsExpanded(m_child1));
473
474 m_tree->Expand(m_child1);
475
476 CPPUNIT_ASSERT(m_tree->IsExpanded(m_child1));
477
478 m_tree->Collapse(m_root);
479
480 CPPUNIT_ASSERT(!m_tree->IsExpanded(m_root));
481 CPPUNIT_ASSERT(m_tree->IsExpanded(m_child1));
482
483 m_tree->CollapseAndReset(m_root);
484
485 CPPUNIT_ASSERT(!m_tree->IsExpanded(m_root));
486 }
487
488 void TreeCtrlTestCase::AssignImageList()
489 {
490 wxSize size(16, 16);
491
492 wxImageList *imagelist = new wxImageList(size.x, size.y);
493 imagelist->Add(wxArtProvider::GetIcon(wxART_QUESTION, wxART_OTHER, size));
494
495 wxImageList *statelist = new wxImageList(size.x, size.y);
496 statelist->Add(wxArtProvider::GetIcon(wxART_ERROR, wxART_OTHER, size));
497
498 m_tree->AssignImageList(imagelist);
499 m_tree->AssignStateImageList(statelist);
500
501 CPPUNIT_ASSERT_EQUAL(imagelist, m_tree->GetImageList());
502 CPPUNIT_ASSERT_EQUAL(statelist, m_tree->GetStateImageList());
503 }
504
505 void TreeCtrlTestCase::Focus()
506 {
507 #if !defined(__WXGTK__) && !defined(__WXOSX__)
508 m_tree->SetFocusedItem(m_child1);
509
510 CPPUNIT_ASSERT_EQUAL(m_child1, m_tree->GetFocusedItem());
511
512 m_tree->ClearFocusedItem();
513
514 CPPUNIT_ASSERT(!m_tree->GetFocusedItem());
515 #endif
516 }
517
518 void TreeCtrlTestCase::Bold()
519 {
520 CPPUNIT_ASSERT(!m_tree->IsBold(m_child1));
521
522 m_tree->SetItemBold(m_child1);
523
524 CPPUNIT_ASSERT(m_tree->IsBold(m_child1));
525
526 m_tree->SetItemBold(m_child1, false);
527
528 CPPUNIT_ASSERT(!m_tree->IsBold(m_child1));
529 }
530
531 void TreeCtrlTestCase::Visible()
532 {
533 m_tree->CollapseAll();
534
535 CPPUNIT_ASSERT(m_tree->IsVisible(m_root));
536 CPPUNIT_ASSERT(!m_tree->IsVisible(m_child1));
537
538 m_tree->EnsureVisible(m_grandchild);
539
540 CPPUNIT_ASSERT(m_tree->IsVisible(m_grandchild));
541
542 m_tree->ExpandAll();
543
544 CPPUNIT_ASSERT_EQUAL(m_root, m_tree->GetFirstVisibleItem());
545 CPPUNIT_ASSERT_EQUAL(m_child1, m_tree->GetNextVisible(m_root));
546 CPPUNIT_ASSERT_EQUAL(m_grandchild, m_tree->GetNextVisible(m_child1));
547 CPPUNIT_ASSERT_EQUAL(m_child2, m_tree->GetNextVisible(m_grandchild));
548
549 CPPUNIT_ASSERT(!m_tree->GetNextVisible(m_child2));
550 CPPUNIT_ASSERT(!m_tree->GetPrevVisible(m_root));
551 }
552
553 void TreeCtrlTestCase::Sort()
554 {
555 wxTreeItemId zitem = m_tree->AppendItem(m_root, "zzzz");
556 wxTreeItemId aitem = m_tree->AppendItem(m_root, "aaaa");
557
558 m_tree->SortChildren(m_root);
559
560 wxTreeItemIdValue cookie;
561
562 CPPUNIT_ASSERT_EQUAL(aitem, m_tree->GetFirstChild(m_root, cookie));
563 CPPUNIT_ASSERT_EQUAL(m_child1, m_tree->GetNextChild(m_root, cookie));
564 CPPUNIT_ASSERT_EQUAL(m_child2, m_tree->GetNextChild(m_root, cookie));
565 CPPUNIT_ASSERT_EQUAL(zitem, m_tree->GetNextChild(m_root, cookie));
566 }
567
568 void TreeCtrlTestCase::KeyNavigation()
569 {
570 #if wxUSE_UIACTIONSIMULATOR && !defined(__WXGTK__)
571 wxUIActionSimulator sim;
572
573 m_tree->CollapseAll();
574
575 m_tree->SelectItem(m_root);
576
577 m_tree->SetFocus();
578 sim.Char(WXK_RIGHT);
579 wxYield();
580
581 CPPUNIT_ASSERT(m_tree->IsExpanded(m_root));
582
583 sim.Char(WXK_LEFT);
584 wxYield();
585
586 CPPUNIT_ASSERT(!m_tree->IsExpanded(m_root));
587
588 sim.Char(WXK_RIGHT);
589 sim.Char(WXK_DOWN);
590 wxYield();
591
592 CPPUNIT_ASSERT_EQUAL(m_child1, m_tree->GetSelection());
593
594 sim.Char(WXK_DOWN);
595 wxYield();
596
597 CPPUNIT_ASSERT_EQUAL(m_child2, m_tree->GetSelection());
598 #endif
599 }
600
601 #endif //wxUSE_TREECTRL