]> git.saurik.com Git - wxWidgets.git/commitdiff
1. Implemented support for different icons for different states (expanded,
authorVadim Zeitlin <vadim@wxwidgets.org>
Wed, 29 Sep 1999 22:47:56 +0000 (22:47 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Wed, 29 Sep 1999 22:47:56 +0000 (22:47 +0000)
   selected, combination of them) for the tree control (and doc'd it)
2. removed code which was sending extra event if wxFrame::SetSize() was
   used
3. important changes to wxWizard interface
4. small compilation corrections

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@3756 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

31 files changed:
docs/latex/wx/treectrl.tex
include/wx/generic/treectrl.h
include/wx/generic/wizard.h [new file with mode: 0644]
include/wx/msw/font.h
include/wx/msw/frame.h
include/wx/msw/notebook.h
include/wx/msw/treectrl.h
include/wx/treectrl.h
include/wx/wizard.h
samples/listctrl/listtest.cpp
samples/mdi/mdi.cpp
samples/treectrl/bitmaps/file2.bmp [new file with mode: 0644]
samples/treectrl/bitmaps/file2.ico [new file with mode: 0644]
samples/treectrl/bitmaps/folder1.ico
samples/treectrl/bitmaps/folder2.bmp [new file with mode: 0644]
samples/treectrl/bitmaps/folder2.ico [new file with mode: 0644]
samples/treectrl/bitmaps/folder3.bmp [new file with mode: 0644]
samples/treectrl/bitmaps/folder3.ico [new file with mode: 0644]
samples/treectrl/icon3.xpm [new file with mode: 0644]
samples/treectrl/treetest.cpp
samples/treectrl/treetest.h
samples/treectrl/treetest.rc
samples/wizard/wiztest.cpp
src/common/docview.cpp
src/common/url.cpp
src/generic/prop.cpp
src/generic/wizard.cpp
src/msw/font.cpp
src/msw/frame.cpp
src/msw/notebook.cpp
src/msw/treectrl.cpp

index 47f182a80058a510be7745d1042926744c3bc512..fafe593cbcaec91face3a69a84324efd269626de 100644 (file)
@@ -287,9 +287,20 @@ associated with the wxTreeItemData for the given item Id.}
 
 \membersection{wxTreeCtrl::GetItemImage}\label{wxtreectrlgetitemimage}
 
-\constfunc{int}{GetItemImage}{\param{const wxTreeItemId\& }{item}}
-
-Gets the normal item image.
+\constfunc{int}{GetItemImage}{\param{const wxTreeItemId\& }{item},
+\param{wxTreeItemIcon }{which = wxTreeItemIcon\_Normal}}
+
+Gets the specified item image. The value of {\it which} may be:
+\begin{itemize}\itemsep=0pt
+\item{wxTreeItemIcon\_Normal} to get the normal item image
+\item{wxTreeItemIcon\_Selected} to get the selected item image (i.e. the image
+which is shown when the item is currently selected)
+\item{wxTreeItemIcon\_Expanded} to get the expanded image (this only
+makes sense for items which have children - then this image is shown when the
+item is expanded and the normal image is shown when it is collapsed)
+\item{wxTreeItemIcon\_SelectedExpanded} to get the selected expanded image
+(which is shown when an expanded item is currently selected)
+\end{itemize}
 
 \membersection{wxTreeCtrl::GetItemText}\label{wxtreectrlgetitemtext}
 
@@ -381,7 +392,8 @@ Returns the root item for the tree control.
 
 \constfunc{int}{GetItemSelectedImage}{\param{const wxTreeItemId\& }{item}}
 
-Gets the selected item image.
+Gets the selected item image (this function is obsolete, use 
+{\tt GetItemImage(item, wxTreeItemIcon\_Selected} instead).
 
 \membersection{wxTreeCtrl::GetSelection}\label{wxtreectrlgetselection}
 
@@ -546,15 +558,19 @@ usage and loading time.
 
 \membersection{wxTreeCtrl::SetItemImage}\label{wxtreectrlsetitemimage}
 
-\func{void}{SetItemImage}{\param{const wxTreeItemId\&}{ item}, \param{int }{image}}
+\func{void}{SetItemImage}{\param{const wxTreeItemId\&}{ item},
+\param{int }{image},
+\param{wxTreeItemIcon }{which = wxTreeItemIcon\_Normal}}
 
-Sets the normal item image. This is an index into the assciated image list.
+Sets the specified item image. See \helpref{GetItemImage}{wxtreectrlgetitemimage} 
+for the description of {\it which} parameter.
 
 \membersection{wxTreeCtrl::SetItemSelectedImage}\label{wxtreectrlsetitemselectedimage}
 
 \func{void}{SetItemSelectedImage}{\param{const wxTreeItemId\&}{ item}, \param{int }{selImage}}
 
-Sets the item selected image. This is an index into the assciated image list.
+Sets the selected item image (this function is obsolete, use 
+{\tt SetItemImage(item, wxTreeItemIcon\_Selected} instead).
 
 \membersection{wxTreeCtrl::SetItemText}\label{wxtreectrlsetitemtext}
 
index 1a42b69ef290216a2e39aaa67c034b139fcf31a3..38994404ba3692d21b1a00a761fce8ad97e32c6e 100644 (file)
@@ -258,10 +258,9 @@ public:
 
         // retrieve items label
     wxString GetItemText(const wxTreeItemId& item) const;
-        // get the normal item image
-    int GetItemImage(const wxTreeItemId& item) const;
-        // get the selected item image
-    int GetItemSelectedImage(const wxTreeItemId& item) const;
+        // get one of the images associated with the item (normal by default)
+    int GetItemImage(const wxTreeItemId& item,
+                     wxTreeItemIcon which = wxTreeItemIcon_Normal) const;
         // get the data associated with the item
     wxTreeItemData *GetItemData(const wxTreeItemId& item) const;
 
@@ -270,10 +269,9 @@ public:
 
         // set items label
     void SetItemText(const wxTreeItemId& item, const wxString& text);
-        // set the normal item image
-    void SetItemImage(const wxTreeItemId& item, int image);
-        // set the selected item image
-    void SetItemSelectedImage(const wxTreeItemId& item, int image);
+        // get one of the images associated with the item (normal by default)
+    void SetItemImage(const wxTreeItemId& item, int image,
+                      wxTreeItemIcon which = wxTreeItemIcon_Normal) const;
         // associate some data with the item
     void SetItemData(const wxTreeItemId& item, wxTreeItemData *data);
 
@@ -433,6 +431,16 @@ public:
         // NB: this function is not reentrant and not MT-safe (FIXME)!
     void SortChildren(const wxTreeItemId& item);
 
+    // deprecated functions: use Set/GetItemImage directly
+        // get the selected item image
+    int GetItemSelectedImage(const wxTreeItemId& item) const
+        { return GetItemImage(item, wxTreeItemIcon_Selected); }
+        // set the selected item image
+    void SetItemSelectedImage(const wxTreeItemId& item, int image)
+        { SetItemImage(item, image, wxTreeItemIcon_Selected); }
+
+    // implementation
+
     // callbacks
     void OnPaint( wxPaintEvent &event );
     void OnSetFocus( wxFocusEvent &event );
diff --git a/include/wx/generic/wizard.h b/include/wx/generic/wizard.h
new file mode 100644 (file)
index 0000000..987113b
--- /dev/null
@@ -0,0 +1,62 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        generic/wizard.h
+// Purpose:     declaration of generic wxWizard class
+// Author:      Vadim Zeitlin
+// Modified by:
+// Created:     28.09.99
+// RCS-ID:      $Id$
+// Copyright:   (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
+// Licence:     wxWindows license
+///////////////////////////////////////////////////////////////////////////////
+
+// ----------------------------------------------------------------------------
+// wxWizard
+// ----------------------------------------------------------------------------
+
+class wxWizard : public wxWizardBase
+{
+public:
+    // ctor
+    wxWizard(wxWindow *parent = NULL,
+             int id = -1,
+             const wxString& title = wxEmptyString,
+             const wxBitmap& bitmap = wxNullBitmap,
+             const wxPoint& pos = wxDefaultPosition,
+             const wxSize& size = wxDefaultSize);
+
+    // implement base class pure virtuals
+    virtual bool RunWizard(wxWizardPage *firstPage);
+    virtual wxWizardPage *GetCurrentPage() const;
+
+    // implementation only from now on
+    // -------------------------------
+
+    // is the wizard running?
+    bool IsRunning() const { return m_page != NULL; }
+
+    // show the prev/next page, but call TransferDataFromWindow on the current
+    // page first and return FALSE without changing the page if it returns
+    // FALSE
+    bool ShowPage(wxWizardPage *page, bool goingForward = TRUE);
+
+private:
+    // event handlers
+    void OnCancel(wxCommandEvent& event);
+    void OnBackOrNext(wxCommandEvent& event);
+
+    // wizard dimensions
+    int          m_x, m_y;      // the origin for the pages
+    int          m_width,       // the size of the page itself
+                 m_height;      // (total width is m_width + m_x)
+
+    // wizard state
+    wxWizardPage *m_page;       // the current page or NULL
+
+    // wizard controls
+    wxButton    *m_btnPrev,     // the "<Back" button
+                *m_btnNext;     // the "Next>" or "Finish" button
+
+    DECLARE_DYNAMIC_CLASS(wxWizard)
+    DECLARE_EVENT_TABLE()
+};
+
index 36642fd4149e58c8de2ccf8122c02df635ce9b37..78a836caac1ef89916964c6e5cc5cbe1e3939caa 100644 (file)
@@ -54,6 +54,9 @@ public:
 
     virtual ~wxFont();
 
+    // assignment
+    wxFont& operator=(const wxFont& font);
+
     // implement base class pure virtuals
     virtual int GetPointSize() const;
     virtual int GetFamily() const;
index f5df0290d1d32cdb6aaf0a9dc09ddbfec4ab4206..722f4bf695e51dfa7ab20bb4058f98bc95bfb9d6 100644 (file)
@@ -177,9 +177,6 @@ protected:
     virtual void DoGetSize(int *width, int *height) const;
     virtual void DoGetPosition(int *x, int *y) const;
 
-    virtual void DoSetSize(int x, int y,
-                           int width, int height,
-                           int sizeFlags = wxSIZE_AUTO);
     virtual void DoSetClientSize(int width, int height);
 
     // a plug in for MDI frame classes which need to do something special when
index 1a5dde10c11223c40559d099d553c6d76b589317..265274a036d3b26a25465760f4eb536f406691bd 100644 (file)
 // ----------------------------------------------------------------------------
 // headers
 // ----------------------------------------------------------------------------
+
 #ifndef   _DYNARRAY_H
   #include <wx/dynarray.h>
 #endif  //_DYNARRAY_H
 
-// This is a work-around for missing defines in gcc-2.95 headers
-#ifndef TCS_RIGHT
-#define TCS_RIGHT       0x0002
-#endif
-#ifndef TCS_VERTICAL
-#define TCS_VERTICAL    0x0080
-#endif
-#ifndef TCS_BOTTOM
-#define TCS_BOTTOM      TCS_RIGHT
-#endif
 // ----------------------------------------------------------------------------
 // types
 // ----------------------------------------------------------------------------
index 313018797d58deeafadd4477232d6578920bebe2..b193782490c2faad9996d97e88ef55de63c8586e 100644 (file)
@@ -149,11 +149,7 @@ public:
 
     // accessors: set/get the item associated with this node
     void SetId(const wxTreeItemId& id) { m_itemId = id; }
-#ifdef __WATCOMC__
-    const wxTreeItemId GetId() const { return m_itemId; }
-#else
-    const wxTreeItemId& GetId() const { return (wxTreeItemId&) m_itemId; }
-#endif
+    const wxTreeItemId GetId() const { return *this; }
 };
 
 // ----------------------------------------------------------------------------
@@ -197,10 +193,10 @@ public:
     unsigned int GetIndent() const;
     void SetIndent(unsigned int indent);
 
-       // spacing is the number of pixels between the start and the Text
-       // not implemented under wxMSW
+    // spacing is the number of pixels between the start and the Text
+        // not implemented under wxMSW
     unsigned int GetSpacing() const { return 18; } // return wxGTK default
-    void SetSpacing(unsigned int ) {}
+    void SetSpacing(unsigned int WXUNUSED(spacing)) { }
 
         // image list: these functions allow to associate an image list with
         // the control and retrieve it. Note that the control does _not_ delete
@@ -228,10 +224,9 @@ public:
 
         // retrieve items label
     wxString GetItemText(const wxTreeItemId& item) const;
-        // get the normal item image
-    int GetItemImage(const wxTreeItemId& item) const;
-        // get the selected item image
-    int GetItemSelectedImage(const wxTreeItemId& item) const;
+        // get one of the images associated with the item (normal by default)
+    int GetItemImage(const wxTreeItemId& item,
+                     wxTreeItemIcon which = wxTreeItemIcon_Normal) const;
         // get the data associated with the item
     wxTreeItemData *GetItemData(const wxTreeItemId& item) const;
 
@@ -240,10 +235,9 @@ public:
 
         // set items label
     void SetItemText(const wxTreeItemId& item, const wxString& text);
-        // set the normal item image
-    void SetItemImage(const wxTreeItemId& item, int image);
-        // set the selected item image
-    void SetItemSelectedImage(const wxTreeItemId& item, int image);
+        // get one of the images associated with the item (normal by default)
+    void SetItemImage(const wxTreeItemId& item, int image,
+                      wxTreeItemIcon which = wxTreeItemIcon_Normal);
         // associate some data with the item
     void SetItemData(const wxTreeItemId& item, wxTreeItemData *data);
 
@@ -452,6 +446,14 @@ public:
     void SetImageList(wxImageList *imageList, int)
         { SetImageList(imageList); }
 
+    // use Set/GetItemImage directly
+        // get the selected item image
+    int GetItemSelectedImage(const wxTreeItemId& item) const
+        { return GetItemImage(item, wxTreeItemIcon_Selected); }
+        // set the selected item image
+    void SetItemSelectedImage(const wxTreeItemId& item, int image)
+        { SetItemImage(item, image, wxTreeItemIcon_Selected); }
+
     // implementation
     // --------------
     virtual bool MSWCommand(WXUINT param, WXWORD id);
@@ -465,7 +467,7 @@ protected:
     // SetImageList helper
     void SetAnyImageList(wxImageList *imageList, int which);
 
-    wxTextCtrl*  m_textCtrl;        // used while editing the item label
+    wxTextCtrl  *m_textCtrl;        // used while editing the item label
     wxImageList *m_imageListNormal, // images for tree elements
                 *m_imageListState;  // special images for app defined states
 
@@ -485,10 +487,23 @@ private:
                               int image, int selectedImage,
                               wxTreeItemData *data);
 
+    int DoGetItemImageFromData(const wxTreeItemId& item,
+                               wxTreeItemIcon which) const;
+    void DoSetItemImageFromData(const wxTreeItemId& item,
+                                int image,
+                                wxTreeItemIcon which) const;
     void DoSetItemImages(const wxTreeItemId& item, int image, int imageSel);
 
     void DeleteTextCtrl();
 
+    // support for additional item images
+    friend class wxTreeItemIndirectData;
+    void SetIndirectItemData(const wxTreeItemId& item,
+                             wxTreeItemIndirectData *data);
+    bool HasIndirectData(const wxTreeItemId& item) const;
+
+    wxArrayTreeItemIds m_itemsWithIndirectData;
+
     DECLARE_DYNAMIC_CLASS(wxTreeCtrl)
 };
 
index b6d81ef686c25dad112a37eb459c340451c5cdef..631c3393acc64c4449f1643b60195cd87309802f 100644 (file)
 // constants
 // ----------------------------------------------------------------------------
 
+// enum for different images associated with a treectrl item
+enum wxTreeItemIcon
+{
+    wxTreeItemIcon_Normal,              // not selected, not expanded
+    wxTreeItemIcon_Selected,            //     selected, not expanded
+    wxTreeItemIcon_Expanded,            // not selected,     expanded
+    wxTreeItemIcon_SelectedExpanded,    //     selected,     expanded
+    wxTreeItemIcon_Max
+};
+
+// tree ctrl default name
 #ifdef __WXMSW__
-WXDLLEXPORT_DATA(extern const char*) wxTreeCtrlNameStr;
+    WXDLLEXPORT_DATA(extern const char*) wxTreeCtrlNameStr;
 #else
-#define wxTreeCtrlNameStr "wxTreeCtrl"
+    #define wxTreeCtrlNameStr "wxTreeCtrl"
 #endif
 
 // ----------------------------------------------------------------------------
index 0c9e577700acd42a5c8d5bdc75d798cd5a9b3065..10f124d7dca193da9466264718fe1ca4069747da 100644 (file)
@@ -15,7 +15,7 @@
 #define _WX_WIZARD_H_
 
 // ----------------------------------------------------------------------------
-// headers
+// headers and other simple declarations
 // ----------------------------------------------------------------------------
 
 #ifndef WX_PRECOMP
     #include "wx/event.h"       // wxEVT_XXX constants
 #endif // WX_PRECOMP
 
+// forward declarations
+class WXDLLEXPORT wxWizard;
+
+// ----------------------------------------------------------------------------
+// wxWizardPage is one of the wizards screen: it must know what are the
+// following and preceding pages (which may be NULL for the first/last page).
+//
+// Other than GetNext/Prev() functions, wxWizardPage is just a panel and may be
+// used as such (i.e. controls may be placed directly on it &c).
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxWizardPage : public wxPanel
+{
+public:
+    // ctor: no other parameters are needed because the wizard will resize and
+    // reposition the page anyhow
+    wxWizardPage(wxWizard *parent);
+
+    // these functions are used by the wizard to show another page when the
+    // user chooses "Back" or "Next" button
+    virtual wxWizardPage *GetPrev() const = 0;
+    virtual wxWizardPage *GetNext() const = 0;
+
+private:
+    DECLARE_ABSTRACT_CLASS(wxWizardPage)
+};
+
+// ----------------------------------------------------------------------------
+// wxWizardPageSimple just returns the pointers given to the ctor and is useful
+// to create a simple wizard where the order of pages never changes.
+//
+// OTOH, it is also possible to dynamicly decide which page to return (i.e.
+// depending on the user's choices) as the wizard sample shows - in order to do
+// this, you must derive from wxWizardPage directly.
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxWizardPageSimple : public wxWizardPage
+{
+public:
+    // ctor takes the previous and next pages
+    wxWizardPageSimple(wxWizard *parent = NULL, // let it be default ctor too
+                       wxWizardPage *prev = (wxWizardPage *)NULL,
+                       wxWizardPage *next = (wxWizardPage *)NULL)
+        : wxWizardPage(parent)
+    {
+        m_prev = prev;
+        m_next = next;
+    }
+
+    // the pointers may be also set later - but before starting the wizard
+    void SetPrev(wxWizardPage *prev) { m_prev = prev; }
+    void SetNext(wxWizardPage *next) { m_next = next; }
+
+    // a convenience function to make the pages follow each other
+    static void Chain(wxWizardPageSimple *first, wxWizardPageSimple *second)
+    {
+        wxCHECK_RET( first && second,
+                     _T("NULL passed to wxWizardPageSimple::Chain") );
+
+        first->SetNext(second);
+        second->SetPrev(first);
+    }
+
+    // base class pure virtuals
+    virtual wxWizardPage *GetPrev() const;
+    virtual wxWizardPage *GetNext() const;
+
+private:
+    // pointers are private, the derived classes shouldn't mess with them -
+    // just derive from wxWizardPage directly to implement different behaviour
+    wxWizardPage *m_prev,
+                 *m_next;
+
+    DECLARE_DYNAMIC_CLASS(wxWizardPageSimple)
+};
+
 // ----------------------------------------------------------------------------
 // wxWizard
 // ----------------------------------------------------------------------------
 
-class WXDLLEXPORT wxWizard : public wxDialog
+class WXDLLEXPORT wxWizardBase : public wxDialog
 {
 public:
     // create the wizard control
@@ -39,40 +115,38 @@ public:
                             const wxPoint& pos = wxDefaultPosition,
                             const wxSize& size = wxDefaultSize);
 
-    // wizard construction: add/insert new page into it
-        // adds a page at the end
-    virtual void AddPage(wxPanel *page) = 0;
-        // adds a page before the page nPage (the new page will have this index)
-    virtual void InsertPage(int nPage, wxPanel *page) = 0;
-
-    // executes the wizard, returns TRUE if it was successfully finished, FALSE
-    // if user cancelled it
-    virtual bool RunWizard() = 0;
+    // executes the wizard starting from the given page, returns TRUE if it was
+    // successfully finished, FALSE if user cancelled it
+    virtual bool RunWizard(wxWizardPage *firstPage) = 0;
 
     // get the current page (NULL if RunWizard() isn't running)
-    virtual wxPanel *GetCurrentPage() const = 0;
-
-private:
-    DECLARE_DYNAMIC_CLASS(wxWizard)
+    virtual wxWizardPage *GetCurrentPage() const = 0;
 };
 
+// include the real class declaration
+#include "wx/generic/wizard.h"
+
 // ----------------------------------------------------------------------------
-// wxWizardEvent class represents an event generated by the wizard
+// wxWizardEvent class represents an event generated by the wizard: this event
+// is first sent to the page itself and, if not processed there, goes up the
+// window hierarchy as usual
 // ----------------------------------------------------------------------------
 
 class WXDLLEXPORT wxWizardEvent : public wxNotifyEvent
 {
 public:
-    wxWizardEvent(wxEventType type = wxEVT_NULL, int id = 0);
-
-    // get the previously active page or -1 if none
-    int GetOldPage() const { return m_pageOld; }
+    wxWizardEvent(wxEventType type = wxEVT_NULL,
+                  int id = -1,
+                  bool direction = TRUE);
 
-    // get the current page or -1 if none
-    int GetPage() const { return m_page; }
+    // for EVT_WIZARD_PAGE_CHANGING, return TRUE if we're going forward or
+    // FALSE otherwise and for EVT_WIZARD_PAGE_CHANGED return TRUE if we came
+    // from the previous page and FALSE if we returned from the next one
+    // (this function doesn't make sense for CANCEL events)
+    bool GetDirection() const { return m_direction; }
 
 private:
-    int m_pageOld, m_page;
+    bool m_direction;
 
     DECLARE_DYNAMIC_CLASS(wxWizardEvent)
 };
@@ -83,7 +157,7 @@ private:
 
 typedef void (wxEvtHandler::*wxWizardEventFunction)(wxWizardEvent&);
 
-// notifies that the page has just been changed
+// notifies that the page has just been changed (can't be vetoed)
 #define EVT_WIZARD_PAGE_CHANGED(id, fn) { wxEVT_WIZARD_PAGE_CHANGED, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxWizardEventFunction) & fn, (wxObject *)NULL },
 
 // the user pressed "<Back" or "Next>" button and the page is going to be
index 13731a6ed31ff675cfd2d2310ba694205f0e6c6b..f8a8a18f3ac574bd90dd67d09d167a5e25386f39 100644 (file)
@@ -482,7 +482,7 @@ void MyListCtrl::OnSetInfo(wxListEvent& WXUNUSED(event))
     text->WriteText("OnSetInfo\n");
 }
 
-void MyListCtrl::OnSelected(wxListEvent& WXUNUSED(event))
+void MyListCtrl::OnSelected(wxListEvent& event)
 {
     if ( !wxGetApp().GetTopWindow() )
         return;
@@ -491,6 +491,20 @@ void MyListCtrl::OnSelected(wxListEvent& WXUNUSED(event))
     if ( !text )
         return;
 
+    wxListItem info;
+    info.m_itemId = event.m_itemIndex;
+    info.m_col = 1;
+    info.m_mask = wxLIST_MASK_TEXT;
+    if ( GetItem(info) )
+    {
+        *text << "Value of the 2nd field of the selected item: "
+              << info.m_text << '\n';
+    }
+    else
+    {
+        wxFAIL_MSG("wxListCtrl::GetItem() failed");
+    }
+
     text->WriteText("OnSelected\n");
 }
 
index 45474995f16ed546934df1c4558c0415dd285666..d22f58af3275d10f8bdbdaa9b809e83b180c05ed 100644 (file)
@@ -255,7 +255,7 @@ void MyFrame::OnNewWindow(wxCommandEvent& WXUNUSED(event) )
     subframe->Show(TRUE);
 }
 
-void MyFrame::OnSize(wxSizeEvent& WXUNUSED(event) )
+void MyFrame::OnSize(wxSizeEvent& WXUNUSED(event))
 {
     int w, h;
     GetClientSize(&w, &h);
diff --git a/samples/treectrl/bitmaps/file2.bmp b/samples/treectrl/bitmaps/file2.bmp
new file mode 100644 (file)
index 0000000..e812d69
Binary files /dev/null and b/samples/treectrl/bitmaps/file2.bmp differ
diff --git a/samples/treectrl/bitmaps/file2.ico b/samples/treectrl/bitmaps/file2.ico
new file mode 100644 (file)
index 0000000..b1059f9
Binary files /dev/null and b/samples/treectrl/bitmaps/file2.ico differ
index 387080ef43b64d5dfd834aa2cb1c487d459f5230..a84318433d48337a6ec69fd4b7eeb3a5b904fd8d 100644 (file)
Binary files a/samples/treectrl/bitmaps/folder1.ico and b/samples/treectrl/bitmaps/folder1.ico differ
diff --git a/samples/treectrl/bitmaps/folder2.bmp b/samples/treectrl/bitmaps/folder2.bmp
new file mode 100644 (file)
index 0000000..35fedba
Binary files /dev/null and b/samples/treectrl/bitmaps/folder2.bmp differ
diff --git a/samples/treectrl/bitmaps/folder2.ico b/samples/treectrl/bitmaps/folder2.ico
new file mode 100644 (file)
index 0000000..ca50cdc
Binary files /dev/null and b/samples/treectrl/bitmaps/folder2.ico differ
diff --git a/samples/treectrl/bitmaps/folder3.bmp b/samples/treectrl/bitmaps/folder3.bmp
new file mode 100644 (file)
index 0000000..dfc3c4f
Binary files /dev/null and b/samples/treectrl/bitmaps/folder3.bmp differ
diff --git a/samples/treectrl/bitmaps/folder3.ico b/samples/treectrl/bitmaps/folder3.ico
new file mode 100644 (file)
index 0000000..ebbb9db
Binary files /dev/null and b/samples/treectrl/bitmaps/folder3.ico differ
diff --git a/samples/treectrl/icon3.xpm b/samples/treectrl/icon3.xpm
new file mode 100644 (file)
index 0000000..a6b8b5f
--- /dev/null
@@ -0,0 +1,45 @@
+/* XPM */
+static char *icon2_xpm[] = {
+/* width height num_colors chars_per_pixel */
+"    32    32        6            1",
+/* colors */
+". c #b2c0dc",
+"# c #000000",
+"a c #c0c0c0",
+"b c #808080",
+"c c #ffff00",
+"d c #ffffff",
+/* pixels */
+"................................",
+"................................",
+"......bbbbbbbbbb................",
+"......bbbbbbbbbb................",
+"....bbccaaccaaccbb..............",
+"....bbccaaccaaccbb..............",
+"..bbccaaccaaccaaccbbbbbbbbbbbb..",
+"..bbccaaccaaccaaccbbbbbbbbbbbb..",
+"..bbddddddddddddddddddddddddbb##",
+"..bbddddddddddddddddddddddddbb##",
+"..bbddccaaccaaccaaccaaccaaccbb##",
+"..bbddccaaccaaccaaccaaccaaccbb##",
+"..bbddaaccaaccaaccaaccaaccaabb##",
+"..bbddaaccaaccaaccaaccaaccaabb##",
+"..bbddccaaccaaccaaccaaccaaccbb##",
+"..bbddccaaccaaccaaccaaccaaccbb##",
+"..bbddaaccaaccaaccaaccaaccaabb##",
+"..bbddaaccaaccaaccaaccaaccaabb##",
+"..bbddccaaccaaccaaccaaccaaccbb##",
+"..bbddccaaccaaccaaccaaccaaccbb##",
+"..bbddaaccaaccaaccaaccaaccaabb##",
+"..bbddaaccaaccaaccaaccaaccaabb##",
+"..bbddccaaccaaccaaccaaccaaccbb##",
+"..bbddccaaccaaccaaccaaccaaccbb##",
+"..bbbbbbbbbbbbbbbbbbbbbbbbbbbb##",
+"..bbbbbbbbbbbbbbbbbbbbbbbbbbbb##",
+"....############################",
+"....############################",
+"................................",
+"................................",
+"................................",
+"................................"
+};
index 8335f176b7604a75b60fe7a432b5c17ae61c0c28..873b8810839634dff1b21219f078df367c74699a 100644 (file)
 
 #include "math.h"
 
-//#ifdef __WXMSW__
+#ifdef __WXMSW__
     #define NO_MULTIPLE_SELECTION
     #define NO_VARIABLE_HEIGHT
-//#endif
+#endif
 
 #include "treetest.h"
 
 // under Windows the icons are in the .rc file
 #ifndef __WXMSW__
-#ifdef NO_VARIABLE_HEIGHT
   #include "icon1.xpm"
-#endif
   #include "icon2.xpm"
+  #include "icon3.xpm"
+  #include "icon4.xpm"
   #include "mondrian.xpm"
 #endif
 
@@ -92,7 +92,9 @@ BEGIN_EVENT_TABLE(MyTreeCtrl, wxTreeCtrl)
     EVT_TREE_BEGIN_LABEL_EDIT(TreeTest_Ctrl, MyTreeCtrl::OnBeginLabelEdit)
     EVT_TREE_END_LABEL_EDIT(TreeTest_Ctrl, MyTreeCtrl::OnEndLabelEdit)
     EVT_TREE_DELETE_ITEM(TreeTest_Ctrl, MyTreeCtrl::OnDeleteItem)
+#if 0       // there are so many of those that logging them causes flicker
     EVT_TREE_GET_INFO(TreeTest_Ctrl, MyTreeCtrl::OnGetInfo)
+#endif
     EVT_TREE_SET_INFO(TreeTest_Ctrl, MyTreeCtrl::OnSetInfo)
     EVT_TREE_ITEM_EXPANDED(TreeTest_Ctrl, MyTreeCtrl::OnItemExpanded)
     EVT_TREE_ITEM_EXPANDING(TreeTest_Ctrl, MyTreeCtrl::OnItemExpanding)
@@ -187,12 +189,12 @@ MyFrame::MyFrame(const wxString& title, int x, int y, int w, int h)
                                 wxTR_HAS_BUTTONS |
                                 wxTR_EDIT_LABELS |
 #ifndef NO_MULTIPLE_SELECTION
-                               wxTR_MULTIPLE |
+                                wxTR_MULTIPLE |
 #endif
 #ifndef NO_VARIABLE_HEIGHT
-                               wxTR_HAS_VARIABLE_ROW_HEIGHT |
+                                wxTR_HAS_VARIABLE_ROW_HEIGHT |
 #endif
-                               wxSUNKEN_BORDER);
+                                wxSUNKEN_BORDER);
     wxTextCtrl *textCtrl = new wxTextCtrl(this, -1, "",
                                 wxDefaultPosition, wxDefaultSize,
                                 wxTE_MULTILINE | wxSUNKEN_BORDER);
@@ -440,6 +442,9 @@ MyTreeCtrl::MyTreeCtrl(wxWindow *parent, const wxWindowID id,
     m_imageListNormal->Add(wxBitmap("bitmap1", wxBITMAP_TYPE_BMP_RESOURCE));
 #  endif
     m_imageListNormal->Add(wxBitmap("bitmap2", wxBITMAP_TYPE_BMP_RESOURCE));
+    m_imageListNormal->Add(wxBitmap("bitmap3", wxBITMAP_TYPE_BMP_RESOURCE));
+    m_imageListNormal->Add(wxBitmap("bitmap4", wxBITMAP_TYPE_BMP_RESOURCE));
+    m_imageListNormal->Add(wxBitmap("bitmap5", wxBITMAP_TYPE_BMP_RESOURCE));
 #else
 #  ifndef NO_VARIABLE_HEIGHT
     m_imageListNormal->Add(image.ConvertToBitmap());
@@ -447,6 +452,9 @@ MyTreeCtrl::MyTreeCtrl(wxWindow *parent, const wxWindowID id,
     m_imageListNormal->Add(wxICON(icon1));
 #  endif
     m_imageListNormal->Add(wxICON(icon2));
+    m_imageListNormal->Add(wxICON(icon3));
+    m_imageListNormal->Add(wxICON(icon4));
+    m_imageListNormal->Add(wxICON(icon5));
 #endif
 
     SetImageList(m_imageListNormal);
@@ -481,21 +489,32 @@ void MyTreeCtrl::AddItemsRecursively(const wxTreeItemId& idParent,
 {
     if ( depth > 0 )
     {
+        bool hasChildren = depth > 1;
+
         wxString str;
         for ( size_t n = 0; n < numChildren; n++ )
         {
             // at depth 1 elements won't have any more children
-            if (depth == 1)
-                str.Printf("%s child %d.%d", "File", folder, n + 1);
-            else
+            if ( hasChildren )
                 str.Printf("%s child %d", "Folder", n + 1);
+            else
+                str.Printf("%s child %d.%d", "File", folder, n + 1);
 
+            // here we pass to AppendItem() normal and selected item images (we
+            // suppose that selected image follows the normal one in the enum)
             int image = depth == 1 ? TreeCtrlIcon_File : TreeCtrlIcon_Folder;
-            wxTreeItemId id = AppendItem(idParent, str, image, image,
+            wxTreeItemId id = AppendItem(idParent, str, image, image + 1,
                                          new MyTreeItemData(str));
 
+            // and now we also set the expanded one (only for the folders)
+            if ( hasChildren )
+            {
+                SetItemImage(id, TreeCtrlIcon_FolderOpened,
+                             wxTreeItemIcon_Expanded);
+            }
+
             // remember the last child for OnEnsureVisible()
-            if ( depth == 1 && n == numChildren - 1 )
+            if ( !hasChildren && n == numChildren - 1 )
             {
                 m_lastItem = id;
             }
@@ -512,6 +531,7 @@ void MyTreeCtrl::AddTestItemsToTree(size_t numChildren,
     wxTreeItemId rootId = AddRoot("Root",
                                   TreeCtrlIcon_Folder, TreeCtrlIcon_Folder,
                                   new MyTreeItemData("Root item"));
+    SetItemImage(rootId, TreeCtrlIcon_FolderOpened, wxTreeItemIcon_Expanded);
 
     AddItemsRecursively(rootId, numChildren, depth, 0);
 }
index dec33dc30a8434864c1b3d1e152facdf31df8414..67562e087bfc7ac78283bc3e65041370bbdb7dcf 100644 (file)
@@ -34,7 +34,10 @@ public:
     enum
     {
         TreeCtrlIcon_File,
-        TreeCtrlIcon_Folder
+        TreeCtrlIcon_FileSelected,
+        TreeCtrlIcon_Folder,
+        TreeCtrlIcon_FolderSelected,
+        TreeCtrlIcon_FolderOpened
     };
 
     MyTreeCtrl() { }
index 550dc2f13558c55d0083d5706a98371c0235b62f..f055b67d4f9b6cfdcfcd96ca4e4a4df638458309 100644 (file)
@@ -1,10 +1,17 @@
 mondrian ICON "mondrian.ico"
 aaaa     ICON "mondrian.ico"
+
 #include "wx/msw/wx.rc"
 
 icon1   ICON "bitmaps\\file1.ico"
-icon2   ICON "bitmaps\\folder1.ico"
+icon2   ICON "bitmaps\\file2.ico"
+icon3   ICON "bitmaps\\folder1.ico"
+icon4   ICON "bitmaps\\folder2.ico"
+icon5   ICON "bitmaps\\folder3.ico"
 
 bitmap1   BITMAP "bitmaps\\file1.bmp"
-bitmap2   BITMAP "bitmaps\\folder1.bmp"
+bitmap2   BITMAP "bitmaps\\file2.bmp"
+bitmap3   BITMAP "bitmaps\\folder1.bmp"
+bitmap4   BITMAP "bitmaps\\folder2.bmp"
+bitmap5   BITMAP "bitmaps\\folder3.bmp"
 
index df1c8f3affdf7d1525ae53e3b46ff0e379c60fdc..3d94b0c92989919965018fb367e1eab00b784600 100644 (file)
@@ -63,19 +63,19 @@ IMPLEMENT_APP(MyApp)
 // overriding TransferDataFromWindow() - of course, in a real program, the
 // check wouldn't be so trivial and the data will be probably saved somewhere
 // too
-class wxCheckboxPage : public wxPanel
+class wxValidationPage : public wxWizardPageSimple
 {
 public:
-    wxCheckboxPage(wxWizard *parent) : wxPanel(parent)
+    wxValidationPage(wxWizard *parent) : wxWizardPageSimple(parent)
     {
-        m_checkbox = new wxCheckBox(this, -1, "Check me", wxPoint(20, 20));
+        m_checkbox = new wxCheckBox(this, -1, "&Check me");
     }
 
     virtual bool TransferDataFromWindow()
     {
-        if ( m_checkbox->GetValue() )
+        if ( !m_checkbox->GetValue() )
         {
-            wxMessageBox("Clear the checkbox first", "No way",
+            wxMessageBox("Check the checkbox first!", "No way",
                          wxICON_WARNING | wxOK, this);
 
             return FALSE;
@@ -88,10 +88,108 @@ private:
     wxCheckBox *m_checkbox;
 };
 
+// This is a more complicated example of validity checking: using events we may
+// allow to return to the previous page, but not to proceed. It also
+// demonstrates how to intercept [Cancel] button press.
+class wxRadioboxPage : public wxWizardPageSimple
+{
+public:
+    // directions in which we allow the user to proceed from this page
+    enum
+    {
+        Forward, Backward, Both, Neither
+    };
+
+    wxRadioboxPage(wxWizard *parent) : wxWizardPageSimple(parent)
+    {
+        // should correspond to the enum above
+        static wxString choices[] = { "forward", "backward", "both", "neither" };
+
+        m_radio = new wxRadioBox(this, -1, "Allow to proceed:",
+                                 wxPoint(5, 5), wxDefaultSize,
+                                 WXSIZEOF(choices), choices,
+                                 1, wxRA_SPECIFY_COLS);
+        m_radio->SetSelection(Both);
+    }
+
+    // wizard event handlers
+    void OnWizardCancel(wxWizardEvent& event)
+    {
+        if ( wxMessageBox("Do you really want to cancel?", "Question",
+                          wxICON_QUESTION | wxYES_NO, this) != wxYES )
+        {
+            // not confirmed
+            event.Veto();
+        }
+    }
+
+    void OnWizardPageChanging(wxWizardEvent& event)
+    {
+        int sel = m_radio->GetSelection();
+
+        if ( sel == Both )
+            return;
+
+        if ( event.GetDirection() && sel == Forward )
+            return;
+
+        if ( !event.GetDirection() && sel == Backward )
+            return;
+
+        wxMessageBox("You can't go there", "Not allowed",
+                     wxICON_WARNING | wxOK, this);
+
+        event.Veto();
+    }
+
+private:
+    wxRadioBox *m_radio;
+
+    DECLARE_EVENT_TABLE()
+};
+
+// this shows how to dynamically (i.e. during run-time) arrange the page order
+class wxCheckboxPage : public wxWizardPage
+{
+public:
+    wxCheckboxPage(wxWizard *parent,
+                   wxWizardPage *prev,
+                   wxWizardPage *next)
+        : wxWizardPage(parent)
+    {
+        m_prev = prev;
+        m_next = next;
+
+        (void)new wxStaticText(this, -1, "Try checking the box below and\n"
+                                         "then going back and clearing it");
+
+        m_checkbox = new wxCheckBox(this, -1, "&Skip the next page",
+                                    wxPoint(5, 30));
+    }
+
+    // implement wxWizardPage functions
+    virtual wxWizardPage *GetPrev() const { return m_prev; }
+    virtual wxWizardPage *GetNext() const
+    {
+        return m_checkbox->GetValue() ? m_next->GetNext() : m_next;
+    }
+
+private:
+    wxWizardPage *m_prev,
+                 *m_next;
+
+    wxCheckBox *m_checkbox;
+};
+
 // ============================================================================
 // implementation
 // ============================================================================
 
+BEGIN_EVENT_TABLE(wxRadioboxPage, wxWizardPageSimple)
+    EVT_WIZARD_PAGE_CHANGING(-1, wxRadioboxPage::OnWizardPageChanging)
+    EVT_WIZARD_CANCEL(-1, wxRadioboxPage::OnWizardCancel)
+END_EVENT_TABLE()
+
 // ----------------------------------------------------------------------------
 // the application class
 // ----------------------------------------------------------------------------
@@ -109,18 +207,30 @@ bool MyApp::OnInit()
                                         "Absolutely Useless Wizard",
                                         bmpWizard);
 
-    wxPanel *panel = new wxPanel(wizard);
-    (void)new wxStaticText(panel, -1,
+    // a wizard page may be either an object of predefined class
+    wxWizardPageSimple *page1 = new wxWizardPageSimple(wizard);
+    (void)new wxStaticText(page1, -1,
                            "This wizard doesn't help you to do anything at "
                            "all.\n"
                            "\n"
                            "The next pages will present you with more useless "
                            "controls.");
-    wizard->AddPage(panel);
 
-    wizard->AddPage(new wxCheckboxPage(wizard));
+    // ... or a derived class
+    wxRadioboxPage *page3 = new wxRadioboxPage(wizard);
+    wxValidationPage *page4 = new wxValidationPage(wizard);
+
+    // set the page order using a convenience function - could also use
+    // SetNext/Prev directly as below
+    wxWizardPageSimple::Chain(page3, page4);
+
+    // this page is not a wxWizardPageSimple, so we use SetNext/Prev to insert
+    // it into the chain of pages
+    wxCheckboxPage *page2 = new wxCheckboxPage(wizard, page1, page3);
+    page1->SetNext(page2);
+    page3->SetPrev(page2);
 
-    if ( wizard->RunWizard() )
+    if ( wizard->RunWizard(page1) )
     {
         wxMessageBox("The wizard successfully completed", "That's all",
                      wxICON_INFORMATION | wxOK);
index b0e3db14b25d6fefb1dde12ab9e39715ffed514e..0f169724392468f9070c80abe4ad020aef9db955 100644 (file)
@@ -56,6 +56,7 @@
 #include "wx/choicdlg.h"
 #include "wx/docview.h"
 #include "wx/confbase.h"
+#include "wx/file.h"
 
 #include <stdio.h>
 #include <string.h>
index 6c735d5599757c85ffe63825733bf0ff1ad0cef2..1e142f1ef1d6215b619e48f7561e3b1a43012c63 100644 (file)
@@ -387,14 +387,11 @@ wxString wxURL::ConvertToValidURI(const wxString& uri)
 
 wxString wxURL::ConvertFromURI(const wxString& uri)
 {
-  int code;
-  int i;
   wxString new_uri;
 
-  new_uri.Empty();
-  
-  i = 0;
+  size_t i = 0;
   while (i<uri.Len()) {
+    int code;
     if (uri[i] == _T('%')) {
       i++;
       if (uri[i] >= _T('A') && uri[i] <= _T('F'))
index 3aa479d8e488d0aa6ce61d0744f1d7958a022549..a44800754d93571f8c731d1b0a98d0ac27a7bb9d 100644 (file)
@@ -379,9 +379,7 @@ void wxPropertyValue::Copy(wxPropertyValue& copyFrom)
 #endif
 #endif // if 0
 
-      // TODO: check if this is right.  MB
-      //
-      (*this) = s;
+      (*this) = (bool)(s != 0);
       
       return ;
     }
index 2131e993d3dabd013d7fa2ebe84c09d0dab8e40c..4d70f33f01c58b10485a02af669fc5b9cf963a06 100644 (file)
 
 WX_DEFINE_ARRAY(wxPanel *, wxArrayPages);
 
-// ----------------------------------------------------------------------------
-// wxWizardGeneric - generic implementation of wxWizard
-// ----------------------------------------------------------------------------
-
-class wxWizardGeneric : public wxWizard
-{
-public:
-    // ctor
-    wxWizardGeneric(wxWindow *parent,
-                    int id,
-                    const wxString& title,
-                    const wxBitmap& bitmap,
-                    const wxPoint& pos,
-                    const wxSize& size);
-
-    // implement base class pure virtuals
-    virtual void AddPage(wxPanel *page);
-    virtual void InsertPage(int nPage, wxPanel *page);
-    virtual bool RunWizard();
-    virtual wxPanel *GetCurrentPage() const;
-
-    // implementation only from now on
-    // -------------------------------
-
-    // is the wizard running?
-    bool IsRunning() const { return m_page != -1; }
-
-    // show the given page calling TransferDataFromWindow - if it returns
-    // FALSE, the old page is not hidden and the function returns FALSE
-    bool ShowPage(size_t page);
-
-    // get the current page assuming the wizard is running
-    wxPanel *DoGetCurrentPage() const
-    {
-        wxASSERT_MSG( IsRunning(), _T("no current page!") );
-
-        return m_pages[(size_t)m_page];
-    }
-
-    // place the given page correctly and hide it
-    void DoAddPage(wxPanel *page);
-
-private:
-    // event handlers
-    void OnCancel(wxCommandEvent& event);
-    void OnBackOrNext(wxCommandEvent& event);
-
-    // wizard dimensions
-    int          m_x, m_y;      // the origin for the pages
-    int          m_width,       // the size of the page itself
-                 m_height;      // (total width is m_width + m_x)
-
-    // wizard state
-    int          m_page;        // the current page or -1
-    wxArrayPages m_pages;       // the array with all wizards pages
-
-    // wizard controls
-    wxButton    *m_btnPrev,     // the "<Back" button
-                *m_btnNext;     // the "Next>" or "Finish" button
-
-    DECLARE_EVENT_TABLE()
-};
-
 // ----------------------------------------------------------------------------
 // event tables and such
 // ----------------------------------------------------------------------------
 
-BEGIN_EVENT_TABLE(wxWizardGeneric, wxDialog)
-    EVT_BUTTON(wxID_CANCEL, wxWizardGeneric::OnCancel)
-    EVT_BUTTON(-1, wxWizardGeneric::OnBackOrNext)
+BEGIN_EVENT_TABLE(wxWizard, wxDialog)
+    EVT_BUTTON(wxID_CANCEL, wxWizard::OnCancel)
+    EVT_BUTTON(-1, wxWizard::OnBackOrNext)
 END_EVENT_TABLE()
 
-IMPLEMENT_ABSTRACT_CLASS(wxWizard, wxDialog)
+IMPLEMENT_DYNAMIC_CLASS(wxWizard, wxDialog)
+IMPLEMENT_ABSTRACT_CLASS(wxWizardPage, wxPanel)
+IMPLEMENT_DYNAMIC_CLASS(wxWizardPageSimple, wxWizardPage)
 IMPLEMENT_DYNAMIC_CLASS(wxWizardEvent, wxNotifyEvent)
 
 // ============================================================================
 // implementation
 // ============================================================================
 
+// ----------------------------------------------------------------------------
+// wxWizardPage
+// ----------------------------------------------------------------------------
+
+wxWizardPage::wxWizardPage(wxWizard *parent) : wxPanel(parent)
+{
+    // initially the page is hidden, it's shown only when it becomes current
+    Hide();
+}
+
+// ----------------------------------------------------------------------------
+// wxWizardPageSimple
+// ----------------------------------------------------------------------------
+
+wxWizardPage *wxWizardPageSimple::GetPrev() const
+{
+    return m_prev;
+}
+
+wxWizardPage *wxWizardPageSimple::GetNext() const
+{
+    return m_next;
+}
 // ----------------------------------------------------------------------------
 // generic wxWizard implementation
 // ----------------------------------------------------------------------------
 
-wxWizardGeneric::wxWizardGeneric(wxWindow *parent,
-                                 int id,
-                                 const wxString& title,
-                                 const wxBitmap& bitmap,
-                                 const wxPoint& pos,
-                                 const wxSize& size)
+wxWizard::wxWizard(wxWindow *parent,
+                   int id,
+                   const wxString& title,
+                   const wxBitmap& bitmap,
+                   const wxPoint& pos,
+                   const wxSize& size)
 {
     // constants defining the dialog layout
     // ------------------------------------
@@ -161,7 +123,7 @@ wxWizardGeneric::wxWizardGeneric(wxWindow *parent,
     // init members
     // ------------
 
-    m_page = -1;
+    m_page = (wxWizardPage *)NULL;
 
     // create controls
     // ---------------
@@ -191,12 +153,12 @@ wxWizardGeneric::wxWizardGeneric(wxWindow *parent,
 
     int x = X_MARGIN;
     int y = m_y + m_height + BITMAP_Y_MARGIN;
-    
-#if wxUSE_STATLINE    
+
+#if wxUSE_STATLINE
     (void)new wxStaticLine(this, -1, wxPoint(x, y),
                            wxSize(m_x + m_width - x, 2));
 #endif
-    
+
     x = m_x + m_width - 3*sizeBtn.x - BUTTON_MARGIN;
     y += SEPARATOR_LINE_MARGIN;
     m_btnPrev = new wxButton(this, -1, _("< &Back"), wxPoint(x, y), sizeBtn);
@@ -223,83 +185,94 @@ wxWizardGeneric::wxWizardGeneric(wxWindow *parent,
     }
 }
 
-bool wxWizardGeneric::ShowPage(size_t page)
+bool wxWizard::ShowPage(wxWizardPage *page, bool goingForward)
 {
-    wxCHECK_MSG( page < m_pages.GetCount(), FALSE,
-                 _T("invalid wizard page index") );
+    wxASSERT_MSG( page != m_page, _T("this is useless") );
 
-    wxASSERT_MSG( page != (size_t)m_page, _T("this is useless") );
+    // we'll use this to decide whether we have to change the label of this
+    // button or not (initially the label is "Next")
+    bool btnLabelWasNext = TRUE;
 
-    size_t last = m_pages.GetCount() - 1;
-    bool mustChangeNextBtnLabel = (size_t)m_page == last || page == last;
-
-    if ( m_page != -1 )
+    if ( m_page )
     {
-        wxPanel *panel = DoGetCurrentPage();
-        if ( !panel->TransferDataFromWindow() )
+        // ask the current page first
+        if ( !m_page->TransferDataFromWindow() )
+        {
+            // the page data is incorrect
+            return FALSE;
+        }
+
+        // send the event to the old page
+        wxWizardEvent event(wxEVT_WIZARD_PAGE_CHANGING, GetId(), goingForward);
+        if ( m_page->GetEventHandler()->ProcessEvent(event) &&
+             !event.IsAllowed() )
+        {
+            // vetoed by the page
             return FALSE;
+        }
 
-        panel->Hide();
+        m_page->Hide();
+
+        btnLabelWasNext = m_page->GetNext() != (wxWizardPage *)NULL;
     }
 
+    // set the new one
     m_page = page;
-    DoGetCurrentPage()->Show();
 
-    // update the buttons state
-    m_btnPrev->Enable(m_page != 0);
-    if ( mustChangeNextBtnLabel )
+    // is this the end?
+    if ( !m_page )
     {
-        m_btnNext->SetLabel((size_t)m_page == last ? _("&Finish")
-                                                   : _("&Next >"));
-    }
+        // terminate successfully
+        EndModal(wxID_OK);
 
-    return TRUE;
-}
+        return TRUE;
+    }
 
-void wxWizardGeneric::DoAddPage(wxPanel *page)
-{
-    page->Hide();
-    page->SetSize(m_x, m_y, m_width, m_height);
-}
+    // send the event to the new page now
+    wxWizardEvent event(wxEVT_WIZARD_PAGE_CHANGED, GetId(), goingForward);
+    (void)m_page->GetEventHandler()->ProcessEvent(event);
 
-void wxWizardGeneric::AddPage(wxPanel *page)
-{
-    m_pages.Add(page);
+    // position and show the new page
+    (void)m_page->TransferDataToWindow();
+    m_page->SetSize(m_x, m_y, m_width, m_height);
+    m_page->Show();
 
-    DoAddPage(page);
-}
+    // and update the buttons state
+    m_btnPrev->Enable(m_page->GetPrev() != (wxWizardPage *)NULL);
 
-void wxWizardGeneric::InsertPage(int nPage, wxPanel *page)
-{
-    m_pages.Insert(page, nPage);
-    if ( nPage < m_page )
+    if ( btnLabelWasNext != (m_page->GetNext() != (wxWizardPage *)NULL) )
     {
-        // the indices of all pages after the inserted one are shifted by 1
-        m_page++;
+        // need to update
+        m_btnNext->SetLabel(btnLabelWasNext ? _("&Finish") : _("&Next >"));
     }
+    // nothing to do: the label was already correct
 
-    DoAddPage(page);
+    return TRUE;
 }
 
-bool wxWizardGeneric::RunWizard()
+bool wxWizard::RunWizard(wxWizardPage *firstPage)
 {
-    wxCHECK_MSG( m_pages.GetCount() != 0, FALSE, _T("can't run empty wizard") );
+    wxCHECK_MSG( firstPage, FALSE, _T("can't run empty wizard") );
 
     // can't return FALSE here because there is no old page
-    (void)ShowPage(0u);
+    (void)ShowPage(firstPage, TRUE /* forward */);
 
     return ShowModal() == wxID_OK;
 }
 
-wxPanel *wxWizardGeneric::GetCurrentPage() const
+wxWizardPage *wxWizard::GetCurrentPage() const
 {
-    return IsRunning() ? DoGetCurrentPage() : (wxPanel *)NULL;
+    return m_page;
 }
 
-void wxWizardGeneric::OnCancel(wxCommandEvent& WXUNUSED(event))
+void wxWizard::OnCancel(wxCommandEvent& WXUNUSED(event))
 {
+    // this function probably can never be called when we don't have an active
+    // page, but a small extra check won't hurt
+    wxWindow *win = m_page ? (wxWindow *)m_page : (wxWindow *)this;
+
     wxWizardEvent event(wxEVT_WIZARD_CANCEL, GetId());
-    if ( !GetEventHandler()->ProcessEvent(event) || event.IsAllowed() )
+    if ( !win->GetEventHandler()->ProcessEvent(event) || event.IsAllowed() )
     {
         // no objections - close the dialog
         EndModal(wxID_CANCEL);
@@ -307,53 +280,52 @@ void wxWizardGeneric::OnCancel(wxCommandEvent& WXUNUSED(event))
     //else: request to Cancel ignored
 }
 
-void wxWizardGeneric::OnBackOrNext(wxCommandEvent& event)
+void wxWizard::OnBackOrNext(wxCommandEvent& event)
 {
     wxASSERT_MSG( (event.GetEventObject() == m_btnNext) ||
                   (event.GetEventObject() == m_btnPrev),
                   _T("unknown button") );
 
-    int delta = event.GetEventObject() == m_btnNext ? 1 : -1;
-    int page = m_page + delta;
+    bool forward = event.GetEventObject() == m_btnNext;
 
-    wxASSERT_MSG( page >= 0, _T("'Back' button should have been disabled!") );
-
-    if ( (size_t)page == m_pages.GetCount() )
+    wxWizardPage *page;
+    if ( forward )
     {
-        // check that we have valid data in the last page too
-        if ( m_pages.Last()->TransferDataFromWindow() )
-        {
-            // that's all, folks!
-            EndModal(wxID_OK);
-        }
+        page = m_page->GetNext();
     }
-    else
+    else // back
     {
-        // just pass to the next page (or may be not - but we don't care here)
-        (void)ShowPage(page);
+        page = m_page->GetPrev();
+
+        wxASSERT_MSG( page, _T("\"<Back\" button should have been disabled") );
     }
+
+    // just pass to the new page (or may be not - but we don't care here)
+    (void)ShowPage(page, forward);
 }
 
 // ----------------------------------------------------------------------------
 // our public interface
 // ----------------------------------------------------------------------------
 
-/* static */ wxWizard *wxWizard::Create(wxWindow *parent,
-                                        int id,
-                                        const wxString& title,
-                                        const wxBitmap& bitmap,
-                                        const wxPoint& pos,
-                                        const wxSize& size)
+/* static */
+wxWizard *wxWizardBase::Create(wxWindow *parent,
+                               int id,
+                               const wxString& title,
+                               const wxBitmap& bitmap,
+                               const wxPoint& pos,
+                               const wxSize& size)
 {
-    return new wxWizardGeneric(parent, id, title, bitmap, pos, size);
+    return new wxWizard(parent, id, title, bitmap, pos, size);
 }
 
 // ----------------------------------------------------------------------------
 // wxWizardEvent
 // ----------------------------------------------------------------------------
 
-wxWizardEvent::wxWizardEvent(wxEventType type, int id)
+wxWizardEvent::wxWizardEvent(wxEventType type, int id, bool direction)
              : wxNotifyEvent(type, id)
 {
-    m_page = m_pageOld = -1;
+    m_direction = direction;
 }
+
index 31f47b02a04f0eb91c25a44eb33a71546af2ddfe..4dc30246ce9767e52fd4851d32e99cd75614c570 100644 (file)
@@ -58,7 +58,8 @@ friend class WXDLLEXPORT wxFont;
 public:
     wxFontRefData()
     {
-        Init();
+        Init(12, wxDEFAULT, wxNORMAL, wxNORMAL, FALSE,
+             "", wxFONTENCODING_DEFAULT);
     }
 
     wxFontRefData(const wxFontRefData& data)
index a5765f0fa08bbbfbeac3a3e41db23c675c9c0e5b..252fc36d9a20effe10572c1d5d0a52a29bab3bc2 100644 (file)
@@ -241,15 +241,6 @@ void wxFrame::DoGetPosition(int *x, int *y) const
   *y = point.y;
 }
 
-void wxFrame::DoSetSize(int x, int y, int width, int height, int sizeFlags)
-{
-    wxWindow::DoSetSize(x, y, width, height, sizeFlags);
-
-    wxSizeEvent event(wxSize(width, height), m_windowId);
-    event.SetEventObject( this );
-    GetEventHandler()->ProcessEvent(event);
-}
-
 bool wxFrame::Show(bool show)
 {
   int cshow;
index fe431a123410a56e2fdff76581004c99d78c1178..67cc03440b9f203b1cc705dd34c00c84126652a1 100644 (file)
 // hide the ugly cast
 #define m_hwnd    (HWND)GetHWND()
 
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+// This is a work-around for missing defines in gcc-2.95 headers
+#ifndef TCS_RIGHT
+    #define TCS_RIGHT       0x0002
+#endif
+
+#ifndef TCS_VERTICAL
+    #define TCS_VERTICAL    0x0080
+#endif
+
+#ifndef TCS_BOTTOM
+    #define TCS_BOTTOM      TCS_RIGHT
+#endif
+
 // ----------------------------------------------------------------------------
 // event table
 // ----------------------------------------------------------------------------
index 8171cae0a3ce9ebe4e3845b0aca6b22a921396f0..a6eb5f572fcde2a925244ba2c8680e40227085e1 100644 (file)
@@ -110,6 +110,115 @@ private:
     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;
+};
+
 // ----------------------------------------------------------------------------
 // macros
 // ----------------------------------------------------------------------------
@@ -216,7 +325,6 @@ bool wxTreeCtrl::Create(wxWindow *parent,
     SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW));
     SetForegroundColour(wxWindow::GetParent()->GetForegroundColour());
 
-
     // VZ: this is some experimental code which may be used to get the
     //     TVS_CHECKBOXES style functionality for comctl32.dll < 4.71.
     //     AFAIK, the standard DLL does about the same thing anyhow.
@@ -350,35 +458,6 @@ void wxTreeCtrl::SetStateImageList(wxImageList *imageList)
     SetAnyImageList(m_imageListState = imageList, TVSIL_STATE);
 }
 
-// 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;
-};
-
-
 size_t wxTreeCtrl::GetChildrenCount(const wxTreeItemId& item,
                                     bool recursively) const
 {
@@ -414,6 +493,46 @@ void wxTreeCtrl::SetItemText(const wxTreeItemId& item, const wxString& text)
     DoSetItem(&tvItem);
 }
 
+int wxTreeCtrl::DoGetItemImageFromData(const wxTreeItemId& item,
+                                       wxTreeItemIcon which) const
+{
+    wxTreeViewItem tvItem(item, TVIF_PARAM);
+    if ( !DoGetItem(&tvItem) )
+    {
+        return -1;
+    }
+
+    return ((wxTreeItemIndirectData *)tvItem.lParam)->GetImage(which);
+}
+
+void wxTreeCtrl::DoSetItemImageFromData(const wxTreeItemId& item,
+                                        int image,
+                                        wxTreeItemIcon which) const
+{
+    wxTreeViewItem tvItem(item, TVIF_PARAM);
+    if ( !DoGetItem(&tvItem) )
+    {
+        return;
+    }
+
+    wxTreeItemIndirectData *data = ((wxTreeItemIndirectData *)tvItem.lParam);
+
+    data->SetImage(image, which);
+
+    // make sure that we have selected images as well
+    if ( which == wxTreeItemIcon_Normal &&
+         !data->HasImage(wxTreeItemIcon_Selected) )
+    {
+        data->SetImage(image, wxTreeItemIcon_Selected);
+    }
+
+    if ( which == wxTreeItemIcon_Expanded &&
+         !data->HasImage(wxTreeItemIcon_SelectedExpanded) )
+    {
+        data->SetImage(image, wxTreeItemIcon_SelectedExpanded);
+    }
+}
+
 void wxTreeCtrl::DoSetItemImages(const wxTreeItemId& item,
                                  int image,
                                  int imageSel)
@@ -424,36 +543,90 @@ void wxTreeCtrl::DoSetItemImages(const wxTreeItemId& item,
     DoSetItem(&tvItem);
 }
 
-int wxTreeCtrl::GetItemImage(const wxTreeItemId& item) const
+int wxTreeCtrl::GetItemImage(const wxTreeItemId& item,
+                             wxTreeItemIcon which) const
 {
-    wxTreeViewItem tvItem(item, TVIF_IMAGE);
-    DoGetItem(&tvItem);
+    if ( HasIndirectData(item) )
+    {
+        return DoGetItemImageFromData(item, which);
+    }
 
-    return tvItem.iImage;
-}
+    UINT mask;
+    switch ( which )
+    {
+        default:
+            wxFAIL_MSG( _T("unknown tree item image type") );
 
-void wxTreeCtrl::SetItemImage(const wxTreeItemId& item, int image)
-{
-    // NB: at least in version 5.00.0518.9 of comctl32.dll we need to always
-    //     change both normal and selected image - otherwise the change simply
-    //     doesn't take place!
-    DoSetItemImages(item, image, GetItemSelectedImage(item));
-}
+        case wxTreeItemIcon_Normal:
+            mask = TVIF_IMAGE;
+            break;
 
-int wxTreeCtrl::GetItemSelectedImage(const wxTreeItemId& item) const
-{
-    wxTreeViewItem tvItem(item, TVIF_SELECTEDIMAGE);
+        case wxTreeItemIcon_Selected:
+            mask = TVIF_SELECTEDIMAGE;
+            break;
+
+        case wxTreeItemIcon_Expanded:
+        case wxTreeItemIcon_SelectedExpanded:
+            return -1;
+    }
+
+    wxTreeViewItem tvItem(item, mask);
     DoGetItem(&tvItem);
 
-    return tvItem.iSelectedImage;
+    return mask == TVIF_IMAGE ? tvItem.iImage : tvItem.iSelectedImage;
 }
 
-void wxTreeCtrl::SetItemSelectedImage(const wxTreeItemId& item, int image)
+void wxTreeCtrl::SetItemImage(const wxTreeItemId& item, int image,
+                              wxTreeItemIcon which)
 {
+    int imageNormal, imageSel;
+    switch ( which )
+    {
+        default:
+            wxFAIL_MSG( _T("unknown tree item image type") );
+
+        case wxTreeItemIcon_Normal:
+            imageNormal = image;
+            imageSel = GetItemSelectedImage(item);
+            break;
+
+        case wxTreeItemIcon_Selected:
+            imageNormal = GetItemImage(item);
+            imageSel = image;
+            break;
+
+        case wxTreeItemIcon_Expanded:
+        case wxTreeItemIcon_SelectedExpanded:
+            if ( !HasIndirectData(item) )
+            {
+                // we need to get the old images first, because after we create
+                // the wxTreeItemIndirectData GetItemXXXImage() will use it to
+                // get the images
+                imageNormal = GetItemImage(item);
+                imageSel = GetItemSelectedImage(item);
+
+                // if it doesn't have it yet, add it
+                wxTreeItemIndirectData *data = new
+                    wxTreeItemIndirectData(this, item);
+
+                // copy the data to the new location
+                data->SetImage(imageNormal, wxTreeItemIcon_Normal);
+                data->SetImage(imageSel, wxTreeItemIcon_Selected);
+            }
+
+            DoSetItemImageFromData(item, image, which);
+
+            // reset the normal/selected images because we won't use them any
+            // more - now they're stored inside the indirect data
+            imageNormal =
+            imageSel = I_IMAGECALLBACK;
+            break;
+    }
+
     // NB: at least in version 5.00.0518.9 of comctl32.dll we need to always
     //     change both normal and selected image - otherwise the change simply
     //     doesn't take place!
-    DoSetItemImages(item, GetItemImage(item), image);
+    DoSetItemImages(item, imageNormal, imageSel);
 }
 
 wxTreeItemData *wxTreeCtrl::GetItemData(const wxTreeItemId& item) const
@@ -464,14 +637,55 @@ wxTreeItemData *wxTreeCtrl::GetItemData(const wxTreeItemId& item) const
         return NULL;
     }
 
-    return (wxTreeItemData *)tvItem.lParam;
+    if ( HasIndirectData(item) )
+    {
+        return ((wxTreeItemIndirectData *)tvItem.lParam)->GetData();
+    }
+    else
+    {
+        return (wxTreeItemData *)tvItem.lParam;
+    }
 }
 
 void wxTreeCtrl::SetItemData(const wxTreeItemId& item, wxTreeItemData *data)
 {
     wxTreeViewItem tvItem(item, TVIF_PARAM);
-    tvItem.lParam = (LPARAM)data;
-    DoSetItem(&tvItem);
+
+    if ( HasIndirectData(item) )
+    {
+        if ( DoGetItem(&tvItem) )
+        {
+            ((wxTreeItemIndirectData *)tvItem.lParam)->SetData(data);
+        }
+        else
+        {
+            wxFAIL_MSG( _T("failed to change tree items data") );
+        }
+    }
+    else
+    {
+        tvItem.lParam = (LPARAM)data;
+        DoSetItem(&tvItem);
+    }
+}
+
+void wxTreeCtrl::SetIndirectItemData(const wxTreeItemId& item,
+                                     wxTreeItemIndirectData *data)
+{
+    // this should never happen because it's unnecessary and will probably lead
+    // to crash too because the code elsewhere supposes that the pointer the
+    // wxTreeItemIndirectData has is a real wxItemData and not
+    // wxTreeItemIndirectData as well
+    wxASSERT_MSG( !HasIndirectData(item), _T("setting indirect data twice?") );
+
+    SetItemData(item, (wxTreeItemData *)data);
+
+    m_itemsWithIndirectData.Add(item);
+}
+
+bool wxTreeCtrl::HasIndirectData(const wxTreeItemId& item) const
+{
+    return m_itemsWithIndirectData.Index(item) != wxNOT_FOUND;
 }
 
 void wxTreeCtrl::SetItemHasChildren(const wxTreeItemId& item, bool has)
@@ -655,34 +869,6 @@ void wxTreeCtrl::SetItemCheck(const wxTreeItemId& item, bool check)
     DoSetItem(&tvItem);
 }
 
-// internal class for getting the selected
-
-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;
-};
-
 size_t wxTreeCtrl::GetSelections(wxArrayTreeItemIds& selections) const
 {
     TraverseSelections selector(this, selections);
@@ -704,8 +890,9 @@ wxTreeItemId wxTreeCtrl::DoInsertItem(const wxTreeItemId& parent,
     tvIns.hParent = (HTREEITEM) (WXHTREEITEM)parent;
     tvIns.hInsertAfter = (HTREEITEM) (WXHTREEITEM) hInsertAfter;
 
-    // This is how we insert the item as the first child: supply a NULL hInsertAfter
-    if (tvIns.hInsertAfter == (HTREEITEM) 0)
+    // this is how we insert the item as the first child: supply a NULL
+    // hInsertAfter
+    if ( !tvIns.hInsertAfter )
     {
         tvIns.hInsertAfter = TVI_FIRST;
     }
@@ -1302,8 +1489,21 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
                 //     prefer to do it here ourself (otherwise deleting a tree
                 //     with many items is just too slow)
                 NM_TREEVIEW* tv = (NM_TREEVIEW *)lParam;
-                wxTreeItemData *data = (wxTreeItemData *)tv->itemOld.lParam;
-                delete data; // may be NULL, ok
+
+                wxTreeItemId item = event.m_item;
+                if ( HasIndirectData(item) )
+                {
+                    wxTreeItemIndirectData *data = (wxTreeItemIndirectData *)
+                                                        tv->itemOld.lParam;
+                    delete data; // can't be NULL here
+
+                    m_itemsWithIndirectData.Remove(item);
+                }
+                else
+                {
+                    wxTreeItemData *data = (wxTreeItemData *)tv->itemOld.lParam;
+                    delete data; // may be NULL, ok
+                }
 
                 processed = TRUE; // Make sure we don't get called twice
             }
@@ -1329,6 +1529,36 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
             *result = !event.IsAllowed();
             break;
 
+        case TVN_GETDISPINFO:
+            // NB: so far the user can't set the image himself anyhow, so do it
+            //     anyway - but this may change later
+            if ( /* !processed && */ 1 )
+            {
+                wxTreeItemId item = event.m_item;
+                TV_DISPINFO *info = (TV_DISPINFO *)lParam;
+                if ( info->item.mask & TVIF_IMAGE )
+                {
+                    info->item.iImage =
+                        DoGetItemImageFromData
+                        (
+                         item,
+                         IsExpanded(item) ? wxTreeItemIcon_Expanded
+                                          : wxTreeItemIcon_Normal
+                        );
+                }
+                if ( info->item.mask & TVIF_SELECTEDIMAGE )
+                {
+                    info->item.iSelectedImage =
+                        DoGetItemImageFromData
+                        (
+                         item,
+                         IsExpanded(item) ? wxTreeItemIcon_SelectedExpanded
+                                          : wxTreeItemIcon_Selected
+                        );
+                }
+            }
+            break;
+
         //default:
             // for the other messages the return value is ignored and there is
             // nothing special to do