]> git.saurik.com Git - wxWidgets.git/commitdiff
Added wxGenericDirCtrl, wxGenericDirDialog and associated icons.
authorJulian Smart <julian@anthemion.co.uk>
Sun, 23 Jul 2000 19:10:27 +0000 (19:10 +0000)
committerJulian Smart <julian@anthemion.co.uk>
Sun, 23 Jul 2000 19:10:27 +0000 (19:10 +0000)
Altered dialog sample to show generic dir dialog.

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

17 files changed:
distrib/msw/tmake/filelist.txt
include/wx/dirctrl.h [new file with mode: 0644]
include/wx/generic/dirctrlg.h [new file with mode: 0644]
include/wx/msw/cdrom.ico [new file with mode: 0644]
include/wx/msw/computer.ico [new file with mode: 0644]
include/wx/msw/drive.ico [new file with mode: 0644]
include/wx/msw/file1.ico [new file with mode: 0644]
include/wx/msw/floppy.ico [new file with mode: 0644]
include/wx/msw/folder1.ico [new file with mode: 0644]
include/wx/msw/folder2.ico [new file with mode: 0644]
include/wx/msw/removble.ico [new file with mode: 0644]
include/wx/msw/wx.rc
samples/dialogs/dialogs.cpp
samples/dialogs/dialogs.h
src/generic/dirctrlg.cpp [new file with mode: 0644]
src/msw/makefile.vc
src/wxvc.dsp

index bc6e317f83b67b351f09baf9ebcf2507fc1c3c93..c8443f57f8bfb5e9884b7b4881f1ce060da1dd2a 100644 (file)
@@ -65,6 +65,7 @@ caret.cpp     G       U
 choicdgg.cpp   G
 colrdlgg.cpp   G       G
 dcpsg.cpp      G       U
+dirctrlg.cpp   G
 dirdlgg.cpp    G       16,P
 dragimgg.cpp   G       P
 fontdlgg.cpp   G       G,R,P
@@ -1084,6 +1085,7 @@ caret.h   N
 choicdgg.h     N
 colrdlgg.h     N
 dcpsg.h        N
+dirctrlg.h     N
 dirdlgg.h      N       16
 dragimgg.h     N       16
 fontdlgg.h     N
diff --git a/include/wx/dirctrl.h b/include/wx/dirctrl.h
new file mode 100644 (file)
index 0000000..6fe73a8
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef _WX_DIRCTRL_H_BASE_
+#define _WX_DIRCTRL_H_BASE_
+
+#include "wx/generic/dirctrlg.h"
+
+#endif
+    // _WX_DIRCTRL_H_BASE_
diff --git a/include/wx/generic/dirctrlg.h b/include/wx/generic/dirctrlg.h
new file mode 100644 (file)
index 0000000..05d354d
--- /dev/null
@@ -0,0 +1,245 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        dirctrlg.h
+// Purpose:     wxGenericDirCtrl class
+//              Builds on wxDirCtrl class written by Robert Roebling for the
+//              wxFile application, modified by Harm van der Heijden.
+//              Further modified for Windows.
+// Author:      Julian Smart et al
+// Modified by:
+// Created:     21/3/2000
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart
+// Licence:    wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_DIRCTRL_H_
+#define _WX_DIRCTRL_H_
+
+#ifdef __GNUG__
+#pragma interface "dirctrlg.h"
+#endif
+
+#include "wx/treectrl.h"
+
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
+class wxDirItemData;
+class wxDirCtrl;
+
+//-----------------------------------------------------------------------------
+// Extra styles for wxGenericDirCtrl
+//-----------------------------------------------------------------------------
+
+// Only allow directory viewing/selection, no files
+#define wxDIRCTRL_DIR_ONLY       0x0010
+// When setting the default path, select the first file in the directory
+#define wxDIRCTRL_SELECT_FIRST   0x0020
+// Show the filter list
+#define wxDIRCTRL_SHOW_FILTERS   0x0040
+// Use 3D borders on internal controls
+#define wxDIRCTRL_3D_INTERNAL    0x0080
+
+//-----------------------------------------------------------------------------
+// wxDirItemData
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxDirItemDataEx : public wxTreeItemData
+{
+public:
+  wxDirItemDataEx(const wxString& path, const wxString& name, bool isDir);
+  ~wxDirItemDataEx();
+  bool HasSubDirs();
+  void SetNewDirName( wxString path );
+  wxString m_path, m_name;
+  bool m_isHidden;
+  bool m_hasSubDirs;
+  bool m_isExpanded;
+  bool m_isDir;
+};
+
+//-----------------------------------------------------------------------------
+// wxDirCtrl
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxDirFilterListCtrl;
+
+class WXDLLEXPORT wxGenericDirCtrl: public wxControl
+{
+public:
+    wxGenericDirCtrl();
+    wxGenericDirCtrl(wxWindow *parent, const wxWindowID id = -1,
+              const wxString &dir = wxDirDialogDefaultFolderStr,
+              const wxPoint& pos = wxDefaultPosition,
+              const wxSize& size = wxDefaultSize,
+              long style = wxDIRCTRL_3D_INTERNAL,
+              const wxString& filter = wxEmptyString,
+              int defaultFilter = 0,
+              const wxString& name = wxTreeCtrlNameStr )
+    {
+        Init();
+        Create(parent, id, dir, pos, size, style, filter, defaultFilter, name);
+    }
+    
+    bool Create(wxWindow *parent, const wxWindowID id = -1,
+              const wxString &dir = wxDirDialogDefaultFolderStr,
+              const wxPoint& pos = wxDefaultPosition,
+              const wxSize& size = wxDefaultSize,
+              long style = wxDIRCTRL_3D_INTERNAL,
+              const wxString& filter = wxEmptyString,
+              int defaultFilter = 0,
+              const wxString& name = wxTreeCtrlNameStr );
+
+    void Init();
+
+    ~wxGenericDirCtrl();
+
+    void OnExpandItem(wxTreeEvent &event );
+    void OnCollapseItem(wxTreeEvent &event );
+    void OnBeginEditItem(wxTreeEvent &event );
+    void OnEndEditItem(wxTreeEvent &event );
+    void OnSize(wxSizeEvent &event );
+
+    // Try to expand as much of the given path as possible.
+    bool ExpandPath(const wxString& path);
+
+    // Accessors
+
+    inline wxString GetDefaultPath() const { return m_defaultPath; }
+    void SetDefaultPath(const wxString& path) { m_defaultPath = path; }
+
+    //inline long GetStyleEx() const { return m_styleEx; }
+    //void SetStyleEx(long styleEx) { m_styleEx = styleEx; }
+
+    // Get dir or filename
+    wxString GetPath() const ;
+    // Get selected filename path only (else empty string).
+    // I.e. don't count a directory as a selection
+    wxString GetFilePath() const ;
+    void SetPath(const wxString& path) ;
+
+    wxString GetFilter() const { return m_filter; }
+    void SetFilter(const wxString& filter);
+
+    int GetFilterIndex() const { return m_currentFilter; }
+    void SetFilterIndex(int n) ;
+
+    wxTreeItemId GetRootId() { return m_rootId; }
+
+    wxTreeCtrl* GetTreeCtrl() const { return m_treeCtrl; }
+    wxDirFilterListCtrl* GetFilterListCtrl() const { return m_filterListCtrl; }
+
+//// Helpers
+    void SetupSections();
+    // Parse the filter into an array of filters and an array of descriptions
+    int ParseFilter(const wxString& filterStr, wxArrayString& filters, wxArrayString& descriptions);
+    // Find the child that matches the first part of 'path'.
+    // E.g. if a child path is "/usr" and 'path' is "/usr/include"
+    // then the child for /usr is returned.
+    // If the path string has been used (we're at the leaf), done is set to TRUE
+    wxTreeItemId FindChild(wxTreeItemId parentId, const wxString& path, bool& done);
+    
+    // Resize the components of the control
+    void DoResize();
+protected:
+    void ExpandDir(wxTreeItemId parentId);
+    void AddSection(const wxString& path, const wxString& name, int imageId = 0);
+    //void FindChildFiles(wxTreeItemId id, int dirFlags, wxArrayString& filenames);
+
+    // Extract description and actual filter from overall filter string
+    bool ExtractWildcard(const wxString& filterStr, int n, wxString& filter, wxString& description);
+
+private:
+    bool            m_showHidden;
+    wxTreeItemId    m_rootId;
+    wxImageList*    m_imageList;
+    wxString        m_defaultPath; // Starting path
+    long            m_styleEx; // Extended style
+    wxString        m_filter;  // Wildcards in same format as per wxFileDialog
+    int             m_currentFilter; // The current filter index
+    wxString        m_currentFilterStr; // Current filter string
+    wxTreeCtrl*     m_treeCtrl;
+    wxDirFilterListCtrl* m_filterListCtrl;
+
+private:
+    DECLARE_EVENT_TABLE()
+    DECLARE_DYNAMIC_CLASS(wxGenericDirCtrl)
+};
+
+//-----------------------------------------------------------------------------
+// wxDirFilterListCtrl
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxDirFilterListCtrl: public wxChoice
+{
+public:
+    wxDirFilterListCtrl() { Init(); }
+    wxDirFilterListCtrl(wxGenericDirCtrl* parent, const wxWindowID id = -1,
+              const wxPoint& pos = wxDefaultPosition,
+              const wxSize& size = wxDefaultSize,
+              long style = 0)
+    {
+        Init();
+        Create(parent, id, pos, size, style);
+    }
+    
+    bool Create(wxGenericDirCtrl* parent, const wxWindowID id = -1,
+              const wxPoint& pos = wxDefaultPosition,
+              const wxSize& size = wxDefaultSize,
+              long style = 0);
+
+    void Init();
+
+    ~wxDirFilterListCtrl() {};
+
+//// Operations
+    void FillFilterList(const wxString& filter, int defaultFilter);
+
+//// Events
+    void OnSelFilter(wxCommandEvent& event);
+
+protected:
+    wxGenericDirCtrl*    m_dirCtrl;
+
+    DECLARE_EVENT_TABLE()
+    DECLARE_CLASS(wxDirFilterListCtrl)
+};
+
+#define wxID_TREECTRL          7000
+#define wxID_FILTERLISTCTRL    7001
+
+//-----------------------------------------------------------------------------
+// wxGenericDirDialog
+//
+//-----------------------------------------------------------------------------
+
+class wxGenericDirDialog: public wxDialog
+{
+DECLARE_EVENT_TABLE()
+public:
+    wxGenericDirDialog(): wxDialog() {}
+    wxGenericDirDialog(wxWindow* parent, const wxString& title,
+        const wxString& defaultPath = wxEmptyString, long style = wxDEFAULT_DIALOG_STYLE, const wxPoint& pos = wxDefaultPosition, const wxSize& sz = wxSize(450, 550), const wxString& name = "dialog");
+
+    void OnCloseWindow(wxCloseEvent& event);
+    void OnOK(wxCommandEvent& event);
+
+    inline void SetMessage(const wxString& message) { m_message = message; }
+    void SetPath(const wxString& path) ;
+    inline void SetStyle(long style) { m_dialogStyle = style; }
+
+    inline wxString GetMessage(void) const { return m_message; }
+    wxString GetPath(void) const ;
+    inline long GetStyle(void) const { return m_dialogStyle; }
+
+protected:
+    wxString    m_message;
+    long        m_dialogStyle;
+    wxString    m_path;
+    wxGenericDirCtrl* m_dirCtrl;
+
+};
+
+#endif
+    // _WX_DIRCTRLG_H_
diff --git a/include/wx/msw/cdrom.ico b/include/wx/msw/cdrom.ico
new file mode 100644 (file)
index 0000000..af5c619
Binary files /dev/null and b/include/wx/msw/cdrom.ico differ
diff --git a/include/wx/msw/computer.ico b/include/wx/msw/computer.ico
new file mode 100644 (file)
index 0000000..64b7c76
Binary files /dev/null and b/include/wx/msw/computer.ico differ
diff --git a/include/wx/msw/drive.ico b/include/wx/msw/drive.ico
new file mode 100644 (file)
index 0000000..4e25200
Binary files /dev/null and b/include/wx/msw/drive.ico differ
diff --git a/include/wx/msw/file1.ico b/include/wx/msw/file1.ico
new file mode 100644 (file)
index 0000000..cc828ab
Binary files /dev/null and b/include/wx/msw/file1.ico differ
diff --git a/include/wx/msw/floppy.ico b/include/wx/msw/floppy.ico
new file mode 100644 (file)
index 0000000..c7f056d
Binary files /dev/null and b/include/wx/msw/floppy.ico differ
diff --git a/include/wx/msw/folder1.ico b/include/wx/msw/folder1.ico
new file mode 100644 (file)
index 0000000..c43de1c
Binary files /dev/null and b/include/wx/msw/folder1.ico differ
diff --git a/include/wx/msw/folder2.ico b/include/wx/msw/folder2.ico
new file mode 100644 (file)
index 0000000..98b6d3f
Binary files /dev/null and b/include/wx/msw/folder2.ico differ
diff --git a/include/wx/msw/removble.ico b/include/wx/msw/removble.ico
new file mode 100644 (file)
index 0000000..db8bb82
Binary files /dev/null and b/include/wx/msw/removble.ico differ
index 0f60b9bca78f1a5eabc5ef674ab77df6522de007..2787d3b645e6f277f6c7cb2cac91b1aaa80750b4 100644 (file)
@@ -115,12 +115,22 @@ WXCURSOR_BLANK          CURSOR  DISCARDABLE     "wx/msw/blank.cur"
 //wxDEFAULT_MDIPARENTFRAME      ICON "wx/msw/mdi.ico"
 //wxDEFAULT_MDICHILDFRAME       ICON "wx/msw/child.ico"
 
-// Standard icons
-wxICON_QUESTION                ICON "wx/msw/question.ico"
-wxICON_WARNING         ICON "wx/msw/warning.ico"
-wxICON_ERROR           ICON "wx/msw/error.ico"
-wxICON_INFO            ICON "wx/msw/info.ico"
-wxICON_TIP             ICON "wx/msw/tip.ico"
+// Standard large icons
+wxICON_QUESTION                        ICON "wx/msw/question.ico"
+wxICON_WARNING                 ICON "wx/msw/warning.ico"
+wxICON_ERROR                   ICON "wx/msw/error.ico"
+wxICON_INFO                    ICON "wx/msw/info.ico"
+wxICON_TIP                     ICON "wx/msw/tip.ico"
+
+// Standard small icons
+wxICON_SMALL_CLOSED_FOLDER      ICON "wx/msw/folder1.ico"
+wxICON_SMALL_OPEN_FOLDER        ICON "wx/msw/folder2.ico"
+wxICON_SMALL_FILE               ICON "wx/msw/file1.ico"
+wxICON_SMALL_COMPUTER           ICON "wx/msw/computer.ico"
+wxICON_SMALL_DRIVE              ICON "wx/msw/drive.ico"
+wxICON_SMALL_CDROM              ICON "wx/msw/cdrom.ico"
+wxICON_SMALL_FLOPPY             ICON "wx/msw/floppy.ico"
+wxICON_SMALL_REMOVEABLE         ICON "wx/msw/removble.ico"
 
 //////////////////////////////////////////////////////////////////////////////
 //
index ecf4a76016ebe5861ec2ad1639be0f77e268993d..3f328b2224b17399d04ca4d5d905de1f8116bf3c 100644 (file)
@@ -33,6 +33,9 @@
 #include "wx/tipdlg.h"
 #include "wx/progdlg.h"
 
+// New wxGenericDirCtrl
+#include "wx/dirctrl.h"
+
 #define wxTEST_GENERIC_DIALOGS_IN_MSW 0
 
 #if defined(__WXMSW__) && wxTEST_GENERIC_DIALOGS_IN_MSW
@@ -61,6 +64,7 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
     EVT_MENU(DIALOGS_FILES_OPEN,                    MyFrame::FilesOpen)
     EVT_MENU(DIALOGS_FILE_SAVE,                     MyFrame::FileSave)
     EVT_MENU(DIALOGS_DIR_CHOOSE,                    MyFrame::DirChoose)
+    EVT_MENU(DIALOGS_GENERIC_DIR_CHOOSE,            MyFrame::GenericDirChoose)
     EVT_MENU(DIALOGS_MODAL,                         MyFrame::ModalDlg)
     EVT_MENU(DIALOGS_MODELESS,                      MyFrame::ModelessDlg)
     EVT_MENU(DIALOGS_TIP,                           MyFrame::ShowTip)
@@ -129,6 +133,7 @@ bool MyApp::OnInit()
   file_menu->Append(DIALOGS_FILES_OPEN,  "Open &files\tCtrl-Q");
   file_menu->Append(DIALOGS_FILE_SAVE,  "Sa&ve file\tCtrl-S");
   file_menu->Append(DIALOGS_DIR_CHOOSE,  "&Choose a directory\tCtrl-D");
+  file_menu->Append(DIALOGS_GENERIC_DIR_CHOOSE,  "&Choose a directory (generic implementation)");
 #if wxUSE_PROGRESSDLG
   file_menu->Append(DIALOGS_PROGRESS, "Pro&gress dialog\tCtrl-G");
 #endif // wxUSE_PROGRESSDLG
@@ -418,6 +423,21 @@ void MyFrame::DirChoose(wxCommandEvent& WXUNUSED(event) )
     }
 }
 
+void MyFrame::GenericDirChoose(wxCommandEvent& WXUNUSED(event) )
+{
+    // pass some initial dir to wxDirDialog
+    wxString dirHome;
+    wxGetHomeDir(&dirHome);
+
+    wxGenericDirDialog dialog(this, "Testing generic directory picker", dirHome);
+
+    if (dialog.ShowModal() == wxID_OK)
+    {
+        wxMessageDialog dialog2(this, dialog.GetPath(), "Selected path");
+        dialog2.ShowModal();
+    }
+}
+
 void MyFrame::ModalDlg(wxCommandEvent& WXUNUSED(event))
 {
     MyModalDialog dlg(this);
index d8e4665ab930c749570393cd3378ee99ff60672d..d1bb0fe773c506f57d4ef04ada3fcb677876d2bb 100644 (file)
@@ -68,6 +68,7 @@ public:
     void FilesOpen(wxCommandEvent& event);
     void FileSave(wxCommandEvent& event);
     void DirChoose(wxCommandEvent& event);
+    void GenericDirChoose(wxCommandEvent& event);
     void ShowTip(wxCommandEvent& event);
     void ModalDlg(wxCommandEvent& event);
     void ModelessDlg(wxCommandEvent& event);
@@ -114,6 +115,7 @@ enum
     DIALOGS_FILES_OPEN,
     DIALOGS_FILE_SAVE,
     DIALOGS_DIR_CHOOSE,
+    DIALOGS_GENERIC_DIR_CHOOSE,
     DIALOGS_TIP,
     DIALOGS_NUM_ENTRY,
     DIALOGS_LOG_DIALOG,
diff --git a/src/generic/dirctrlg.cpp b/src/generic/dirctrlg.cpp
new file mode 100644 (file)
index 0000000..33a6be8
--- /dev/null
@@ -0,0 +1,1204 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        dirctrlg.cpp
+// Purpose:     wxGenericDirCtrl
+// Author:      Harm van der Heijden, Robert Roebling, Julian Smart
+// Modified by:
+// Created:     12/12/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Harm van der Heijden, Robert Roebling and Julian Smart
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "dirctrl.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#include "wx/defs.h"
+
+#include "wx/utils.h"
+#include "wx/dialog.h"
+#include "wx/button.h"
+#include "wx/layout.h"
+#include "wx/msgdlg.h"
+#include "wx/textdlg.h"
+#include "wx/filefn.h"
+#include "wx/cmndata.h"
+#include "wx/gdicmn.h"
+#include "wx/intl.h"
+#include "wx/imaglist.h"
+#include "wx/icon.h"
+#include "wx/log.h"
+#include "wx/sizer.h"
+#include "wx/tokenzr.h"
+#include "wx/dir.h"
+
+#if wxUSE_STATLINE
+    #include "wx/statline.h"
+#endif
+
+#include "wx/generic/dirctrlg.h"
+
+#ifdef __WXMSW__
+#include <direct.h>
+#include <stdlib.h>
+#include <ctype.h>
+#endif
+
+// If compiled under Windows, this macro can cause problems
+#ifdef GetFirstChild
+#undef GetFirstChild
+#endif
+
+#if !defined(__WXMSW__) || wxUSE_XPM_IN_MSW
+/* Closed folder */
+static char * icon1_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"   s None  c None",
+".  c #000000",
+"+  c #c0c0c0",
+"@  c #808080",
+"#  c #ffff00",
+"$  c #ffffff",
+/* pixels */
+"                ",
+"   @@@@@        ",
+"  @#+#+#@       ",
+" @#+#+#+#@@@@@@ ",
+" @$$$$$$$$$$$$@.",
+" @$#+#+#+#+#+#@.",
+" @$+#+#+#+#+#+@.",
+" @$#+#+#+#+#+#@.",
+" @$+#+#+#+#+#+@.",
+" @$#+#+#+#+#+#@.",
+" @$+#+#+#+#+#+@.",
+" @$#+#+#+#+#+#@.",
+" @@@@@@@@@@@@@@.",
+"  ..............",
+"                ",
+"                "};
+
+/* Open folder */
+static char * icon2_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 6 1",
+/* colors */
+"   s None  c None",
+".  c #000000",
+"+  c #c0c0c0",
+"@  c #808080",
+"#  c #ffff00",
+"$  c #ffffff",
+/* pixels */
+"                ",
+"   @@@@@        ",
+"  @$$$$$@       ",
+" @$#+#+#$@@@@@@ ",
+" @$+#+#+$$$$$$@.",
+" @$#+#+#+#+#+#@.",
+"@@@@@@@@@@@@@#@.",
+"@$$$$$$$$$$@@+@.",
+"@$#+#+#+#+##.@@.",
+" @$#+#+#+#+#+.@.",
+" @$+#+#+#+#+#.@.",
+"  @$+#+#+#+##@..",
+"  @@@@@@@@@@@@@.",
+"   .............",
+"                ",
+"                "};
+
+/* File */
+static char * icon3_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"16 16 3 1",
+/* colors */
+"      s None  c None",
+".     c #000000",
+"+     c #ffffff",
+/* pixels */
+"                ",
+"  ........      ",
+"  .++++++..     ",
+"  .+.+.++.+.    ",
+"  .++++++....   ",
+"  .+.+.+++++.   ",
+"  .+++++++++.   ",
+"  .+.+.+.+.+.   ",
+"  .+++++++++.   ",
+"  .+.+.+.+.+.   ",
+"  .+++++++++.   ",
+"  .+.+.+.+.+.   ",
+"  .+++++++++.   ",
+"  ...........   ",
+"                ",
+"                "};
+
+/* Computer */
+static char * icon4_xpm[] = {
+"16 16 7 1",
+"      s None  c None",
+".     c #808080",
+"X     c #c0c0c0",
+"o     c Black",
+"O     c Gray100",
+"+     c #008080",
+"@     c Blue",
+"    ........... ",
+"   .XXXXXXXXXX.o",
+"   .OOOOOOOOO..o",
+"   .OoooooooX..o",
+"   .Oo+...@+X..o",
+"   .Oo+XXX.+X..o",
+"   .Oo+....+X..o",
+"   .Oo++++++X..o",
+"   .OXXXXXXXX.oo",
+"   ..........o.o",
+"   ...........Xo",
+"   .XXXXXXXXXX.o",
+"  .o.o.o.o.o...o",
+" .oXoXoXoXoXo.o ",
+".XOXXXXXXXXX.o  ",
+"............o   "};
+
+/* Drive */
+static char * icon5_xpm[] = {
+"16 16 7 1",
+"      s None  c None",
+".     c #808080",
+"X     c #c0c0c0",
+"o     c Black",
+"O     c Gray100",
+"+     c Green",
+"@     c #008000",
+"                ",
+"                ",
+"                ",
+"                ",
+"  ............. ",
+" .XXXXXXXXXXXX.o",
+".OOOOOOOOOOOO..o",
+".XXXXXXXXX+@X..o",
+".XXXXXXXXXXXX..o",
+".X..........X..o",
+".XOOOOOOOOOOX..o",
+"..............o ",
+" ooooooooooooo  ",
+"                ",
+"                ",
+"                "};
+
+/* CD-ROM */
+static char *icon6_xpm[] = {
+"16 16 10 1",
+"      s None  c None",
+".     c #808080",
+"X     c #c0c0c0",
+"o     c Yellow",
+"O     c Blue",
+"+     c Black",
+"@     c Gray100",
+"#     c #008080",
+"$     c Green",
+"%     c #008000",
+"        ...     ",
+"      ..XoX..   ",
+"     .O.XoXXX+  ",
+"    ...O.oXXXX+ ",
+"    .O..X.XXXX+ ",
+"   ....X.+..XXX+",
+"   .XXX.+@+.XXX+",
+"   .X@XX.+.X@@X+",
+" .....X...#XX@+ ",
+".@@@...XXo.O@X+ ",
+".@XXX..XXoXOO+  ",
+".@++++..XoX+++  ",
+".@$%@@XX+++X.+  ",
+".............+  ",
+" ++++++++++++   ",
+"                "};
+
+/* Floppy */
+static char * icon7_xpm[] = {
+"16 16 7 1",
+"      s None  c None",
+".     c #808080",
+"X     c Gray100",
+"o     c #c0c0c0",
+"O     c Black",
+"+     c Cyan",
+"@     c Red",
+"         ......X",
+"        .ooooooO",
+"        .+++++OO",
+"        .++++++O",
+"        .++++++O",
+"        .ooooooO",
+"  .......o....oO",
+" .oooooo.o.O.XoO",
+".XXXXXXXXOOOOOO ",
+".ooooooooo@o..O ",
+".ooo....oooo..O ",
+".o..OOOO...o..O ",
+".oooXXXXoooo..O ",
+".............O  ",
+" OOOOOOOOOOOO   ",
+"                "};
+
+/* Removeable */
+static char * icon8_xpm[] = {
+"16 16 7 1",
+"      s None  c None",
+".     c #808080",
+"X     c #c0c0c0",
+"o     c Black",
+"O     c Gray100",
+"+     c Red",
+"@     c #800000",
+"                ",
+"                ",
+"                ",
+"  ............. ",
+" .XXXXXXXXXXXX.o",
+".OOOOOOOOOOOO..o",
+".OXXXXXXXXXXX..o",
+".O+@.oooooo.X..o",
+".OXXOooooooOX..o",
+".OXXXOOOOOOXX..o",
+".OXXXXXXXXXXX..o",
+".O............o ",
+" ooooooooooooo  ",
+"                ",
+"                ",
+"                "};
+#endif // !wxMSW
+
+static const int ID_DIRCTRL = 1000;
+static const int ID_TEXTCTRL = 1001;
+static const int ID_OK = 1002;
+static const int ID_CANCEL = 1003;
+static const int ID_NEW = 1004;
+//static const int ID_CHECK = 1005;
+
+//-----------------------------------------------------------------------------
+// wxDirItemDataEx
+//-----------------------------------------------------------------------------
+
+wxDirItemDataEx::wxDirItemDataEx(const wxString& path, const wxString& name,
+                                 bool isDir)
+{
+    m_path = path;
+    m_name = name;
+    /* Insert logic to detect hidden files here
+     * In UnixLand we just check whether the first char is a dot
+     * For FileNameFromPath read LastDirNameInThisPath ;-) */
+    // m_isHidden = (bool)(wxFileNameFromPath(*m_path)[0] == '.');
+    m_isHidden = FALSE;
+    m_hasSubDirs = HasSubDirs();
+    m_isExpanded = FALSE;
+    m_isDir = isDir;
+}
+
+wxDirItemDataEx::~wxDirItemDataEx()
+{
+}
+
+void wxDirItemDataEx::SetNewDirName( wxString path )
+{
+    m_path = path;
+    m_name = wxFileNameFromPath( path );
+}
+
+bool wxDirItemDataEx::HasSubDirs()
+{
+    wxString search = m_path + wxT("/*");
+    wxLogNull log;
+    wxString path = wxFindFirstFile( search, wxDIR );
+    return (bool)(!path.IsNull());
+}
+
+//-----------------------------------------------------------------------------
+// wxGenericDirCtrl
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxGenericDirCtrl, wxControl)
+
+BEGIN_EVENT_TABLE(wxGenericDirCtrl, wxControl)
+  EVT_TREE_ITEM_EXPANDING     (-1, wxGenericDirCtrl::OnExpandItem)
+  EVT_TREE_ITEM_COLLAPSED     (-1, wxGenericDirCtrl::OnCollapseItem)
+  EVT_TREE_BEGIN_LABEL_EDIT   (-1, wxGenericDirCtrl::OnBeginEditItem)
+  EVT_TREE_END_LABEL_EDIT     (-1, wxGenericDirCtrl::OnEndEditItem)
+  EVT_SIZE                    (wxGenericDirCtrl::OnSize)
+END_EVENT_TABLE()
+
+wxGenericDirCtrl::wxGenericDirCtrl(void)
+{
+    Init();
+}
+
+bool wxGenericDirCtrl::Create(wxWindow *parent,
+                     const wxWindowID id,
+                     const wxString& dir,
+                     const wxPoint& pos,
+                     const wxSize& size,
+                     long style,
+                     const wxString& filter,
+                     int defaultFilter,
+                     const wxString& name )
+{
+    if (!wxControl::Create(parent, id, pos, size, style, wxDefaultValidator, name))
+        return FALSE;
+
+    SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
+
+    Init();
+
+    long treeStyle = wxTR_HAS_BUTTONS;
+    if ((style & wxDIRCTRL_3D_INTERNAL) == 0)
+        treeStyle |= wxNO_BORDER;
+
+    long filterStyle = 0;
+    if ((style & wxDIRCTRL_3D_INTERNAL) == 0)
+        filterStyle |= wxNO_BORDER;
+
+    m_treeCtrl = new wxTreeCtrl(this, wxID_TREECTRL, pos, size, treeStyle);
+
+    if (!filter.IsEmpty() && (style & wxDIRCTRL_SHOW_FILTERS))
+        m_filterListCtrl = new wxDirFilterListCtrl(this, wxID_FILTERLISTCTRL, wxDefaultPosition, wxDefaultSize, filterStyle);
+
+    m_defaultPath = dir;
+    m_filter = filter;
+
+    SetFilterIndex(defaultFilter);
+
+    if (m_filterListCtrl)
+        m_filterListCtrl->FillFilterList(filter, defaultFilter);
+
+    m_imageList = new wxImageList(16, 16, TRUE);
+#if !defined(__WXMSW__) || wxUSE_XPM_IN_MSW
+    m_imageList->Add(wxIcon(icon1_xpm));
+    m_imageList->Add(wxIcon(icon2_xpm));
+    m_imageList->Add(wxIcon(icon3_xpm));
+    m_imageList->Add(wxIcon(icon4_xpm));
+    m_imageList->Add(wxIcon(icon5_xpm));
+    m_imageList->Add(wxIcon(icon6_xpm));
+    m_imageList->Add(wxIcon(icon7_xpm));
+    m_imageList->Add(wxIcon(icon8_xpm));
+#elif defined(__WXMSW__)
+    m_imageList->Add(wxIcon(wxT("wxICON_SMALL_CLOSED_FOLDER"), wxBITMAP_TYPE_RESOURCE));
+    m_imageList->Add(wxIcon(wxT("wxICON_SMALL_OPEN_FOLDER"), wxBITMAP_TYPE_RESOURCE));
+    m_imageList->Add(wxIcon(wxT("wxICON_SMALL_FILE"), wxBITMAP_TYPE_RESOURCE));
+    m_imageList->Add(wxIcon(wxT("wxICON_SMALL_COMPUTER"), wxBITMAP_TYPE_RESOURCE));
+    m_imageList->Add(wxIcon(wxT("wxICON_SMALL_DRIVE"), wxBITMAP_TYPE_RESOURCE));
+    m_imageList->Add(wxIcon(wxT("wxICON_SMALL_CDROM"), wxBITMAP_TYPE_RESOURCE));
+    m_imageList->Add(wxIcon(wxT("wxICON_SMALL_FLOPPY"), wxBITMAP_TYPE_RESOURCE));
+    m_imageList->Add(wxIcon(wxT("wxICON_SMALL_REMOVEABLE"), wxBITMAP_TYPE_RESOURCE));
+#else
+#error "Sorry, we don't have icons available for this platforms."
+#endif
+    m_treeCtrl->SetImageList(m_imageList);
+
+    m_showHidden = FALSE;
+    wxDirItemDataEx* rootData = new wxDirItemDataEx(wxT(""), wxT(""), TRUE);
+
+    wxString rootName;
+
+#ifdef __WXMSW__
+    rootName = _("Computer");
+#else
+    rootName = _("Sections");
+#endif
+
+    m_rootId = m_treeCtrl->AddRoot( rootName, 3, -1, rootData);
+    m_treeCtrl->SetItemHasChildren(m_rootId);
+    m_treeCtrl->Expand(m_rootId); // automatically expand first level
+
+    // Expand and select the default path
+    if (!m_defaultPath.IsEmpty())
+        ExpandPath(m_defaultPath);
+
+    DoResize();
+
+    return TRUE;
+}
+
+wxGenericDirCtrl::~wxGenericDirCtrl()
+{
+   m_treeCtrl->SetImageList(NULL);
+   delete m_imageList;
+}
+
+void wxGenericDirCtrl::Init()
+{
+    m_showHidden = FALSE;
+    m_imageList = NULL;
+    m_rootId = 0;
+    m_currentFilter = 0;
+    m_currentFilterStr = wxEmptyString; // Default: any file
+    m_treeCtrl = NULL;
+    m_filterListCtrl = NULL;
+}
+
+void wxGenericDirCtrl::AddSection(const wxString& path, const wxString& name, int imageId)
+{
+    wxDirItemDataEx *dir_item = new wxDirItemDataEx(path,name,TRUE);
+
+#ifdef __WXMSW__
+    // Windows: sections are displayed as drives
+    wxTreeItemId id = m_treeCtrl->AppendItem( m_rootId, name, imageId, -1, dir_item);
+#else
+    // Unix: sections are displayed as folders
+    wxTreeItemId id = m_treeCtrl->AppendItem( m_rootId, name, 0, -1, dir_item);
+    SetItemImage( id, 1, wxTreeItemIcon_Expanded );
+#endif
+    // TODO: other operating systems.
+
+    m_treeCtrl->SetItemHasChildren(id);
+}
+
+void wxGenericDirCtrl::SetupSections()
+{
+#ifdef __WXMSW__
+
+#ifdef __WIN32__
+    wxChar driveBuffer[256];
+    size_t n = (size_t) GetLogicalDriveStrings(255, driveBuffer);
+    size_t i = 0;
+    while (i < n)
+    {
+        wxString path, name;
+        path.Printf(wxT("%c:\\"), driveBuffer[i]);
+        name.Printf(wxT("(%c:)"), driveBuffer[i]);
+
+        int imageId = 4;
+        int driveType = ::GetDriveType(path);
+        switch (driveType)
+        {
+            case DRIVE_REMOVABLE:
+                if (path == wxT("a:\\") || path == wxT("b:\\"))
+                    imageId = 6; // Floppy
+                else
+                    imageId = 7;
+                break;
+            case DRIVE_FIXED:
+                imageId = 4;
+                break;
+            case DRIVE_REMOTE:
+                imageId = 4;
+                break;
+            case DRIVE_CDROM:
+                imageId = 5;
+                break;
+            default:
+                imageId = 4;
+                break;
+        }
+
+        AddSection(path, name, imageId);
+
+        while (driveBuffer[i] != wxT('\0'))
+            i ++;
+        i ++;
+        if (driveBuffer[i] == wxT('\0'))
+            break;
+    }
+#else
+    int drive;
+    int currentDrive;
+
+    /* Save current drive. */
+    currentDrive = _getdrive();
+
+    /* If we can switch to the drive, it exists. */
+    for( drive = 1; drive <= 26; drive++ )
+    {
+        wxString path, name;
+        path.Printf(wxT("%c:\\"), (char) (drive + 'a' - 1));
+        name.Printf(wxT("(%c:)"), (char) (drive + 'a' - 1));
+
+        if( !_chdrive( drive ) )
+        {
+            
+            AddSection(path, name);
+        }
+    }
+
+    /* Restore original drive.*/
+    _chdrive( currentDrive );
+#endif
+
+#else
+  wxString home;
+  AddSection(wxT("/"), _("The Computer"), 0)
+  wxGetHomeDir(&home);
+  AddSection(home, _("My Home"), 0 )
+  AddSection(wxT("/mnt"), _("Mounted Devices"), 0 )
+  AddSection(wxT("/usr/local"), _("User Local"), 0 )
+  AddSection(wxT("/usr"), _("User"), 0 )
+  AddSection(wxT("/var"), _("Variables"), 0 )
+  AddSection(wxT("/etc"), _("Etcetera"), 0 )
+  AddSection(wxT("/tmp"), _("Temporary"), 0 )
+#endif
+}
+
+void wxGenericDirCtrl::OnBeginEditItem(wxTreeEvent &event)
+{
+    // don't rename the main entry "Sections"
+    if (event.GetItem() == m_rootId)
+    {
+        event.Veto();
+        return;
+    }
+
+    // don't rename the individual sections
+    if (m_treeCtrl->GetParent( event.GetItem() ) == m_rootId)
+    {
+        event.Veto();
+        return;
+    }
+}
+
+void wxGenericDirCtrl::OnEndEditItem(wxTreeEvent &event)
+{
+    if ((event.GetLabel().IsEmpty()) ||
+        (event.GetLabel() == _(".")) ||
+        (event.GetLabel() == _("..")) ||
+        (event.GetLabel().First( wxT("/") ) != wxNOT_FOUND))
+    {
+        wxMessageDialog dialog(this, _("Illegal directory name."), _("Error"), wxOK | wxICON_ERROR );
+        dialog.ShowModal();
+        event.Veto();
+        return;
+    }
+
+    wxTreeItemId id = event.GetItem();
+    wxDirItemDataEx *data = (wxDirItemDataEx*)m_treeCtrl->GetItemData( id );
+    wxASSERT( data );
+
+    wxString new_name( wxPathOnly( data->m_path ) );
+    new_name += wxT("/");
+    new_name += event.GetLabel();
+
+    wxLogNull log;
+
+    if (wxFileExists(new_name))
+    {
+        wxMessageDialog dialog(this, _("File name exists already."), _("Error"), wxOK | wxICON_ERROR );
+        dialog.ShowModal();
+        event.Veto();
+    }
+
+    if (wxRenameFile(data->m_path,new_name))
+    {
+        data->SetNewDirName( new_name );
+    }
+    else
+    {
+        wxMessageDialog dialog(this, _("Operation not permitted."), _("Error"), wxOK | wxICON_ERROR );
+        dialog.ShowModal();
+        event.Veto();
+    }
+}
+
+void wxGenericDirCtrl::OnExpandItem(wxTreeEvent &event)
+{
+    wxTreeItemId parentId = event.GetItem();
+
+    ExpandDir(parentId);
+}
+
+void wxGenericDirCtrl::OnCollapseItem(wxTreeEvent &event )
+{
+    wxTreeItemId child, parent = event.GetItem();
+
+    wxDirItemDataEx *data = (wxDirItemDataEx *) m_treeCtrl->GetItemData(event.GetItem());
+    if (!data->m_isExpanded)
+        return;
+
+    data->m_isExpanded = FALSE;
+    long cookie;
+    /* Workaround because DeleteChildren has disapeared (why?) and
+     * CollapseAndReset doesn't work as advertised (deletes parent too) */
+    child = m_treeCtrl->GetFirstChild(parent, cookie);
+    while (child.IsOk())
+    {
+        m_treeCtrl->Delete(child);
+        /* Not GetNextChild below, because the cookie mechanism can't
+         * handle disappearing children! */
+        child = m_treeCtrl->GetFirstChild(parent, cookie);
+    }
+}
+
+void wxGenericDirCtrl::ExpandDir(wxTreeItemId parentId)
+{
+    wxDirItemDataEx *data = (wxDirItemDataEx *) m_treeCtrl->GetItemData(parentId);
+
+    if (data->m_isExpanded)
+        return;
+
+    data->m_isExpanded = TRUE;
+
+    if (parentId == m_rootId)
+    {
+        SetupSections();
+        return;
+    }
+
+    wxASSERT(data);
+
+    wxString search,path,filename;
+
+    wxString dirName(data->m_path);
+
+#ifdef __WXMSW__
+    // Check if this is a root directory and if so,
+    // whether the drive is avaiable.
+    if (dirName.Len() == 3 && dirName[1] == wxT(':'))
+    {
+        int currentDrive = _getdrive();
+        int thisDrive = (int) (dirName[0] - 'a' + 1) ;
+        int err = _chdrive( thisDrive ) ;
+        _chdrive( currentDrive );
+
+        if (err == -1)
+        {
+            data->m_isExpanded = FALSE;
+            wxMessageBox(wxT("Sorry, this drive is not available."));
+            return;
+        }
+    }
+#endif
+
+    // This may take a longish time. Go to busy cursor
+    wxBusyCursor busy;
+
+#ifdef __WXMSW__
+    if (dirName.Last() == ':')
+        dirName += wxString(wxFILE_SEP_PATH);
+#endif
+
+    wxArrayString dirs;
+    wxArrayString filenames;
+
+    wxDir d;
+    wxString eachFilename;
+
+    d.Open(dirName);
+
+    if (d.IsOpened())
+    {
+        if (d.GetFirst(& eachFilename, wxEmptyString, wxDIR_DIRS))
+        {
+            do
+            {
+                if ((eachFilename != wxT(".")) && (eachFilename != wxT("..")))
+                {
+                    dirs.Add(eachFilename);
+                }
+            }
+            while (d.GetNext(& eachFilename)) ;
+        }
+    }
+    dirs.Sort();
+
+    // Now do the filenames -- but only if we're allowed to
+    if ((GetWindowStyle() & wxDIRCTRL_DIR_ONLY) == 0)
+    {
+        d.Open(dirName);
+        
+        if (d.IsOpened())
+        {
+            if (d.GetFirst(& eachFilename, m_currentFilterStr, wxDIR_FILES))
+            {
+                do
+                {
+                    if ((eachFilename != wxT(".")) && (eachFilename != wxT("..")))
+                    {
+                        filenames.Add(eachFilename);
+                    }
+                }
+                while (d.GetNext(& eachFilename)) ;
+            }
+        }
+        filenames.Sort();
+    }
+
+    // Add the sorted dirs
+    size_t i;
+    for (i = 0; i < dirs.Count(); i++)
+    {
+        wxString eachFilename(dirs[i]);
+        path = dirName;
+        if (path.Last() != wxFILE_SEP_PATH)
+            path += wxString(wxFILE_SEP_PATH);
+        path += eachFilename;
+
+        wxDirItemDataEx *dir_item = new wxDirItemDataEx(path,eachFilename,TRUE);
+        wxTreeItemId id = m_treeCtrl->AppendItem( parentId, eachFilename, 0, -1, dir_item);
+        m_treeCtrl->SetItemImage( id, 1, wxTreeItemIcon_Expanded );
+        
+        // Has this got any children? If so, make it expandable.
+        int options = wxDIR_DEFAULT;
+        if (GetWindowStyle() & wxDIRCTRL_DIR_ONLY) // If only showing dirs, then we specify dirs only here
+        {
+            options = wxDIR_DIRS;
+        }
+
+        wxDir dir2(path);
+        wxString str;
+        // Have to test for wxDIR_DIRS separately in case m_currentFilterStr is non-empty and
+        // and filters out any directories
+        if (dir2.GetFirst(& str, m_currentFilterStr, options) || dir2.GetFirst(& str, wxEmptyString, wxDIR_DIRS))
+        {
+            m_treeCtrl->SetItemHasChildren(id);
+        }
+    }
+
+    // Add the sorted filenames
+    if ((GetWindowStyle() & wxDIRCTRL_DIR_ONLY) == 0)
+    {
+        for (i = 0; i < filenames.Count(); i++)
+        {
+            wxString eachFilename(filenames[i]);
+            path = dirName;
+            if (path.Last() != wxFILE_SEP_PATH)
+                path += wxString(wxFILE_SEP_PATH);
+            path += eachFilename;
+            //path = dirName + wxString(wxT("/")) + eachFilename;
+            wxDirItemDataEx *dir_item = new wxDirItemDataEx(path,eachFilename,FALSE);
+            wxTreeItemId id = m_treeCtrl->AppendItem( parentId, eachFilename, 2, -1, dir_item);
+        }
+    }
+}
+
+// Find the child that matches the first part of 'path'.
+// E.g. if a child path is "/usr" and 'path' is "/usr/include"
+// then the child for /usr is returned.
+wxTreeItemId wxGenericDirCtrl::FindChild(wxTreeItemId parentId, const wxString& path, bool& done)
+{
+    wxString path2(path);
+    
+    // Make sure all separators are as per the current platform
+    path2.Replace(wxT("\\"), wxString(wxFILE_SEP_PATH));
+    path2.Replace(wxT("/"), wxString(wxFILE_SEP_PATH));
+    
+    // Append a separator to foil bogus substring matching
+    path2 += wxString(wxFILE_SEP_PATH);
+    
+    // In MSW, case is not significant
+#ifdef __WXMSW__
+    path2.MakeLower();
+#endif
+    
+    long cookie;
+    wxTreeItemId childId = m_treeCtrl->GetFirstChild(parentId, cookie);
+    while (childId != 0)
+    {
+        wxDirItemDataEx* data = (wxDirItemDataEx*) m_treeCtrl->GetItemData(childId);
+        
+        if (data && data->m_path != "")
+        {
+            wxString childPath(data->m_path);
+            if (childPath.Last() != wxFILE_SEP_PATH)
+                childPath += wxString(wxFILE_SEP_PATH);
+            
+            // In MSW, case is not significant
+#ifdef __WXMSW__
+            childPath.MakeLower();
+#endif
+            
+            if (childPath.Len() <= path2.Len())
+            {
+                wxString path3 = path2.Mid(0, childPath.Len());
+                if (childPath == path3)
+                {
+                    if (path3.Len() == path2.Len())
+                        done = TRUE;
+                    else
+                        done = FALSE;
+                    return childId;
+                }
+            }
+        }
+        
+        childId = m_treeCtrl->GetNextChild(childId, cookie);
+    }
+    return 0;
+}
+
+// Try to expand as much of the given path as possible,
+// and select the given tree item.
+bool wxGenericDirCtrl::ExpandPath(const wxString& path)
+{
+    bool done = FALSE;
+    wxTreeItemId id = FindChild(m_rootId, path, done);
+    wxTreeItemId lastId = id; // The last non-zero id
+    while ((id > 0) && !done)
+    {
+        ExpandDir(id);
+
+        id = FindChild(id, path, done);
+        if (id != 0)
+            lastId = id;
+    }
+    if (lastId > 0)
+    {
+        wxDirItemDataEx *data = (wxDirItemDataEx *) m_treeCtrl->GetItemData(lastId);
+        if (data->m_isDir)
+        {
+            m_treeCtrl->Expand(lastId);
+        }
+        if ((GetWindowStyle() & wxDIRCTRL_SELECT_FIRST) && data->m_isDir)
+        {
+            // Find the first file in this directory
+            long cookie;
+            wxTreeItemId childId = m_treeCtrl->GetFirstChild(lastId, cookie);
+            bool selectedChild = FALSE;
+            while (childId != 0)
+            {
+                wxDirItemDataEx* data = (wxDirItemDataEx*) m_treeCtrl->GetItemData(childId);
+                
+                if (data && data->m_path != "" && !data->m_isDir)
+                {
+                    m_treeCtrl->SelectItem(childId);
+                    m_treeCtrl->EnsureVisible(childId);
+                    selectedChild = TRUE;
+                    break;
+                }
+                childId = m_treeCtrl->GetNextChild(lastId, cookie);
+            }
+            if (!selectedChild)
+            {
+                m_treeCtrl->SelectItem(lastId);
+                m_treeCtrl->EnsureVisible(lastId);
+            }
+        }
+        else
+        {
+            m_treeCtrl->SelectItem(lastId);
+            m_treeCtrl->EnsureVisible(lastId);
+        }
+
+        return TRUE;
+    }
+    else
+        return FALSE;
+}
+
+wxString wxGenericDirCtrl::GetPath() const
+{
+    wxTreeItemId id = m_treeCtrl->GetSelection();
+    if (id)
+    {
+        wxDirItemDataEx* data = (wxDirItemDataEx*) m_treeCtrl->GetItemData(id);
+        return data->m_path;
+    }
+    else
+        return wxEmptyString;
+}
+
+wxString wxGenericDirCtrl::GetFilePath() const
+{
+    wxTreeItemId id = m_treeCtrl->GetSelection();
+    if (id)
+    {
+        wxDirItemDataEx* data = (wxDirItemDataEx*) m_treeCtrl->GetItemData(id);
+        if (data->m_isDir)
+            return wxEmptyString;
+        else
+            return data->m_path;
+    }
+    else
+        return wxEmptyString;
+}
+
+void wxGenericDirCtrl::SetPath(const wxString& path)
+{
+    m_defaultPath = path;
+    if (m_rootId)
+        ExpandPath(path);
+}
+
+// Not used
+#if 0
+void wxGenericDirCtrl::FindChildFiles(wxTreeItemId id, int dirFlags, wxArrayString& filenames)
+{
+    wxDirItemDataEx *data = (wxDirItemDataEx *) m_treeCtrl->GetItemData(id);
+
+    // This may take a longish time. Go to busy cursor
+    wxBusyCursor busy;
+
+    wxASSERT(data);
+
+    wxString search,path,filename;
+
+    wxString dirName(data->m_path);
+
+#ifdef __WXMSW__
+    if (dirName.Last() == ':')
+        dirName += wxString(wxFILE_SEP_PATH);
+#endif
+
+    wxDir d;
+    wxString eachFilename;
+
+    d.Open(dirName);
+
+    if (d.IsOpened())
+    {
+        if (d.GetFirst(& eachFilename, m_currentFilterStr, dirFlags))
+        {
+            do
+            {
+                if ((eachFilename != wxT(".")) && (eachFilename != wxT("..")))
+                {
+                    filenames.Add(eachFilename);
+                }
+            }
+            while (d.GetNext(& eachFilename)) ;
+        }
+    }
+}
+#endif
+
+void wxGenericDirCtrl::SetFilterIndex(int n)
+{
+    m_currentFilter = n;
+
+    wxString f, d;
+    if (ExtractWildcard(m_filter, n, f, d))
+        m_currentFilterStr = f;
+    else
+        m_currentFilterStr = wxT("*.*");
+}
+
+void wxGenericDirCtrl::SetFilter(const wxString& filter)
+{
+    m_filter = filter;
+
+    wxString f, d;
+    if (ExtractWildcard(m_filter, m_currentFilter, f, d))
+        m_currentFilterStr = f;
+    else
+        m_currentFilterStr = wxT("*.*");
+}
+
+// Extract description and actual filter from overall filter string
+bool wxGenericDirCtrl::ExtractWildcard(const wxString& filterStr, int n, wxString& filter, wxString& description)
+{
+    wxArrayString filters, descriptions;
+    int count = ParseFilter(filterStr, filters, descriptions);
+    if (count > 0 && n < count)
+    {
+        filter = filters[n];
+        description = descriptions[n];
+        return TRUE;
+    }
+    else
+        return FALSE;
+}
+
+// Parses the global filter, returning the number of filters.
+// Returns 0 if none or if there's a problem.
+// filterStr is in the form:
+//
+// "All files (*.*)|*.*|JPEG Files (*.jpeg)|*.jpg"
+
+int wxGenericDirCtrl::ParseFilter(const wxString& filterStr, wxArrayString& filters, wxArrayString& descriptions)
+{
+    wxString str(filterStr);
+
+    wxString description, filter;
+    int pos;
+    bool finished = FALSE;
+    do
+    {
+        pos = str.Find(wxT('|'));
+        if (pos == -1)
+            return 0; // Problem
+        description = str.Left(pos);
+        str = str.Mid(pos+1);
+        pos = str.Find(wxT('|'));
+        if (pos == -1)
+        {
+            filter = str;
+            finished = TRUE;
+        }
+        else
+        {
+            filter = str.Left(pos);
+            str = str.Mid(pos+1);
+        }
+        descriptions.Add(description);
+        filters.Add(filter);
+    }
+    while (!finished) ;
+
+    return filters.Count();
+}
+
+void wxGenericDirCtrl::DoResize()
+{
+    wxSize sz = GetClientSize();
+    int verticalSpacing = 3;
+    if (m_treeCtrl)
+    {
+        wxSize filterSz ;
+        if (m_filterListCtrl)
+        {
+            filterSz = m_filterListCtrl->GetSize();
+            sz.y -= (filterSz.y + verticalSpacing);
+        }
+        m_treeCtrl->SetSize(0, 0, sz.x, sz.y);
+        if (m_filterListCtrl)
+        {
+            m_filterListCtrl->SetSize(0, sz.y + verticalSpacing, sz.x, filterSz.y);
+            // Don't know why, but this needs refreshing after a resize (wxMSW)
+            m_filterListCtrl->Refresh();
+        }
+    }
+}
+
+
+void wxGenericDirCtrl::OnSize(wxSizeEvent &event)
+{
+    DoResize();
+}
+
+//-----------------------------------------------------------------------------
+// wxDirFilterListCtrl
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_CLASS(wxDirFilterListCtrl, wxChoice)
+
+BEGIN_EVENT_TABLE(wxDirFilterListCtrl, wxChoice)
+    EVT_CHOICE(-1, wxDirFilterListCtrl::OnSelFilter)
+END_EVENT_TABLE()
+
+bool wxDirFilterListCtrl::Create(wxGenericDirCtrl* parent, const wxWindowID id,
+              const wxPoint& pos,
+              const wxSize& size,
+              long style)
+{
+    m_dirCtrl = parent;
+    return wxChoice::Create(parent, id, pos, size, 0, NULL, style);
+}
+
+void wxDirFilterListCtrl::Init()
+{
+    m_dirCtrl = NULL;
+}
+
+void wxDirFilterListCtrl::OnSelFilter(wxCommandEvent& event)
+{
+    int sel = GetSelection();
+
+    wxString currentPath = m_dirCtrl->GetPath();
+        
+    m_dirCtrl->SetFilterIndex(sel);
+
+    // If the filter has changed, the view is out of date, so
+    // collapse the tree.
+    m_dirCtrl->GetTreeCtrl()->Collapse(m_dirCtrl->GetRootId());
+    m_dirCtrl->GetTreeCtrl()->Expand(m_dirCtrl->GetRootId());
+
+    // Try to restore the selection, or at least the directory
+    m_dirCtrl->ExpandPath(currentPath);
+}
+
+void wxDirFilterListCtrl::FillFilterList(const wxString& filter, int defaultFilter)
+{
+    Clear();
+    wxArrayString descriptions, filters;
+    size_t n = (size_t) m_dirCtrl->ParseFilter(filter, filters, descriptions);
+
+    if (n > 0 && defaultFilter < (int) n)
+    {
+        size_t i = 0;
+        for (i = 0; i < n; i++)
+            Append(descriptions[i]);
+        SetSelection(defaultFilter);
+    }
+}
+
+// wxGenericDirDialog implementation
+// This should be moved into dirdlgg.cpp eventually
+
+BEGIN_EVENT_TABLE(wxGenericDirDialog, wxDialog)
+    EVT_BUTTON(wxID_OK,  wxGenericDirDialog::OnOK)
+    EVT_CLOSE(wxGenericDirDialog::OnCloseWindow)
+END_EVENT_TABLE()
+
+wxGenericDirDialog::wxGenericDirDialog(wxWindow* parent, const wxString& title,
+        const wxString& defaultPath, long style, const wxPoint& pos, const wxSize& sz, const wxString& name):
+   wxDialog(parent, ID_DIRCTRL, title, pos, sz, style, name)
+{
+    wxBusyCursor cursor;
+
+    wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
+
+    // 1) dir ctrl
+    m_dirCtrl = new wxGenericDirCtrl(this, ID_DIRCTRL,
+        defaultPath, wxPoint(5, 5),
+        wxSize(300, 200), wxDIRCTRL_DIR_ONLY);
+
+    topsizer->Add( m_dirCtrl, 1, wxTOP|wxLEFT|wxRIGHT | wxEXPAND, 10 );
+
+    // 2) TODO: text control for entering path?
+
+#if wxUSE_STATLINE
+    // 3) Static line
+    topsizer->Add( new wxStaticLine( this, -1 ), 0, wxEXPAND | wxLEFT|wxRIGHT|wxTOP, 10 );
+#endif
+
+    // 4) Buttons
+    wxSizer* buttonsizer = new wxBoxSizer( wxHORIZONTAL );
+    wxButton* okButton = new wxButton(this, wxID_OK, _("OK"));
+    buttonsizer->Add( okButton, 0, wxLEFT|wxRIGHT, 10 );
+    wxButton* cancelButton = new wxButton(this, wxID_CANCEL, _("Cancel"));
+    buttonsizer->Add( cancelButton, 0, wxLEFT|wxRIGHT, 10 );
+
+/* TODO: new directory button
+    wxButton* newButton = new wxButton( this, ID_NEW, _("New...") );
+    buttonsizer->Add( newButton, 0, wxLEFT|wxRIGHT, 10 );
+*/
+    topsizer->Add( buttonsizer, 0, wxALL | wxCENTER, 10 );
+
+    okButton->SetDefault();
+    m_dirCtrl->SetFocus();
+
+    SetAutoLayout( TRUE );
+    SetSizer( topsizer );
+
+    topsizer->SetSizeHints( this );
+    topsizer->Fit( this );
+
+    Centre( wxBOTH );
+}
+
+void wxGenericDirDialog::OnCloseWindow(wxCloseEvent& event)
+{
+    EndModal(wxID_CANCEL);
+}
+
+void wxGenericDirDialog::OnOK(wxCommandEvent& event)
+{
+    EndModal(wxID_OK);
+}
+
+void wxGenericDirDialog::SetPath(const wxString& path)
+{
+    m_dirCtrl->SetPath(path);
+}
+
+wxString wxGenericDirDialog::GetPath(void) const
+{
+    return m_dirCtrl->GetPath();
+}
index 35a926406762725c466c9fc9c6b450088a1ad50c..60b01a0e9193ae2ca5c0bb8ae9be1b894e8e449f 100644 (file)
@@ -86,6 +86,7 @@ $(CPPFLAGS) /Fo$@ /c /Tp $<
 GENERICOBJS= ..\generic\$D\busyinfo.obj \
                ..\generic\$D\calctrl.obj \
                ..\generic\$D\choicdgg.obj \
+               ..\generic\$D\dirctrlg.obj \
                ..\generic\$D\dragimgg.obj \
                ..\generic\$D\grid.obj \
                ..\generic\$D\gridsel.obj \
index 3f70598debc1343dc3103ddd8a42415073388b4c..a69945aef990c5c1294e57aa22ee831b83d011c4 100644 (file)
@@ -512,6 +512,10 @@ SOURCE=.\generic\choicdgg.cpp
 # End Source File
 # Begin Source File
 
+SOURCE=.\generic\dirctrlg.cpp
+# End Source File
+# Begin Source File
+
 SOURCE=.\generic\dragimgg.cpp
 # End Source File
 # Begin Source File