]> git.saurik.com Git - wxWidgets.git/blame - src/generic/treebkg.cpp
Fixed a crash when deleting the last timer
[wxWidgets.git] / src / generic / treebkg.cpp
CommitLineData
eca15c0d
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: src/generic/treebkg.cpp
3// Purpose: generic implementation of wxTreebook
4// Author: Evgeniy Tarassov, Vadim Zeitlin
5// Modified by:
6// Created: 2005-09-15
7// RCS-ID: $Id$
8// Copyright: (c) 2005 Vadim Zeitlin <vadim@wxwidgets.org>
9// Licence: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
27#if wxUSE_TREEBOOK
28
29#include "wx/treebook.h"
30#include "wx/imaglist.h"
31#include "wx/settings.h"
32
33// ----------------------------------------------------------------------------
34// various wxWidgets macros
35// ----------------------------------------------------------------------------
36
37// check that the page index is valid
38#define IS_VALID_PAGE(nPage) ((nPage) < DoInternalGetPageCount())
39
40// ----------------------------------------------------------------------------
41// event table
42// ----------------------------------------------------------------------------
43
2ddb4d13 44IMPLEMENT_DYNAMIC_CLASS(wxTreebook, wxBookCtrlBase)
eca15c0d
VZ
45IMPLEMENT_DYNAMIC_CLASS(wxTreebookEvent, wxNotifyEvent)
46
47const wxEventType wxEVT_COMMAND_TREEBOOK_PAGE_CHANGING = wxNewEventType();
48const wxEventType wxEVT_COMMAND_TREEBOOK_PAGE_CHANGED = wxNewEventType();
49const wxEventType wxEVT_COMMAND_TREEBOOK_NODE_COLLAPSED = wxNewEventType();
50const wxEventType wxEVT_COMMAND_TREEBOOK_NODE_EXPANDED = wxNewEventType();
51const int wxID_TREEBOOKTREEVIEW = wxNewId();
52
53BEGIN_EVENT_TABLE(wxTreebook, wxBookCtrlBase)
eca15c0d
VZ
54 EVT_TREE_SEL_CHANGED (wxID_TREEBOOKTREEVIEW, wxTreebook::OnTreeSelectionChange)
55 EVT_TREE_ITEM_EXPANDED (wxID_TREEBOOKTREEVIEW, wxTreebook::OnTreeNodeExpandedCollapsed)
56 EVT_TREE_ITEM_COLLAPSED(wxID_TREEBOOKTREEVIEW, wxTreebook::OnTreeNodeExpandedCollapsed)
57END_EVENT_TABLE()
58
59// ============================================================================
60// wxTreebook implementation
61// ============================================================================
62
63// ----------------------------------------------------------------------------
64// wxTreebook creation
65// ----------------------------------------------------------------------------
66
67void wxTreebook::Init()
68{
eca15c0d
VZ
69 m_selection =
70 m_actualSelection = wxNOT_FOUND;
71}
72
73bool
74wxTreebook::Create(wxWindow *parent,
75 wxWindowID id,
76 const wxPoint& pos,
77 const wxSize& size,
78 long style,
79 const wxString& name)
80{
81 // Check the style flag to have either wxTBK_RIGHT or wxTBK_LEFT
2ddb4d13 82 if ( (style & wxBK_ALIGN_MASK) == wxBK_DEFAULT )
eca15c0d 83 {
2ddb4d13 84 style |= wxBK_LEFT;
eca15c0d
VZ
85 }
86
87 // no border for this control, it doesn't look nice together with the tree
88 style &= ~wxBORDER_MASK;
89 style |= wxBORDER_NONE;
90
91 if ( !wxControl::Create(parent, id, pos, size,
92 style, wxDefaultValidator, name) )
93 return false;
94
2ddb4d13 95 m_bookctrl = new wxTreeCtrl
eca15c0d
VZ
96 (
97 this,
98 wxID_TREEBOOKTREEVIEW,
99 wxDefaultPosition,
100 wxDefaultSize,
101 wxBORDER_SIMPLE |
bc454ef8 102 wxTR_DEFAULT_STYLE |
eca15c0d 103 wxTR_HIDE_ROOT |
eca15c0d
VZ
104 wxTR_SINGLE
105 );
2ddb4d13 106 GetTreeCtrl()->AddRoot(wxEmptyString); // label doesn't matter, it's hidden
eca15c0d
VZ
107
108#ifdef __WXMSW__
2ddb4d13 109 // We need to add dummy size event to force possible scrollbar hiding
eca15c0d
VZ
110 wxSizeEvent evt;
111 GetEventHandler()->AddPendingEvent(evt);
112#endif
113
114 return true;
115}
116
117
118// insert a new page just before the pagePos
119bool wxTreebook::InsertPage(size_t pagePos,
120 wxWindow *page,
121 const wxString& text,
122 bool bSelect,
123 int imageId)
124{
125 return DoInsertPage(pagePos, page, text, bSelect, imageId);
126}
127
9d5371c6
VZ
128bool wxTreebook::InsertSubPage(size_t pagePos,
129 wxWindow *page,
130 const wxString& text,
131 bool bSelect,
132 int imageId)
eca15c0d
VZ
133{
134 return DoInsertSubPage(pagePos, page, text, bSelect, imageId);
135}
136
137bool wxTreebook::AddPage(wxWindow *page, const wxString& text, bool bSelect,
138 int imageId)
139{
140 return DoInsertPage(m_treeIds.GetCount(), page, text, bSelect, imageId);
141}
142
143// insertion time is linear to the number of top-pages
144bool wxTreebook::AddSubPage(wxWindow *page, const wxString& text, bool bSelect, int imageId)
145{
146 return DoAddSubPage(page, text, bSelect, imageId);
147}
148
149
150bool wxTreebook::DoInsertPage(size_t pagePos,
151 wxWindow *page,
152 const wxString& text,
153 bool bSelect,
154 int imageId)
155{
156 wxCHECK_MSG( pagePos <= DoInternalGetPageCount(), false,
157 wxT("Invalid treebook page position") );
158
159 if ( !wxBookCtrlBase::InsertPage(pagePos, page, text, bSelect, imageId) )
160 return false;
161
2ddb4d13 162 wxTreeCtrl *tree = GetTreeCtrl();
eca15c0d
VZ
163 wxTreeItemId newId;
164 if ( pagePos == DoInternalGetPageCount() )
165 {
166 // append the page to the end
2ddb4d13 167 wxTreeItemId rootId = tree->GetRootItem();
eca15c0d 168
2ddb4d13 169 newId = tree->AppendItem(rootId, text, imageId);
eca15c0d
VZ
170 }
171 else // insert the new page before the given one
172 {
173 wxTreeItemId nodeId = m_treeIds[pagePos];
174
2ddb4d13
WS
175 wxTreeItemId previousId = tree->GetPrevSibling(nodeId);
176 wxTreeItemId parentId = tree->GetItemParent(nodeId);
eca15c0d
VZ
177
178 if ( previousId.IsOk() )
179 {
180 // insert before the sibling - previousId
2ddb4d13 181 newId = tree->InsertItem(parentId, previousId, text, imageId);
eca15c0d
VZ
182 }
183 else // no prev siblings -- insert as a first child
184 {
185 wxASSERT_MSG( parentId.IsOk(), wxT( "Tree has no root node?" ) );
186
2ddb4d13 187 newId = tree->PrependItem(parentId, text, imageId);
eca15c0d
VZ
188 }
189 }
190
191 if ( !newId.IsOk() )
192 {
193 //something wrong -> cleaning and returning with false
194 (void)wxBookCtrlBase::DoRemovePage(pagePos);
195
196 wxFAIL_MSG( wxT("Failed to insert treebook page") );
197 return false;
198 }
199
200 DoInternalAddPage(pagePos, page, newId);
201
202 DoUpdateSelection(bSelect, pagePos);
203
2ddb4d13 204 m_bookctrl->InvalidateBestSize();
bc454ef8 205
eca15c0d
VZ
206 return true;
207}
208
209bool wxTreebook::DoAddSubPage(wxWindow *page, const wxString& text, bool bSelect, int imageId)
210{
2ddb4d13 211 wxTreeCtrl *tree = GetTreeCtrl();
eca15c0d 212
2ddb4d13
WS
213 wxTreeItemId rootId = tree->GetRootItem();
214
215 wxTreeItemId lastNodeId = tree->GetLastChild(rootId);
eca15c0d
VZ
216
217 wxCHECK_MSG( lastNodeId.IsOk(), false,
218 _T("Can't insert sub page when there are no pages") );
219
220 // now calculate its position (should we save/update it too?)
2ddb4d13
WS
221 size_t newPos = tree->GetCount() -
222 (tree->GetChildrenCount(lastNodeId, true) + 1);
eca15c0d
VZ
223
224 return DoInsertSubPage(newPos, page, text, bSelect, imageId);
225}
226
227bool wxTreebook::DoInsertSubPage(size_t pagePos,
228 wxTreebookPage *page,
229 const wxString& text,
230 bool bSelect,
231 int imageId)
232{
233 wxTreeItemId parentId = DoInternalGetPage(pagePos);
234 wxCHECK_MSG( parentId.IsOk(), false, wxT("invalid tree item") );
235
2ddb4d13
WS
236 wxTreeCtrl *tree = GetTreeCtrl();
237
238 size_t newPos = pagePos + tree->GetChildrenCount(parentId, true) + 1;
eca15c0d
VZ
239 wxASSERT_MSG( newPos <= DoInternalGetPageCount(),
240 wxT("Internal error in tree insert point calculation") );
241
242 if ( !wxBookCtrlBase::InsertPage(newPos, page, text, bSelect, imageId) )
243 return false;
244
2ddb4d13 245 wxTreeItemId newId = tree->AppendItem(parentId, text, imageId);
eca15c0d
VZ
246
247 if ( !newId.IsOk() )
248 {
249 (void)wxBookCtrlBase::DoRemovePage(newPos);
250
251 wxFAIL_MSG( wxT("Failed to insert treebook page") );
252 return false;
253 }
254
255 DoInternalAddPage(newPos, page, newId);
256
257 DoUpdateSelection(bSelect, newPos);
258
2ddb4d13 259 m_bookctrl->InvalidateBestSize();
bc454ef8 260
eca15c0d
VZ
261 return true;
262}
263
264bool wxTreebook::DeletePage(size_t pagePos)
265{
266 wxCHECK_MSG( IS_VALID_PAGE(pagePos), false, wxT("Invalid tree index") );
267
268 wxTreebookPage *oldPage = DoRemovePage(pagePos);
269 if ( !oldPage )
270 return false;
271
272 delete oldPage;
273
274 return true;
275}
276
277wxTreebookPage *wxTreebook::DoRemovePage(size_t pagePos)
278{
279 wxTreeItemId pageId = DoInternalGetPage(pagePos);
280 wxCHECK_MSG( pageId.IsOk(), NULL, wxT("Invalid tree index") );
281
282 wxTreebookPage * oldPage = GetPage(pagePos);
2ddb4d13 283 wxTreeCtrl *tree = GetTreeCtrl();
eca15c0d 284
2ddb4d13 285 size_t subCount = tree->GetChildrenCount(pageId, true);
eca15c0d
VZ
286 wxASSERT_MSG ( IS_VALID_PAGE(pagePos + subCount),
287 wxT("Internal error in wxTreebook::DoRemovePage") );
288
289 // here we are going to delete ALL the pages in the range
290 // [pagePos, pagePos + subCount] -- the page and its children
291
292 // deleting all the pages from the base class
293 for ( size_t i = 0; i <= subCount; ++i )
294 {
295 wxTreebookPage *page = wxBookCtrlBase::DoRemovePage(pagePos);
296
297 // don't delete the page itself though -- it will be deleted in
298 // DeletePage() when we return
299 if ( i )
300 {
301 delete page;
302 }
303 }
304
305 DoInternalRemovePageRange(pagePos, subCount);
306
2ddb4d13
WS
307 tree->DeleteChildren( pageId );
308 tree->Delete( pageId );
309 tree->InvalidateBestSize();
eca15c0d
VZ
310
311 return oldPage;
312}
313
314bool wxTreebook::DeleteAllPages()
315{
316 wxBookCtrlBase::DeleteAllPages();
317 m_treeIds.Clear();
318 m_selection =
319 m_actualSelection = wxNOT_FOUND;
320
2ddb4d13
WS
321 wxTreeCtrl *tree = GetTreeCtrl();
322 tree->DeleteChildren(tree->GetRootItem());
eca15c0d
VZ
323
324 return true;
325}
326
327void wxTreebook::DoInternalAddPage(size_t newPos,
328 wxTreebookPage *page,
329 wxTreeItemId pageId)
330{
331 wxASSERT_MSG( newPos <= m_treeIds.GetCount(), wxT("Ivalid index passed to wxTreebook::DoInternalAddPage") );
332
333 // hide newly inserted page initially (it will be shown when selected)
334 if ( page )
335 page->Hide();
336
337 if ( newPos == m_treeIds.GetCount() )
338 {
339 // append
340 m_treeIds.Add(pageId);
341 }
342 else // insert
343 {
344 m_treeIds.Insert(pageId, newPos);
345
346 if ( m_selection != wxNOT_FOUND && newPos <= (size_t)m_selection )
347 {
348 // selection has been moved one unit toward the end
349 ++m_selection;
350 if ( m_actualSelection != wxNOT_FOUND )
351 ++m_actualSelection;
352 }
353 else if ( m_actualSelection != wxNOT_FOUND &&
354 newPos <= (size_t)m_actualSelection )
355 {
356 DoSetSelection(m_selection);
357 }
358 }
359}
360
361void wxTreebook::DoInternalRemovePageRange(size_t pagePos, size_t subCount)
362{
363 // Attention: this function is only for a situation when we delete a node
364 // with all its children so pagePos is the node's index and subCount is the
365 // node children count
366 wxASSERT_MSG( pagePos + subCount < m_treeIds.GetCount(),
367 wxT("Ivalid page index") );
368
369 wxTreeItemId pageId = m_treeIds[pagePos];
370
371 m_treeIds.RemoveAt(pagePos, subCount + 1);
372
373 if ( m_selection != wxNOT_FOUND )
374 {
375 if ( (size_t)m_selection > pagePos + subCount)
376 {
377 // selection is far after the deleted page, so just update the index and move on
378 m_selection -= 1 + subCount;
379 if ( m_actualSelection != wxNOT_FOUND)
380 {
381 m_actualSelection -= subCount + 1;
382 }
383 }
384 else if ( (size_t)m_selection >= pagePos )
385 {
2ddb4d13
WS
386 wxTreeCtrl *tree = GetTreeCtrl();
387
eca15c0d
VZ
388 // as selected page is going to be deleted, try to select the next
389 // sibling if exists, if not then the parent
2ddb4d13 390 wxTreeItemId nodeId = tree->GetNextSibling(pageId);
eca15c0d
VZ
391
392 m_selection = wxNOT_FOUND;
393 m_actualSelection = wxNOT_FOUND;
394
395 if ( nodeId.IsOk() )
396 {
397 // selecting next siblings
2ddb4d13 398 tree->SelectItem(nodeId);
eca15c0d
VZ
399 }
400 else // no next sibling, select the parent
401 {
2ddb4d13 402 wxTreeItemId parentId = tree->GetItemParent(pageId);
eca15c0d 403
2ddb4d13 404 if ( parentId.IsOk() && parentId != tree->GetRootItem() )
eca15c0d 405 {
2ddb4d13 406 tree->SelectItem(parentId);
eca15c0d
VZ
407 }
408 else // parent is root
409 {
410 // we can't select it as it's hidden
411 DoUpdateSelection(false, wxNOT_FOUND);
412 }
413 }
414 }
415 else if ( m_actualSelection != wxNOT_FOUND &&
416 (size_t)m_actualSelection >= pagePos )
417 {
418 // nothing to do -- selection is before the deleted node, but
419 // actually shown page (the first (sub)child with page != NULL) is
420 // already deleted
421 m_actualSelection = m_selection;
422 DoSetSelection(m_selection);
423 }
424 //else: nothing to do -- selection is before the deleted node
425 }
426 else
427 {
428 DoUpdateSelection(false, wxNOT_FOUND);
429 }
430}
431
432
433void wxTreebook::DoUpdateSelection(bool bSelect, int newPos)
434{
435 int newSelPos;
436 if ( bSelect )
437 {
438 newSelPos = newPos;
439 }
440 else if ( m_selection == wxNOT_FOUND && DoInternalGetPageCount() > 0 )
441 {
442 newSelPos = 0;
443 }
444 else
445 {
446 newSelPos = wxNOT_FOUND;
447 }
448
449 if ( newSelPos != wxNOT_FOUND )
450 {
451 SetSelection((size_t)newSelPos);
452 }
453}
454
455wxTreeItemId wxTreebook::DoInternalGetPage(size_t pagePos) const
456{
457 if ( pagePos >= m_treeIds.GetCount() )
458 {
459 // invalid position but ok here, in this internal function, don't assert
460 // (the caller will do it)
461 return wxTreeItemId();
462 }
463
464 return m_treeIds[pagePos];
465}
466
467int wxTreebook::DoInternalFindPageById(wxTreeItemId pageId) const
468{
469 const size_t count = m_treeIds.GetCount();
470 for ( size_t i = 0; i < count; ++i )
471 {
472 if ( m_treeIds[i] == pageId )
473 return i;
474 }
475
476 return wxNOT_FOUND;
477}
478
479bool wxTreebook::IsNodeExpanded(size_t pagePos) const
480{
481 wxTreeItemId pageId = DoInternalGetPage(pagePos);
482
483 wxCHECK_MSG( pageId.IsOk(), false, wxT("invalid tree item") );
484
2ddb4d13 485 return GetTreeCtrl()->IsExpanded(pageId);
eca15c0d
VZ
486}
487
488bool wxTreebook::ExpandNode(size_t pagePos, bool expand)
489{
490 wxTreeItemId pageId = DoInternalGetPage(pagePos);
491
492 wxCHECK_MSG( pageId.IsOk(), false, wxT("invalid tree item") );
493
494 if ( expand )
495 {
2ddb4d13 496 GetTreeCtrl()->Expand( pageId );
eca15c0d
VZ
497 }
498 else // collapse
499 {
2ddb4d13 500 GetTreeCtrl()->Collapse( pageId );
eca15c0d
VZ
501
502 // rely on the events generated by wxTreeCtrl to update selection
503 }
504
505 return true;
506}
507
508int wxTreebook::GetPageParent(size_t pagePos) const
509{
510 wxTreeItemId nodeId = DoInternalGetPage( pagePos );
511 wxCHECK_MSG( nodeId.IsOk(), wxNOT_FOUND, wxT("Invalid page index spacified!") );
512
2ddb4d13 513 const wxTreeItemId parent = GetTreeCtrl()->GetItemParent( nodeId );
eca15c0d
VZ
514
515 return parent.IsOk() ? DoInternalFindPageById(parent) : wxNOT_FOUND;
516}
517
518bool wxTreebook::SetPageText(size_t n, const wxString& strText)
519{
520 wxTreeItemId pageId = DoInternalGetPage(n);
521
522 wxCHECK_MSG( pageId.IsOk(), false, wxT("invalid tree item") );
523
2ddb4d13 524 GetTreeCtrl()->SetItemText(pageId, strText);
eca15c0d
VZ
525
526 return true;
527}
528
529wxString wxTreebook::GetPageText(size_t n) const
530{
531 wxTreeItemId pageId = DoInternalGetPage(n);
532
533 wxCHECK_MSG( pageId.IsOk(), wxString(), wxT("invalid tree item") );
534
2ddb4d13 535 return GetTreeCtrl()->GetItemText(pageId);
eca15c0d
VZ
536}
537
538int wxTreebook::GetPageImage(size_t n) const
539{
540 wxTreeItemId pageId = DoInternalGetPage(n);
541
542 wxCHECK_MSG( pageId.IsOk(), wxNOT_FOUND, wxT("invalid tree item") );
543
2ddb4d13 544 return GetTreeCtrl()->GetItemImage(pageId);
eca15c0d
VZ
545}
546
547bool wxTreebook::SetPageImage(size_t n, int imageId)
548{
549 wxTreeItemId pageId = DoInternalGetPage(n);
550
551 wxCHECK_MSG( pageId.IsOk(), false, wxT("invalid tree item") );
552
2ddb4d13 553 GetTreeCtrl()->SetItemImage(pageId, imageId);
eca15c0d
VZ
554
555 return true;
556}
557
558wxSize wxTreebook::CalcSizeFromPage(const wxSize& sizePage) const
559{
2ddb4d13 560 const wxSize sizeTree = GetControllerSize();
eca15c0d
VZ
561
562 wxSize size = sizePage;
563 size.x += sizeTree.x;
564
565 return size;
566}
567
568int wxTreebook::GetSelection() const
569{
570 return m_selection;
571}
572
573int wxTreebook::SetSelection(size_t pagePos)
574{
575 if ( (size_t)m_selection != pagePos )
576 return DoSetSelection(pagePos);
577
578 return m_selection;
579}
580
581int wxTreebook::DoSetSelection(size_t pagePos)
582{
583 wxCHECK_MSG( IS_VALID_PAGE(pagePos), wxNOT_FOUND,
584 wxT("invalid page index in wxListbook::SetSelection()") );
585 wxASSERT_MSG( GetPageCount() == DoInternalGetPageCount(),
586 wxT("wxTreebook logic error: m_treeIds and m_pages not in sync!"));
587
588 const int oldSel = m_selection;
2ddb4d13 589 wxTreeCtrl *tree = GetTreeCtrl();
eca15c0d
VZ
590
591 wxTreebookEvent event(wxEVT_COMMAND_TREEBOOK_PAGE_CHANGING, m_windowId);
592 event.SetEventObject(this);
593 event.SetSelection(pagePos);
594 event.SetOldSelection(m_selection);
595
596 // don't send the event if the old and new pages are the same; do send it
597 // otherwise and be prepared for it to be vetoed
598 if ( (int)pagePos == m_selection ||
599 !GetEventHandler()->ProcessEvent(event) ||
600 event.IsAllowed() )
601 {
602 // hide the previously shown page
603 wxTreebookPage * const oldPage = DoGetCurrentPage();
604 if ( oldPage )
605 oldPage->Hide();
606
607 // then show the new one
608 m_selection = pagePos;
609 wxTreebookPage *page = wxBookCtrlBase::GetPage(m_selection);
610 if ( !page )
611 {
612 // find the next page suitable to be shown: the first (grand)child
613 // of this one with a non-NULL associated page
614 wxTreeItemId childId = m_treeIds[pagePos];
615 m_actualSelection = pagePos;
616 while ( !page && childId.IsOk() )
617 {
618 wxTreeItemIdValue cookie;
2ddb4d13 619 childId = tree->GetFirstChild( childId, cookie );
eca15c0d
VZ
620 if ( childId.IsOk() )
621 {
622 page = wxBookCtrlBase::GetPage(++m_actualSelection);
623 }
624 }
625
626 wxASSERT_MSG( page, wxT("no page to show found!") );
627 }
628
629 if ( page )
630 {
631 page->SetSize(GetPageRect());
632 page->Show();
633 }
634
2ddb4d13 635 tree->SelectItem(DoInternalGetPage(pagePos));
eca15c0d
VZ
636
637 // notify about the (now completed) page change
638 event.SetEventType(wxEVT_COMMAND_TREEBOOK_PAGE_CHANGED);
639 (void)GetEventHandler()->ProcessEvent(event);
640 }
641 else // page change vetoed
642 {
643 // tree selection might have already had changed
2ddb4d13 644 tree->SelectItem(DoInternalGetPage(oldSel));
eca15c0d
VZ
645 }
646
647 return oldSel;
648}
649
650void wxTreebook::SetImageList(wxImageList *imageList)
651{
652 wxBookCtrlBase::SetImageList(imageList);
2ddb4d13 653 GetTreeCtrl()->SetImageList(imageList);
eca15c0d
VZ
654}
655
656void wxTreebook::AssignImageList(wxImageList *imageList)
657{
658 wxBookCtrlBase::AssignImageList(imageList);
2ddb4d13 659 GetTreeCtrl()->SetImageList(imageList);
eca15c0d
VZ
660}
661
662// ----------------------------------------------------------------------------
663// event handlers
664// ----------------------------------------------------------------------------
665
666void wxTreebook::OnTreeSelectionChange(wxTreeEvent& event)
667{
668 wxTreeItemId newId = event.GetItem();
669
670 if ( (m_selection == wxNOT_FOUND &&
2ddb4d13 671 (!newId.IsOk() || newId == GetTreeCtrl()->GetRootItem())) ||
eca15c0d
VZ
672 (m_selection != wxNOT_FOUND && newId == m_treeIds[m_selection]) )
673 {
674 // this event can only come when we modify the tree selection ourselves
675 // so we should simply ignore it
676 return;
677 }
678
679 int newPos = DoInternalFindPageById(newId);
680
681 if ( newPos != wxNOT_FOUND )
682 SetSelection( newPos );
683}
684
685void wxTreebook::OnTreeNodeExpandedCollapsed(wxTreeEvent & event)
686{
687 wxTreeItemId nodeId = event.GetItem();
2ddb4d13 688 if ( !nodeId.IsOk() || nodeId == GetTreeCtrl()->GetRootItem() )
eca15c0d
VZ
689 return;
690 int pagePos = DoInternalFindPageById(nodeId);
691 wxCHECK_RET( pagePos != wxNOT_FOUND, wxT("Internal problem in wxTreebook!..") );
692
2ddb4d13 693 wxTreebookEvent ev(GetTreeCtrl()->IsExpanded(nodeId)
eca15c0d
VZ
694 ? wxEVT_COMMAND_TREEBOOK_NODE_EXPANDED
695 : wxEVT_COMMAND_TREEBOOK_NODE_COLLAPSED,
696 m_windowId);
697
698 ev.SetSelection(pagePos);
699 ev.SetOldSelection(pagePos);
700 ev.SetEventObject(this);
701
702 GetEventHandler()->ProcessEvent(ev);
703}
704
705// ----------------------------------------------------------------------------
706// wxTreebook geometry management
707// ----------------------------------------------------------------------------
708
eca15c0d
VZ
709wxTreebookPage * wxTreebook::DoGetCurrentPage() const
710{
711 if ( m_selection == wxNOT_FOUND )
712 return NULL;
713
714 wxTreebookPage *page = wxBookCtrlBase::GetPage(m_selection);
715 if ( !page && m_actualSelection != wxNOT_FOUND )
716 {
717 page = wxBookCtrlBase::GetPage(m_actualSelection);
718 }
719
720 return page;
721}
722
723#endif // wxUSE_TREEBOOK