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