]> Creatis software - bbtk.git/blobdiff - kernel/src/ThirdParty/wx/treemultictrl/wxTreeMultiCtrl.cpp
Works with visual studio 2009
[bbtk.git] / kernel / src / ThirdParty / wx / treemultictrl / wxTreeMultiCtrl.cpp
index 00cb190b502cc199a7487e0a05b9db9ca1972396..6a5c1579b4bea2fb2b23c630b60f84153f12851c 100644 (file)
-//---------------------------------------------------------------------------\r
-// $RCSfile: wxTreeMultiCtrl.cpp,v $\r
-// $Source: /cvs/creatis/bbtk/kernel/src/ThirdParty/wx/treemultictrl/wxTreeMultiCtrl.cpp,v $\r
-// $Revision: 1.1 $\r
-// $Date: 2008/03/28 13:42:19 $\r
-//---------------------------------------------------------------------------\r
-// Author:      Jorgen Bodde\r
-// Copyright:   (c) Jorgen Bodde\r
-// License:     wxWidgets License\r
-//---------------------------------------------------------------------------\r
-\r
-#ifdef __GNUG__\r
-    #pragma implementation "wxTreeMultiCtrl.h"\r
-#endif\r
-\r
-// For compilers that support precompilation, includes "wx/wx.h".\r
-#include "wx/wxprec.h"\r
-#include "wx/treebase.h"\r
-\r
-#ifdef __BORLANDC__\r
-    #pragma hdrstop\r
-#endif\r
-\r
-#include "wx/arrimpl.cpp"\r
-\r
-#include "wx/treemultictrl/wxTreeMultiCtrl.h"\r
-#include "wx/treemultictrl/wxTreeMultiEvent.h"\r
-#include "tmcimages.h"\r
-\r
-\r
-\r
-//----------------------------------------------------------------------------\r
-// wxTreeMultiItem\r
-//----------------------------------------------------------------------------\r
-\r
-WX_DEFINE_OBJARRAY(wxArrayTreeMultiItem);\r
-\r
-//----------------------------------------------------------------------------\r
-// wxTreeMultiCtrl\r
-//----------------------------------------------------------------------------\r
-\r
-IMPLEMENT_DYNAMIC_CLASS(wxTreeMultiCtrl, wxScrolledWindow)\r
-\r
-// WDR: event table for wxTreeMultiCtrl\r
-BEGIN_EVENT_TABLE(wxTreeMultiCtrl, wxScrolledWindow)\r
-  EVT_LEFT_DOWN  (wxTreeMultiCtrl::OnMouseClick)\r
-  EVT_LEFT_DCLICK(wxTreeMultiCtrl::OnMouseClick)\r
-  EVT_RIGHT_DOWN (wxTreeMultiCtrl::OnRightMouseClick)\r
-  EVT_PAINT(wxTreeMultiCtrl::OnPaint)\r
-  EVT_SIZE(wxTreeMultiCtrl::OnSize)\r
-//  EVT_KEY_UP(wxTreeMultiCtrl::OnKey)\r
-END_EVENT_TABLE()\r
-\r
-bool wxTreeMultiCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos,\r
-                               const wxSize& size, long style, const wxValidator & WXUNUSED(validator),\r
-                               const wxString& name )\r
-{\r
-    wxScrolledWindow::Create( parent, id, pos, size, style | wxTAB_TRAVERSAL, name);\r
-\r
-        _create_called = true;\r
-\r
-       // do the init\r
-       Init();\r
-\r
-    return TRUE;\r
-}\r
-\r
-void wxTreeMultiCtrl::Init()\r
-{\r
-       _root.Clear();\r
-\r
-       _expandBmp = 0;\r
-       _collBmp = 0;\r
-\r
-#if(CHECKBOXVIEW)\r
-       _checkBmp = 0;\r
-       _uncheckBmp = 0;\r
-       _tristateBmp = 0;\r
-\r
-       _checkHeight = 11;\r
-       _checkWidth = 11;\r
-\r
-       _checkboxView = false;\r
-#endif\r
-\r
-       _gutterWidth = WXTMC_GUTTER_DEFAULT;\r
-       _iconWidth = 11;\r
-       _iconHeight = 11;\r
-       _maxHeight = 1;;\r
-       _iconDeltaY = 2;\r
-       _spacingY = WXTMC_YSPACING_DEFAULT;\r
-       _captionHeight = 13;\r
-\r
-       // create two bitmap nodes for drawing\r
-\r
-       _expandBmp = new wxBitmap(expand_xpm);\r
-       _collBmp = new wxBitmap(collapse_xpm);\r
-\r
-       // calculate average font height for bitmap centering\r
-\r
-       _iconWidth = _expandBmp->GetWidth();\r
-       _iconHeight = _expandBmp->GetHeight();\r
-\r
-#if(CHECKBOXVIEW)\r
-       // create bitmaps for checkboxes\r
-       _checkBmp = new wxBitmap(checked_icon);\r
-       _uncheckBmp = new wxBitmap(unchecked_icon);\r
-       _tristateBmp = new wxBitmap(tristate_icon);\r
-\r
-       // adjust the height if the checkboxes are higher\r
-       // so that everything is alligned properly\r
-       _checkHeight = _checkBmp->GetHeight();\r
-       _checkWidth = _checkBmp->GetWidth();\r
-#endif\r
-\r
-       // remember the highest of the two bitmaps so there is\r
-       // always enough room\r
-       _maxHeight = _iconHeight;\r
-\r
-#if(CHECKBOXVIEW)\r
-       if(_maxHeight < _checkHeight)\r
-                _maxHeight = _checkHeight;\r
-#endif\r
-\r
- // set standard highlighting brush\r
-  this->m_HilightBrush = new wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT),wxSOLID);\r
-\r
-        // set standard DC font\r
-    _captionFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);\r
-\r
-        // adjust bitmap icon y position so they are centered\r
-        AdjustIconsDeltaY();\r
-\r
-       // set virtual size to this window size\r
-       if (_create_called) {\r
-               wxSize wndsize = GetSize();\r
-               SetVirtualSize(wndsize.GetWidth(), wndsize.GetWidth());\r
-       }\r
-}\r
-\r
-void wxTreeMultiCtrl::SetCaptionFont(const wxFont &font)\r
-{\r
-       _captionFont = font;\r
-\r
-       // adjust the icons so that they are in the middle\r
-       AdjustIconsDeltaY();\r
-\r
-       RedrawFromNode(0);\r
-};\r
-\r
-void wxTreeMultiCtrl::AdjustIconsDeltaY()\r
-{\r
-       int x = 0, y = 0;\r
-\r
-       if(_captionFont.Ok())\r
-      GetTextExtent(wxT("jG"), &x, &y, 0, 0, &_captionFont);\r
-       _captionHeight = y;\r
-\r
-       if(_maxHeight < _captionHeight)\r
-               _maxHeight = _captionHeight;\r
-\r
-       // determine the center pos for the [+]\r
-       _iconDeltaY = abs(_maxHeight - _iconHeight) / 2 + 1;\r
-       if(_iconDeltaY < 1)\r
-               _iconDeltaY = 1;\r
-\r
-#if(CHECKBOXVIEW)\r
-       // determine the center pos for the checkbox\r
-       _checkDeltaY = abs(_maxHeight - _checkHeight) / 2 + 1;\r
-       if(_checkDeltaY < 1)\r
-               _checkDeltaY = 1;\r
-#endif\r
-}\r
-\r
-wxTreeMultiCtrl::~wxTreeMultiCtrl()\r
-{\r
-       // delete the bitmap resources\r
-       delete _expandBmp;\r
-       delete _collBmp;\r
-\r
-#if(CHECKBOXVIEW)\r
-       delete _checkBmp;\r
-       delete _uncheckBmp;\r
-       delete _tristateBmp;\r
-#endif\r
-}\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::AddRoot(const wxString &caption, const wxString &name)\r
-{\r
-       wxTreeMultiItem result((TreeMultiItemBase *)&_root);\r
-       result = AppendNode(result, caption, name);\r
-\r
-        return result;\r
-}\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::AppendWindow(const wxTreeMultiItem &ParentItem, wxWindow *window, const wxString &name, const wxTreeMultiWindowInfo &info, int flags)\r
-{\r
- // add window only if the parent item is valid and...\r
-        wxCHECK(ParentItem.IsOk(), wxTreeMultiItem(0));\r
-\r
-        TreeMultiItemNode* parent = ParentItem.GetItem()->IsTreeMultiItemNode(); // also roots are nodes\r
-\r
- // ... is a node\r
-  wxCHECK(parent != NULL, wxTreeMultiItem(0));\r
-\r
- // now, append node to the tree control:\r
-  wxTreeMultiItem NewWindowItem(this->InsertWindow(parent,wx_static_cast(size_t,parent->GetNodeCount()),window,name,info,flags));\r
- // redraw the stucture:\r
-        this->RedrawFromNode(parent);\r
- // return the new window\r
-        return NewWindowItem;\r
-}\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::InsertWindow(wxTreeMultiItem const& ParentItem, size_t Position, wxWindow *window, wxString const& name, wxTreeMultiWindowInfo const& info, int flags)\r
-{\r
- // add window only if the parent item is valid and...\r
-        wxCHECK(ParentItem.IsOk(), wxTreeMultiItem(0));\r
-\r
-        TreeMultiItemNode* parent = ParentItem.GetItem()->IsTreeMultiItemNode(); // also roots are nodes\r
-\r
- // ... is a node\r
-  wxCHECK(parent != NULL, wxTreeMultiItem(0));\r
-\r
- // now, append node to the tree control:\r
-  wxTreeMultiItem NewWindowItem(this->InsertWindow(parent,Position,window,name,info,flags));\r
- // redraw the stucture:\r
-        this->RedrawFromNode(parent);\r
- // return the new window\r
-        return NewWindowItem;\r
-} /* wxTreeMultiCtrl::InsertWindow(wxTreeMultiItem const&, size_t, wxWindow*, wxString const&, wxTreeMultiWindowInfo const&, int) */\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::PrependWindow(wxTreeMultiItem const& ParentItem, wxWindow *window, const wxString &name, wxTreeMultiWindowInfo const& info, int flags)\r
-{\r
- // add window only if the parent item is valid and...\r
-        wxCHECK(ParentItem.IsOk(), wxTreeMultiItem(0));\r
-\r
-        TreeMultiItemNode* parent = ParentItem.GetItem()->IsTreeMultiItemNode(); // also roots are nodes\r
-\r
- // ... is a node\r
-  wxCHECK(parent != NULL, wxTreeMultiItem(0));\r
-\r
- // now, append node to the tree control:\r
-  wxTreeMultiItem NewWindowItem(this->InsertWindow(parent,0,window,name,info,flags));\r
- // redraw the stucture:\r
-        this->RedrawFromNode(parent);\r
- // return the new window\r
-        return NewWindowItem;\r
-} /* wxTreeMultiCtrl::PrependWindow(wxTreeMultiItem const&, wxWindow*, const wxString &, wxTreeMultiWindowInfo const&, int) */\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::AppendNode(wxTreeMultiItem const& ParentItem, const wxString &caption, const wxString &name)\r
-{\r
- // add window only if the parent item is valid and...\r
-        wxCHECK(ParentItem.IsOk(), wxTreeMultiItem(0));\r
-\r
-        TreeMultiItemNode* parent = ParentItem.GetItem()->IsTreeMultiItemNode(); // also roots are nodes\r
-\r
- // ... is a node\r
-  wxCHECK(parent != NULL, wxTreeMultiItem(0));\r
-\r
- // now, append node to the tree control:\r
-  wxTreeMultiItem NewNodeItem(this->InsertNode(parent,wx_static_cast(size_t,parent->GetNodeCount()),caption,name));\r
- // redraw the structure:\r
-        this->RedrawFromNode(parent);\r
- // return the new node:\r
-        return NewNodeItem;\r
-} /* wxTreeMultiCtrl::AppendNode(wxTreeMultiItem const&, const wxString &, const wxString&) */\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::InsertNode(wxTreeMultiItem const& ParentItem, size_t Position, wxString const& caption, wxString const& name)\r
-{\r
- // add window only if the parent item is valid and...\r
-        wxCHECK(ParentItem.IsOk(), wxTreeMultiItem(0));\r
-\r
-        TreeMultiItemNode* parent = ParentItem.GetItem()->IsTreeMultiItemNode(); // also roots are nodes\r
-\r
- // ... is a node\r
-  wxCHECK(parent != NULL, wxTreeMultiItem(0));\r
-\r
- // now, append node to the tree control:\r
-  wxTreeMultiItem NewNodeItem(this->InsertNode(parent,Position,caption,name));\r
- // redraw the structure:\r
-        this->RedrawFromNode(parent);\r
- // return the new node:\r
-        return NewNodeItem;\r
-} /* wxTreeMultiCtrl::InsertNode(wxTreeMultiItem const&, size_t, wxString const&, wxString const&) */\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::PrependNode(wxTreeMultiItem const& ParentItem, wxString const& caption, wxString const& name)\r
-{\r
- // add window only if the parent item is valid and...\r
-        wxCHECK(ParentItem.IsOk(), wxTreeMultiItem(0));\r
-\r
-        TreeMultiItemNode* parent = ParentItem.GetItem()->IsTreeMultiItemNode(); // also roots are nodes\r
-\r
- // ... is a node\r
-  wxCHECK(parent != NULL, wxTreeMultiItem(0));\r
-\r
- // now, append node to the tree control:\r
-  wxTreeMultiItem NewNodeItem(this->InsertNode(parent,0,caption,name));\r
- // redraw the structure:\r
-        this->RedrawFromNode(parent);\r
- // return the new node:\r
-        return NewNodeItem;\r
-} /* wxTreeMultiCtrl::PrependNode(wxTreeMultiItem const&, wxString const&, wxString const&) */\r
-\r
-bool wxTreeMultiCtrl::Delete(wxTreeMultiItem &item)\r
-{\r
-       bool redraw = true;\r
-       wxCHECK(item.IsOk(), false);\r
-\r
-        wxTreeMultiItem nullItem(0);\r
-\r
-\r
- // if item has been selected, remove it from the selected list:\r
-  size_t ItemIndex(this->GetSelectedItemIndex(item));\r
-\r
-  if (ItemIndex != this->GetSelectedItemCount())\r
-    this->m_SelectedItems.RemoveAt(ItemIndex);\r
-\r
-        // get parent, to delete item from\r
-        TreeMultiItemNode *p = item.GetItem()->GetParent();\r
-\r
-       // first check if it was visible, if so from the parent off\r
-       // it needs redrawing\r
-       redraw = item.GetItem()->IsVisible();\r
-       if(p)\r
-               p->DeleteNode(item.GetItem());\r
-       else\r
-               _root.DeleteNode(item.GetItem());\r
-\r
-       item = nullItem;\r
-\r
-       // do redraw when node was visible\r
-       if(redraw)\r
-               RedrawFromNode(p);\r
-\r
-       return true;\r
-}\r
-\r
-void wxTreeMultiCtrl::DeleteChildren(const wxTreeMultiItem &item)\r
-{\r
-        if(item.IsNodeItem())\r
-        {\r
-                TreeMultiItemNode *n = (TreeMultiItemNode *)item.GetItem();\r
-\r
-   // remove all children from the selected item list:\r
-          if (n->GetNodeCount() > 0)\r
-          {\r
-           // variable definitions and initializations:\r
-            int Cookie;\r
-            wxTreeMultiItem FirstItemIterator(this->GetFirstChild(item,Cookie)), LastItemIterator(this->GetLastChild(item));\r
-\r
-            for (;;)\r
-            {\r
-              size_t ItemIndex(this->GetSelectedItemIndex(item)); // variable definition and initialization\r
-\r
-              if (ItemIndex != this->GetSelectedItemCount())\r
-                this->m_SelectedItems.RemoveAt(ItemIndex);\r
-              if (FirstItemIterator == LastItemIterator)\r
-                break; // all children checked\r
-              else\r
-                FirstItemIterator = this->GetNext(FirstItemIterator);\r
-            } /* for */\r
-          } /* if */\r
-         // delete children:\r
-                n->Clear();\r
-        // redraw:\r
-                RedrawFromNode(n);\r
-        }\r
-}\r
-\r
-void wxTreeMultiCtrl::Expand(const wxTreeMultiItem &item, bool recursive)\r
-{\r
-       if(item.IsOk())\r
-       {\r
-        TreeMultiItemNode *n = item.GetItem()->IsTreeMultiItemNode();\r
-               if(!n)\r
-                       n = item.GetItem()->GetParent();\r
-        DoFold(n, true, recursive);\r
-               RedrawFromNode(item.GetItem()->IsTreeMultiItemNode());\r
-       }\r
-}\r
-\r
-void wxTreeMultiCtrl::Collapse(const wxTreeMultiItem &item, bool recursive)\r
-{\r
-       if(item.IsOk())\r
-       {\r
-        TreeMultiItemNode *n = item.GetItem()->IsTreeMultiItemNode();\r
-               if(!n)\r
-                       n = item.GetItem()->GetParent();\r
-               DoFold(n, false, recursive);\r
-               RedrawFromNode(item.GetItem()->IsTreeMultiItemNode());\r
-       }\r
-}\r
-\r
-\r
-void wxTreeMultiCtrl::ExpandNodes(bool recursive)\r
-{\r
-       // go through all children and call DoFold recursively\r
-       for(int i = 0; i < _root.GetNodeCount(); i++)\r
-               DoFold(_root.GetNode(i), true, recursive);\r
-       RedrawFromNode(0);\r
-}\r
-\r
-void wxTreeMultiCtrl::CollapseNodes(bool recursive)\r
-{\r
-       // go through all children and call DoFold recursively\r
-       for(int i = 0; i < _root.GetNodeCount(); i++)\r
-               DoFold(_root.GetNode(i), false, recursive);\r
-       RedrawFromNode(0);\r
-}\r
-\r
-void wxTreeMultiCtrl::CollapseAndReset(const wxTreeMultiItem &item)\r
-{\r
-       if(item.IsNodeItem())\r
-       {\r
-                TreeMultiItemNode *n = (TreeMultiItemNode *)item.GetItem();\r
-\r
-                // delete all kids\r
-                n->Clear();\r
-                Collapse(item, false);\r
-        }\r
-}\r
-\r
-// Selection manipulation\r
-wxTreeMultiItem wxTreeMultiCtrl::GetFirstSelectedItem(void) const\r
-{\r
-  if (this->GetSelectedItemCount() > 0)\r
-    return this->m_SelectedItems[0];\r
-  else\r
-    return wxTreeMultiItem();\r
-} /* wxTreeMultiCtrl::GetFirstSelectedItem(void) const */\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::GetLastSelectedItem(void) const\r
-{\r
-  if (this->GetSelectedItemCount() > 0)\r
-    return this->m_SelectedItems[this->GetSelectedItemCount()-1];\r
-  else\r
-    return wxTreeMultiItem();\r
-} /* wxTreeMultiCtrl::GetLastSelectedItem(void) const */\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::GetSelectedItem(size_t Index) const\r
-{\r
-  if (Index < this->GetSelectedItemCount())\r
-    return this->m_SelectedItems[Index];\r
-  else\r
-    return wxTreeMultiItem();\r
-} /* wxTreeMultiCtrl::GetSelectedItem(size_t Index) const */\r
-\r
-size_t wxTreeMultiCtrl::GetSelectedItemIndex(wxTreeMultiItem const& Item) const\r
-{\r
- // attention: the function wxArray::Index() can NOT be used in a save manner as it only checks the address of an item\r
- //            element but it is not guaranteed that Item may not be a copy of the originally inserted item\r
-  const size_t NoOfSelectedItems = this->GetSelectedItemCount();\r
-\r
-  size_t Index(0);\r
-\r
-\r
-  while ((Index < NoOfSelectedItems) && (this->m_SelectedItems[Index] != Item))\r
-    ++Index;\r
-  return Index;\r
-} /* wxTreeMultiCtrl::GetSelectedItemIndex(wxTreeMultiItem const&) const */\r
-\r
-void wxTreeMultiCtrl::SelectItem(wxTreeMultiItem const& Item, bool UnselectOthers, bool ExpandSelection)\r
-{\r
-  TreeMultiItemNode* NodePtr(Item.GetItem()->IsTreeMultiItemNode());\r
-\r
-\r
- // only nodes can be selected and they can only be selected if they are not already selected:\r
-  if ((NodePtr == NULL) || NodePtr->IsSelected())\r
-   return;\r
-\r
- // inform that we are about to change:\r
-  wxTreeMultiEvent Event(wxEVT_COMMAND_TREE_MULTI_SEL_CHANGING,Item); // variable definition and initialization\r
-\r
-  if (this->m_SelectedItems.GetCount() > 0) // the last item in the array is always the latest inserted item\r
-    Event.SetOldItem(this->m_SelectedItems.Last());\r
-  Event.SetEventObject(this);\r
-  if (this->GetEventHandler()->ProcessEvent(Event) && !(Event.IsAllowed()))\r
-      return; // vetoed\r
-\r
- // make sure that the to be selected item can be seen:\r
-  this->Include(Item);\r
-\r
- // variable definition and initialization:\r
-  wxTreeMultiItem ExcludedParent(this->GetExcludedParent(Item));\r
-\r
-  while (ExcludedParent.IsOk())\r
-  {\r
-    this->Include(ExcludedParent);\r
-    ExcludedParent = this->GetExcludedParent(Item);\r
-  } /* while */\r
-\r
- // unselect items if necessary:\r
-  if (UnselectOthers)\r
-    this->UnselectAll();\r
- // expand selection if necessary:\r
-  if (ExpandSelection)\r
-  {\r
-   // variable definition:\r
-    wxTreeMultiItem FirstItemIterator, LastItemIterator;\r
-    wxTreeMultiItem LastSelectedItem;\r
-\r
-   // determine the last selected item or the first item in case nothing has been selected before:\r
-    if (this->m_SelectedItems.GetCount() > 0)\r
-      LastSelectedItem = this->m_SelectedItems.Last();\r
-    else\r
-      LastSelectedItem = this->GetFirstRoot();\r
-   // determine the item from which to start and the one with which to end the selection:\r
-    if (Item.GetItem()->GetY() > LastSelectedItem.GetItem()->GetY())\r
-    {\r
-      FirstItemIterator = LastSelectedItem;\r
-      LastItemIterator  = Item;\r
-    } /* if */\r
-    else\r
-    {\r
-      FirstItemIterator = Item;\r
-      LastItemIterator  = LastSelectedItem;\r
-    } /* if */\r
-   // select all items that are a node and are placed between the two limiting iterators (included the limits):\r
-    for (;;)\r
-    {\r
-      if (!(FirstItemIterator.IsSelected()) && FirstItemIterator.IsNodeItem())\r
-      {\r
-        FirstItemIterator.GetItem()->Select();\r
-        this->m_SelectedItems.Add(FirstItemIterator);\r
-        this->RefreshRect(wxRect(FirstItemIterator.GetItem()->GetX(),    FirstItemIterator.GetItem()->GetY(),\r
-                                 FirstItemIterator.GetItem()->GetWidth(),FirstItemIterator.GetItem()->GetHeight()));\r
-      } /* if */\r
-      if (FirstItemIterator == LastItemIterator)\r
-        break; // done\r
-     // continue iterating:\r
-      FirstItemIterator = this->GetNext(FirstItemIterator);\r
-    } /* for */\r
-  } /* if */\r
-  else // select passed item only\r
-  {\r
-    NodePtr->Select();\r
-    this->m_SelectedItems.Add(NodePtr);\r
-    this->RefreshRect(wxRect(NodePtr->GetX(),NodePtr->GetY(),NodePtr->GetWidth(),NodePtr->GetHeight()));\r
-  } /* if */\r
-\r
- // inform that we have selected the item:\r
-  Event.SetEventType(wxEVT_COMMAND_TREE_MULTI_SEL_CHANGED);\r
-  this->GetEventHandler()->ProcessEvent(Event);\r
-} /* wxTreeMultiCtrl::SelectItem(wxTreeMultiItem const&, bool, bool) */\r
-\r
-void wxTreeMultiCtrl::UnselectAll(void)\r
-{\r
-  const size_t NoOfSelectedItems = this->m_SelectedItems.GetCount();\r
-\r
-\r
-  for (size_t i=0; i<NoOfSelectedItems; ++i)\r
-  {\r
-    this->RefreshRect(wxRect(this->m_SelectedItems[i].GetItem()->GetX(),    this->m_SelectedItems[i].GetItem()->GetY(),\r
-                             this->m_SelectedItems[i].GetItem()->GetWidth(),this->m_SelectedItems[i].GetItem()->GetHeight()));\r
-    this->m_SelectedItems[i].GetItem()->Unselect();\r
-  } /* for */\r
-  this->m_SelectedItems.Clear();\r
-} /* wxTreeMultiCtrl::UnselectAll(void) */\r
-\r
-void wxTreeMultiCtrl::Unselect(wxTreeMultiItem const& Item)\r
-{\r
-  size_t ItemIndex(this->GetSelectedItemIndex(Item));\r
-\r
-\r
-  if (ItemIndex != this->GetSelectedItemCount())\r
-  {\r
-    Item.GetItem()->Unselect();\r
-    this->m_SelectedItems.RemoveAt(ItemIndex);\r
-    this->RefreshRect(wxRect(Item.GetItem()->GetX(),Item.GetItem()->GetY(),Item.GetItem()->GetWidth(),Item.GetItem()->GetHeight()));\r
-  } /* if */\r
-} /* wxTreeMultiCtrl::Unselect(wxTreeMultiItem const&) */\r
-\r
-void wxTreeMultiCtrl::DoFold(TreeMultiItemBase *item, bool expand, bool recursive)\r
-{\r
-\r
-       // go through all node objects on this level, and expand or\r
-       // collapse them\r
-\r
-       if(item == 0)\r
-               return;\r
-\r
-       // if this is a node, use it to go through all the subnodes (if needed)\r
-       // if not, then just exit.\r
-\r
-       TreeMultiItemNode *node = item->IsTreeMultiItemNode();\r
-       if(node)\r
-       {\r
-               node->Fold(expand);\r
-\r
-               // go recursive\r
-               if(recursive)\r
-               {\r
-                       TreeMultiItemNode *p;\r
-                       for(int i = 0; i < node->GetNodeCount(); i++)\r
-                       {\r
-                               // get node, and if a real node, then call fold\r
-                               p = node->GetNode(i)->IsTreeMultiItemNode();\r
-                               if(p)\r
-                                       p->Fold(expand);\r
-\r
-                               // go recursive for every node\r
-                               DoFold(p, expand, recursive);\r
-                       }\r
-               }\r
-       }\r
-}\r
-\r
-void wxTreeMultiCtrl::Exclude(const wxTreeMultiItem &item)\r
-{\r
-       wxCHECK2(item.IsOk(), return);\r
-\r
-       // exclude the item, and refresh\r
-       // if already excluded, skip\r
-\r
-       if(!item.GetItem()->IsExcluded())\r
-       {\r
-               item.GetItem()->SetExcluded(true);\r
-               RedrawFromParentNode(item.GetItem());\r
-       }\r
-}\r
-\r
-void wxTreeMultiCtrl::Include(const wxTreeMultiItem &item)\r
-{\r
-       wxCHECK2(item.IsOk(), return);\r
-\r
-       // include the item, and refresh. If not\r
-       // excluded, do nothing\r
-\r
-       if(item.GetItem()->IsExcluded())\r
-       {\r
-               item.GetItem()->SetExcluded(false);\r
-               RedrawFromParentNode(item.GetItem());\r
-       }\r
-}\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::GetExcludedParent(const wxTreeMultiItem &item)\r
-{\r
-       wxCHECK(item.IsOk(), wxTreeMultiItem(0));\r
-\r
-       // go find the parent (including this one) that\r
-       // can be the excluded one\r
-\r
-       TreeMultiItemNode *n = item.GetItem()->IsTreeMultiItemNode();\r
-       if(n && n->IsExcluded())\r
-               return wxTreeMultiItem(n);\r
-\r
-       n = item.GetItem()->GetParent();\r
-       while(n)\r
-       {\r
-               if(n->IsExcluded())\r
-                       return wxTreeMultiItem(n);\r
-               else\r
-                       n = n->GetParent();\r
-       }\r
-\r
-        return wxTreeMultiItem(0);\r
-}\r
-\r
-void wxTreeMultiCtrl::OnSize(wxSizeEvent &WXUNUSED(event))\r
-{\r
-        RecalculateSpanSizes();\r
-}\r
-\r
-void wxTreeMultiCtrl::OnPaint(wxPaintEvent& WXUNUSED(event) )\r
-{\r
-        wxPaintDC dc(this);\r
-\r
-        PrepareDC(dc);\r
-\r
-        // go recursive and draw the whole visible tree.\r
-        dc.SetFont(_captionFont);\r
-        for(int i = 0; i < _root.GetNodeCount(); i++)\r
-                DrawNode(_root.GetNode(i), dc);\r
-}\r
-\r
-void wxTreeMultiCtrl::DrawNode(TreeMultiItemBase *b, wxDC &dc)\r
-{\r
-       // go through this item .. if it is a node, draw\r
-       // the caption, else reposition the window.\r
-\r
-       if(!b)\r
-               return;\r
-\r
-       // forget it if this node is not visible\r
-       if(b->IsVisible())\r
-       {\r
-               int bmpOffsetX = b->GetX() - (_gutterWidth + _iconWidth);\r
-\r
-#if(CHECKBOXVIEW)\r
-               // now draw the checkbox if there is any, in the proper state\r
-               if(b->GetCheckbox())\r
-               {\r
-                       DrawCheckbox(b, dc);\r
-\r
-                       // adjust the bmpOffset because we also have a checkbox\r
-                       bmpOffsetX -= _checkWidth;\r
-               }\r
-#endif\r
-\r
-               if(b->IsTreeMultiItemNode())\r
-                {\r
-                        // draw the node icon and the caption\r
-                        TreeMultiItemNode *n = (TreeMultiItemNode *)b;\r
-\r
-                 // set background of caption item\r
-                  if (n->IsSelected())\r
-                  {\r
-                    dc.SetBrush(*(this->m_HilightBrush));\r
-        dc.SetPen(wxPen(this->m_HilightBrush->GetColour(),1,wxSOLID));\r
-                  } /* if */\r
-                  else\r
-                  {\r
-                    dc.SetBrush(wxBrush(*wxWHITE,wxSOLID));\r
-        dc.SetPen(wxPen(*wxWHITE,1,wxSOLID));\r
-                  } /* if */\r
-                  dc.DrawRectangle(n->GetX(),n->GetY(),n->GetWidth(),n->GetHeight());\r
-                 // draw caption\r
-                        dc.DrawText(n->GetCaption(), n->GetX(), n->GetY());\r
-\r
-                        // draw the bitmap for the state\r
-                       if(n->IsExpanded())\r
-                               dc.DrawBitmap(*_expandBmp, bmpOffsetX, n->GetY() + _iconDeltaY, true);\r
-                       else\r
-                               dc.DrawBitmap(*_collBmp, bmpOffsetX, n->GetY() + _iconDeltaY, true);\r
-\r
-                       // now go through all the subnodes\r
-                       for(int i = 0; i < n->GetNodeCount(); i++)\r
-                               DrawNode(n->GetNode(i), dc);\r
-\r
-               }\r
-       }\r
-}\r
-\r
-#if(CHECKBOXVIEW)\r
-\r
-void wxTreeMultiCtrl::DrawCheckbox(TreeMultiItemBase *b, wxDC &dc, bool convertScrolled)\r
-{\r
-       wxCHECK2(b, return);\r
-\r
-       wxBitmap *bmp;\r
-       int bmpOffsetX = b->GetX() - (_gutterWidth + _iconWidth);\r
-\r
-       switch(b->GetCheckboxState())\r
-       {\r
-       case 0:\r
-               bmp = _uncheckBmp;\r
-               break;\r
-       case 1:\r
-               bmp = _checkBmp;\r
-               break;\r
-       default:\r
-               bmp = _tristateBmp;\r
-               break;\r
-       }\r
-\r
-       int x, xx, y, yy;\r
-\r
-       if(b->IsTreeMultiItemWindow())\r
-       {\r
-               xx = x = bmpOffsetX - ((TreeMultiItemWindow *)b)->GetFrontSpacing() + _checkWidth;\r
-               yy = y = b->GetY() + _checkDeltaY;\r
-       }\r
-       else\r
-       {\r
-               xx = x = bmpOffsetX;\r
-               yy = y = b->GetY() + _checkDeltaY;\r
-       }\r
-\r
-       if(convertScrolled)\r
-               CalcScrolledPosition(x, y, &xx, &yy);\r
-\r
-       dc.DrawBitmap(*bmp, xx, yy, true);\r
-}\r
-\r
-#endif // #if(CHECKBOXVIEW)\r
-\r
-void wxTreeMultiCtrl::OnKey(wxKeyEvent &event)\r
-{\r
-       // check if we need to traverse to upper or lower\r
-       // control in the list\r
-       if(event.GetKeyCode() == WXK_TAB)\r
-       {\r
-               wxTreeMultiItem item = GetFocus();\r
-               if(item.IsOk())\r
-               {\r
-                       // traverse down direction\r
-                       if(!event.ShiftDown())\r
-                               item = FindNextVisibleWindowItem(item.GetItem());\r
-                       //else // traverse in up direction\r
-                       //      item = FindPreviousVisibleWindowItem(item);\r
-\r
-                       if(item.IsOk())\r
-                       {\r
-                               TreeMultiItemWindow *w = item.GetItem()->IsTreeMultiItemWindow();\r
-                               if(w)\r
-                               {\r
-                                       wxWindow *wnd = w->GetWindow();\r
-                                       wnd->SetFocus();\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-       else\r
-               event.Skip();\r
-}\r
-\r
-void wxTreeMultiCtrl::OnMouseClick( wxMouseEvent &event )\r
-{\r
-       // react on double click and left mouse down\r
-       if(event.LeftDown() || event.LeftDClick())\r
-       {\r
-               // get translation point\r
-               wxPoint pt( event.GetPosition() );\r
-\r
-               int x = 0, y = 0;\r
-               CalcUnscrolledPosition( pt.x, pt.y, &x, &y );\r
-\r
-               // go check if we clicked a treenode\r
-               int flags;\r
-               wxPoint p(x,y);\r
-               wxTreeMultiItem id = HitTest(p, flags);\r
-\r
-#if(CHECKBOXVIEW)\r
-               if(flags == wxTMC_HITTEST_CHECKBOX)\r
-               {\r
-                       // toggle the checkbox, and redraw\r
-                       if(id.IsOk())\r
-                       {\r
-                               TreeMultiItemBase *b = id.GetItem();\r
-                               b->SetCheckboxState((b->GetCheckboxState()+1) & 0x1);\r
-\r
-                               TreeMultiItemWindow *w = b->IsTreeMultiItemWindow();\r
-                               if(w)\r
-                               {\r
-                                       // try to force a focus on the window. This could\r
-                                       // be extended by searching for the first edit control\r
-                                       // class but for now, just a focus is tried.\r
-                                       w->GetWindow()->Enable(b->GetCheckboxState() == 1);\r
-                                       w->GetWindow()->SetFocus();\r
-\r
-                                       // draw the checkbox in the state needed\r
-                                       wxClientDC dc(this);\r
-                                       DrawCheckbox(b, dc, true);\r
-\r
-                                       // TODO: determine if the upper parents should be\r
-                                       // tristated or not\r
-\r
-                                       ScanTristateCheckstates(b);\r
-\r
-                               }\r
-                               else if(b->IsTreeMultiItemNode())\r
-                               {\r
-                                       // descend to all the children and set the state of the parent\r
-                                       SetRecursiveCheckState((TreeMultiItemNode *)b, b->GetCheckboxState() == 1);\r
-                                       RedrawFromNode((TreeMultiItemNode *)b);\r
-                               }\r
-                       }\r
-               }\r
-               else\r
-#endif // #if(CHECKBOXVIEW)\r
-               {\r
-                       // react on left mouse button, to fold and on\r
-                       // right for caption doubleclick\r
-                       int area = -1;\r
-\r
-// adjust behaviour for Linux (single click = always fold)\r
-#ifndef LINUX\r
-                       if(event.LeftDClick())\r
-                               area = wxTMC_HITTEST_CAPTION;\r
-                       else\r
-                               area = wxTMC_HITTEST_GUTTER;\r
-#else\r
-                        area = flags;\r
-#endif\r
-\r
-// Linux (single or double click -> always fold\r
-      if (id.IsOk())\r
-      {\r
-#ifdef LINUX\r
-                                // we have a valid item, if it is a node, then fold\r
-                                TreeMultiItemNode *n = id.GetItem()->IsTreeMultiItemNode();\r
-                                if(n)\r
-                                {\r
-                                  this->SelectItem(id);\r
-                                        Fold(n, !n->IsExpanded());\r
-                                } /* if */\r
-#else\r
-        if (event.LeftDown())\r
-          if (flags == wxTMC_HITTEST_GUTTER)\r
-          {\r
-                                TreeMultiItemNode *n = id.GetItem()->IsTreeMultiItemNode(); // for some reasons also windows may have set the flag\r
-\r
-            if (n != NULL)\r
-                                        Fold(n, !n->IsExpanded());\r
-          } /* if */\r
-          else if (flags == wxTMC_HITTEST_CAPTION)\r
-          {\r
-                                TreeMultiItemNode *n = id.GetItem()->IsTreeMultiItemNode(); // for some reasons also windows may have set the flag\r
-\r
-                                if (n != NULL)\r
-                                {\r
-                                  this->SelectItem(id);\r
-                                this->RedrawFromNode(n);\r
-                                } /* if */\r
-          } /* if */\r
-#endif\r
-      } /* if */\r
-      else\r
-        this->UnselectAll();\r
-                }\r
-        }\r
-}\r
-\r
-void wxTreeMultiCtrl::OnRightMouseClick(wxMouseEvent& Event)\r
-{\r
-  if (Event.RightDown())\r
-    if (Event.Dragging())\r
-      this->UnselectAll();\r
-    else\r
-    {\r
-     // variable definitions:\r
-        int Flags;\r
-        wxPoint Point;\r
-\r
-     // translate mouse coordinates:\r
-        CalcUnscrolledPosition(Event.GetPosition().x,Event.GetPosition().y,&(Point.x),&(Point.y));\r
-     // check if the mouse is above the caption of an item:\r
-      wxTreeMultiItem Item(this->HitTest(Point,Flags)); // variable definition and initialization\r
-\r
-      if (Item.IsOk() && (Flags == wxTMC_HITTEST_CAPTION))\r
-      {\r
-        this->SelectItem(Item);\r
-                                this->RedrawFromNode(Item.GetItem()->IsTreeMultiItemNode());\r
-          Event.Skip(); // window will convert right mouse click to a context menu event or proceed with\r
-                        // a right mouse click event if the context menu event cannot be processed\r
-      } /* if */\r
-      else\r
-        this->UnselectAll();\r
-    } /* if */\r
-  else\r
-    this->UnselectAll();\r
-} /* wxTreeMultiCtrl::OnRightMouseClick(wxMouseEvent&) */\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::HitTest(wxPoint const& pt, int &flags)\r
-{\r
-        // scan all nodes to see which one matches\r
-        TreeMultiItemBase *b = 0;\r
-       for(int i = 0; i < _root.GetNodeCount() && !b; i++)\r
-               b = FindNodeByPoint(_root.GetNode(i), pt, flags);\r
-\r
-       if(!b)\r
-       {\r
-               // none found, reset\r
-               flags = 0;\r
-               return wxTreeMultiItem(0);\r
-       }\r
-\r
-       // return an item\r
-        return wxTreeMultiItem(b);\r
-}\r
-\r
-TreeMultiItemBase *wxTreeMultiCtrl::FindNodeByPoint(TreeMultiItemBase *b, wxPoint const& pt, int &area)\r
-{\r
-        wxCHECK(b, 0);\r
-\r
-       // if this layer is not visible, return with nothing.\r
-       if(!b->IsVisible())\r
-               return 0;\r
-\r
-       area = 0;\r
-\r
-       // now see if our y is matching the mouse\r
-       if(pt.y >= b->GetY() && pt.y < (b->GetY() + b->GetHeight()))\r
-       {\r
-#if(CHECKBOXVIEW)\r
-               // if we are checkboxed, calculate the checkbox position\r
-               if(b->GetCheckbox())\r
-               {\r
-                       int extraSpacing = 0, extraWidth = 0;\r
-\r
-                       // now for a windows item, this is minus the gutter. For a normal node it is X minus checkbox\r
-                       if(b->IsTreeMultiItemWindow())\r
-                       {\r
-                           extraWidth = _checkWidth;\r
-                               extraSpacing = ((TreeMultiItemWindow *)b)->GetFrontSpacing();\r
-                       }\r
-                       else\r
-                               extraSpacing = 4;\r
-\r
-                       if(pt.x > (b->GetX() - extraSpacing - _checkWidth) && pt.x < (b->GetX() - extraSpacing + extraWidth))\r
-                       {\r
-                               area = wxTMC_HITTEST_CHECKBOX;\r
-                               return b;\r
-                       }\r
-               }\r
-#endif\r
-\r
-               // allrighty we have something, now where and what is it (look with x)\r
-               if(pt.x < b->GetX())\r
-                       area = wxTMC_HITTEST_GUTTER;\r
-\r
-               /** \todo Match only the real part of the caption, window (we assume x > GetX() which is the rest)\r
-                       HOWEVER the window probably doesn't propagate the click event back to the parent, so we might\r
-                       leave it like this so the use can click behind a window so it will be selected.\r
-               */\r
-               else\r
-               {\r
-                       // inside area, return proper flag\r
-                       if(b->IsTreeMultiItemNode())\r
-                               area = wxTMC_HITTEST_CAPTION;\r
-                       else\r
-                               area = wxTMC_HITTEST_WINDOW;\r
-               }\r
-\r
-               return b;\r
-       }\r
-       else\r
-       {\r
-               // not found, let's try our children if we have some\r
-               TreeMultiItemNode *n = b->IsTreeMultiItemNode();\r
-               if(n)\r
-               {\r
-                       TreeMultiItemBase *bb = 0;\r
-                       for(int i = 0; i < n->GetNodeCount() && !bb; i++)\r
-                               bb = FindNodeByPoint(n->GetNode(i), pt, area);\r
-\r
-                       // keep returning result to caller\r
-                       return bb;\r
-               }\r
-       }\r
-\r
-       return 0;\r
-}\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::GetFocus()\r
-{\r
-       wxWindow *wnd = wxWindow::FindFocus();\r
-\r
-       // now find window that holds this item. if not\r
-       // visible it cannot have focus (should not have)\r
-\r
-       wxTreeMultiItem item = FindWindowNode(wnd);\r
-       if(item.IsOk() && item.GetItem()->IsVisible())\r
-               return item;\r
-\r
-       return wxTreeMultiItem(0);\r
-}\r
-\r
-#if(CHECKBOXVIEW)\r
-\r
-void wxTreeMultiCtrl::SetRecursiveCheckState(TreeMultiItemNode *n, bool check)\r
-{\r
-       int state = 0;\r
-       if(check)\r
-               state++;\r
-\r
-       // go check all kids on this level\r
-       for(int i = 0; i < n->GetNodeCount(); i++)\r
-       {\r
-               // check all the nodes, and go deeper\r
-               n->GetNode(i)->SetCheckboxState(state);\r
-               if(n->GetNode(i)->IsTreeMultiItemNode())\r
-                       SetRecursiveCheckState((TreeMultiItemNode *)n->GetNode(i), check);\r
-       }\r
-}\r
-\r
-void wxTreeMultiCtrl::ScanTristateCheckstates(TreeMultiItemBase *b)\r
-{\r
-       // check from the parent on, all node entries and see if they are\r
-       // checked or cleared or scattered\r
-       TreeMultiItemNode *p = b->GetParent();\r
-\r
-       if(p && p->GetCheckbox())\r
-       {\r
-               bool foundcheck = false, foundclear = false;\r
-               for(size_t i = 0; i < (size_t)p->GetNodeCount(); ++i)\r
-               {\r
-                       // only evaluate when checkboxed\r
-                       if(p->GetNode(i)->IsTreeMultiItemWindow() && p->GetNode(i)->GetCheckbox())\r
-                       {\r
-                               // record instance of a cleared checkbox\r
-                               if(!p->GetNode(i)->GetCheckboxState())\r
-                                       foundclear = true;\r
-                               // record instance of checked checkbox\r
-                               if(p->GetNode(i)->GetCheckboxState() == 1)\r
-                                       foundcheck = true;\r
-                       }\r
-               }\r
-\r
-               // if we have both check and clear, go tristate\r
-               // if all clear, clear parent and if all set, then set parent\r
-               if(foundclear && !foundcheck)\r
-                       p->SetCheckboxState(0);\r
-               else if(!foundclear && foundcheck)\r
-                       p->SetCheckboxState(1);\r
-               else if(foundclear && foundcheck)\r
-                       p->SetCheckboxState(2);\r
-\r
-               //wxClientDC dc;\r
-               //DrawCheckbox(p, dc, false);\r
-               RedrawFromNode(p);\r
-       }\r
-}\r
-\r
-#endif // #if(CHECKBOXVIEW)\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::InsertNode(TreeMultiItemNode* ParentPtr, size_t Position, wxString const& Caption, wxString const& Name)\r
-{\r
-        int extX, extY;\r
-\r
-  TreeMultiItemNode* NodePtr(new TreeMultiItemNode(ParentPtr,Caption,Name)); // generate new node pointer\r
-\r
-\r
- // continue with initializing the new node:\r
-#if(CHECKBOXVIEW)\r
- // if checkbox view is desired, tag this item as a checkbox\r
- // and set the state as 'false'\r
-        NodePtr->SetCheckbox(_checkboxView);\r
-        NodePtr->SetCheckboxState(0);\r
-#endif\r
- // calculate the height and width\r
-        this->GetTextExtent(Caption,&extX,&extY,0,0,&(this->_captionFont));\r
-        NodePtr->SetHeight(extY);\r
-        NodePtr->SetWidth(extX);\r
- // finally, insert node:\r
-  if (Position < (size_t)ParentPtr->GetNodeCount())\r
-    ParentPtr->InsertNode(NodePtr,Position);\r
-  else\r
-    ParentPtr->AddNode(NodePtr);\r
- // return the newly created node:\r
-  return wxTreeMultiItem(NodePtr);\r
-} /* wxTreeMultiCtrl::InsertNode(TreeMultiItemNode*, size_t, wxString const&, wxString const&) */\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::InsertWindow(TreeMultiItemNode* ParentPtr, size_t Position, wxWindow* WindowPtr, wxString const& Name, wxTreeMultiWindowInfo const& Info, int Flags)\r
-{\r
-  int WindowFlags;\r
-\r
-        TreeMultiItemWindow* NewWindowPtr = new TreeMultiItemWindow(ParentPtr,Name); // generate new window pointer\r
-\r
-\r
- // get flags from passed variable "Flags"; in case this variable does not contain any flags use the window's information flags:\r
-  if (Flags != 0)\r
-    WindowFlags = Flags;\r
-  else\r
-    WindowFlags = Info.GetFlags();\r
-\r
- // continue with initializing the new window:\r
-#if(CHECKBOXVIEW)\r
-        // if checkbox view is desired, tag this item as a checkbox\r
-        // and set the state as 'false'\r
-        NewWindowPtr->SetCheckbox(_checkboxView);\r
-#endif\r
- // if style wants us to change background, set it to our background\r
-        if (WindowFlags & wxTMC_BG_ADJUST_ALL)\r
-        {\r
-                // go through all children of this window, and set the\r
-                // background of it (recursively)\r
-                this->SetWindowBackgroundColour(WindowPtr,this->GetBackgroundColour(),WindowFlags);\r
-        } /* if */\r
-\r
- // set the spacing:\r
-        NewWindowPtr->SetTopSpacing(Info.GetTopSpacing());\r
-#if(CHECKBOXVIEW)\r
-        // make sure that the checkboxes are at least indented enough\r
-        if (this->_checkboxView)\r
-               NewWindowPtr->SetFrontSpacing(Info.GetFrontSpacing() + this->_checkWidth);\r
-        else\r
-#endif\r
-               NewWindowPtr->SetFrontSpacing(Info.GetFrontSpacing());\r
- // assign finally the window:\r
-        NewWindowPtr->AssignWindow(WindowPtr);\r
-\r
-#if(CHECKBOXVIEW)\r
- // set the checkbox state after the window is assigned\r
-        NewWindowPtr->SetCheckboxState(Info.GetDefaultCheckState());\r
-#endif\r
-\r
- // if the window is not visible, set hide flag\r
-        this->ShowTreeMultiWindow(NewWindowPtr,NewWindowPtr->IsVisible());\r
-\r
- // finally, insert the newly constructed window:\r
-  if (Position < (size_t)ParentPtr->GetNodeCount())\r
-    ParentPtr->InsertNode(NewWindowPtr,Position);\r
-  else\r
-    ParentPtr->AddNode(NewWindowPtr);\r
- // return the newly created window:\r
-        return wxTreeMultiItem(NewWindowPtr);\r
-} /* wxTreeMultiCtrl::InsertWindow(TreeMultiItemNode*, size_t, wxWindow*, wxString const&, wxTreeMultiWindowInfo const&, int) */\r
-\r
-void wxTreeMultiCtrl::RedrawFromParentNode(TreeMultiItemBase *n)\r
-{\r
-        TreeMultiItemNode *p = 0;\r
-       if(n)\r
-               p = n->GetParent();\r
-\r
-       RedrawFromNode(p);\r
-}\r
-\r
-void wxTreeMultiCtrl::RedrawFromNode(TreeMultiItemNode *n)\r
-{\r
-       static int recalcMutex = 0;\r
-       bool visible = true;\r
-\r
-       if(recalcMutex > 0)\r
-               return;\r
-\r
-       recalcMutex ++;\r
-\r
-       // when node is not visible or excluded\r
-       // then don't redraw.\r
-\r
-       if(n)\r
-               visible = n->IsVisible();\r
-\r
-       if(visible)\r
-       {\r
-               int h, h1,w, w1;\r
-               GetVirtualSize(&w, &h);\r
-\r
-               UpdateAllWindowVisibility();\r
-               RecalculateNodePositions();\r
-               RecalculateVirtualSize();\r
-\r
-               // why is this needed? Because folding or collapsing can change\r
-               // the state. When the virtual area gets smaller, we need to keep\r
-               // the largest one and the other way atound. And since we do not\r
-               // know here we are folding or collapsing, we remember the biggest\r
-               GetVirtualSize(&w1, &h1);\r
-\r
-                if(h1 > h)\r
-                        h = h1;\r
-\r
-                // only refresh the part from x,y down\r
-                if(n)\r
-               {\r
-                       int x, y;\r
-                       CalcScrolledPosition(n->GetX(), n->GetY(), &x, &y);\r
-                       if(h - y > 0)\r
-                       {\r
-                               wxRect rect(0, y, w, h - y);\r
-                               RefreshRect(rect);\r
-                       }\r
-                       else\r
-                               Refresh();\r
-               }\r
-               else\r
-                       Refresh();      // do a full refresh\r
-       }\r
-\r
-       recalcMutex --;\r
-}\r
-\r
-void wxTreeMultiCtrl::RecalculateNodePositions()\r
-{\r
-       int currentY = _spacingY;\r
-       // go recursive on every node, and store the information in the node\r
-\r
-       for(int i = 0; i < _root.GetNodeCount(); i++)\r
-        currentY += CalculateNodeDimensions(_root.GetNode(i), currentY, 0);\r
-}\r
-\r
-int wxTreeMultiCtrl::CalculateNodeDimensions(TreeMultiItemBase *b, int currentY, int level)\r
-{\r
-       int gutter = (_gutterWidth * 2) + _iconWidth;\r
-       int y = 0, topSpacing = 0;\r
-\r
-       // return same if no proper object\r
-       wxCHECK(b, 0);\r
-\r
-#if(CHECKBOXVIEW)\r
-       if(b->GetCheckbox())\r
-               gutter += _checkWidth;\r
-#endif\r
-\r
-       // if we are not visible, skip recalculation and descending\r
-       if(b->IsVisible())\r
-       {\r
-               b->SetY(currentY);\r
-\r
-               // if level is 0, calculate with front gutter, else without\r
-               y = currentY + b->GetHeight();\r
-               if(b->IsTreeMultiItemNode())\r
-               {\r
-                       TreeMultiItemNode *n = (TreeMultiItemNode *)b;\r
-\r
-                       if(level == 0)\r
-                               b->SetX(gutter);\r
-                       else\r
-                               b->SetX(gutter + (level * (_gutterWidth + _iconWidth)));\r
-\r
-                       // now do children of this node\r
-\r
-                       for(int i = 0; i < n->GetNodeCount(); i++)\r
-                               y += CalculateNodeDimensions(n->GetNode(i), y + _spacingY, level+1);\r
-               }\r
-               else if(b->IsTreeMultiItemWindow())\r
-               {\r
-                       TreeMultiItemWindow *w = (TreeMultiItemWindow *)b;\r
-\r
-                       if(level == 0)\r
-                               b->SetX(gutter + w->GetFrontSpacing());\r
-                       else\r
-                               b->SetX(_gutterWidth + (level * (_gutterWidth + _iconWidth)) + w->GetFrontSpacing());\r
-\r
-                       topSpacing = w->GetTopSpacing();\r
-\r
-                       // reposition the window\r
-\r
-                       wxWindow *wnd = w->GetWindow();\r
-                       if(wnd)\r
-                       {\r
-                               int x = 0, y = 0;\r
-                               CalcScrolledPosition(w->GetX(), w->GetY(), &x, &y);\r
-                               wnd->SetSize(x, y, w->GetWidth(), w->GetHeight());\r
-                       }\r
-               }\r
-\r
-               if(y > 0)\r
-                       return (y - currentY) + _spacingY + topSpacing; // return delta\r
-               else\r
-                       return 0;\r
-       }\r
-\r
-       return 0;       // not visible, thus we skip calculations\r
-}\r
-\r
-void wxTreeMultiCtrl::RecalculateSpanSizes()\r
-{\r
-       for(int i = 0; i < _root.GetNodeCount(); i++)\r
-        CalculateNodeSpanning(_root.GetNode(i));\r
-}\r
-\r
-void wxTreeMultiCtrl::CalculateNodeSpanning(TreeMultiItemBase *b)\r
-{\r
-       // return same if no proper object\r
-       wxCHECK2(b, return);\r
-\r
-       if(b->IsTreeMultiItemNode())\r
-       {\r
-               TreeMultiItemNode *n = (TreeMultiItemNode *)b;\r
-\r
-               // now do children of this node\r
-\r
-               for(int i = 0; i < n->GetNodeCount(); i++)\r
-                       CalculateNodeSpanning(n->GetNode(i));\r
-       }\r
-       else if(b->IsTreeMultiItemWindow())\r
-       {\r
-               TreeMultiItemWindow *w = (TreeMultiItemWindow *)b;\r
-               wxWindow *wnd = w->GetWindow();\r
-               if(wnd)\r
-               {\r
-                       // if the window is spanning, we adjust the width to the max width of the control\r
-                       if(w->GetHorizontalSpan())\r
-                       {\r
-                               wxSize tmcsize = GetClientSize();\r
-                               int maxwidth = tmcsize.GetWidth() - w->GetX() - 8; // extract 3 for border\r
-\r
-                               wxSizer *sz = wnd->GetSizer();\r
-                               if(sz)\r
-                               {\r
-                                       if(maxwidth < sz->GetMinSize().GetWidth())\r
-                                               maxwidth = sz->GetMinSize().GetWidth();\r
-                               }\r
-\r
-                               // prevent a size of 0\r
-                               if(maxwidth < 1)\r
-                                       maxwidth = 1;\r
-\r
-                               // set the size\r
-                               w->SetWidth(maxwidth);\r
-                               wnd->SetSize(w->GetWidth(), w->GetHeight());\r
-\r
-                               // layout by sizer (not sure if this is needed)\r
-                               if(wnd->GetSizer())\r
-                                       wnd->GetSizer()->Layout();\r
-                       }\r
-               }\r
-       }\r
-}\r
-\r
-void wxTreeMultiCtrl::RecalculateVirtualSize()\r
-{\r
-       // go through all the nodes, and store the largest x and largest y\r
-\r
-       int x = 0, y = 0;\r
-       RecalculateVirtualSizeFromNode(&_root, x, y);\r
-\r
-       // now adjust virtual size\r
-       SetVirtualSize(x, y);\r
-       AdjustScrollbars(x, y);\r
-}\r
-\r
-void wxTreeMultiCtrl::AdjustScrollbars(int x, int y)\r
-{\r
-       // adjust scrollbars\r
-       // courtesy of treectrlg.cpp\r
-\r
-       y += WXTMC_PIXELS_PER_UNIT+2; // one more scrollbar unit + 2 pixels\r
-    x += WXTMC_PIXELS_PER_UNIT+2; // one more scrollbar unit + 2 pixels\r
-    int x_pos = GetScrollPos( wxHORIZONTAL );\r
-    int y_pos = GetScrollPos( wxVERTICAL );\r
-    SetScrollbars( WXTMC_PIXELS_PER_UNIT, WXTMC_PIXELS_PER_UNIT, x/WXTMC_PIXELS_PER_UNIT,\r
-                          y/WXTMC_PIXELS_PER_UNIT, x_pos, y_pos, true );\r
-}\r
-\r
-void wxTreeMultiCtrl::RecalculateVirtualSizeFromNode(const TreeMultiItemNode *node, int &x, int &y)\r
-{\r
-       if(node->IsExcluded())\r
-               return;\r
-\r
-       // if calulate this node's dimensions\r
-       if(x < (node->GetWidth() + node->GetX()))\r
-               x = node->GetWidth() + node->GetX();\r
-\r
-       y = node->GetY() + node->GetHeight();\r
-\r
-       // if this node is collapsed, no subnodes are visible, else\r
-       // go through all subnodes as well, node needs to be included as well\r
-       if(node->IsExpanded())\r
-       {\r
-               TreeMultiItemBase *b;\r
-               for(int i = 0; i < node->GetNodeCount(); i++)\r
-               {\r
-                       b = node->GetNode(i);\r
-\r
-                       // calculate x and y\r
-                       if(x < (b->GetWidth() + b->GetX()))\r
-                               x = b->GetWidth() + b->GetX();\r
-\r
-                       y = b->GetY() + b->GetHeight();\r
-\r
-                       if(b->IsTreeMultiItemNode())\r
-                               RecalculateVirtualSizeFromNode((TreeMultiItemNode *)b, x, y);\r
-               }\r
-       }\r
-}\r
-\r
-void wxTreeMultiCtrl::SetWindowBackgroundColour(wxWindow *wnd, const wxColour &col, int flags)\r
-{\r
-       if(wnd)\r
-       {\r
-               // if we cannot change a button, make sure all button\r
-               // classes are not changed\r
-\r
-               wxButton *btn = wxDynamicCast(wnd, wxButton);\r
-               if(!btn || ((flags & wxTMC_BG_ADJUST_BTN) != 0))\r
-                       wnd->SetBackgroundColour(col);\r
-\r
-               // get every window, and make the background equal to the given one\r
-               wxWindowListNode *node = wnd->GetChildren().GetFirst();\r
-               while (node)\r
-               {\r
-                       SetWindowBackgroundColour(node->GetData(), col, flags);\r
-                       node = node->GetNext();\r
-               }\r
-       }\r
-}\r
-\r
-void wxTreeMultiCtrl::ShowTreeMultiWindow(TreeMultiItemWindow *window, bool show)\r
-{\r
-       // show or hide window\r
-       if(window && window->GetWindow())\r
-               window->GetWindow()->Show(show);\r
-}\r
-\r
-void wxTreeMultiCtrl::UpdateAllWindowVisibility()\r
-{\r
-       // all roots are visible, but what lies beneath ... who knows\r
-       for(int i = 0; i < _root.GetNodeCount(); i++)\r
-               UpdateTreeMultiWindowVisibility(_root.GetNode(i), true);\r
-}\r
-\r
-void wxTreeMultiCtrl::UpdateTreeMultiWindowVisibility(TreeMultiItemBase *b, bool show)\r
-{\r
-       if(b)\r
-       {\r
-               // this is done for performance issues. IsVisible can go all\r
-               // the way up the tree to check. However if show is already\r
-               // false, there is no need to check (some higher one is collapsed)\r
-               bool showMe = show;\r
-\r
-               if(showMe)\r
-                       showMe = b->IsVisible();\r
-\r
-               if(b->IsTreeMultiItemWindow())\r
-               {\r
-                       // if this level must be hidden, hide\r
-                       ShowTreeMultiWindow((TreeMultiItemWindow*)b, showMe);\r
-               }\r
-               else if(b->IsTreeMultiItemNode())\r
-               {\r
-                       TreeMultiItemNode *node = (TreeMultiItemNode *)b;\r
-\r
-                       // if hidden, descend and hide all windows\r
-                       for(int i = 0; i < node->GetNodeCount(); i++)\r
-                               UpdateTreeMultiWindowVisibility(node->GetNode(i), showMe);\r
-               }\r
-       }\r
-}\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::FindItem(const wxTreeMultiItem &item, const wxString &name, bool ignoreCase, bool skipFirst)\r
-{\r
-       if(item.IsOk())\r
-       {\r
-               TreeMultiItemBase *b = item.GetItem();\r
-\r
-               // check this item first (or not)\r
-\r
-               if(!skipFirst)\r
-               {\r
-                       if(b->GetName().IsSameAs(name, !ignoreCase))\r
-                               return wxTreeMultiItem(b);\r
-               }\r
-\r
-               if(b->IsTreeMultiItemNode())\r
-               {\r
-                       // now check whether we are a node, then go check children\r
-\r
-                       TreeMultiItemNode *n = (TreeMultiItemNode *)b;\r
-                       wxTreeMultiItem result(0);\r
-                       for(int i = 0; i < n->GetNodeCount() && !result.IsOk(); i++)\r
-                               result = FindItem(wxTreeMultiItem(n->GetNode(i)), name, ignoreCase, false);\r
-\r
-                       return result;\r
-               }\r
-       }\r
-\r
-       return wxTreeMultiItem(0);\r
-}\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::FindWindowNode(wxWindow *wnd, TreeMultiItemNode *n)\r
-{\r
-       wxCHECK(wnd, wxTreeMultiItem(0));\r
-\r
-       // take root node if not assigned one\r
-\r
-       if(!n)\r
-               n = (TreeMultiItemNode *)&_root;\r
-\r
-       // check on this level for the wxWindow pointer\r
-\r
-       TreeMultiItemWindow *w;\r
-       wxTreeMultiItem result(0);\r
-       for(int i = 0; i < n->GetNodeCount() && !result.IsOk(); i++)\r
-       {\r
-               // if window node\r
-               w = n->GetNode(i)->IsTreeMultiItemWindow();\r
-               if(w && w->GetWindow() == wnd)\r
-                       return wxTreeMultiItem(n);\r
-\r
-               // if node, go deeper\r
-               if(n->GetNode(i)->IsTreeMultiItemNode())\r
-                       result = FindWindowNode(wnd, (TreeMultiItemNode*)n->GetNode(i));\r
-       }\r
-\r
-       return result;\r
-}\r
-\r
-TreeMultiItemWindow *wxTreeMultiCtrl::FindNextVisibleWindowItem(TreeMultiItemBase *b, int index)\r
-{\r
-       wxCHECK(b, 0);\r
-\r
-       // check on this level, go deeper with every node we got. When a node is not\r
-       // visible anymore, skip the node.\r
-\r
-       TreeMultiItemWindow *value = 0;\r
-       if(b->IsVisible())\r
-       {\r
-               // if we are already searching on a node with an index\r
-\r
-               TreeMultiItemBase *bn = 0;\r
-               TreeMultiItemNode *n = b->IsTreeMultiItemNode();\r
-               if(n)\r
-               {\r
-                       for(int i = index + 1; i < n->GetNodeCount() && !value; i++)\r
-                       {\r
-                               bn = n->GetNode(i);\r
-                               value = bn->IsTreeMultiItemWindow();\r
-\r
-                               // assume a node, root when not a a window\r
-                               if(!value)\r
-                                       value = FindNextVisibleWindowItem(bn, -1);\r
-                       }\r
-\r
-               }\r
-               else\r
-               {\r
-                       if(b->IsTreeMultiItemWindow())\r
-                       {\r
-                               // get parent first, and locate child as ptr\r
-                               TreeMultiItemNode *p = b->GetParent();\r
-                               wxCHECK(p, 0);\r
-\r
-                               // go scan the parent from the given index, if\r
-                               // the index is valid else there is no child with that index\r
-\r
-                               int idx = p->Index(b);\r
-                               wxCHECK(idx >= 0, 0);\r
-\r
-                               value = FindNextVisibleWindowItem(p, idx);\r
-                       }\r
-               }\r
-       }\r
-\r
-       return value;\r
-\r
-}\r
-\r
-bool wxTreeMultiCtrl::GetBooleanValue(int wndId)\r
-{\r
-       wxWindow *wnd = wxWindow::FindWindow(wndId);\r
-       wxCHECK(wnd, false);\r
-\r
-       // try a radio button\r
-       wxRadioButton *b = wxDynamicCast(wnd, wxRadioButton);\r
-       if(b)\r
-               return b->GetValue();\r
-\r
-       // try a check box\r
-       wxCheckBox *c = wxDynamicCast(wnd, wxCheckBox);\r
-       if(c)\r
-               return c->GetValue();\r
-\r
-       /** \todo For custom controls we should put something in wxMultiTreeItemData class\r
-           which can be overridden to retrieve the boolean value. It will also be passed\r
-           the pointer to the window, so the derived class can figure out how to get a boolean\r
-           value.\r
-       */\r
-\r
-       // generate assert or just return with false\r
-       wxCHECK(0, false);\r
-}\r
-\r
-void wxTreeMultiCtrl::SetBooleanValue(int wndId, bool value)\r
-{\r
-       wxWindow *wnd = wxWindow::FindWindow(wndId);\r
-       wxCHECK2(wnd, return);\r
-\r
-       // try a radio button\r
-       wxRadioButton *b = wxDynamicCast(wnd, wxRadioButton);\r
-       if(b)\r
-       {\r
-               b->SetValue(value);\r
-               return;\r
-       }\r
-\r
-       // try a check box\r
-       wxCheckBox *c = wxDynamicCast(wnd, wxCheckBox);\r
-       if(c)\r
-       {\r
-               c->SetValue(value);\r
-               return;\r
-       }\r
-\r
-       /** \todo For custom controls we should put something in wxMultiTreeItemData class\r
-                   which can be overridden to retrieve the boolean value. It will also be passed\r
-                   the pointer to the window, so the derived class can figure out how to get a boolean\r
-                   value.\r
-       */\r
-\r
-       // generate assert\r
-       wxCHECK2(0, return);\r
-}\r
-\r
-void wxTreeMultiCtrl::SetTextValue(int wndId, const wxString &value)\r
-{\r
-       wxWindow *wnd = wxWindow::FindWindow(wndId);\r
-       wxCHECK2(wnd, return);\r
-\r
-       // try a radio button\r
-       wxTextCtrl *t = wxDynamicCast(wnd, wxTextCtrl);\r
-       if(t)\r
-       {\r
-               t->SetValue(value);\r
-               return;\r
-       }\r
-\r
-       /** \todo For custom controls we should put something in wxMultiTreeItemData class\r
-                   which can be overridden to retrieve the boolean value. It will also be passed\r
-                   the pointer to the window, so the derived class can figure out how to get a boolean\r
-                   value.\r
-       */\r
-\r
-       // generate assert\r
-       wxCHECK2(0, return);\r
-}\r
-\r
-wxString wxTreeMultiCtrl::GetTextValue(int wndId)\r
-{\r
-       wxWindow *wnd = wxWindow::FindWindow(wndId);\r
-       wxCHECK(wnd, wxEmptyString);\r
-\r
-       // try a radio button\r
-       wxTextCtrl *t = wxDynamicCast(wnd, wxTextCtrl);\r
-       if(t)\r
-               return t->GetValue();\r
-\r
-       // try a choice box\r
-       wxChoice *c1 = wxDynamicCast(wnd, wxChoice);\r
-       if(c1)\r
-               return c1->GetStringSelection();\r
-\r
-       // try a combo box\r
-       wxComboBox *c2 = wxDynamicCast(wnd, wxComboBox);\r
-       if(c2)\r
-               return c2->GetStringSelection();\r
-\r
-       // try a listbox\r
-       wxListBox *l = wxDynamicCast(wnd, wxListBox);\r
-       if(l)\r
-               return l->GetStringSelection();\r
-\r
-       /** \todo For custom controls we should put something in wxMultiTreeItemData class\r
-           which can be overridden to retrieve the boolean value. It will also be passed\r
-           the pointer to the window, so the derived class can figure out how to get a boolean\r
-           value.\r
-       */\r
-\r
-       // generate assert or just return with string\r
-       wxCHECK(0, wxEmptyString);\r
-}\r
-\r
-int wxTreeMultiCtrl::GetSelectionValue(int wndId)\r
-{\r
-       wxWindow *wnd = wxWindow::FindWindow(wndId);\r
-       wxCHECK(wnd, -1);\r
-\r
-       // try a choice box\r
-       wxChoice *c1 = wxDynamicCast(wnd, wxChoice);\r
-       if(c1)\r
-               return c1->GetSelection();\r
-\r
-       // try a combo box\r
-       wxComboBox *c2 = wxDynamicCast(wnd, wxComboBox);\r
-       if(c2)\r
-               return c2->GetSelection();\r
-\r
-       // try a listbox\r
-       wxListBox *l = wxDynamicCast(wnd, wxListBox);\r
-       if(l)\r
-               return l->GetSelection();\r
-\r
-       /** \todo For custom controls we should put something in wxMultiTreeItemData class\r
-           which can be overridden to retrieve the boolean value. It will also be passed\r
-           the pointer to the window, so the derived class can figure out how to get a boolean\r
-           value.\r
-       */\r
-\r
-       // generate assert or just return with string\r
-       wxCHECK(0, -1);\r
-}\r
-\r
-void wxTreeMultiCtrl::GetSelectionValues(int wndId, wxArrayInt &sels)\r
-{\r
-       sels.Clear();\r
-\r
-       wxWindow *wnd = wxWindow::FindWindow(wndId);\r
-       wxCHECK2(wnd, return);\r
-\r
-       // try a listbox\r
-       wxListBox *l = wxDynamicCast(wnd, wxListBox);\r
-       if(l)\r
-       {\r
-               l->GetSelections(sels);\r
-               return;\r
-       }\r
-\r
-       /** \todo For custom controls we should put something in wxMultiTreeItemData class\r
-           which can be overridden to retrieve the boolean value. It will also be passed\r
-           the pointer to the window, so the derived class can figure out how to get a boolean\r
-           value.\r
-       */\r
-\r
-       // generate assert or just return with string\r
-       wxCHECK2(0, return);\r
-}\r
-\r
-void wxTreeMultiCtrl::SetSelectionValue(int wndId, int sel)\r
-{\r
-       wxWindow *wnd = wxWindow::FindWindow(wndId);\r
-       wxCHECK2(wnd, return);\r
-\r
-       // try a choice box\r
-       wxChoice *c1 = wxDynamicCast(wnd, wxChoice);\r
-       if(c1)\r
-       {\r
-               c1->SetSelection(sel);\r
-               return;\r
-       }\r
-\r
-       // try a combo box\r
-       wxComboBox *c2 = wxDynamicCast(wnd, wxComboBox);\r
-       if(c2)\r
-       {\r
-               c2->SetSelection(sel);\r
-               return;\r
-       }\r
-\r
-       // try a listbox\r
-       wxListBox *l = wxDynamicCast(wnd, wxListBox);\r
-       if(l)\r
-       {\r
-               l->SetSelection(sel);\r
-               return;\r
-       }\r
-\r
-       /** \todo For custom controls we should put something in wxMultiTreeItemData class\r
-           which can be overridden to retrieve the boolean value. It will also be passed\r
-           the pointer to the window, so the derived class can figure out how to get a boolean\r
-           value.\r
-       */\r
-\r
-       // generate assert or just return with string\r
-       wxCHECK2(0, return);\r
-}\r
-\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::GetParent(wxTreeMultiItem const& item) const\r
-{\r
- // check if valid or root item has been passed, both do not have parents:\r
-  if (!(item.IsOk()) || item.GetItem()->IsTreeMultiItemRoot())\r
-    return wxTreeMultiItem();\r
-  else\r
-    return wxTreeMultiItem(item.GetItem()->GetParent()); // GetParent() returns a valid pointer in case of a root item!!\r
-                                                         // therefore, the check if the passed item is a root item is necessary\r
-} /* wxTreeMultiCtrl::GetParent(wxTreeMultiItem const& item) const */\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::GetFirstChild(const wxTreeMultiItem &item, int &cookie) const\r
-{\r
-       if(item.IsNodeItem())\r
-       {\r
-               TreeMultiItemNode *n = (TreeMultiItemNode *)item.GetItem();\r
-\r
-               if(n->GetNodeCount() > 0)\r
-               {\r
-                       cookie = 0;\r
-                       return wxTreeMultiItem(n->GetNode(0));\r
-               }\r
-       }\r
-\r
-       // no children or no valid node\r
-       cookie = -1;\r
-       return wxTreeMultiItem(0);\r
-}\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::GetNextChild(const wxTreeMultiItem &item, int &cookie) const\r
-{\r
-       if(item.IsNodeItem())\r
-       {\r
-               TreeMultiItemNode *n = (TreeMultiItemNode *)item.GetItem();\r
-\r
-               if(cookie >= 0 && cookie < (n->GetNodeCount()-1))\r
-               {\r
-                       // increment cookie, return node\r
-                       cookie ++;\r
-                       return wxTreeMultiItem(n->GetNode(cookie));\r
-               }\r
-       }\r
-\r
-       // end of query, or no valid node\r
-       cookie = -1;\r
-       return wxTreeMultiItem(0);\r
-}\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::GetLastChild(const wxTreeMultiItem &item) const\r
-{\r
-       if(item.IsNodeItem())\r
-       {\r
-               TreeMultiItemNode *n = (TreeMultiItemNode *)item.GetItem();\r
-\r
-               if(n->GetNodeCount() > 0)\r
-                       return wxTreeMultiItem(n->GetNode(n->GetNodeCount()-1));\r
-       }\r
-\r
-        return wxTreeMultiItem(0);\r
-}\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::GetNextSibling(wxTreeMultiItem const& item) const\r
-{\r
- // check if a valid item has been passed:\r
-  if (!(item.IsOk()))\r
-    return wxTreeMultiItem();\r
-\r
-  TreeMultiItemNode* ParentPtr(item.GetItem()->GetParent());\r
-\r
-\r
-  if (ParentPtr != NULL) // the parent pointer is only null if the passed item is the root\r
-  {\r
-   // find the current item in the parent's list; the next sibling has an index that is one higher than the one of the current item:\r
-    int NextItemIndex(ParentPtr->Index(item.GetItem())+1); // variable definition and initialization\r
-\r
-    if (NextItemIndex < ParentPtr->GetNodeCount())\r
-      return ParentPtr->GetNode(NextItemIndex);\r
-    else\r
-      return wxTreeMultiItem();\r
-  } /* if */\r
-  else\r
-    return wxTreeMultiItem();\r
-} /* wxTreeMultiCtrl::GetNextSibling(wxTreeMultiItem const&) const */\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::GetPrevSibling(wxTreeMultiItem const& item) const\r
-{\r
- // check if a valid item has been passed:\r
-  if (!(item.IsOk()))\r
-    return wxTreeMultiItem();\r
-\r
-  TreeMultiItemNode* ParentPtr(item.GetItem()->GetParent());\r
-\r
-\r
-  if (ParentPtr != NULL)\r
-  {\r
-   // find the current item in the parent's list; the next sibling has an index that is one higher than the one of the current item:\r
-    int PrevItemIndex(ParentPtr->Index(item.GetItem())-1); // variable definition and initialization\r
-\r
-    if (PrevItemIndex >= 0)\r
-      return ParentPtr->GetNode(PrevItemIndex);\r
-    else\r
-      return wxTreeMultiItem();\r
-  } /* if */\r
-  else\r
-    return wxTreeMultiItem();\r
-} /* wxTreeMultiCtrl::GetPrevSibling(wxTreeMultiItem const&) const */\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::GetNext(wxTreeMultiItem const& item) const\r
-{\r
- // check if a valid item has been passed:\r
-  if (!(item.IsOk()))\r
-    return wxTreeMultiItem();\r
-\r
-  TreeMultiItemNode* NodePtr(item.GetItem()->IsTreeMultiItemNode()); // variable definition and initialization\r
-\r
-  if ((NodePtr != NULL) && (NodePtr->GetNodeCount() > 0))\r
-    return wxTreeMultiItem(NodePtr->First());\r
-  else\r
-  {\r
-   // variable definitions and initializations:\r
-    wxTreeMultiItem Parent(item);\r
-    wxTreeMultiItem Sibling;\r
-\r
-    do\r
-    {\r
-      Sibling = this->GetNextSibling(Parent); // try to find next sibling\r
-      Parent = this->GetParent(Parent);       // get next ancestor\r
-    } while (!(Sibling.IsOk()) && Parent.IsOk());\r
-   // in case the loop ended with Sibling.IsOk() "Sibling" contains a valid sibling otherwise an invalid\r
-    return Sibling;\r
-  } /* if */\r
-} /* wxTreeMultiCtrl::GetNextSibling(wxTreeMultiItem const&) const */\r
-\r
-wxTreeMultiItem wxTreeMultiCtrl::GetPrevious(wxTreeMultiItem const& item) const\r
-{\r
- // check if a valid item has been passed:\r
-  if (!(item.IsOk()))\r
-    return wxTreeMultiItem();\r
-\r
-  TreeMultiItemNode* NodePtr(item.GetItem()->IsTreeMultiItemNode()); // variable definition and initialization\r
-\r
-  if ((NodePtr != NULL) && (NodePtr->GetNodeCount() > 0))\r
-    return wxTreeMultiItem(NodePtr->Last());\r
-  else\r
-  {\r
-   // variable definitions and initializations:\r
-    wxTreeMultiItem Parent(item);\r
-    wxTreeMultiItem Sibling;\r
-\r
-    do\r
-    {\r
-      Sibling = this->GetPrevSibling(Parent); // try to find next sibling\r
-      Parent = this->GetParent(Parent);       // get next ancestor\r
-    } while (!(Sibling.IsOk()) && Parent.IsOk());\r
-   // in case the loop ended with Sibling.IsOk() "Sibling" contains a valid sibling otherwise an invalid\r
-    return Sibling;\r
-  } /* if */\r
-} /* wxTreeMultiCtrl::GetPrevious(wxTreeMultiItem const&) const */\r
-\r
-// WDR: handler implementations for wxTreeMultiCtrl\r
-\r
-void wxTreeMultiCtrl::OnDraw(wxDC& dc)\r
-{\r
-        // go recursive and draw the whole visible tree.\r
-        dc.SetFont(_captionFont);\r
-        for(int i = 0; i < _root.GetNodeCount(); i++)\r
-                DrawNode(_root.GetNode(i), dc);\r
-} /*  */\r
+//---------------------------------------------------------------------------
+// $RCSfile: wxTreeMultiCtrl.cpp,v $
+// $Source: /cvs/creatis/bbtk/kernel/src/ThirdParty/wx/treemultictrl/wxTreeMultiCtrl.cpp,v $
+// $Revision: 1.2 $
+// $Date: 2009/10/05 22:44:50 $
+//---------------------------------------------------------------------------
+// Author:      Jorgen Bodde
+// Copyright:   (c) Jorgen Bodde
+// License:     wxWidgets License
+//---------------------------------------------------------------------------
+
+#ifdef __GNUG__
+    #pragma implementation "wxTreeMultiCtrl.h"
+#endif
+
+// For compilers that support precompilation, includes "wx/wx.h".
+#include "wx/wxprec.h"
+#include "wx/treebase.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/arrimpl.cpp"
+
+#include "wx/treemultictrl/wxTreeMultiCtrl.h"
+#include "wx/treemultictrl/wxTreeMultiEvent.h"
+#include "tmcimages.h"
+
+
+
+//----------------------------------------------------------------------------
+// wxTreeMultiItem
+//----------------------------------------------------------------------------
+
+WX_DEFINE_OBJARRAY(wxArrayTreeMultiItem);
+
+//----------------------------------------------------------------------------
+// wxTreeMultiCtrl
+//----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxTreeMultiCtrl, wxScrolledWindow)
+
+// WDR: event table for wxTreeMultiCtrl
+BEGIN_EVENT_TABLE(wxTreeMultiCtrl, wxScrolledWindow)
+  EVT_LEFT_DOWN  (wxTreeMultiCtrl::OnMouseClick)
+  EVT_LEFT_DCLICK(wxTreeMultiCtrl::OnMouseClick)
+  EVT_RIGHT_DOWN (wxTreeMultiCtrl::OnRightMouseClick)
+  EVT_PAINT(wxTreeMultiCtrl::OnPaint)
+  EVT_SIZE(wxTreeMultiCtrl::OnSize)
+//  EVT_KEY_UP(wxTreeMultiCtrl::OnKey)
+END_EVENT_TABLE()
+
+bool wxTreeMultiCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos,
+                               const wxSize& size, long style, const wxValidator & WXUNUSED(validator),
+                               const wxString& name )
+{
+    wxScrolledWindow::Create( parent, id, pos, size, style | wxTAB_TRAVERSAL, name);
+
+        _create_called = true;
+
+       // do the init
+       Init();
+
+    return TRUE;
+}
+
+void wxTreeMultiCtrl::Init()
+{
+       _root.Clear();
+
+       _expandBmp = 0;
+       _collBmp = 0;
+
+#if(CHECKBOXVIEW)
+       _checkBmp = 0;
+       _uncheckBmp = 0;
+       _tristateBmp = 0;
+
+       _checkHeight = 11;
+       _checkWidth = 11;
+
+       _checkboxView = false;
+#endif
+
+       _gutterWidth = WXTMC_GUTTER_DEFAULT;
+       _iconWidth = 11;
+       _iconHeight = 11;
+       _maxHeight = 1;;
+       _iconDeltaY = 2;
+       _spacingY = WXTMC_YSPACING_DEFAULT;
+       _captionHeight = 13;
+
+       // create two bitmap nodes for drawing
+
+       _expandBmp = new wxBitmap(expand_xpm);
+       _collBmp = new wxBitmap(collapse_xpm);
+
+       // calculate average font height for bitmap centering
+
+       _iconWidth = _expandBmp->GetWidth();
+       _iconHeight = _expandBmp->GetHeight();
+
+#if(CHECKBOXVIEW)
+       // create bitmaps for checkboxes
+       _checkBmp = new wxBitmap(checked_icon);
+       _uncheckBmp = new wxBitmap(unchecked_icon);
+       _tristateBmp = new wxBitmap(tristate_icon);
+
+       // adjust the height if the checkboxes are higher
+       // so that everything is alligned properly
+       _checkHeight = _checkBmp->GetHeight();
+       _checkWidth = _checkBmp->GetWidth();
+#endif
+
+       // remember the highest of the two bitmaps so there is
+       // always enough room
+       _maxHeight = _iconHeight;
+
+#if(CHECKBOXVIEW)
+       if(_maxHeight < _checkHeight)
+                _maxHeight = _checkHeight;
+#endif
+
+ // set standard highlighting brush
+  this->m_HilightBrush = new wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT),wxSOLID);
+
+        // set standard DC font
+    _captionFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
+
+        // adjust bitmap icon y position so they are centered
+        AdjustIconsDeltaY();
+
+       // set virtual size to this window size
+       if (_create_called) {
+               wxSize wndsize = GetSize();
+               SetVirtualSize(wndsize.GetWidth(), wndsize.GetWidth());
+       }
+}
+
+void wxTreeMultiCtrl::SetCaptionFont(const wxFont &font)
+{
+       _captionFont = font;
+
+       // adjust the icons so that they are in the middle
+       AdjustIconsDeltaY();
+
+       RedrawFromNode(0);
+};
+
+void wxTreeMultiCtrl::AdjustIconsDeltaY()
+{
+       int x = 0, y = 0;
+
+       if(_captionFont.Ok())
+      GetTextExtent(wxT("jG"), &x, &y, 0, 0, &_captionFont);
+       _captionHeight = y;
+
+       if(_maxHeight < _captionHeight)
+               _maxHeight = _captionHeight;
+
+       // determine the center pos for the [+]
+       _iconDeltaY = abs(_maxHeight - _iconHeight) / 2 + 1;
+       if(_iconDeltaY < 1)
+               _iconDeltaY = 1;
+
+#if(CHECKBOXVIEW)
+       // determine the center pos for the checkbox
+       _checkDeltaY = abs(_maxHeight - _checkHeight) / 2 + 1;
+       if(_checkDeltaY < 1)
+               _checkDeltaY = 1;
+#endif
+}
+
+wxTreeMultiCtrl::~wxTreeMultiCtrl()
+{
+       // delete the bitmap resources
+       delete _expandBmp;
+       delete _collBmp;
+
+#if(CHECKBOXVIEW)
+       delete _checkBmp;
+       delete _uncheckBmp;
+       delete _tristateBmp;
+#endif
+}
+
+wxTreeMultiItem wxTreeMultiCtrl::AddRoot(const wxString &caption, const wxString &name)
+{
+       wxTreeMultiItem result((TreeMultiItemBase *)&_root);
+       result = AppendNode(result, caption, name);
+
+        return result;
+}
+
+wxTreeMultiItem wxTreeMultiCtrl::AppendWindow(const wxTreeMultiItem &ParentItem, wxWindow *window, const wxString &name, const wxTreeMultiWindowInfo &info, int flags)
+{
+ // add window only if the parent item is valid and...
+        wxCHECK(ParentItem.IsOk(), wxTreeMultiItem(0));
+
+        TreeMultiItemNode* parent = ParentItem.GetItem()->IsTreeMultiItemNode(); // also roots are nodes
+
+ // ... is a node
+  wxCHECK(parent != NULL, wxTreeMultiItem(0));
+
+ // now, append node to the tree control:
+  wxTreeMultiItem NewWindowItem(this->InsertWindow(parent,wx_static_cast(size_t,parent->GetNodeCount()),window,name,info,flags));
+ // redraw the stucture:
+        this->RedrawFromNode(parent);
+ // return the new window
+        return NewWindowItem;
+}
+
+wxTreeMultiItem wxTreeMultiCtrl::InsertWindow(wxTreeMultiItem const& ParentItem, size_t Position, wxWindow *window, wxString const& name, wxTreeMultiWindowInfo const& info, int flags)
+{
+ // add window only if the parent item is valid and...
+        wxCHECK(ParentItem.IsOk(), wxTreeMultiItem(0));
+
+        TreeMultiItemNode* parent = ParentItem.GetItem()->IsTreeMultiItemNode(); // also roots are nodes
+
+ // ... is a node
+  wxCHECK(parent != NULL, wxTreeMultiItem(0));
+
+ // now, append node to the tree control:
+  wxTreeMultiItem NewWindowItem(this->InsertWindow(parent,Position,window,name,info,flags));
+ // redraw the stucture:
+        this->RedrawFromNode(parent);
+ // return the new window
+        return NewWindowItem;
+} /* wxTreeMultiCtrl::InsertWindow(wxTreeMultiItem const&, size_t, wxWindow*, wxString const&, wxTreeMultiWindowInfo const&, int) */
+
+wxTreeMultiItem wxTreeMultiCtrl::PrependWindow(wxTreeMultiItem const& ParentItem, wxWindow *window, const wxString &name, wxTreeMultiWindowInfo const& info, int flags)
+{
+ // add window only if the parent item is valid and...
+        wxCHECK(ParentItem.IsOk(), wxTreeMultiItem(0));
+
+        TreeMultiItemNode* parent = ParentItem.GetItem()->IsTreeMultiItemNode(); // also roots are nodes
+
+ // ... is a node
+  wxCHECK(parent != NULL, wxTreeMultiItem(0));
+
+ // now, append node to the tree control:
+  wxTreeMultiItem NewWindowItem(this->InsertWindow(parent,0,window,name,info,flags));
+ // redraw the stucture:
+        this->RedrawFromNode(parent);
+ // return the new window
+        return NewWindowItem;
+} /* wxTreeMultiCtrl::PrependWindow(wxTreeMultiItem const&, wxWindow*, const wxString &, wxTreeMultiWindowInfo const&, int) */
+
+wxTreeMultiItem wxTreeMultiCtrl::AppendNode(wxTreeMultiItem const& ParentItem, const wxString &caption, const wxString &name)
+{
+ // add window only if the parent item is valid and...
+        wxCHECK(ParentItem.IsOk(), wxTreeMultiItem(0));
+
+        TreeMultiItemNode* parent = ParentItem.GetItem()->IsTreeMultiItemNode(); // also roots are nodes
+
+ // ... is a node
+  wxCHECK(parent != NULL, wxTreeMultiItem(0));
+
+ // now, append node to the tree control:
+  wxTreeMultiItem NewNodeItem(this->InsertNode(parent,wx_static_cast(size_t,parent->GetNodeCount()),caption,name));
+ // redraw the structure:
+        this->RedrawFromNode(parent);
+ // return the new node:
+        return NewNodeItem;
+} /* wxTreeMultiCtrl::AppendNode(wxTreeMultiItem const&, const wxString &, const wxString&) */
+
+wxTreeMultiItem wxTreeMultiCtrl::InsertNode(wxTreeMultiItem const& ParentItem, size_t Position, wxString const& caption, wxString const& name)
+{
+ // add window only if the parent item is valid and...
+        wxCHECK(ParentItem.IsOk(), wxTreeMultiItem(0));
+
+        TreeMultiItemNode* parent = ParentItem.GetItem()->IsTreeMultiItemNode(); // also roots are nodes
+
+ // ... is a node
+  wxCHECK(parent != NULL, wxTreeMultiItem(0));
+
+ // now, append node to the tree control:
+  wxTreeMultiItem NewNodeItem(this->InsertNode(parent,Position,caption,name));
+ // redraw the structure:
+        this->RedrawFromNode(parent);
+ // return the new node:
+        return NewNodeItem;
+} /* wxTreeMultiCtrl::InsertNode(wxTreeMultiItem const&, size_t, wxString const&, wxString const&) */
+
+wxTreeMultiItem wxTreeMultiCtrl::PrependNode(wxTreeMultiItem const& ParentItem, wxString const& caption, wxString const& name)
+{
+ // add window only if the parent item is valid and...
+        wxCHECK(ParentItem.IsOk(), wxTreeMultiItem(0));
+
+        TreeMultiItemNode* parent = ParentItem.GetItem()->IsTreeMultiItemNode(); // also roots are nodes
+
+ // ... is a node
+  wxCHECK(parent != NULL, wxTreeMultiItem(0));
+
+ // now, append node to the tree control:
+  wxTreeMultiItem NewNodeItem(this->InsertNode(parent,0,caption,name));
+ // redraw the structure:
+        this->RedrawFromNode(parent);
+ // return the new node:
+        return NewNodeItem;
+} /* wxTreeMultiCtrl::PrependNode(wxTreeMultiItem const&, wxString const&, wxString const&) */
+
+bool wxTreeMultiCtrl::Delete(wxTreeMultiItem &item)
+{
+       bool redraw = true;
+       wxCHECK(item.IsOk(), false);
+
+        wxTreeMultiItem nullItem(0);
+
+
+ // if item has been selected, remove it from the selected list:
+  size_t ItemIndex(this->GetSelectedItemIndex(item));
+
+  if (ItemIndex != this->GetSelectedItemCount())
+    this->m_SelectedItems.RemoveAt(ItemIndex);
+
+        // get parent, to delete item from
+        TreeMultiItemNode *p = item.GetItem()->GetParent();
+
+       // first check if it was visible, if so from the parent off
+       // it needs redrawing
+       redraw = item.GetItem()->IsVisible();
+       if(p)
+               p->DeleteNode(item.GetItem());
+       else
+               _root.DeleteNode(item.GetItem());
+
+       item = nullItem;
+
+       // do redraw when node was visible
+       if(redraw)
+               RedrawFromNode(p);
+
+       return true;
+}
+
+void wxTreeMultiCtrl::DeleteChildren(const wxTreeMultiItem &item)
+{
+        if(item.IsNodeItem())
+        {
+                TreeMultiItemNode *n = (TreeMultiItemNode *)item.GetItem();
+
+   // remove all children from the selected item list:
+          if (n->GetNodeCount() > 0)
+          {
+           // variable definitions and initializations:
+            int Cookie;
+            wxTreeMultiItem FirstItemIterator(this->GetFirstChild(item,Cookie)), LastItemIterator(this->GetLastChild(item));
+
+            for (;;)
+            {
+              size_t ItemIndex(this->GetSelectedItemIndex(item)); // variable definition and initialization
+
+              if (ItemIndex != this->GetSelectedItemCount())
+                this->m_SelectedItems.RemoveAt(ItemIndex);
+              if (FirstItemIterator == LastItemIterator)
+                break; // all children checked
+              else
+                FirstItemIterator = this->GetNext(FirstItemIterator);
+            } /* for */
+          } /* if */
+         // delete children:
+                n->Clear();
+        // redraw:
+                RedrawFromNode(n);
+        }
+}
+
+void wxTreeMultiCtrl::Expand(const wxTreeMultiItem &item, bool recursive)
+{
+       if(item.IsOk())
+       {
+        TreeMultiItemNode *n = item.GetItem()->IsTreeMultiItemNode();
+               if(!n)
+                       n = item.GetItem()->GetParent();
+        DoFold(n, true, recursive);
+               RedrawFromNode(item.GetItem()->IsTreeMultiItemNode());
+       }
+}
+
+void wxTreeMultiCtrl::Collapse(const wxTreeMultiItem &item, bool recursive)
+{
+       if(item.IsOk())
+       {
+        TreeMultiItemNode *n = item.GetItem()->IsTreeMultiItemNode();
+               if(!n)
+                       n = item.GetItem()->GetParent();
+               DoFold(n, false, recursive);
+               RedrawFromNode(item.GetItem()->IsTreeMultiItemNode());
+       }
+}
+
+
+void wxTreeMultiCtrl::ExpandNodes(bool recursive)
+{
+       // go through all children and call DoFold recursively
+       for(int i = 0; i < _root.GetNodeCount(); i++)
+               DoFold(_root.GetNode(i), true, recursive);
+       RedrawFromNode(0);
+}
+
+void wxTreeMultiCtrl::CollapseNodes(bool recursive)
+{
+       // go through all children and call DoFold recursively
+       for(int i = 0; i < _root.GetNodeCount(); i++)
+               DoFold(_root.GetNode(i), false, recursive);
+       RedrawFromNode(0);
+}
+
+void wxTreeMultiCtrl::CollapseAndReset(const wxTreeMultiItem &item)
+{
+       if(item.IsNodeItem())
+       {
+                TreeMultiItemNode *n = (TreeMultiItemNode *)item.GetItem();
+
+                // delete all kids
+                n->Clear();
+                Collapse(item, false);
+        }
+}
+
+// Selection manipulation
+wxTreeMultiItem wxTreeMultiCtrl::GetFirstSelectedItem(void) const
+{
+  if (this->GetSelectedItemCount() > 0)
+    return this->m_SelectedItems[0];
+  else
+    return wxTreeMultiItem();
+} /* wxTreeMultiCtrl::GetFirstSelectedItem(void) const */
+
+wxTreeMultiItem wxTreeMultiCtrl::GetLastSelectedItem(void) const
+{
+  if (this->GetSelectedItemCount() > 0)
+    return this->m_SelectedItems[this->GetSelectedItemCount()-1];
+  else
+    return wxTreeMultiItem();
+} /* wxTreeMultiCtrl::GetLastSelectedItem(void) const */
+
+wxTreeMultiItem wxTreeMultiCtrl::GetSelectedItem(size_t Index) const
+{
+  if (Index < this->GetSelectedItemCount())
+    return this->m_SelectedItems[Index];
+  else
+    return wxTreeMultiItem();
+} /* wxTreeMultiCtrl::GetSelectedItem(size_t Index) const */
+
+size_t wxTreeMultiCtrl::GetSelectedItemIndex(wxTreeMultiItem const& Item) const
+{
+ // attention: the function wxArray::Index() can NOT be used in a save manner as it only checks the address of an item
+ //            element but it is not guaranteed that Item may not be a copy of the originally inserted item
+  const size_t NoOfSelectedItems = this->GetSelectedItemCount();
+
+  size_t Index(0);
+
+
+  while ((Index < NoOfSelectedItems) && (this->m_SelectedItems[Index] != Item))
+    ++Index;
+  return Index;
+} /* wxTreeMultiCtrl::GetSelectedItemIndex(wxTreeMultiItem const&) const */
+
+void wxTreeMultiCtrl::SelectItem(wxTreeMultiItem const& Item, bool UnselectOthers, bool ExpandSelection)
+{
+  TreeMultiItemNode* NodePtr(Item.GetItem()->IsTreeMultiItemNode());
+
+
+ // only nodes can be selected and they can only be selected if they are not already selected:
+  if ((NodePtr == NULL) || NodePtr->IsSelected())
+   return;
+
+ // inform that we are about to change:
+  wxTreeMultiEvent Event(wxEVT_COMMAND_TREE_MULTI_SEL_CHANGING,Item); // variable definition and initialization
+
+  if (this->m_SelectedItems.GetCount() > 0) // the last item in the array is always the latest inserted item
+    Event.SetOldItem(this->m_SelectedItems.Last());
+  Event.SetEventObject(this);
+  if (this->GetEventHandler()->ProcessEvent(Event) && !(Event.IsAllowed()))
+      return; // vetoed
+
+ // make sure that the to be selected item can be seen:
+  this->Include(Item);
+
+ // variable definition and initialization:
+  wxTreeMultiItem ExcludedParent(this->GetExcludedParent(Item));
+
+  while (ExcludedParent.IsOk())
+  {
+    this->Include(ExcludedParent);
+    ExcludedParent = this->GetExcludedParent(Item);
+  } /* while */
+
+ // unselect items if necessary:
+  if (UnselectOthers)
+    this->UnselectAll();
+ // expand selection if necessary:
+  if (ExpandSelection)
+  {
+   // variable definition:
+    wxTreeMultiItem FirstItemIterator, LastItemIterator;
+    wxTreeMultiItem LastSelectedItem;
+
+   // determine the last selected item or the first item in case nothing has been selected before:
+    if (this->m_SelectedItems.GetCount() > 0)
+      LastSelectedItem = this->m_SelectedItems.Last();
+    else
+      LastSelectedItem = this->GetFirstRoot();
+   // determine the item from which to start and the one with which to end the selection:
+    if (Item.GetItem()->GetY() > LastSelectedItem.GetItem()->GetY())
+    {
+      FirstItemIterator = LastSelectedItem;
+      LastItemIterator  = Item;
+    } /* if */
+    else
+    {
+      FirstItemIterator = Item;
+      LastItemIterator  = LastSelectedItem;
+    } /* if */
+   // select all items that are a node and are placed between the two limiting iterators (included the limits):
+    for (;;)
+    {
+      if (!(FirstItemIterator.IsSelected()) && FirstItemIterator.IsNodeItem())
+      {
+        FirstItemIterator.GetItem()->Select();
+        this->m_SelectedItems.Add(FirstItemIterator);
+        this->RefreshRect(wxRect(FirstItemIterator.GetItem()->GetX(),    FirstItemIterator.GetItem()->GetY(),
+                                 FirstItemIterator.GetItem()->GetWidth(),FirstItemIterator.GetItem()->GetHeight()));
+      } /* if */
+      if (FirstItemIterator == LastItemIterator)
+        break; // done
+     // continue iterating:
+      FirstItemIterator = this->GetNext(FirstItemIterator);
+    } /* for */
+  } /* if */
+  else // select passed item only
+  {
+    NodePtr->Select();
+    this->m_SelectedItems.Add(NodePtr);
+    this->RefreshRect(wxRect(NodePtr->GetX(),NodePtr->GetY(),NodePtr->GetWidth(),NodePtr->GetHeight()));
+  } /* if */
+
+ // inform that we have selected the item:
+  Event.SetEventType(wxEVT_COMMAND_TREE_MULTI_SEL_CHANGED);
+  this->GetEventHandler()->ProcessEvent(Event);
+} /* wxTreeMultiCtrl::SelectItem(wxTreeMultiItem const&, bool, bool) */
+
+void wxTreeMultiCtrl::UnselectAll(void)
+{
+  const size_t NoOfSelectedItems = this->m_SelectedItems.GetCount();
+
+
+  for (size_t i=0; i<NoOfSelectedItems; ++i)
+  {
+    this->RefreshRect(wxRect(this->m_SelectedItems[i].GetItem()->GetX(),    this->m_SelectedItems[i].GetItem()->GetY(),
+                             this->m_SelectedItems[i].GetItem()->GetWidth(),this->m_SelectedItems[i].GetItem()->GetHeight()));
+    this->m_SelectedItems[i].GetItem()->Unselect();
+  } /* for */
+  this->m_SelectedItems.Clear();
+} /* wxTreeMultiCtrl::UnselectAll(void) */
+
+void wxTreeMultiCtrl::Unselect(wxTreeMultiItem const& Item)
+{
+  size_t ItemIndex(this->GetSelectedItemIndex(Item));
+
+
+  if (ItemIndex != this->GetSelectedItemCount())
+  {
+    Item.GetItem()->Unselect();
+    this->m_SelectedItems.RemoveAt(ItemIndex);
+    this->RefreshRect(wxRect(Item.GetItem()->GetX(),Item.GetItem()->GetY(),Item.GetItem()->GetWidth(),Item.GetItem()->GetHeight()));
+  } /* if */
+} /* wxTreeMultiCtrl::Unselect(wxTreeMultiItem const&) */
+
+void wxTreeMultiCtrl::DoFold(TreeMultiItemBase *item, bool expand, bool recursive)
+{
+
+       // go through all node objects on this level, and expand or
+       // collapse them
+
+       if(item == 0)
+               return;
+
+       // if this is a node, use it to go through all the subnodes (if needed)
+       // if not, then just exit.
+
+       TreeMultiItemNode *node = item->IsTreeMultiItemNode();
+       if(node)
+       {
+               node->Fold(expand);
+
+               // go recursive
+               if(recursive)
+               {
+                       TreeMultiItemNode *p;
+                       for(int i = 0; i < node->GetNodeCount(); i++)
+                       {
+                               // get node, and if a real node, then call fold
+                               p = node->GetNode(i)->IsTreeMultiItemNode();
+                               if(p)
+                                       p->Fold(expand);
+
+                               // go recursive for every node
+                               DoFold(p, expand, recursive);
+                       }
+               }
+       }
+}
+
+void wxTreeMultiCtrl::Exclude(const wxTreeMultiItem &item)
+{
+       wxCHECK2(item.IsOk(), return);
+
+       // exclude the item, and refresh
+       // if already excluded, skip
+
+       if(!item.GetItem()->IsExcluded())
+       {
+               item.GetItem()->SetExcluded(true);
+               RedrawFromParentNode(item.GetItem());
+       }
+}
+
+void wxTreeMultiCtrl::Include(const wxTreeMultiItem &item)
+{
+       wxCHECK2(item.IsOk(), return);
+
+       // include the item, and refresh. If not
+       // excluded, do nothing
+
+       if(item.GetItem()->IsExcluded())
+       {
+               item.GetItem()->SetExcluded(false);
+               RedrawFromParentNode(item.GetItem());
+       }
+}
+
+wxTreeMultiItem wxTreeMultiCtrl::GetExcludedParent(const wxTreeMultiItem &item)
+{
+       wxCHECK(item.IsOk(), wxTreeMultiItem(0));
+
+       // go find the parent (including this one) that
+       // can be the excluded one
+
+       TreeMultiItemNode *n = item.GetItem()->IsTreeMultiItemNode();
+       if(n && n->IsExcluded())
+               return wxTreeMultiItem(n);
+
+       n = item.GetItem()->GetParent();
+       while(n)
+       {
+               if(n->IsExcluded())
+                       return wxTreeMultiItem(n);
+               else
+                       n = n->GetParent();
+       }
+
+        return wxTreeMultiItem(0);
+}
+
+void wxTreeMultiCtrl::OnSize(wxSizeEvent &WXUNUSED(event))
+{
+        RecalculateSpanSizes();
+}
+
+void wxTreeMultiCtrl::OnPaint(wxPaintEvent& WXUNUSED(event) )
+{
+        wxPaintDC dc(this);
+
+        PrepareDC(dc);
+
+        // go recursive and draw the whole visible tree.
+        dc.SetFont(_captionFont);
+        for(int i = 0; i < _root.GetNodeCount(); i++)
+                DrawNode(_root.GetNode(i), dc);
+}
+
+void wxTreeMultiCtrl::DrawNode(TreeMultiItemBase *b, wxDC &dc)
+{
+       // go through this item .. if it is a node, draw
+       // the caption, else reposition the window.
+
+       if(!b)
+               return;
+
+       // forget it if this node is not visible
+       if(b->IsVisible())
+       {
+               int bmpOffsetX = b->GetX() - (_gutterWidth + _iconWidth);
+
+#if(CHECKBOXVIEW)
+               // now draw the checkbox if there is any, in the proper state
+               if(b->GetCheckbox())
+               {
+                       DrawCheckbox(b, dc);
+
+                       // adjust the bmpOffset because we also have a checkbox
+                       bmpOffsetX -= _checkWidth;
+               }
+#endif
+
+               if(b->IsTreeMultiItemNode())
+                {
+                        // draw the node icon and the caption
+                        TreeMultiItemNode *n = (TreeMultiItemNode *)b;
+
+                 // set background of caption item
+                  if (n->IsSelected())
+                  {
+                    dc.SetBrush(*(this->m_HilightBrush));
+        dc.SetPen(wxPen(this->m_HilightBrush->GetColour(),1,wxSOLID));
+                  } /* if */
+                  else
+                  {
+                    dc.SetBrush(wxBrush(*wxWHITE,wxSOLID));
+        dc.SetPen(wxPen(*wxWHITE,1,wxSOLID));
+                  } /* if */
+                  dc.DrawRectangle(n->GetX(),n->GetY(),n->GetWidth(),n->GetHeight());
+                 // draw caption
+                        dc.DrawText(n->GetCaption(), n->GetX(), n->GetY());
+
+                        // draw the bitmap for the state
+                       if(n->IsExpanded())
+                               dc.DrawBitmap(*_expandBmp, bmpOffsetX, n->GetY() + _iconDeltaY, true);
+                       else
+                               dc.DrawBitmap(*_collBmp, bmpOffsetX, n->GetY() + _iconDeltaY, true);
+
+                       // now go through all the subnodes
+                       for(int i = 0; i < n->GetNodeCount(); i++)
+                               DrawNode(n->GetNode(i), dc);
+
+               }
+       }
+}
+
+#if(CHECKBOXVIEW)
+
+void wxTreeMultiCtrl::DrawCheckbox(TreeMultiItemBase *b, wxDC &dc, bool convertScrolled)
+{
+       wxCHECK2(b, return);
+
+       wxBitmap *bmp;
+       int bmpOffsetX = b->GetX() - (_gutterWidth + _iconWidth);
+
+       switch(b->GetCheckboxState())
+       {
+       case 0:
+               bmp = _uncheckBmp;
+               break;
+       case 1:
+               bmp = _checkBmp;
+               break;
+       default:
+               bmp = _tristateBmp;
+               break;
+       }
+
+       int x, xx, y, yy;
+
+       if(b->IsTreeMultiItemWindow())
+       {
+               xx = x = bmpOffsetX - ((TreeMultiItemWindow *)b)->GetFrontSpacing() + _checkWidth;
+               yy = y = b->GetY() + _checkDeltaY;
+       }
+       else
+       {
+               xx = x = bmpOffsetX;
+               yy = y = b->GetY() + _checkDeltaY;
+       }
+
+       if(convertScrolled)
+               CalcScrolledPosition(x, y, &xx, &yy);
+
+       dc.DrawBitmap(*bmp, xx, yy, true);
+}
+
+#endif // #if(CHECKBOXVIEW)
+
+void wxTreeMultiCtrl::OnKey(wxKeyEvent &event)
+{
+       // check if we need to traverse to upper or lower
+       // control in the list
+       if(event.GetKeyCode() == WXK_TAB)
+       {
+               wxTreeMultiItem item = GetFocus();
+               if(item.IsOk())
+               {
+                       // traverse down direction
+                       if(!event.ShiftDown())
+                               item = FindNextVisibleWindowItem(item.GetItem());
+                       //else // traverse in up direction
+                       //      item = FindPreviousVisibleWindowItem(item);
+
+                       if(item.IsOk())
+                       {
+                               TreeMultiItemWindow *w = item.GetItem()->IsTreeMultiItemWindow();
+                               if(w)
+                               {
+                                       wxWindow *wnd = w->GetWindow();
+                                       wnd->SetFocus();
+                               }
+                       }
+               }
+       }
+       else
+               event.Skip();
+}
+
+void wxTreeMultiCtrl::OnMouseClick( wxMouseEvent &event )
+{
+       // react on double click and left mouse down
+       if(event.LeftDown() || event.LeftDClick())
+       {
+               // get translation point
+               wxPoint pt( event.GetPosition() );
+
+               int x = 0, y = 0;
+               CalcUnscrolledPosition( pt.x, pt.y, &x, &y );
+
+               // go check if we clicked a treenode
+               int flags;
+               wxPoint p(x,y);
+               wxTreeMultiItem id = HitTest(p, flags);
+
+#if(CHECKBOXVIEW)
+               if(flags == wxTMC_HITTEST_CHECKBOX)
+               {
+                       // toggle the checkbox, and redraw
+                       if(id.IsOk())
+                       {
+                               TreeMultiItemBase *b = id.GetItem();
+                               b->SetCheckboxState((b->GetCheckboxState()+1) & 0x1);
+
+                               TreeMultiItemWindow *w = b->IsTreeMultiItemWindow();
+                               if(w)
+                               {
+                                       // try to force a focus on the window. This could
+                                       // be extended by searching for the first edit control
+                                       // class but for now, just a focus is tried.
+                                       w->GetWindow()->Enable(b->GetCheckboxState() == 1);
+                                       w->GetWindow()->SetFocus();
+
+                                       // draw the checkbox in the state needed
+                                       wxClientDC dc(this);
+                                       DrawCheckbox(b, dc, true);
+
+                                       // TODO: determine if the upper parents should be
+                                       // tristated or not
+
+                                       ScanTristateCheckstates(b);
+
+                               }
+                               else if(b->IsTreeMultiItemNode())
+                               {
+                                       // descend to all the children and set the state of the parent
+                                       SetRecursiveCheckState((TreeMultiItemNode *)b, b->GetCheckboxState() == 1);
+                                       RedrawFromNode((TreeMultiItemNode *)b);
+                               }
+                       }
+               }
+               else
+#endif // #if(CHECKBOXVIEW)
+               {
+                       // react on left mouse button, to fold and on
+                       // right for caption doubleclick
+                       int area = -1;
+
+// adjust behaviour for Linux (single click = always fold)
+#ifndef LINUX
+                       if(event.LeftDClick())
+                               area = wxTMC_HITTEST_CAPTION;
+                       else
+                               area = wxTMC_HITTEST_GUTTER;
+#else
+                        area = flags;
+#endif
+
+// Linux (single or double click -> always fold
+      if (id.IsOk())
+      {
+#ifdef LINUX
+                                // we have a valid item, if it is a node, then fold
+                                TreeMultiItemNode *n = id.GetItem()->IsTreeMultiItemNode();
+                                if(n)
+                                {
+                                  this->SelectItem(id);
+                                        Fold(n, !n->IsExpanded());
+                                } /* if */
+#else
+        if (event.LeftDown())
+          if (flags == wxTMC_HITTEST_GUTTER)
+          {
+                                TreeMultiItemNode *n = id.GetItem()->IsTreeMultiItemNode(); // for some reasons also windows may have set the flag
+
+            if (n != NULL)
+                                        Fold(n, !n->IsExpanded());
+          } /* if */
+          else if (flags == wxTMC_HITTEST_CAPTION)
+          {
+                                TreeMultiItemNode *n = id.GetItem()->IsTreeMultiItemNode(); // for some reasons also windows may have set the flag
+
+                                if (n != NULL)
+                                {
+                                  this->SelectItem(id);
+                                this->RedrawFromNode(n);
+                                } /* if */
+          } /* if */
+#endif
+      } /* if */
+      else
+        this->UnselectAll();
+                }
+        }
+}
+
+void wxTreeMultiCtrl::OnRightMouseClick(wxMouseEvent& Event)
+{
+  if (Event.RightDown())
+    if (Event.Dragging())
+      this->UnselectAll();
+    else
+    {
+     // variable definitions:
+        int Flags;
+        wxPoint Point;
+
+     // translate mouse coordinates:
+        CalcUnscrolledPosition(Event.GetPosition().x,Event.GetPosition().y,&(Point.x),&(Point.y));
+     // check if the mouse is above the caption of an item:
+      wxTreeMultiItem Item(this->HitTest(Point,Flags)); // variable definition and initialization
+
+      if (Item.IsOk() && (Flags == wxTMC_HITTEST_CAPTION))
+      {
+        this->SelectItem(Item);
+                                this->RedrawFromNode(Item.GetItem()->IsTreeMultiItemNode());
+          Event.Skip(); // window will convert right mouse click to a context menu event or proceed with
+                        // a right mouse click event if the context menu event cannot be processed
+      } /* if */
+      else
+        this->UnselectAll();
+    } /* if */
+  else
+    this->UnselectAll();
+} /* wxTreeMultiCtrl::OnRightMouseClick(wxMouseEvent&) */
+
+wxTreeMultiItem wxTreeMultiCtrl::HitTest(wxPoint const& pt, int &flags)
+{
+        // scan all nodes to see which one matches
+        TreeMultiItemBase *b = 0;
+       for(int i = 0; i < _root.GetNodeCount() && !b; i++)
+               b = FindNodeByPoint(_root.GetNode(i), pt, flags);
+
+       if(!b)
+       {
+               // none found, reset
+               flags = 0;
+               return wxTreeMultiItem(0);
+       }
+
+       // return an item
+        return wxTreeMultiItem(b);
+}
+
+TreeMultiItemBase *wxTreeMultiCtrl::FindNodeByPoint(TreeMultiItemBase *b, wxPoint const& pt, int &area)
+{
+        wxCHECK(b, 0);
+
+       // if this layer is not visible, return with nothing.
+       if(!b->IsVisible())
+               return 0;
+
+       area = 0;
+
+       // now see if our y is matching the mouse
+       if(pt.y >= b->GetY() && pt.y < (b->GetY() + b->GetHeight()))
+       {
+#if(CHECKBOXVIEW)
+               // if we are checkboxed, calculate the checkbox position
+               if(b->GetCheckbox())
+               {
+                       int extraSpacing = 0, extraWidth = 0;
+
+                       // now for a windows item, this is minus the gutter. For a normal node it is X minus checkbox
+                       if(b->IsTreeMultiItemWindow())
+                       {
+                           extraWidth = _checkWidth;
+                               extraSpacing = ((TreeMultiItemWindow *)b)->GetFrontSpacing();
+                       }
+                       else
+                               extraSpacing = 4;
+
+                       if(pt.x > (b->GetX() - extraSpacing - _checkWidth) && pt.x < (b->GetX() - extraSpacing + extraWidth))
+                       {
+                               area = wxTMC_HITTEST_CHECKBOX;
+                               return b;
+                       }
+               }
+#endif
+
+               // allrighty we have something, now where and what is it (look with x)
+               if(pt.x < b->GetX())
+                       area = wxTMC_HITTEST_GUTTER;
+
+               /** \todo Match only the real part of the caption, window (we assume x > GetX() which is the rest)
+                       HOWEVER the window probably doesn't propagate the click event back to the parent, so we might
+                       leave it like this so the use can click behind a window so it will be selected.
+               */
+               else
+               {
+                       // inside area, return proper flag
+                       if(b->IsTreeMultiItemNode())
+                               area = wxTMC_HITTEST_CAPTION;
+                       else
+                               area = wxTMC_HITTEST_WINDOW;
+               }
+
+               return b;
+       }
+       else
+       {
+               // not found, let's try our children if we have some
+               TreeMultiItemNode *n = b->IsTreeMultiItemNode();
+               if(n)
+               {
+                       TreeMultiItemBase *bb = 0;
+                       for(int i = 0; i < n->GetNodeCount() && !bb; i++)
+                               bb = FindNodeByPoint(n->GetNode(i), pt, area);
+
+                       // keep returning result to caller
+                       return bb;
+               }
+       }
+
+       return 0;
+}
+
+wxTreeMultiItem wxTreeMultiCtrl::GetFocus()
+{
+       wxWindow *wnd = wxWindow::FindFocus();
+
+       // now find window that holds this item. if not
+       // visible it cannot have focus (should not have)
+
+       wxTreeMultiItem item = FindWindowNode(wnd);
+       if(item.IsOk() && item.GetItem()->IsVisible())
+               return item;
+
+       return wxTreeMultiItem(0);
+}
+
+#if(CHECKBOXVIEW)
+
+void wxTreeMultiCtrl::SetRecursiveCheckState(TreeMultiItemNode *n, bool check)
+{
+       int state = 0;
+       if(check)
+               state++;
+
+       // go check all kids on this level
+       for(int i = 0; i < n->GetNodeCount(); i++)
+       {
+               // check all the nodes, and go deeper
+               n->GetNode(i)->SetCheckboxState(state);
+               if(n->GetNode(i)->IsTreeMultiItemNode())
+                       SetRecursiveCheckState((TreeMultiItemNode *)n->GetNode(i), check);
+       }
+}
+
+void wxTreeMultiCtrl::ScanTristateCheckstates(TreeMultiItemBase *b)
+{
+       // check from the parent on, all node entries and see if they are
+       // checked or cleared or scattered
+       TreeMultiItemNode *p = b->GetParent();
+
+       if(p && p->GetCheckbox())
+       {
+               bool foundcheck = false, foundclear = false;
+               for(size_t i = 0; i < (size_t)p->GetNodeCount(); ++i)
+               {
+                       // only evaluate when checkboxed
+                       if(p->GetNode(i)->IsTreeMultiItemWindow() && p->GetNode(i)->GetCheckbox())
+                       {
+                               // record instance of a cleared checkbox
+                               if(!p->GetNode(i)->GetCheckboxState())
+                                       foundclear = true;
+                               // record instance of checked checkbox
+                               if(p->GetNode(i)->GetCheckboxState() == 1)
+                                       foundcheck = true;
+                       }
+               }
+
+               // if we have both check and clear, go tristate
+               // if all clear, clear parent and if all set, then set parent
+               if(foundclear && !foundcheck)
+                       p->SetCheckboxState(0);
+               else if(!foundclear && foundcheck)
+                       p->SetCheckboxState(1);
+               else if(foundclear && foundcheck)
+                       p->SetCheckboxState(2);
+
+               //wxClientDC dc;
+               //DrawCheckbox(p, dc, false);
+               RedrawFromNode(p);
+       }
+}
+
+#endif // #if(CHECKBOXVIEW)
+
+wxTreeMultiItem wxTreeMultiCtrl::InsertNode(TreeMultiItemNode* ParentPtr, size_t Position, wxString const& Caption, wxString const& Name)
+{
+        int extX, extY;
+
+  TreeMultiItemNode* NodePtr(new TreeMultiItemNode(ParentPtr,Caption,Name)); // generate new node pointer
+
+
+ // continue with initializing the new node:
+#if(CHECKBOXVIEW)
+ // if checkbox view is desired, tag this item as a checkbox
+ // and set the state as 'false'
+        NodePtr->SetCheckbox(_checkboxView);
+        NodePtr->SetCheckboxState(0);
+#endif
+ // calculate the height and width
+        this->GetTextExtent(Caption,&extX,&extY,0,0,&(this->_captionFont));
+        NodePtr->SetHeight(extY);
+        NodePtr->SetWidth(extX);
+ // finally, insert node:
+  if (Position < (size_t)ParentPtr->GetNodeCount())
+    ParentPtr->InsertNode(NodePtr,Position);
+  else
+    ParentPtr->AddNode(NodePtr);
+ // return the newly created node:
+  return wxTreeMultiItem(NodePtr);
+} /* wxTreeMultiCtrl::InsertNode(TreeMultiItemNode*, size_t, wxString const&, wxString const&) */
+
+wxTreeMultiItem wxTreeMultiCtrl::InsertWindow(TreeMultiItemNode* ParentPtr, size_t Position, wxWindow* WindowPtr, wxString const& Name, wxTreeMultiWindowInfo const& Info, int Flags)
+{
+  int WindowFlags;
+
+        TreeMultiItemWindow* NewWindowPtr = new TreeMultiItemWindow(ParentPtr,Name); // generate new window pointer
+
+
+ // get flags from passed variable "Flags"; in case this variable does not contain any flags use the window's information flags:
+  if (Flags != 0)
+    WindowFlags = Flags;
+  else
+    WindowFlags = Info.GetFlags();
+
+ // continue with initializing the new window:
+#if(CHECKBOXVIEW)
+        // if checkbox view is desired, tag this item as a checkbox
+        // and set the state as 'false'
+        NewWindowPtr->SetCheckbox(_checkboxView);
+#endif
+ // if style wants us to change background, set it to our background
+        if (WindowFlags & wxTMC_BG_ADJUST_ALL)
+        {
+                // go through all children of this window, and set the
+                // background of it (recursively)
+                this->SetWindowBackgroundColour(WindowPtr,this->GetBackgroundColour(),WindowFlags);
+        } /* if */
+
+ // set the spacing:
+        NewWindowPtr->SetTopSpacing(Info.GetTopSpacing());
+#if(CHECKBOXVIEW)
+        // make sure that the checkboxes are at least indented enough
+        if (this->_checkboxView)
+               NewWindowPtr->SetFrontSpacing(Info.GetFrontSpacing() + this->_checkWidth);
+        else
+#endif
+               NewWindowPtr->SetFrontSpacing(Info.GetFrontSpacing());
+ // assign finally the window:
+        NewWindowPtr->AssignWindow(WindowPtr);
+
+#if(CHECKBOXVIEW)
+ // set the checkbox state after the window is assigned
+        NewWindowPtr->SetCheckboxState(Info.GetDefaultCheckState());
+#endif
+
+ // if the window is not visible, set hide flag
+        this->ShowTreeMultiWindow(NewWindowPtr,NewWindowPtr->IsVisible());
+
+ // finally, insert the newly constructed window:
+  if (Position < (size_t)ParentPtr->GetNodeCount())
+    ParentPtr->InsertNode(NewWindowPtr,Position);
+  else
+    ParentPtr->AddNode(NewWindowPtr);
+ // return the newly created window:
+        return wxTreeMultiItem(NewWindowPtr);
+} /* wxTreeMultiCtrl::InsertWindow(TreeMultiItemNode*, size_t, wxWindow*, wxString const&, wxTreeMultiWindowInfo const&, int) */
+
+void wxTreeMultiCtrl::RedrawFromParentNode(TreeMultiItemBase *n)
+{
+        TreeMultiItemNode *p = 0;
+       if(n)
+               p = n->GetParent();
+
+       RedrawFromNode(p);
+}
+
+void wxTreeMultiCtrl::RedrawFromNode(TreeMultiItemNode *n)
+{
+       static int recalcMutex = 0;
+       bool visible = true;
+
+       if(recalcMutex > 0)
+               return;
+
+       recalcMutex ++;
+
+       // when node is not visible or excluded
+       // then don't redraw.
+
+       if(n)
+               visible = n->IsVisible();
+
+       if(visible)
+       {
+               int h, h1,w, w1;
+               GetVirtualSize(&w, &h);
+
+               UpdateAllWindowVisibility();
+               RecalculateNodePositions();
+               RecalculateVirtualSize();
+
+               // why is this needed? Because folding or collapsing can change
+               // the state. When the virtual area gets smaller, we need to keep
+               // the largest one and the other way atound. And since we do not
+               // know here we are folding or collapsing, we remember the biggest
+               GetVirtualSize(&w1, &h1);
+
+                if(h1 > h)
+                        h = h1;
+
+                // only refresh the part from x,y down
+                if(n)
+               {
+                       int x, y;
+                       CalcScrolledPosition(n->GetX(), n->GetY(), &x, &y);
+                       if(h - y > 0)
+                       {
+                               wxRect rect(0, y, w, h - y);
+                               RefreshRect(rect);
+                       }
+                       else
+                               Refresh();
+               }
+               else
+                       Refresh();      // do a full refresh
+       }
+
+       recalcMutex --;
+}
+
+void wxTreeMultiCtrl::RecalculateNodePositions()
+{
+       int currentY = _spacingY;
+       // go recursive on every node, and store the information in the node
+
+       for(int i = 0; i < _root.GetNodeCount(); i++)
+        currentY += CalculateNodeDimensions(_root.GetNode(i), currentY, 0);
+}
+
+int wxTreeMultiCtrl::CalculateNodeDimensions(TreeMultiItemBase *b, int currentY, int level)
+{
+       int gutter = (_gutterWidth * 2) + _iconWidth;
+       int y = 0, topSpacing = 0;
+
+       // return same if no proper object
+       wxCHECK(b, 0);
+
+#if(CHECKBOXVIEW)
+       if(b->GetCheckbox())
+               gutter += _checkWidth;
+#endif
+
+       // if we are not visible, skip recalculation and descending
+       if(b->IsVisible())
+       {
+               b->SetY(currentY);
+
+               // if level is 0, calculate with front gutter, else without
+               y = currentY + b->GetHeight();
+               if(b->IsTreeMultiItemNode())
+               {
+                       TreeMultiItemNode *n = (TreeMultiItemNode *)b;
+
+                       if(level == 0)
+                               b->SetX(gutter);
+                       else
+                               b->SetX(gutter + (level * (_gutterWidth + _iconWidth)));
+
+                       // now do children of this node
+
+                       for(int i = 0; i < n->GetNodeCount(); i++)
+                               y += CalculateNodeDimensions(n->GetNode(i), y + _spacingY, level+1);
+               }
+               else if(b->IsTreeMultiItemWindow())
+               {
+                       TreeMultiItemWindow *w = (TreeMultiItemWindow *)b;
+
+                       if(level == 0)
+                               b->SetX(gutter + w->GetFrontSpacing());
+                       else
+                               b->SetX(_gutterWidth + (level * (_gutterWidth + _iconWidth)) + w->GetFrontSpacing());
+
+                       topSpacing = w->GetTopSpacing();
+
+                       // reposition the window
+
+                       wxWindow *wnd = w->GetWindow();
+                       if(wnd)
+                       {
+                               int x = 0, y = 0;
+                               CalcScrolledPosition(w->GetX(), w->GetY(), &x, &y);
+                               wnd->SetSize(x, y, w->GetWidth(), w->GetHeight());
+                       }
+               }
+
+               if(y > 0)
+                       return (y - currentY) + _spacingY + topSpacing; // return delta
+               else
+                       return 0;
+       }
+
+       return 0;       // not visible, thus we skip calculations
+}
+
+void wxTreeMultiCtrl::RecalculateSpanSizes()
+{
+       for(int i = 0; i < _root.GetNodeCount(); i++)
+        CalculateNodeSpanning(_root.GetNode(i));
+}
+
+void wxTreeMultiCtrl::CalculateNodeSpanning(TreeMultiItemBase *b)
+{
+       // return same if no proper object
+       wxCHECK2(b, return);
+
+       if(b->IsTreeMultiItemNode())
+       {
+               TreeMultiItemNode *n = (TreeMultiItemNode *)b;
+
+               // now do children of this node
+
+               for(int i = 0; i < n->GetNodeCount(); i++)
+                       CalculateNodeSpanning(n->GetNode(i));
+       }
+       else if(b->IsTreeMultiItemWindow())
+       {
+               TreeMultiItemWindow *w = (TreeMultiItemWindow *)b;
+               wxWindow *wnd = w->GetWindow();
+               if(wnd)
+               {
+                       // if the window is spanning, we adjust the width to the max width of the control
+                       if(w->GetHorizontalSpan())
+                       {
+                               wxSize tmcsize = GetClientSize();
+                               int maxwidth = tmcsize.GetWidth() - w->GetX() - 8; // extract 3 for border
+
+                               wxSizer *sz = wnd->GetSizer();
+                               if(sz)
+                               {
+                                       if(maxwidth < sz->GetMinSize().GetWidth())
+                                               maxwidth = sz->GetMinSize().GetWidth();
+                               }
+
+                               // prevent a size of 0
+                               if(maxwidth < 1)
+                                       maxwidth = 1;
+
+                               // set the size
+                               w->SetWidth(maxwidth);
+                               wnd->SetSize(w->GetWidth(), w->GetHeight());
+
+                               // layout by sizer (not sure if this is needed)
+                               if(wnd->GetSizer())
+                                       wnd->GetSizer()->Layout();
+                       }
+               }
+       }
+}
+
+void wxTreeMultiCtrl::RecalculateVirtualSize()
+{
+       // go through all the nodes, and store the largest x and largest y
+
+       int x = 0, y = 0;
+       RecalculateVirtualSizeFromNode(&_root, x, y);
+
+       // now adjust virtual size
+       SetVirtualSize(x, y);
+       AdjustScrollbars(x, y);
+}
+
+void wxTreeMultiCtrl::AdjustScrollbars(int x, int y)
+{
+       // adjust scrollbars
+       // courtesy of treectrlg.cpp
+
+       y += WXTMC_PIXELS_PER_UNIT+2; // one more scrollbar unit + 2 pixels
+    x += WXTMC_PIXELS_PER_UNIT+2; // one more scrollbar unit + 2 pixels
+    int x_pos = GetScrollPos( wxHORIZONTAL );
+    int y_pos = GetScrollPos( wxVERTICAL );
+    SetScrollbars( WXTMC_PIXELS_PER_UNIT, WXTMC_PIXELS_PER_UNIT, x/WXTMC_PIXELS_PER_UNIT,
+                          y/WXTMC_PIXELS_PER_UNIT, x_pos, y_pos, true );
+}
+
+void wxTreeMultiCtrl::RecalculateVirtualSizeFromNode(const TreeMultiItemNode *node, int &x, int &y)
+{
+       if(node->IsExcluded())
+               return;
+
+       // if calulate this node's dimensions
+       if(x < (node->GetWidth() + node->GetX()))
+               x = node->GetWidth() + node->GetX();
+
+       y = node->GetY() + node->GetHeight();
+
+       // if this node is collapsed, no subnodes are visible, else
+       // go through all subnodes as well, node needs to be included as well
+       if(node->IsExpanded())
+       {
+               TreeMultiItemBase *b;
+               for(int i = 0; i < node->GetNodeCount(); i++)
+               {
+                       b = node->GetNode(i);
+
+                       // calculate x and y
+                       if(x < (b->GetWidth() + b->GetX()))
+                               x = b->GetWidth() + b->GetX();
+
+                       y = b->GetY() + b->GetHeight();
+
+                       if(b->IsTreeMultiItemNode())
+                               RecalculateVirtualSizeFromNode((TreeMultiItemNode *)b, x, y);
+               }
+       }
+}
+
+void wxTreeMultiCtrl::SetWindowBackgroundColour(wxWindow *wnd, const wxColour &col, int flags)
+{
+       if(wnd)
+       {
+               // if we cannot change a button, make sure all button
+               // classes are not changed
+
+               wxButton *btn = wxDynamicCast(wnd, wxButton);
+               if(!btn || ((flags & wxTMC_BG_ADJUST_BTN) != 0))
+                       wnd->SetBackgroundColour(col);
+
+               // get every window, and make the background equal to the given one
+               wxWindowListNode *node = wnd->GetChildren().GetFirst();
+               while (node)
+               {
+                       SetWindowBackgroundColour(node->GetData(), col, flags);
+                       node = node->GetNext();
+               }
+       }
+}
+
+void wxTreeMultiCtrl::ShowTreeMultiWindow(TreeMultiItemWindow *window, bool show)
+{
+       // show or hide window
+       if(window && window->GetWindow())
+               window->GetWindow()->Show(show);
+}
+
+void wxTreeMultiCtrl::UpdateAllWindowVisibility()
+{
+       // all roots are visible, but what lies beneath ... who knows
+       for(int i = 0; i < _root.GetNodeCount(); i++)
+               UpdateTreeMultiWindowVisibility(_root.GetNode(i), true);
+}
+
+void wxTreeMultiCtrl::UpdateTreeMultiWindowVisibility(TreeMultiItemBase *b, bool show)
+{
+       if(b)
+       {
+               // this is done for performance issues. IsVisible can go all
+               // the way up the tree to check. However if show is already
+               // false, there is no need to check (some higher one is collapsed)
+               bool showMe = show;
+
+               if(showMe)
+                       showMe = b->IsVisible();
+
+               if(b->IsTreeMultiItemWindow())
+               {
+                       // if this level must be hidden, hide
+                       ShowTreeMultiWindow((TreeMultiItemWindow*)b, showMe);
+               }
+               else if(b->IsTreeMultiItemNode())
+               {
+                       TreeMultiItemNode *node = (TreeMultiItemNode *)b;
+
+                       // if hidden, descend and hide all windows
+                       for(int i = 0; i < node->GetNodeCount(); i++)
+                               UpdateTreeMultiWindowVisibility(node->GetNode(i), showMe);
+               }
+       }
+}
+
+wxTreeMultiItem wxTreeMultiCtrl::FindItem(const wxTreeMultiItem &item, const wxString &name, bool ignoreCase, bool skipFirst)
+{
+       if(item.IsOk())
+       {
+               TreeMultiItemBase *b = item.GetItem();
+
+               // check this item first (or not)
+
+               if(!skipFirst)
+               {
+                       if(b->GetName().IsSameAs(name, !ignoreCase))
+                               return wxTreeMultiItem(b);
+               }
+
+               if(b->IsTreeMultiItemNode())
+               {
+                       // now check whether we are a node, then go check children
+
+                       TreeMultiItemNode *n = (TreeMultiItemNode *)b;
+                       wxTreeMultiItem result(0);
+                       for(int i = 0; i < n->GetNodeCount() && !result.IsOk(); i++)
+                               result = FindItem(wxTreeMultiItem(n->GetNode(i)), name, ignoreCase, false);
+
+                       return result;
+               }
+       }
+
+       return wxTreeMultiItem(0);
+}
+
+wxTreeMultiItem wxTreeMultiCtrl::FindWindowNode(wxWindow *wnd, TreeMultiItemNode *n)
+{
+       wxCHECK(wnd, wxTreeMultiItem(0));
+
+       // take root node if not assigned one
+
+       if(!n)
+               n = (TreeMultiItemNode *)&_root;
+
+       // check on this level for the wxWindow pointer
+
+       TreeMultiItemWindow *w;
+       wxTreeMultiItem result(0);
+       for(int i = 0; i < n->GetNodeCount() && !result.IsOk(); i++)
+       {
+               // if window node
+               w = n->GetNode(i)->IsTreeMultiItemWindow();
+               if(w && w->GetWindow() == wnd)
+                       return wxTreeMultiItem(n);
+
+               // if node, go deeper
+               if(n->GetNode(i)->IsTreeMultiItemNode())
+                       result = FindWindowNode(wnd, (TreeMultiItemNode*)n->GetNode(i));
+       }
+
+       return result;
+}
+
+TreeMultiItemWindow *wxTreeMultiCtrl::FindNextVisibleWindowItem(TreeMultiItemBase *b, int index)
+{
+       wxCHECK(b, 0);
+
+       // check on this level, go deeper with every node we got. When a node is not
+       // visible anymore, skip the node.
+
+       TreeMultiItemWindow *value = 0;
+       if(b->IsVisible())
+       {
+               // if we are already searching on a node with an index
+
+               TreeMultiItemBase *bn = 0;
+               TreeMultiItemNode *n = b->IsTreeMultiItemNode();
+               if(n)
+               {
+                       for(int i = index + 1; i < n->GetNodeCount() && !value; i++)
+                       {
+                               bn = n->GetNode(i);
+                               value = bn->IsTreeMultiItemWindow();
+
+                               // assume a node, root when not a a window
+                               if(!value)
+                                       value = FindNextVisibleWindowItem(bn, -1);
+                       }
+
+               }
+               else
+               {
+                       if(b->IsTreeMultiItemWindow())
+                       {
+                               // get parent first, and locate child as ptr
+                               TreeMultiItemNode *p = b->GetParent();
+                               wxCHECK(p, 0);
+
+                               // go scan the parent from the given index, if
+                               // the index is valid else there is no child with that index
+
+                               int idx = p->Index(b);
+                               wxCHECK(idx >= 0, 0);
+
+                               value = FindNextVisibleWindowItem(p, idx);
+                       }
+               }
+       }
+
+       return value;
+
+}
+
+bool wxTreeMultiCtrl::GetBooleanValue(int wndId)
+{
+       wxWindow *wnd = wxWindow::FindWindow(wndId);
+       wxCHECK(wnd, false);
+
+       // try a radio button
+       wxRadioButton *b = wxDynamicCast(wnd, wxRadioButton);
+       if(b)
+               return b->GetValue();
+
+       // try a check box
+       wxCheckBox *c = wxDynamicCast(wnd, wxCheckBox);
+       if(c)
+               return c->GetValue();
+
+       /** \todo For custom controls we should put something in wxMultiTreeItemData class
+           which can be overridden to retrieve the boolean value. It will also be passed
+           the pointer to the window, so the derived class can figure out how to get a boolean
+           value.
+       */
+
+       // generate assert or just return with false
+       wxCHECK(0, false);
+}
+
+void wxTreeMultiCtrl::SetBooleanValue(int wndId, bool value)
+{
+       wxWindow *wnd = wxWindow::FindWindow(wndId);
+       wxCHECK2(wnd, return);
+
+       // try a radio button
+       wxRadioButton *b = wxDynamicCast(wnd, wxRadioButton);
+       if(b)
+       {
+               b->SetValue(value);
+               return;
+       }
+
+       // try a check box
+       wxCheckBox *c = wxDynamicCast(wnd, wxCheckBox);
+       if(c)
+       {
+               c->SetValue(value);
+               return;
+       }
+
+       /** \todo For custom controls we should put something in wxMultiTreeItemData class
+                   which can be overridden to retrieve the boolean value. It will also be passed
+                   the pointer to the window, so the derived class can figure out how to get a boolean
+                   value.
+       */
+
+       // generate assert
+       wxCHECK2(0, return);
+}
+
+void wxTreeMultiCtrl::SetTextValue(int wndId, const wxString &value)
+{
+       wxWindow *wnd = wxWindow::FindWindow(wndId);
+       wxCHECK2(wnd, return);
+
+       // try a radio button
+       wxTextCtrl *t = wxDynamicCast(wnd, wxTextCtrl);
+       if(t)
+       {
+               t->SetValue(value);
+               return;
+       }
+
+       /** \todo For custom controls we should put something in wxMultiTreeItemData class
+                   which can be overridden to retrieve the boolean value. It will also be passed
+                   the pointer to the window, so the derived class can figure out how to get a boolean
+                   value.
+       */
+
+       // generate assert
+       wxCHECK2(0, return);
+}
+
+wxString wxTreeMultiCtrl::GetTextValue(int wndId)
+{
+       wxWindow *wnd = wxWindow::FindWindow(wndId);
+       wxCHECK(wnd, wxEmptyString);
+
+       // try a radio button
+       wxTextCtrl *t = wxDynamicCast(wnd, wxTextCtrl);
+       if(t)
+               return t->GetValue();
+
+       // try a choice box
+       wxChoice *c1 = wxDynamicCast(wnd, wxChoice);
+       if(c1)
+               return c1->GetStringSelection();
+
+       // try a combo box
+       wxComboBox *c2 = wxDynamicCast(wnd, wxComboBox);
+       if(c2)
+               return c2->GetStringSelection();
+
+       // try a listbox
+       wxListBox *l = wxDynamicCast(wnd, wxListBox);
+       if(l)
+               return l->GetStringSelection();
+
+       /** \todo For custom controls we should put something in wxMultiTreeItemData class
+           which can be overridden to retrieve the boolean value. It will also be passed
+           the pointer to the window, so the derived class can figure out how to get a boolean
+           value.
+       */
+
+       // generate assert or just return with string
+       wxCHECK(0, wxEmptyString);
+}
+
+int wxTreeMultiCtrl::GetSelectionValue(int wndId)
+{
+       wxWindow *wnd = wxWindow::FindWindow(wndId);
+       wxCHECK(wnd, -1);
+
+       // try a choice box
+       wxChoice *c1 = wxDynamicCast(wnd, wxChoice);
+       if(c1)
+               return c1->GetSelection();
+
+       // try a combo box
+       wxComboBox *c2 = wxDynamicCast(wnd, wxComboBox);
+       if(c2)
+               return c2->GetSelection();
+
+       // try a listbox
+       wxListBox *l = wxDynamicCast(wnd, wxListBox);
+       if(l)
+               return l->GetSelection();
+
+       /** \todo For custom controls we should put something in wxMultiTreeItemData class
+           which can be overridden to retrieve the boolean value. It will also be passed
+           the pointer to the window, so the derived class can figure out how to get a boolean
+           value.
+       */
+
+       // generate assert or just return with string
+       wxCHECK(0, -1);
+}
+
+void wxTreeMultiCtrl::GetSelectionValues(int wndId, wxArrayInt &sels)
+{
+       sels.Clear();
+
+       wxWindow *wnd = wxWindow::FindWindow(wndId);
+       wxCHECK2(wnd, return);
+
+       // try a listbox
+       wxListBox *l = wxDynamicCast(wnd, wxListBox);
+       if(l)
+       {
+               l->GetSelections(sels);
+               return;
+       }
+
+       /** \todo For custom controls we should put something in wxMultiTreeItemData class
+           which can be overridden to retrieve the boolean value. It will also be passed
+           the pointer to the window, so the derived class can figure out how to get a boolean
+           value.
+       */
+
+       // generate assert or just return with string
+       wxCHECK2(0, return);
+}
+
+void wxTreeMultiCtrl::SetSelectionValue(int wndId, int sel)
+{
+       wxWindow *wnd = wxWindow::FindWindow(wndId);
+       wxCHECK2(wnd, return);
+
+       // try a choice box
+       wxChoice *c1 = wxDynamicCast(wnd, wxChoice);
+       if(c1)
+       {
+               c1->SetSelection(sel);
+               return;
+       }
+
+       // try a combo box
+       wxComboBox *c2 = wxDynamicCast(wnd, wxComboBox);
+       if(c2)
+       {
+               c2->SetSelection(sel);
+               return;
+       }
+
+       // try a listbox
+       wxListBox *l = wxDynamicCast(wnd, wxListBox);
+       if(l)
+       {
+               l->SetSelection(sel);
+               return;
+       }
+
+       /** \todo For custom controls we should put something in wxMultiTreeItemData class
+           which can be overridden to retrieve the boolean value. It will also be passed
+           the pointer to the window, so the derived class can figure out how to get a boolean
+           value.
+       */
+
+       // generate assert or just return with string
+       wxCHECK2(0, return);
+}
+
+
+wxTreeMultiItem wxTreeMultiCtrl::GetParent(wxTreeMultiItem const& item) const
+{
+ // check if valid or root item has been passed, both do not have parents:
+  if (!(item.IsOk()) || item.GetItem()->IsTreeMultiItemRoot())
+    return wxTreeMultiItem();
+  else
+    return wxTreeMultiItem(item.GetItem()->GetParent()); // GetParent() returns a valid pointer in case of a root item!!
+                                                         // therefore, the check if the passed item is a root item is necessary
+} /* wxTreeMultiCtrl::GetParent(wxTreeMultiItem const& item) const */
+
+wxTreeMultiItem wxTreeMultiCtrl::GetFirstChild(const wxTreeMultiItem &item, int &cookie) const
+{
+       if(item.IsNodeItem())
+       {
+               TreeMultiItemNode *n = (TreeMultiItemNode *)item.GetItem();
+
+               if(n->GetNodeCount() > 0)
+               {
+                       cookie = 0;
+                       return wxTreeMultiItem(n->GetNode(0));
+               }
+       }
+
+       // no children or no valid node
+       cookie = -1;
+       return wxTreeMultiItem(0);
+}
+
+wxTreeMultiItem wxTreeMultiCtrl::GetNextChild(const wxTreeMultiItem &item, int &cookie) const
+{
+       if(item.IsNodeItem())
+       {
+               TreeMultiItemNode *n = (TreeMultiItemNode *)item.GetItem();
+
+               if(cookie >= 0 && cookie < (n->GetNodeCount()-1))
+               {
+                       // increment cookie, return node
+                       cookie ++;
+                       return wxTreeMultiItem(n->GetNode(cookie));
+               }
+       }
+
+       // end of query, or no valid node
+       cookie = -1;
+       return wxTreeMultiItem(0);
+}
+
+wxTreeMultiItem wxTreeMultiCtrl::GetLastChild(const wxTreeMultiItem &item) const
+{
+       if(item.IsNodeItem())
+       {
+               TreeMultiItemNode *n = (TreeMultiItemNode *)item.GetItem();
+
+               if(n->GetNodeCount() > 0)
+                       return wxTreeMultiItem(n->GetNode(n->GetNodeCount()-1));
+       }
+
+        return wxTreeMultiItem(0);
+}
+
+wxTreeMultiItem wxTreeMultiCtrl::GetNextSibling(wxTreeMultiItem const& item) const
+{
+ // check if a valid item has been passed:
+  if (!(item.IsOk()))
+    return wxTreeMultiItem();
+
+  TreeMultiItemNode* ParentPtr(item.GetItem()->GetParent());
+
+
+  if (ParentPtr != NULL) // the parent pointer is only null if the passed item is the root
+  {
+   // find the current item in the parent's list; the next sibling has an index that is one higher than the one of the current item:
+    int NextItemIndex(ParentPtr->Index(item.GetItem())+1); // variable definition and initialization
+
+    if (NextItemIndex < ParentPtr->GetNodeCount())
+      return ParentPtr->GetNode(NextItemIndex);
+    else
+      return wxTreeMultiItem();
+  } /* if */
+  else
+    return wxTreeMultiItem();
+} /* wxTreeMultiCtrl::GetNextSibling(wxTreeMultiItem const&) const */
+
+wxTreeMultiItem wxTreeMultiCtrl::GetPrevSibling(wxTreeMultiItem const& item) const
+{
+ // check if a valid item has been passed:
+  if (!(item.IsOk()))
+    return wxTreeMultiItem();
+
+  TreeMultiItemNode* ParentPtr(item.GetItem()->GetParent());
+
+
+  if (ParentPtr != NULL)
+  {
+   // find the current item in the parent's list; the next sibling has an index that is one higher than the one of the current item:
+    int PrevItemIndex(ParentPtr->Index(item.GetItem())-1); // variable definition and initialization
+
+    if (PrevItemIndex >= 0)
+      return ParentPtr->GetNode(PrevItemIndex);
+    else
+      return wxTreeMultiItem();
+  } /* if */
+  else
+    return wxTreeMultiItem();
+} /* wxTreeMultiCtrl::GetPrevSibling(wxTreeMultiItem const&) const */
+
+wxTreeMultiItem wxTreeMultiCtrl::GetNext(wxTreeMultiItem const& item) const
+{
+ // check if a valid item has been passed:
+  if (!(item.IsOk()))
+    return wxTreeMultiItem();
+
+  TreeMultiItemNode* NodePtr(item.GetItem()->IsTreeMultiItemNode()); // variable definition and initialization
+
+  if ((NodePtr != NULL) && (NodePtr->GetNodeCount() > 0))
+    return wxTreeMultiItem(NodePtr->First());
+  else
+  {
+   // variable definitions and initializations:
+    wxTreeMultiItem Parent(item);
+    wxTreeMultiItem Sibling;
+
+    do
+    {
+      Sibling = this->GetNextSibling(Parent); // try to find next sibling
+      Parent = this->GetParent(Parent);       // get next ancestor
+    } while (!(Sibling.IsOk()) && Parent.IsOk());
+   // in case the loop ended with Sibling.IsOk() "Sibling" contains a valid sibling otherwise an invalid
+    return Sibling;
+  } /* if */
+} /* wxTreeMultiCtrl::GetNextSibling(wxTreeMultiItem const&) const */
+
+wxTreeMultiItem wxTreeMultiCtrl::GetPrevious(wxTreeMultiItem const& item) const
+{
+ // check if a valid item has been passed:
+  if (!(item.IsOk()))
+    return wxTreeMultiItem();
+
+  TreeMultiItemNode* NodePtr(item.GetItem()->IsTreeMultiItemNode()); // variable definition and initialization
+
+  if ((NodePtr != NULL) && (NodePtr->GetNodeCount() > 0))
+    return wxTreeMultiItem(NodePtr->Last());
+  else
+  {
+   // variable definitions and initializations:
+    wxTreeMultiItem Parent(item);
+    wxTreeMultiItem Sibling;
+
+    do
+    {
+      Sibling = this->GetPrevSibling(Parent); // try to find next sibling
+      Parent = this->GetParent(Parent);       // get next ancestor
+    } while (!(Sibling.IsOk()) && Parent.IsOk());
+   // in case the loop ended with Sibling.IsOk() "Sibling" contains a valid sibling otherwise an invalid
+    return Sibling;
+  } /* if */
+} /* wxTreeMultiCtrl::GetPrevious(wxTreeMultiItem const&) const */
+
+// WDR: handler implementations for wxTreeMultiCtrl
+
+void wxTreeMultiCtrl::OnDraw(wxDC& dc)
+{
+        // go recursive and draw the whole visible tree.
+        dc.SetFont(_captionFont);
+        for(int i = 0; i < _root.GetNodeCount(); i++)
+                DrawNode(_root.GetNode(i), dc);
+} /*  */