+#ifdef __VISUALC__
+#pragma warning( default : 4097 )
+#endif
+
+// a class which encapsulates the tree traversal logic: it vists all (unless
+// OnVisit() returns FALSE) items under the given one
+class wxTreeTraversal
+{
+public:
+ wxTreeTraversal(const wxTreeCtrl *tree)
+ {
+ m_tree = tree;
+ }
+
+ // do traverse the tree: visit all items (recursively by default) under the
+ // given one; return TRUE if all items were traversed or FALSE if the
+ // traversal was aborted because OnVisit returned FALSE
+ bool DoTraverse(const wxTreeItemId& root, bool recursively = TRUE);
+
+ // override this function to do whatever is needed for each item, return
+ // FALSE to stop traversing
+ virtual bool OnVisit(const wxTreeItemId& item) = 0;
+
+protected:
+ const wxTreeCtrl *GetTree() const { return m_tree; }
+
+private:
+ bool Traverse(const wxTreeItemId& root, bool recursively);
+
+ const wxTreeCtrl *m_tree;
+};
+
+// internal class for getting the selected items
+class TraverseSelections : public wxTreeTraversal
+{
+public:
+ TraverseSelections(const wxTreeCtrl *tree,
+ wxArrayTreeItemIds& selections)
+ : wxTreeTraversal(tree), m_selections(selections)
+ {
+ m_selections.Empty();
+
+ DoTraverse(tree->GetRootItem());
+ }
+
+ virtual bool OnVisit(const wxTreeItemId& item)
+ {
+ if ( GetTree()->IsItemChecked(item) )
+ {
+ m_selections.Add(item);
+ }
+
+ return TRUE;
+ }
+
+private:
+ wxArrayTreeItemIds& m_selections;
+};
+
+// internal class for counting tree items
+class TraverseCounter : public wxTreeTraversal
+{
+public:
+ TraverseCounter(const wxTreeCtrl *tree,
+ const wxTreeItemId& root,
+ bool recursively)
+ : wxTreeTraversal(tree)
+ {
+ m_count = 0;
+
+ DoTraverse(root, recursively);
+ }
+
+ virtual bool OnVisit(const wxTreeItemId& item)
+ {
+ m_count++;
+
+ return TRUE;
+ }
+
+ size_t GetCount() const { return m_count; }
+
+private:
+ size_t m_count;
+};
+
+// ----------------------------------------------------------------------------
+// This class is needed for support of different images: the Win32 common
+// control natively supports only 2 images (the normal one and another for the
+// selected state). We wish to provide support for 2 more of them for folder
+// items (i.e. those which have children): for expanded state and for expanded
+// selected state. For this we use this structure to store the additional items
+// images.
+//
+// There is only one problem with this: when we retrieve the item's data, we
+// don't know whether we get a pointer to wxTreeItemData or
+// wxTreeItemIndirectData. So we have to maintain a list of all items which
+// have indirect data inside the listctrl itself.
+// ----------------------------------------------------------------------------
+class wxTreeItemIndirectData
+{
+public:
+ // ctor associates this data with the item and the real item data becomes
+ // available through our GetData() method
+ wxTreeItemIndirectData(wxTreeCtrl *tree, const wxTreeItemId& item)
+ {
+ for ( size_t n = 0; n < WXSIZEOF(m_images); n++ )
+ {
+ m_images[n] = -1;
+ }
+
+ // save the old data
+ m_data = tree->GetItemData(item);
+
+ // and set ourselves as the new one
+ tree->SetIndirectItemData(item, this);
+ }
+
+ // dtor deletes the associated data as well
+ ~wxTreeItemIndirectData() { delete m_data; }
+
+ // accessors
+ // get the real data associated with the item
+ wxTreeItemData *GetData() const { return m_data; }
+ // change it
+ void SetData(wxTreeItemData *data) { m_data = data; }
+
+ // do we have such image?
+ bool HasImage(wxTreeItemIcon which) const { return m_images[which] != -1; }
+ // get image
+ int GetImage(wxTreeItemIcon which) const { return m_images[which]; }
+ // change it
+ void SetImage(int image, wxTreeItemIcon which) { m_images[which] = image; }
+
+private:
+ // all the images associated with the item
+ int m_images[wxTreeItemIcon_Max];
+
+ wxTreeItemData *m_data;
+};
+