[Date Prev][Date Next][Thread Prev][Thread Next][Thread Index]

[XaraXtreme-commits] Commit Complete



Commit by  : alex
Repository : xara
Revision   : 1188
Date       : Thu May 25 13:53:53 BST 2006

Changed paths:
   M /Trunk/XaraLX/Kernel/appprefs.h
   M /Trunk/XaraLX/wxOil/camresource.cpp
   M /Trunk/XaraLX/wxOil/dlgmgr.cpp
   M /Trunk/XaraLX/wxXtra/Makefile.am
   A /Trunk/XaraLX/wxXtra/treebook.cpp
   A /Trunk/XaraLX/wxXtra/treebook.h
   M /Trunk/XaraLX/wxXtra/wxXtra.h
   A /Trunk/XaraLX/wxXtra/xh_treebk.cpp
   A /Trunk/XaraLX/wxXtra/xh_treebk.h

Backport wxTreebook to 2.6

Use a wxTreeBook instead of an wxListBook in the options dialog


Diff:
Index: Trunk/XaraLX/Kernel/appprefs.h
===================================================================
--- Trunk/XaraLX/Kernel/appprefs.h	(revision 1187)
+++ Trunk/XaraLX/Kernel/appprefs.h	(revision 1188)
@@ -172,7 +172,7 @@
 	BOOL CommitDialogValues();
 
 	BOOL HasImages() {return TRUE;}
-	TabType GetTabType() {return TABTYPE_LIST;}
+	TabType GetTabType() {return TABTYPE_TREE/*TABTYPE_LIST*/;}
 
 private:
 	String_256 TitleString;					// title of dialog box
Index: Trunk/XaraLX/wxXtra/wxXtra.h
===================================================================
--- Trunk/XaraLX/wxXtra/wxXtra.h	(revision 1187)
+++ Trunk/XaraLX/wxXtra/wxXtra.h	(revision 1188)
@@ -15,3 +15,5 @@
 #include "odcombo.h"
 #include "platform.h"
 #include "advsplash.h"
+#include "treebook.h"
+#include "xh_treebk.h"
Index: Trunk/XaraLX/wxXtra/treebook.cpp
===================================================================
--- Trunk/XaraLX/wxXtra/treebook.cpp	(revision 0)
+++ Trunk/XaraLX/wxXtra/treebook.cpp	(revision 1188)
@@ -0,0 +1,861 @@
+// $Id: treebook.cpp 1089 2006-05-16 17:57:54Z alex $
+/* @@tag:xara-cn-tp@@ THIRD PARTY COPYRIGHT */
+// The following line makes normalize.pl skip type fixing
+/* SKIPFIXTYPES: START */
+
+///////////////////////////////////////////////////////////////////////////////
+// Name:        src/generic/treebkg.cpp
+// Purpose:     generic implementation of wxTreebook
+// Author:      Evgeniy Tarassov, Vadim Zeitlin
+// Modified by:
+// Created:     2005-09-15
+// RCS-ID:      $Id: treebkg.cpp,v 1.7 2006/05/03 00:42:33 VZ Exp $
+// Copyright:   (c) 2005 Vadim Zeitlin <vadim@xxxxxxxxxxxxx>
+// Licence:     wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#include "treebook.h"
+#if wxXTRA_TREEBOOK
+
+#include <wx/imaglist.h>
+#include <wx/settings.h>
+
+// ----------------------------------------------------------------------------
+// various wxWidgets macros
+// ----------------------------------------------------------------------------
+
+// check that the page index is valid
+#define IS_VALID_PAGE(nPage) ((nPage) < DoInternalGetPageCount())
+
+// ----------------------------------------------------------------------------
+// event table
+// ----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxTreebook, wxBookCtrlBase)
+IMPLEMENT_DYNAMIC_CLASS(wxTreebookEvent, wxNotifyEvent)
+
+#if !WXWIN_COMPATIBILITY_EVENT_TYPES
+const wxEventType wxEVT_COMMAND_TREEBOOK_PAGE_CHANGING = wxNewEventType();
+const wxEventType wxEVT_COMMAND_TREEBOOK_PAGE_CHANGED = wxNewEventType();
+const wxEventType wxEVT_COMMAND_TREEBOOK_NODE_COLLAPSED = wxNewEventType();
+const wxEventType wxEVT_COMMAND_TREEBOOK_NODE_EXPANDED = wxNewEventType();
+#endif
+const int wxID_TREEBOOKTREEVIEW = wxNewId();
+
+BEGIN_EVENT_TABLE(wxTreebook, wxBookCtrlBase)
+    EVT_TREE_SEL_CHANGED   (wxID_TREEBOOKTREEVIEW, wxTreebook::OnTreeSelectionChange)
+    EVT_TREE_ITEM_EXPANDED (wxID_TREEBOOKTREEVIEW, wxTreebook::OnTreeNodeExpandedCollapsed)
+    EVT_TREE_ITEM_COLLAPSED(wxID_TREEBOOKTREEVIEW, wxTreebook::OnTreeNodeExpandedCollapsed)
+    EVT_SIZE(wxTreebook::OnSize)
+END_EVENT_TABLE()
+
+// ============================================================================
+// wxTreebook implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxTreebook creation
+// ----------------------------------------------------------------------------
+
+void wxTreebook::Init()
+{
+    m_bookctrl = NULL;
+    m_selection =
+    m_actualSelection = wxNOT_FOUND;
+#if defined(__WXWINCE__)
+    m_internalBorder = 1;
+#else
+    m_internalBorder = 5;
+#endif
+
+}
+
+bool
+wxTreebook::Create(wxWindow *parent,
+                   wxWindowID id,
+                   const wxPoint& pos,
+                   const wxSize& size,
+                   long style,
+                   const wxString& name)
+{
+    // Check the style flag to have either wxTBK_RIGHT or wxTBK_LEFT
+    if ( (style & wxBK_ALIGN_MASK ) == wxBK_DEFAULT )
+    {
+        style |= wxBK_LEFT;
+    }
+
+    // no border for this control, it doesn't look nice together with the tree
+    style &= ~wxBORDER_MASK;
+    style |= wxBORDER_NONE;
+
+    if ( !wxControl::Create(parent, id, pos, size,
+                            style, wxDefaultValidator, name) )
+        return false;
+
+    m_bookctrl = new wxTreeCtrl
+                 (
+                    this,
+                    wxID_TREEBOOKTREEVIEW,
+                    wxDefaultPosition,
+                    wxDefaultSize,
+                    wxBORDER_SIMPLE |
+                    wxTR_DEFAULT_STYLE |
+                    wxTR_HIDE_ROOT |
+                    wxTR_SINGLE
+                 );
+    GetTreeCtrl()->AddRoot(wxEmptyString); // label doesn't matter, it's hidden
+
+#ifdef __WXMSW__
+    // We need to add dummy size event to force possible scrollbar hiding
+    wxSizeEvent evt;
+    GetEventHandler()->AddPendingEvent(evt);
+#endif
+
+    return true;
+}
+
+
+// insert a new page just before the pagePos
+bool wxTreebook::InsertPage(size_t pagePos,
+                            wxWindow *page,
+                            const wxString& text,
+                            bool bSelect,
+                            int imageId)
+{
+    return DoInsertPage(pagePos, page, text, bSelect, imageId);
+}
+
+bool wxTreebook::InsertSubPage(size_t pagePos,
+                               wxWindow *page,
+                               const wxString& text,
+                               bool bSelect,
+                               int imageId)
+{
+    return DoInsertSubPage(pagePos, page, text, bSelect, imageId);
+}
+
+bool wxTreebook::AddPage(wxWindow *page, const wxString& text, bool bSelect,
+                         int imageId)
+{
+    return DoInsertPage(m_treeIds.GetCount(), page, text, bSelect, imageId);
+}
+
+// insertion time is linear to the number of top-pages
+bool wxTreebook::AddSubPage(wxWindow *page, const wxString& text, bool bSelect, int imageId)
+{
+    return DoAddSubPage(page, text, bSelect, imageId);
+}
+
+
+bool wxTreebook::DoInsertPage(size_t pagePos,
+                              wxWindow *page,
+                              const wxString& text,
+                              bool bSelect,
+                              int imageId)
+{
+    wxCHECK_MSG( pagePos <= DoInternalGetPageCount(), false,
+                        wxT("Invalid treebook page position") );
+
+    if ( !wxBookCtrlBase::InsertPage(pagePos, page, text, bSelect, imageId) )
+        return false;
+
+    wxTreeCtrl *tree = GetTreeCtrl();
+    wxTreeItemId newId;
+    if ( pagePos == DoInternalGetPageCount() )
+    {
+        // append the page to the end
+        wxTreeItemId rootId = tree->GetRootItem();
+
+        newId = tree->AppendItem(rootId, text, imageId);
+    }
+    else // insert the new page before the given one
+    {
+        wxTreeItemId nodeId = m_treeIds[pagePos];
+
+        wxTreeItemId previousId = tree->GetPrevSibling(nodeId);
+        wxTreeItemId parentId = tree->GetItemParent(nodeId);
+
+        if ( previousId.IsOk() )
+        {
+            // insert before the sibling - previousId
+            newId = tree->InsertItem(parentId, previousId, text, imageId);
+        }
+        else // no prev siblings -- insert as a first child
+        {
+            wxASSERT_MSG( parentId.IsOk(), wxT( "Tree has no root node?" ) );
+
+            newId = tree->PrependItem(parentId, text, imageId);
+        }
+    }
+
+    if ( !newId.IsOk() )
+    {
+        //something wrong -> cleaning and returning with false
+        (void)wxBookCtrlBase::DoRemovePage(pagePos);
+
+        wxFAIL_MSG( wxT("Failed to insert treebook page") );
+        return false;
+    }
+
+    DoInternalAddPage(pagePos, page, newId);
+
+    DoUpdateSelection(bSelect, pagePos);
+
+    return true;
+}
+
+bool wxTreebook::DoAddSubPage(wxWindow *page, const wxString& text, bool bSelect, int imageId)
+{
+    wxTreeCtrl *tree = GetTreeCtrl();
+
+    wxTreeItemId rootId = tree->GetRootItem();
+
+    wxTreeItemId lastNodeId = tree->GetLastChild(rootId);
+
+    wxCHECK_MSG( lastNodeId.IsOk(), false,
+                        _T("Can't insert sub page when there are no pages") );
+
+    // now calculate its position (should we save/update it too?)
+    size_t newPos = tree->GetCount() -
+                        (tree->GetChildrenCount(lastNodeId, true) + 1);
+
+    return DoInsertSubPage(newPos, page, text, bSelect, imageId);
+}
+
+bool wxTreebook::DoInsertSubPage(size_t pagePos,
+                                 wxTreebookPage *page,
+                                 const wxString& text,
+                                 bool bSelect,
+                                 int imageId)
+{
+    wxTreeItemId parentId = DoInternalGetPage(pagePos);
+    wxCHECK_MSG( parentId.IsOk(), false, wxT("invalid tree item") );
+
+    wxTreeCtrl *tree = GetTreeCtrl();
+
+    size_t newPos = pagePos + tree->GetChildrenCount(parentId, true) + 1;
+    wxASSERT_MSG( newPos <= DoInternalGetPageCount(),
+                    wxT("Internal error in tree insert point calculation") );
+
+    if ( !wxBookCtrlBase::InsertPage(newPos, page, text, bSelect, imageId) )
+        return false;
+
+    wxTreeItemId newId = tree->AppendItem(parentId, text, imageId);
+
+    if ( !newId.IsOk() )
+    {
+        (void)wxBookCtrlBase::DoRemovePage(newPos);
+
+        wxFAIL_MSG( wxT("Failed to insert treebook page") );
+        return false;
+    }
+
+    DoInternalAddPage(newPos, page, newId);
+
+    DoUpdateSelection(bSelect, newPos);
+
+    return true;
+}
+
+bool wxTreebook::DeletePage(size_t pagePos)
+{
+    wxCHECK_MSG( IS_VALID_PAGE(pagePos), false, wxT("Invalid tree index") );
+
+    wxTreebookPage *oldPage = DoRemovePage(pagePos);
+    if ( !oldPage )
+        return false;
+
+    delete oldPage;
+
+    return true;
+}
+
+wxTreebookPage *wxTreebook::DoRemovePage(size_t pagePos)
+{
+    wxTreeItemId pageId = DoInternalGetPage(pagePos);
+    wxCHECK_MSG( pageId.IsOk(), NULL, wxT("Invalid tree index") );
+
+    wxTreebookPage * oldPage = GetPage(pagePos);
+    wxTreeCtrl *tree = GetTreeCtrl();
+
+    size_t subCount = tree->GetChildrenCount(pageId, true);
+    wxASSERT_MSG ( IS_VALID_PAGE(pagePos + subCount),
+                        wxT("Internal error in wxTreebook::DoRemovePage") );
+
+    // here we are going to delete ALL the pages in the range
+    // [pagePos, pagePos + subCount] -- the page and its children
+
+    // deleting all the pages from the base class
+    for ( size_t i = 0; i <= subCount; ++i )
+    {
+        wxTreebookPage *page = wxBookCtrlBase::DoRemovePage(pagePos);
+
+        // don't delete the page itself though -- it will be deleted in
+        // DeletePage() when we return
+        if ( i )
+        {
+            delete page;
+        }
+    }
+
+    DoInternalRemovePageRange(pagePos, subCount);
+
+    tree->DeleteChildren( pageId );
+    tree->Delete( pageId );
+
+    return oldPage;
+}
+
+bool wxTreebook::DeleteAllPages()
+{
+    wxBookCtrlBase::DeleteAllPages();
+    m_treeIds.Clear();
+    m_selection =
+    m_actualSelection = wxNOT_FOUND;
+
+    wxTreeCtrl *tree = GetTreeCtrl();
+    tree->DeleteChildren(tree->GetRootItem());
+
+    return true;
+}
+
+void wxTreebook::DoInternalAddPage(size_t newPos,
+                                   wxTreebookPage *page,
+                                   wxTreeItemId pageId)
+{
+    wxASSERT_MSG( newPos <= m_treeIds.GetCount(), wxT("Ivalid index passed to wxTreebook::DoInternalAddPage") );
+
+    // hide newly inserted page initially (it will be shown when selected)
+    if ( page )
+        page->Hide();
+
+    if ( newPos == m_treeIds.GetCount() )
+    {
+        // append
+        m_treeIds.Add(pageId);
+    }
+    else // insert
+    {
+        m_treeIds.Insert(pageId.m_pItem, newPos);
+
+        if ( m_selection != wxNOT_FOUND && newPos <= (size_t)m_selection )
+        {
+            // selection has been moved one unit toward the end
+            ++m_selection;
+            if ( m_actualSelection != wxNOT_FOUND )
+                ++m_actualSelection;
+        }
+        else if ( m_actualSelection != wxNOT_FOUND &&
+                    newPos <= (size_t)m_actualSelection )
+        {
+            DoSetSelection(m_selection);
+        }
+    }
+}
+
+void wxTreebook::DoInternalRemovePageRange(size_t pagePos, size_t subCount)
+{
+    // Attention: this function is only for a situation when we delete a node
+    // with all its children so pagePos is the node's index and subCount is the
+    // node children count
+    wxASSERT_MSG( pagePos + subCount < m_treeIds.GetCount(),
+                    wxT("Ivalid page index") );
+
+    wxTreeItemId pageId = m_treeIds[pagePos];
+
+    m_treeIds.RemoveAt(pagePos, subCount + 1);
+
+    if ( m_selection != wxNOT_FOUND )
+    {
+        if ( (size_t)m_selection > pagePos + subCount)
+        {
+            // selection is far after the deleted page, so just update the index and move on
+            m_selection -= 1 + subCount;
+            if ( m_actualSelection != wxNOT_FOUND)
+            {
+                m_actualSelection -= subCount + 1;
+            }
+        }
+        else if ( (size_t)m_selection >= pagePos )
+        {
+            wxTreeCtrl *tree = GetTreeCtrl();
+
+            // as selected page is going to be deleted, try to select the next
+            // sibling if exists, if not then the parent
+            wxTreeItemId nodeId = tree->GetNextSibling(pageId);
+
+            m_selection = wxNOT_FOUND;
+            m_actualSelection = wxNOT_FOUND;
+
+            if ( nodeId.IsOk() )
+            {
+                // selecting next siblings
+                tree->SelectItem(nodeId);
+            }
+            else // no next sibling, select the parent
+            {
+                wxTreeItemId parentId = tree->GetItemParent(pageId);
+
+                if ( parentId.IsOk() && parentId != tree->GetRootItem() )
+                {
+                    tree->SelectItem(parentId);
+                }
+                else // parent is root
+                {
+                    // we can't select it as it's hidden
+                    DoUpdateSelection(false, wxNOT_FOUND);
+                }
+            }
+        }
+        else if ( m_actualSelection != wxNOT_FOUND &&
+                    (size_t)m_actualSelection >= pagePos )
+        {
+            // nothing to do -- selection is before the deleted node, but
+            // actually shown page (the first (sub)child with page != NULL) is
+            // already deleted
+            m_actualSelection = m_selection;
+            DoSetSelection(m_selection);
+        }
+        //else: nothing to do -- selection is before the deleted node
+    }
+    else
+    {
+        DoUpdateSelection(false, wxNOT_FOUND);
+    }
+}
+
+
+void wxTreebook::DoUpdateSelection(bool bSelect, int newPos)
+{
+    int newSelPos;
+    if ( bSelect )
+    {
+        newSelPos = newPos;
+    }
+    else if ( m_selection == wxNOT_FOUND && DoInternalGetPageCount() > 0 )
+    {
+        newSelPos = 0;
+    }
+    else
+    {
+        newSelPos = wxNOT_FOUND;
+    }
+
+    if ( newSelPos != wxNOT_FOUND )
+    {
+        SetSelection((size_t)newSelPos);
+    }
+}
+
+wxTreeItemId wxTreebook::DoInternalGetPage(size_t pagePos) const
+{
+    if ( pagePos >= m_treeIds.GetCount() )
+    {
+        // invalid position but ok here, in this internal function, don't assert
+        // (the caller will do it)
+        return wxTreeItemId();
+    }
+
+    return m_treeIds[pagePos];
+}
+
+int wxTreebook::DoInternalFindPageById(wxTreeItemId pageId) const
+{
+    const size_t count = m_treeIds.GetCount();
+    for ( size_t i = 0; i < count; ++i )
+    {
+        if ( m_treeIds[i] == pageId )
+            return i;
+    }
+
+    return wxNOT_FOUND;
+}
+
+bool wxTreebook::IsNodeExpanded(size_t pagePos) const
+{
+    wxTreeItemId pageId = DoInternalGetPage(pagePos);
+
+    wxCHECK_MSG( pageId.IsOk(), false, wxT("invalid tree item") );
+
+    return GetTreeCtrl()->IsExpanded(pageId);
+}
+
+bool wxTreebook::ExpandNode(size_t pagePos, bool expand)
+{
+    wxTreeItemId pageId = DoInternalGetPage(pagePos);
+
+    wxCHECK_MSG( pageId.IsOk(), false, wxT("invalid tree item") );
+
+    if ( expand )
+    {
+        GetTreeCtrl()->Expand( pageId );
+    }
+    else // collapse
+    {
+        GetTreeCtrl()->Collapse( pageId );
+
+        // rely on the events generated by wxTreeCtrl to update selection
+    }
+
+    return true;
+}
+
+int wxTreebook::GetPageParent(size_t pagePos) const
+{
+    wxTreeItemId nodeId = DoInternalGetPage( pagePos );
+    wxCHECK_MSG( nodeId.IsOk(), wxNOT_FOUND, wxT("Invalid page index spacified!") );
+
+    const wxTreeItemId parent = GetTreeCtrl()->GetItemParent( nodeId );
+
+    return parent.IsOk() ? DoInternalFindPageById(parent) : wxNOT_FOUND;
+}
+
+bool wxTreebook::SetPageText(size_t n, const wxString& strText)
+{
+    wxTreeItemId pageId = DoInternalGetPage(n);
+
+    wxCHECK_MSG( pageId.IsOk(), false, wxT("invalid tree item") );
+
+    GetTreeCtrl()->SetItemText(pageId, strText);
+
+    return true;
+}
+
+wxString wxTreebook::GetPageText(size_t n) const
+{
+    wxTreeItemId pageId = DoInternalGetPage(n);
+
+    wxCHECK_MSG( pageId.IsOk(), wxString(), wxT("invalid tree item") );
+
+    return GetTreeCtrl()->GetItemText(pageId);
+}
+
+int wxTreebook::GetPageImage(size_t n) const
+{
+    wxTreeItemId pageId = DoInternalGetPage(n);
+
+    wxCHECK_MSG( pageId.IsOk(), wxNOT_FOUND, wxT("invalid tree item") );
+
+    return GetTreeCtrl()->GetItemImage(pageId);
+}
+
+bool wxTreebook::SetPageImage(size_t n, int imageId)
+{
+    wxTreeItemId pageId = DoInternalGetPage(n);
+
+    wxCHECK_MSG( pageId.IsOk(), false, wxT("invalid tree item") );
+
+    GetTreeCtrl()->SetItemImage(pageId, imageId);
+
+    return true;
+}
+
+wxSize wxTreebook::CalcSizeFromPage(const wxSize& sizePage) const
+{
+    const wxSize sizeTree = GetControllerSize();
+
+    wxSize size = sizePage;
+    size.x += sizeTree.x;
+
+    return size;
+}
+
+int wxTreebook::GetSelection() const
+{
+   return m_selection;
+}
+
+int wxTreebook::SetSelection(size_t pagePos)
+{
+   if ( (size_t)m_selection != pagePos )
+       return DoSetSelection(pagePos);
+
+   return m_selection;
+}
+
+int wxTreebook::DoSetSelection(size_t pagePos)
+{
+    wxCHECK_MSG( IS_VALID_PAGE(pagePos), wxNOT_FOUND,
+                 wxT("invalid page index in wxListbook::SetSelection()") );
+    wxASSERT_MSG( GetPageCount() == DoInternalGetPageCount(),
+                  wxT("wxTreebook logic error: m_treeIds and m_pages not in sync!"));
+
+    const int oldSel = m_selection;
+    wxTreeCtrl *tree = GetTreeCtrl();
+
+    wxTreebookEvent event(wxEVT_COMMAND_TREEBOOK_PAGE_CHANGING, m_windowId);
+    event.SetEventObject(this);
+    event.SetSelection(pagePos);
+    event.SetOldSelection(m_selection);
+
+    // don't send the event if the old and new pages are the same; do send it
+    // otherwise and be prepared for it to be vetoed
+    if ( (int)pagePos == m_selection ||
+            !GetEventHandler()->ProcessEvent(event) ||
+                event.IsAllowed() )
+    {
+        // hide the previously shown page
+        wxTreebookPage * const oldPage = DoGetCurrentPage();
+        if ( oldPage )
+            oldPage->Hide();
+
+        // then show the new one
+        m_selection = pagePos;
+        wxTreebookPage *page = wxBookCtrlBase::GetPage(m_selection);
+        if ( !page )
+        {
+            // find the next page suitable to be shown: the first (grand)child
+            // of this one with a non-NULL associated page
+            wxTreeItemId childId = m_treeIds[pagePos];
+            int actualPagePos = pagePos;
+            while ( !page && childId.IsOk() )
+            {
+                wxTreeItemIdValue cookie;
+                childId = tree->GetFirstChild( childId, cookie );
+                if ( childId.IsOk() )
+                {
+                    page = wxBookCtrlBase::GetPage(++actualPagePos);
+                }
+            }
+
+            m_actualSelection = page ? actualPagePos : m_selection;
+        }
+
+        if ( page )
+            page->Show();
+
+        tree->SelectItem(DoInternalGetPage(pagePos));
+
+        // notify about the (now completed) page change
+        event.SetEventType(wxEVT_COMMAND_TREEBOOK_PAGE_CHANGED);
+        (void)GetEventHandler()->ProcessEvent(event);
+    }
+    else // page change vetoed
+    {
+        // tree selection might have already had changed
+        tree->SelectItem(DoInternalGetPage(oldSel));
+    }
+
+    return oldSel;
+}
+
+void wxTreebook::SetImageList(wxImageList *imageList)
+{
+    wxBookCtrlBase::SetImageList(imageList);
+    GetTreeCtrl()->SetImageList(imageList);
+}
+
+void wxTreebook::AssignImageList(wxImageList *imageList)
+{
+    wxBookCtrlBase::AssignImageList(imageList);
+    GetTreeCtrl()->SetImageList(imageList);
+}
+
+// ----------------------------------------------------------------------------
+// event handlers
+// ----------------------------------------------------------------------------
+
+void wxTreebook::OnTreeSelectionChange(wxTreeEvent& event)
+{
+    wxTreeItemId newId = event.GetItem();
+
+    if ( (m_selection == wxNOT_FOUND &&
+                (!newId.IsOk() || newId == GetTreeCtrl()->GetRootItem())) ||
+            (m_selection != wxNOT_FOUND && newId == m_treeIds[m_selection]) )
+    {
+        // this event can only come when we modify the tree selection ourselves
+        // so we should simply ignore it
+        return;
+    }
+
+    int newPos = DoInternalFindPageById(newId);
+
+    if ( newPos != wxNOT_FOUND )
+        SetSelection( newPos );
+}
+
+void wxTreebook::OnTreeNodeExpandedCollapsed(wxTreeEvent & event)
+{
+    wxTreeItemId nodeId = event.GetItem();
+    if ( !nodeId.IsOk() || nodeId == GetTreeCtrl()->GetRootItem() )
+        return;
+    int pagePos = DoInternalFindPageById(nodeId);
+    wxCHECK_RET( pagePos != wxNOT_FOUND, wxT("Internal problem in wxTreebook!..") );
+
+    wxTreebookEvent ev(GetTreeCtrl()->IsExpanded(nodeId)
+            ? wxEVT_COMMAND_TREEBOOK_NODE_EXPANDED
+            : wxEVT_COMMAND_TREEBOOK_NODE_COLLAPSED,
+        m_windowId);
+
+    ev.SetSelection(pagePos);
+    ev.SetOldSelection(pagePos);
+    ev.SetEventObject(this);
+
+    GetEventHandler()->ProcessEvent(ev);
+}
+
+// ----------------------------------------------------------------------------
+// wxTreebook geometry management
+// ----------------------------------------------------------------------------
+
+wxTreebookPage * wxTreebook::DoGetCurrentPage()
+{
+    if ( m_selection == wxNOT_FOUND )
+        return NULL;
+
+    wxTreebookPage *page = wxBookCtrlBase::GetPage(m_selection);
+    if ( !page && m_actualSelection != wxNOT_FOUND )
+    {
+        page = wxBookCtrlBase::GetPage(m_actualSelection);
+    }
+
+    return page;
+}
+
+// Some routines from the base class
+
+
+// Lay out controls
+void wxTreebook::DoSize()
+{
+    if ( !m_bookctrl )
+    {
+        // we're not fully created yet or OnSize() should be hidden by derived class
+        return;
+    }
+
+    if (GetSizer())
+        Layout();
+    else
+    {
+        // resize controller and the page area to fit inside our new size
+        const wxSize sizeClient( GetClientSize() ),
+                    sizeBorder( m_bookctrl->GetSize() - m_bookctrl->GetClientSize() ),
+                    sizeCtrl( GetControllerSize() );
+
+        m_bookctrl->SetClientSize( sizeCtrl.x - sizeBorder.x, sizeCtrl.y - sizeBorder.y );
+
+        const wxSize sizeNew = m_bookctrl->GetSize();
+        wxPoint posCtrl;
+        switch ( GetWindowStyle() & wxBK_ALIGN_MASK )
+        {
+            default:
+                wxFAIL_MSG( _T("unexpected alignment") );
+                // fall through
+
+            case wxBK_TOP:
+            case wxBK_LEFT:
+                // posCtrl is already ok
+                break;
+
+            case wxBK_BOTTOM:
+                posCtrl.y = sizeClient.y - sizeNew.y;
+                break;
+
+            case wxBK_RIGHT:
+                posCtrl.x = sizeClient.x - sizeNew.x;
+                break;
+        }
+
+        if ( m_bookctrl->GetPosition() != posCtrl )
+            m_bookctrl->Move(posCtrl);
+    }
+
+    // resize all pages to fit the new control size
+    const wxRect pageRect = GetPageRect();
+    const unsigned pagesCount = m_pages.Count();
+    for ( unsigned int i = 0; i < pagesCount; ++i )
+    {
+        wxWindow * const page = m_pages[i];
+        if ( !page )
+        {
+            wxASSERT_MSG( AllowNullPage(),
+                _T("Null page in a control that does not allow null pages?") );
+            continue;
+        }
+
+        page->SetSize(pageRect);
+    }
+}
+
+void wxTreebook::OnSize(wxSizeEvent& event)
+{
+    m_bookctrl->InvalidateBestSize();
+    m_bookctrl->SetSize(m_bookctrl->GetBestSize());
+
+    event.Skip();
+
+    DoSize();
+}
+
+wxSize wxTreebook::GetControllerSize() const
+{
+    if(!m_bookctrl)
+        return wxSize(0,0);
+
+    wxSize cbestsize = m_bookctrl->GetBestSize();
+
+    cbestsize.SetWidth(200); // ***BODGE FOR OPTIONS DIALOG***
+
+    wxSize sizeClient = GetClientSize(),
+                 sizeBorder = m_bookctrl->GetSize() - m_bookctrl->GetClientSize(),
+                 sizeCtrl =  cbestsize + sizeBorder;
+
+    wxSize size;
+
+    if ( HasFlag(wxBK_BOTTOM | wxBK_TOP) )
+    {
+        size.x = sizeClient.x;
+        size.y = sizeCtrl.y;
+    }
+    else // left/right aligned
+    {
+        size.x = sizeCtrl.x;
+        size.y = sizeClient.y;
+    }
+
+    return size;
+}
+
+wxRect wxTreebook::GetPageRect() const
+{
+    const wxSize size = GetControllerSize();
+
+    wxPoint pt;
+    wxRect rectPage(pt, GetClientSize());
+    switch ( GetWindowStyle() & wxBK_ALIGN_MASK )
+    {
+        default:
+            wxFAIL_MSG( _T("unexpected alignment") );
+            // fall through
+
+        case wxBK_TOP:
+            rectPage.y = size.y + GetInternalBorder();
+            // fall through
+
+        case wxBK_BOTTOM:
+            rectPage.height -= size.y + GetInternalBorder();
+            break;
+
+        case wxBK_LEFT:
+            rectPage.x = size.x + GetInternalBorder();
+            // fall through
+
+        case wxBK_RIGHT:
+            rectPage.width -= size.x + GetInternalBorder();
+            break;
+    }
+
+    return rectPage;
+}
+
+
+#endif // wxXTRA_TREEBOOK
Index: Trunk/XaraLX/wxXtra/xh_treebk.cpp
===================================================================
--- Trunk/XaraLX/wxXtra/xh_treebk.cpp	(revision 0)
+++ Trunk/XaraLX/wxXtra/xh_treebk.cpp	(revision 1188)
@@ -0,0 +1,140 @@
+// $Id: xh_treebook.cpp 1089 2006-05-16 17:57:54Z alex $
+/* @@tag:xara-cn-tp@@ THIRD PARTY COPYRIGHT */
+// The following line makes normalize.pl skip type fixing
+/* SKIPFIXTYPES: START */
+
+/////////////////////////////////////////////////////////////////////////////
+// Name:        src/xrc/xh_treebk.cpp
+// Purpose:     XRC resource handler for wxTreebook
+// Author:      Evgeniy Tarassov
+// Created:     2005/09/28
+// RCS-ID:      $Id: xh_treebk.cpp,v 1.5 2006/04/26 08:21:31 ABX Exp $
+// Copyright:   (c) 2005 TT-Solutions <vadim@xxxxxxxxxxxxxxxx>
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+// For compilers that support precompilation, includes "wx.h".
+
+#include "treebook.h"
+
+#if wxUSE_XRC && wxXTRA_TREEBOOK
+
+#include "xh_treebk.h"
+
+#include <wx/log.h>
+
+#include <wx/imaglist.h>
+
+IMPLEMENT_DYNAMIC_CLASS(wxTreebookXmlHandler, wxXmlResourceHandler)
+
+wxTreebookXmlHandler::wxTreebookXmlHandler()
+                    : wxXmlResourceHandler(),
+                      m_tbk(NULL),
+                      m_isInside(false)
+{
+    XRC_ADD_STYLE(wxBK_DEFAULT);
+    XRC_ADD_STYLE(wxBK_TOP);
+    XRC_ADD_STYLE(wxBK_BOTTOM);
+    XRC_ADD_STYLE(wxBK_LEFT);
+    XRC_ADD_STYLE(wxBK_RIGHT);
+
+    AddWindowStyles();
+}
+
+bool wxTreebookXmlHandler::CanHandle(wxXmlNode *node)
+{
+    return ((!m_isInside && IsOfClass(node, wxT("wxTreebook"))) ||
+            (m_isInside && IsOfClass(node, wxT("treebookpage"))));
+}
+
+
+wxObject *wxTreebookXmlHandler::DoCreateResource()
+{
+    if (m_class == wxT("wxTreebook"))
+    {
+        XRC_MAKE_INSTANCE(tbk, wxTreebook)
+
+        tbk->Create(m_parentAsWindow,
+                    GetID(),
+                    GetPosition(), GetSize(),
+                    GetStyle(wxT("style")),
+                    GetName());
+
+        wxTreebook * old_par = m_tbk;
+        m_tbk = tbk;
+
+        bool old_ins = m_isInside;
+        m_isInside = true;
+
+        wxArrayTbkPageIndexes old_treeContext = m_treeContext;
+        m_treeContext.Clear();
+
+        CreateChildren(m_tbk, true/*only this handler*/);
+
+        m_treeContext = old_treeContext;
+        m_isInside = old_ins;
+        m_tbk = old_par;
+
+        return tbk;
+    }
+
+//    else ( m_class == wxT("treebookpage") )
+    wxXmlNode *n = GetParamNode(wxT("object"));
+    wxWindow *wnd = NULL;
+
+    if ( !n )
+        n = GetParamNode(wxT("object_ref"));
+
+    if (n)
+    {
+        bool old_ins = m_isInside;
+        m_isInside = false;
+        wxObject *item = CreateResFromNode(n, m_tbk, NULL);
+        m_isInside = old_ins;
+        wnd = wxDynamicCast(item, wxWindow);
+
+        if (wnd == NULL && item != NULL)
+            wxLogError(wxT("Error in resource: control within treebook's <page> tag is not a window."));
+    }
+
+    size_t depth = GetLong( wxT("depth") );
+
+    if( depth <= m_treeContext.Count() )
+    {
+        // first prepare the icon
+        int imgIndex = wxNOT_FOUND;
+        if ( HasParam(wxT("bitmap")) )
+        {
+            wxBitmap bmp = GetBitmap(wxT("bitmap"), wxART_OTHER);
+            wxImageList *imgList = m_tbk->GetImageList();
+            if ( imgList == NULL )
+            {
+                imgList = new wxImageList( bmp.GetWidth(), bmp.GetHeight() );
+                m_tbk->AssignImageList( imgList );
+            }
+            imgIndex = imgList->Add(bmp);
+        }
+
+        // then add the page to the corresponding parent
+        if( depth < m_treeContext.Count() )
+            m_treeContext.RemoveAt(depth, m_treeContext.Count() - depth );
+        if( depth == 0)
+        {
+            m_tbk->AddPage(wnd,
+                GetText(wxT("label")), GetBool(wxT("selected")), imgIndex);
+        }
+        else
+        {
+            m_tbk->InsertSubPage(m_treeContext.Item(depth - 1), wnd,
+                GetText(wxT("label")), GetBool(wxT("selected")), imgIndex);
+        }
+
+        m_treeContext.Add( m_tbk->GetPageCount() - 1);
+
+    }
+    else
+        wxLogError(wxT("Error in resource. wxTreebookPage has an invalid depth."));
+    return wnd;
+}
+
+#endif // wxUSE_XRC && wxUSE_TREEBOOK
Index: Trunk/XaraLX/wxXtra/treebook.h
===================================================================
--- Trunk/XaraLX/wxXtra/treebook.h	(revision 0)
+++ Trunk/XaraLX/wxXtra/treebook.h	(revision 1188)
@@ -0,0 +1,314 @@
+// $Id: treebook.h 1089 2006-05-16 17:57:54Z alex $
+/* @@tag:xara-cn-tp@@ THIRD PARTY COPYRIGHT */
+// The following line makes normalize.pl skip type fixing
+/* SKIPFIXTYPES: START */
+
+///////////////////////////////////////////////////////////////////////////////
+// Name:        wx/treebook.h
+// Purpose:     wxTreebook: wxNotebook-like control presenting pages in a tree
+// Author:      Evgeniy Tarassov, Vadim Zeitlin
+// Modified by:
+// Created:     2005-09-15
+// RCS-ID:      $Id: treebook.h,v 1.5 2006/02/08 21:44:23 VZ Exp $
+// Copyright:   (c) 2005 Vadim Zeitlin <vadim@xxxxxxxxxxxxx>
+// Licence:     wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WXXTRA_TREEBOOK_H_
+#define _WXXTRA_TREEBOOK_H_
+
+#include <wx/defs.h>
+
+#if wxUSE_TREEBOOK
+#define wxXTRA_TREEBOOK 0
+#else
+#define wxXTRA_TREEBOOK 1
+
+#include <wx/bookctrl.h>
+#include <wx/treectrl.h>        // for wxArrayTreeItemIds
+
+#define wxBK_TOP		wxBC_TOP
+#define wxBK_BOTTOM		wxBC_BOTTOM
+#define wxBK_LEFT		wxBC_LEFT
+#define wxBK_RIGHT		wxBC_RIGHT
+#define wxBK_DEFAULT	wxBC_DEFAULT
+#define wxBK_ALIGN_MASK	(wxBK_LEFT | wxBK_RIGHT | wxBK_TOP | wxBK_BOTTOM)
+
+class wxTreeCtrl;
+typedef wxWindow wxTreebookPage;
+
+class WXDLLEXPORT wxTreeEvent;
+
+// ----------------------------------------------------------------------------
+// wxTreebook
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxTreebook : public wxBookCtrlBase
+{
+public:
+    // Constructors and such
+    // ---------------------
+
+    // Default ctor doesn't create the control, use Create() afterwards
+    wxTreebook()
+    {
+        Init();
+    }
+
+    // This ctor creates the tree book control
+    wxTreebook(wxWindow *parent,
+               wxWindowID id,
+               const wxPoint& pos = wxDefaultPosition,
+               const wxSize& size = wxDefaultSize,
+               long style = wxBK_DEFAULT,
+               const wxString& name = wxEmptyString)
+    {
+        Init();
+
+        (void)Create(parent, id, pos, size, style, name);
+    }
+
+    // Really creates the control
+    bool Create(wxWindow *parent,
+                wxWindowID id,
+                const wxPoint& pos = wxDefaultPosition,
+                const wxSize& size = wxDefaultSize,
+                long style = wxBK_DEFAULT,
+                const wxString& name = wxEmptyString);
+
+
+    // Page insertion operations
+    // -------------------------
+
+    // Notice that page pointer may be NULL in which case the next non NULL
+    // page (usually the first child page of a node) is shown when this page is
+    // selected
+
+    // Inserts a new page just before the page indicated by page.
+    // The new page is placed on the same level as page.
+    virtual bool InsertPage(size_t pos,
+                            wxWindow *page,
+                            const wxString& text,
+                            bool bSelect = false,
+                            int imageId = wxNOT_FOUND);
+
+    // Inserts a new sub-page to the end of children of the page at given pos.
+    virtual bool InsertSubPage(size_t pos,
+                               wxWindow *page,
+                               const wxString& text,
+                               bool bSelect = false,
+                               int imageId = wxNOT_FOUND);
+
+    // Adds a new page at top level after all other pages.
+    virtual bool AddPage(wxWindow *page,
+                         const wxString& text,
+                         bool bSelect = false,
+                         int imageId = wxNOT_FOUND);
+
+    // Adds a new child-page to the last top-level page inserted.
+    // Useful when constructing 1 level tree structure.
+    virtual bool AddSubPage(wxWindow *page,
+                            const wxString& text,
+                            bool bSelect = false,
+                            int imageId = wxNOT_FOUND);
+
+    // Deletes the page and ALL its children. Could trigger page selection
+    // change in a case when selected page is removed. In that case its parent
+    // is selected (or the next page if no parent).
+    virtual bool DeletePage(size_t pos);
+
+
+    // Tree operations
+    // ---------------
+
+    // Gets the page node state -- node is expanded or collapsed
+    virtual bool IsNodeExpanded(size_t pos) const;
+
+    // Expands or collapses the page node. Returns the previous state.
+    // May generate page changing events (if selected page
+    // is under the collapsed branch, then parent is autoselected).
+    virtual bool ExpandNode(size_t pos, bool expand = true);
+
+    // shortcut for ExpandNode(pos, false)
+    bool CollapseNode(size_t pos) { return ExpandNode(pos, false); }
+
+    // get the parent page or wxNOT_FOUND if this is a top level page
+    int GetPageParent(size_t pos) const;
+
+    // the tree control we use for showing the pages index tree
+    wxTreeCtrl* GetTreeCtrl() const { return (wxTreeCtrl*)m_bookctrl; }
+
+
+    // Standard operations inherited from wxBookCtrlBase
+    // -------------------------------------------------
+
+    virtual int GetSelection() const;
+    virtual bool SetPageText(size_t n, const wxString& strText);
+    virtual wxString GetPageText(size_t n) const;
+    virtual int GetPageImage(size_t n) const;
+    virtual bool SetPageImage(size_t n, int imageId);
+    virtual wxSize CalcSizeFromPage(const wxSize& sizePage) const;
+    virtual int SetSelection(size_t n);
+    virtual void SetImageList(wxImageList *imageList);
+    virtual void AssignImageList(wxImageList *imageList);
+    virtual bool DeleteAllPages();
+
+protected:
+    // Implementation of a page removal. See DeletPage for comments.
+    wxTreebookPage *DoRemovePage(size_t pos);
+
+    // This subclass of wxBookCtrlBase accepts NULL page pointers (empty pages)
+    virtual bool AllowNullPage() const { return true; }
+
+    // event handlers
+    void OnTreeSelectionChange(wxTreeEvent& event);
+    void OnTreeNodeExpandedCollapsed(wxTreeEvent& event);
+
+    // array of page ids and page windows
+    wxArrayTreeItemIds m_treeIds;
+
+    // the currently selected page or wxNOT_FOUND if none
+    int m_selection;
+
+    // in the situation when m_selection page is not wxNOT_FOUND but page is
+    // NULL this is the first (sub)child that has a non-NULL page
+    int m_actualSelection;
+
+    // Some functions imported from the base class in 2.7
+    wxSize GetControllerSize() const;
+    virtual void DoSize();
+    void OnSize(wxSizeEvent& event);
+    wxRect GetPageRect() const;
+    // get/set size of area between book control area and page area
+    inline unsigned int GetInternalBorder() const
+    {
+        return m_internalBorder;
+    }
+    void SetInternalBorder(unsigned int internalBorder)
+    {
+        m_internalBorder = internalBorder;
+    }
+
+    unsigned int m_internalBorder;
+
+private:
+    // common part of all constructors
+    void Init();
+
+    // The real implementations of page insertion functions
+    // ------------------------------------------------------
+    // All DoInsert/Add(Sub)Page functions add the page into :
+    // - the base class
+    // - the tree control
+    // - update the index/TreeItemId corespondance array
+    bool DoInsertPage(size_t pos,
+                      wxWindow *page,
+                      const wxString& text,
+                      bool bSelect = false,
+                      int imageId = wxNOT_FOUND);
+    bool DoInsertSubPage(size_t pos,
+                         wxWindow *page,
+                         const wxString& text,
+                         bool bSelect = false,
+                         int imageId = wxNOT_FOUND);
+    bool DoAddSubPage(wxWindow *page,
+                         const wxString& text,
+                         bool bSelect = false,
+                         int imageId = wxNOT_FOUND);
+
+    // Sets selection in the tree control and updates the page being shown.
+    int DoSetSelection(size_t pos);
+
+    // Returns currently shown page. In a case when selected the node
+    // has empty (NULL) page finds first (sub)child with not-empty page.
+    wxTreebookPage *DoGetCurrentPage();
+
+    // Does the selection update. Called from page insertion functions
+    // to update selection if the selected page was pushed by the newly inserted
+    void DoUpdateSelection(bool bSelect, int page);
+
+
+    // Operations on the internal private members of the class
+    // -------------------------------------------------------
+    // Returns the page TreeItemId for the page.
+    // Or, if the page index is incorrect, a fake one (fakePage.IsOk() == false)
+    wxTreeItemId DoInternalGetPage(size_t pos) const;
+
+    // Linear search for a page with the id specified. If no page
+    // found wxNOT_FOUND is returned. The function is used when we catch an event
+    // from m_tree (wxTreeCtrl) component.
+    int DoInternalFindPageById(wxTreeItemId page) const;
+
+    // Updates page and wxTreeItemId correspondance.
+    void DoInternalAddPage(size_t newPos, wxWindow *page, wxTreeItemId pageId);
+
+    // Removes the page from internal structure.
+    void DoInternalRemovePage(size_t pos)
+        { DoInternalRemovePageRange(pos, 0); }
+
+    // Removes the page and all its children designated by subCount
+    // from internal structures of the control.
+    void DoInternalRemovePageRange(size_t pos, size_t subCount);
+
+    // Returns internal number of pages which can be different from
+    // GetPageCount() while performing a page insertion or removal.
+    size_t DoInternalGetPageCount() const { return m_treeIds.Count(); }
+
+
+    DECLARE_EVENT_TABLE()
+    DECLARE_DYNAMIC_CLASS_NO_COPY(wxTreebook)
+
+	wxTreeCtrl * m_bookctrl;
+};
+
+
+// ----------------------------------------------------------------------------
+// treebook event class and related stuff
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxTreebookEvent : public wxBookCtrlBaseEvent
+{
+public:
+    wxTreebookEvent(wxEventType commandType = wxEVT_NULL, int id = 0,
+                    int nSel = wxNOT_FOUND, int nOldSel = wxNOT_FOUND)
+        : wxBookCtrlBaseEvent(commandType, id, nSel, nOldSel)
+    {
+    }
+
+    wxTreebookEvent(const wxTreebookEvent& event)
+        : wxBookCtrlBaseEvent(event)
+    {
+    }
+
+    virtual wxEvent *Clone() const { return new wxTreebookEvent(*this); }
+
+private:
+    DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxTreebookEvent)
+};
+
+extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_TREEBOOK_PAGE_CHANGED;
+extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_TREEBOOK_PAGE_CHANGING;
+extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_TREEBOOK_NODE_COLLAPSED;
+extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_TREEBOOK_NODE_EXPANDED;
+
+typedef void (wxEvtHandler::*wxTreebookEventFunction)(wxTreebookEvent&);
+
+#define wxTreebookEventHandler(func) \
+    (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxTreebookEventFunction, &func)
+
+#define EVT_TREEBOOK_PAGE_CHANGED(winid, fn) \
+    wx__DECLARE_EVT1(wxEVT_COMMAND_TREEBOOK_PAGE_CHANGED, winid, wxTreebookEventHandler(fn))
+
+#define EVT_TREEBOOK_PAGE_CHANGING(winid, fn) \
+    wx__DECLARE_EVT1(wxEVT_COMMAND_TREEBOOK_PAGE_CHANGING, winid, wxTreebookEventHandler(fn))
+
+#define EVT_TREEBOOK_NODE_COLLAPSED(winid, fn) \
+    wx__DECLARE_EVT1(wxEVT_COMMAND_TREEBOOK_NODE_COLLAPSED, winid, wxTreebookEventHandler(fn))
+
+#define EVT_TREEBOOK_NODE_EXPANDED(winid, fn) \
+    wx__DECLARE_EVT1(wxEVT_COMMAND_TREEBOOK_NODE_EXPANDED, winid, wxTreebookEventHandler(fn))
+
+
+#endif // wxUSE_TREEBOOK
+
+#endif // _WX_TREEBOOK_H_
Index: Trunk/XaraLX/wxXtra/xh_treebk.h
===================================================================
--- Trunk/XaraLX/wxXtra/xh_treebk.h	(revision 0)
+++ Trunk/XaraLX/wxXtra/xh_treebk.h	(revision 1188)
@@ -0,0 +1,89 @@
+// $Id: xh_treebook.h 1089 2006-05-16 17:57:54Z alex $
+/* @@tag:xara-cn-tp@@ THIRD PARTY COPYRIGHT */
+// The following line makes normalize.pl skip type fixing
+/* SKIPFIXTYPES: START */
+
+/////////////////////////////////////////////////////////////////////////////
+// Name:        xh_treebk.h
+// Purpose:     XML resource handler for wxTreebook
+// Author:      Evgeniy Tarassov
+// Created:     2005/09/28
+// Copyright:   (c) 2005 TT-Solutions <vadim@xxxxxxxxxxxxxxxx>
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WXXTRA_XH_TREEBK_H_
+#define _WXXTRA_XH_TREEBK_H_
+
+#include "treebook.h"
+
+#if wxXTRA_TREEBOOK
+
+#include <wx/xrc/xmlres.h>
+#include <wx/dynarray.h>
+
+WX_DEFINE_USER_EXPORTED_ARRAY_SIZE_T(size_t, wxArrayTbkPageIndexes,
+                                     class WXDLLIMPEXP_XRC);
+
+// ---------------------------------------------------------------------
+// wxTreebookXmlHandler class
+// ---------------------------------------------------------------------
+// Resource xml structure have to be almost the "same" as for wxNotebook
+// except the additional (size_t)depth parameter for treebookpage nodes
+// which indicates the depth of the page in the tree.
+// There is only one logical constraint on this parameter :
+// it cannot be greater than the previous page depth plus one
+class WXDLLIMPEXP_XRC wxTreebookXmlHandler : public wxXmlResourceHandler
+{
+public:
+    wxTreebookXmlHandler();
+    virtual wxObject *DoCreateResource();
+    virtual bool CanHandle(wxXmlNode *node);
+
+private:
+    wxTreebook *m_tbk;
+    wxArrayTbkPageIndexes m_treeContext;
+    bool m_isInside;
+
+    DECLARE_DYNAMIC_CLASS(wxTreebookXmlHandler)
+};
+
+
+// Example:
+// -------
+// Label
+// \--First
+// |  \--Second
+// \--Third
+//
+//<resource>
+//  ...
+//  <object class="wxTreebook">
+//    <object class="treebookpage">
+//      <object class="wxWindow" />
+//      <label>My first page</label>
+//      <depth>0</depth>
+//    </object>
+//    <object class="treebookpage">
+//      <object class="wxWindow" />
+//      <label>First</label>
+//      <depth>1</depth>
+//    </object>
+//    <object class="treebookpage">
+//      <object class="wxWindow" />
+//      <label>Second</label>
+//      <depth>2</depth>
+//    </object>
+//    <object class="treebookpage">
+//      <object class="wxWindow" />
+//      <label>Third</label>
+//      <depth>1</depth>
+//    </object>
+//  </object>
+//  ...
+//</resource>
+
+#endif // wxXTRA_TREEBOOK
+
+#endif // _WX_XH_TREEBK_H_
+
Index: Trunk/XaraLX/wxXtra/Makefile.am
===================================================================
--- Trunk/XaraLX/wxXtra/Makefile.am	(revision 1187)
+++ Trunk/XaraLX/wxXtra/Makefile.am	(revision 1188)
@@ -8,7 +8,7 @@
 # the application source, library search path, and link libraries
 libwxXtra_a_SOURCES = \
 	manager.cpp wxmousestate.cpp doublebuffer.cpp cwfrompoint.cpp combo.cpp combog.cpp odcombo.cpp \
-	platform.cpp advsplash.cpp
+	platform.cpp advsplash.cpp treebook.cpp xh_treebk.cpp
 
 # make sure this does NOT have our include files in the path
 # Don't use GTK includes for now - you will need this with sub-2.6.3 but that's not supported
Index: Trunk/XaraLX/wxOil/camresource.cpp
===================================================================
--- Trunk/XaraLX/wxOil/camresource.cpp	(revision 1187)
+++ Trunk/XaraLX/wxOil/camresource.cpp	(revision 1188)
@@ -1439,7 +1439,10 @@
 	wxXmlResource::Get()->AddHandler(new wxOwnerDrawnComboBoxXmlHandler);
 	wxXmlResource::Get()->AddHandler(new wxComboControlXmlHandler);
 #endif
+#if WXXTRA_TREEBOOK
+	wxXmlResource::Get()->AddHandler(new wxTreebookXmlHandler);
 #endif
+#endif
 
 	if (!pwxFileSystem) pwxFileSystem = new wxFileSystem;
 	if (!pwxFileSystem)
Index: Trunk/XaraLX/wxOil/dlgmgr.cpp
===================================================================
--- Trunk/XaraLX/wxOil/dlgmgr.cpp	(revision 1187)
+++ Trunk/XaraLX/wxOil/dlgmgr.cpp	(revision 1188)
@@ -273,10 +273,15 @@
 				return new wxChoicebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, style );
 				break;
 #endif
-#if wxUSE_TREEBOOK
+#if wxUSE_TREEBOOK || wxXTRA_TREEBOOK
 			case TABTYPE_TREE:
 				return new wxTreebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, style );
 				break;
+#else
+			// Default to a ListBook if there is no treebook availables
+			case TABTYPE_TREE:
+				return new wxListbook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, style );
+				break;
 #endif
 #if wxUSE_TOOLBOOK
 			case TABTYPE_TOOLBAR:


Xara