From 4afd752902ae7c44f4b3dc2edb11d7c24f95ed54 Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Sat, 11 Dec 1999 00:43:59 +0000
Subject: [PATCH] 1. wxDir works for MSW and documented 2. wxDateTime works
 with dates very close to the Epoch 3. setting font for wxRadioBox works

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4899 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/latex/wx/category.tex  |   1 +
 docs/latex/wx/classes.tex   |   1 +
 docs/latex/wx/dir.tex       | 119 ++++++++++++++++++++++++++++++++++++
 docs/latex/wx/tfile.tex     |   5 +-
 include/wx/msw/radiobox.h   |   2 +
 samples/console/console.cpp |   4 +-
 samples/text/text.cpp       |  32 +++++-----
 src/common/datetime.cpp     |  20 +++++-
 src/msw/dir.cpp             |  36 +++++------
 src/msw/radiobox.cpp        |  23 ++++++-
 10 files changed, 204 insertions(+), 39 deletions(-)
 create mode 100644 docs/latex/wx/dir.tex

diff --git a/docs/latex/wx/category.tex b/docs/latex/wx/category.tex
index 124f06d7ca..bc6a912826 100644
--- a/docs/latex/wx/category.tex
+++ b/docs/latex/wx/category.tex
@@ -377,6 +377,7 @@ wxWindows has several small classes to work with disk files, see \helpref{file c
 overview}{wxfileoverview} for more details.
 
 \begin{twocollist}\itemsep=0pt
+\twocolitem{\helpref{wxDir}{wxdir}}{Class for enumerating files/subdirectories.}
 \twocolitem{\helpref{wxFile}{wxfile}}{Low-level file input/output class.}
 \twocolitem{\helpref{wxFFile}{wxffile}}{Another low-level file input/output class.}
 \twocolitem{\helpref{wxTempFile}{wxtempfile}}{Class to safely replace an existing file}
diff --git a/docs/latex/wx/classes.tex b/docs/latex/wx/classes.tex
index 9a1e78ac43..38b1ac3b46 100644
--- a/docs/latex/wx/classes.tex
+++ b/docs/latex/wx/classes.tex
@@ -52,6 +52,7 @@
 \input ddeservr.tex
 \input debugcxt.tex
 \input dialog.tex
+\input dir.tex
 \input dirdlg.tex
 \input docchfrm.tex
 \input docmanag.tex
diff --git a/docs/latex/wx/dir.tex b/docs/latex/wx/dir.tex
new file mode 100644
index 0000000000..676d62c3b2
--- /dev/null
+++ b/docs/latex/wx/dir.tex
@@ -0,0 +1,119 @@
+%
+% automatically generated by HelpGen from
+% include\wx\dir.h at 11/Dec/99 00:55:30
+%
+
+
+\section{\class{wxDir}}\label{wxdir}
+
+wxDir is a portable equivalent of Unix {open/read/close}dir functions which
+allow enumerating of the files in a directory. wxDir allows enumerate files as
+well as directories.
+
+Example of use:
+
+\begin{verbatim}
+    wxDir dir(wxGetCwd());
+
+    if ( !dir.IsOpened() )
+    {
+        // deal with the error here - wxDir would already log an error message
+        // explaining the exact reason of the failure
+        return;
+    }
+
+    puts("Enumerating object files in current directory:");
+
+    wxString filename;
+
+    bool cont = dir.GetFirst(&filename, filespec, flags);
+    while ( cont )
+    {
+        printf("%s\n", filename.c_str());
+
+        cont = dir.GetNext(&filename);
+    }
+\end{verbatim}
+
+\wxheading{Derived from}
+
+No base class
+
+\wxheading{Constants}
+
+These flags define what kind of filenames is included in the list of files
+enumerated by GetFirst/GetNext
+
+{\small
+\begin{verbatim}
+enum
+{
+    wxDIR_FILES     = 0x0001,       // include files
+    wxDIR_DIRS      = 0x0002,       // include directories
+    wxDIR_HIDDEN    = 0x0004,       // include hidden files
+    wxDIR_DOTDOT    = 0x0008,       // include '.' and '..'
+
+    // by default, enumerate everything except '.' and '..'
+    wxDIR_DEFAULT   = wxDIR\_FILES | wxDIR\_DIRS | wxDIR\_HIDDEN
+}
+\end{verbatim}
+}
+
+\wxheading{Include files}
+
+<wx/dir.h>
+
+\latexignore{\rtfignore{\wxheading{Members}}}
+
+\membersection{wxDir::Exists}\label{wxdirexists}
+
+\func{static bool}{Exists}{\param{const wxString\& }{dir}}
+
+Test for existence of a directory with the given name
+
+\membersection{wxDir::wxDir}\label{wxdirwxdir}
+
+\func{}{wxDir}{\void}
+
+Default constructor, use \helpref{Open()}{wxdiropen} afterwards.
+
+\func{}{wxDir}{\param{const wxString\& }{dir}}
+
+Opens the directory for enumeration, use \helpref{IsOpened()}{wxdirisopened} 
+to test for errors.
+
+\membersection{wxDir::\destruct{wxDir}}\label{wxdirdtor}
+
+\func{}{\destruct{wxDir}}{\void}
+
+Destructor cleans up the associated ressources. It is not virtual and so this
+class is not meant to be used polymorphically.
+
+\membersection{wxDir::Open}\label{wxdiropen}
+
+\func{bool}{Open}{\param{const wxString\& }{dir}}
+
+Open the directory for enumerating, returns TRUE on success or FALSE if an
+error occured.
+
+\membersection{wxDir::IsOpened}\label{wxdirisopened}
+
+\constfunc{bool}{IsOpened}{\void}
+
+Returns TRUE if the directory was successfully opened by a previous call to 
+\helpref{Open}{wxdiropen}.
+
+\membersection{wxDir::GetFirst}\label{wxdirgetfirst}
+
+\constfunc{bool}{GetFirst}{\param{wxString* }{filename}, \param{const wxString\& }{filespec = wxEmptyString}, \param{int }{flags = wxDIR\_DEFAULT}}
+
+Start enumerating all files matching {\it filespec} (or all files if it is
+empty) and flags, return TRUE on success.
+
+\membersection{wxDir::GetNext}\label{wxdirgetnext}
+
+\constfunc{bool}{GetNext}{\param{wxString* }{filename}}
+
+Continue enumerating files satisfying the criteria specified by the last call
+to \helpref{GetFirst}{wxdirgetfirst}.
+
diff --git a/docs/latex/wx/tfile.tex b/docs/latex/wx/tfile.tex
index 52c7f65e36..f077b0a267 100644
--- a/docs/latex/wx/tfile.tex
+++ b/docs/latex/wx/tfile.tex
@@ -1,6 +1,6 @@
 \section{File classes and functions overview}\label{wxfileoverview}
 
-Classes: \helpref{wxFile}{wxfile}, \helpref{wxTempFile}{wxtempfile}, 
+Classes: \helpref{wxFile}{wxfile}, \helpref{wxDir}{wxdir}, \helpref{wxTempFile}{wxtempfile}, 
 \helpref{wxTextFile}{wxtextfile}
 
 Functions: see \helpref{file functions}{filefunctions}.
@@ -25,3 +25,6 @@ and program source files. It can be also used to work with files with "non
 native" line termination characters and write them as "native" files if needed
 (in fact, the files may be written in any format).
 
+wxDir is a helper class for enumerating the files or subdirectories of a
+directory. It may be used to enumerate all files, only files satisfying the
+given template mask or only non-hidden files.
diff --git a/include/wx/msw/radiobox.h b/include/wx/msw/radiobox.h
index 4460f80d02..d574266121 100644
--- a/include/wx/msw/radiobox.h
+++ b/include/wx/msw/radiobox.h
@@ -78,6 +78,8 @@ public:
     // implementation only from now on
     // -------------------------------
 
+    virtual bool SetFont(const wxFont& font);
+
     long MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
     WXHWND *GetRadioButtons() const { return m_radioButtons; }
     bool ContainsHWND(WXHWND hWnd) const;
diff --git a/samples/console/console.cpp b/samples/console/console.cpp
index f94b716028..a60440aae9 100644
--- a/samples/console/console.cpp
+++ b/samples/console/console.cpp
@@ -30,12 +30,12 @@
 // what to test?
 
 //#define TEST_ARRAYS
-//#define TEST_DIR
+#define TEST_DIR
 //#define TEST_LOG
 //#define TEST_MIME
 //#define TEST_STRINGS
 //#define TEST_THREADS
-#define TEST_TIME
+//#define TEST_TIME
 //#define TEST_LONGLONG
 
 // ============================================================================
diff --git a/samples/text/text.cpp b/samples/text/text.cpp
index 391cc7ce0e..d592388bf4 100644
--- a/samples/text/text.cpp
+++ b/samples/text/text.cpp
@@ -340,13 +340,13 @@ void MyTextCtrl::LogEvent(const wxChar *name, wxKeyEvent& event) const
             case WXK_NUMPAD_SUBTRACT: key = "NUMPAD_SUBTRACT"; break;
             case WXK_NUMPAD_DECIMAL: key = "NUMPAD_DECIMAL"; break;
 
-	    default:
+            default:
             {
                if ( wxIsprint((int)keycode) )
                    key.Printf( _T("'%c'") , (char)keycode);
                else
-		   key.Printf( _T("unknown (%ld)"), keycode);
-	    }
+                   key.Printf( _T("unknown (%ld)"), keycode);
+            }
         }
     }
 
@@ -417,21 +417,25 @@ void MyTextCtrl::OnKeyDown(wxKeyEvent& event)
             // go to position 10
             SetInsertionPoint(10);
             break;
-	    
+
         case WXK_F4:
-	    if (!m_hasCapture)
-	    {
+            if (!m_hasCapture)
+            {
                 wxLogDebug( wxT("Now capturing mouse and events.") );
-	        m_hasCapture = TRUE;
-	        CaptureMouse();
-	    }
-	    else
-	    {
+                m_hasCapture = TRUE;
+                CaptureMouse();
+            }
+            else
+            {
                 wxLogDebug( wxT("Stopped capturing mouse and events.") );
-	        m_hasCapture = TRUE;
-	        ReleaseMouse();
-	    }
+                m_hasCapture = TRUE;
+                ReleaseMouse();
+            }
             break;
+
+        case WXK_F5:
+            // insert a blank line
+            WriteText("\n");
     }
 
     LogEvent( _("Key down"), event);
diff --git a/src/common/datetime.cpp b/src/common/datetime.cpp
index 815813e151..d93cb2d179 100644
--- a/src/common/datetime.cpp
+++ b/src/common/datetime.cpp
@@ -553,9 +553,25 @@ wxDateTime& wxDateTime::Set(const struct tm& tm)
     struct tm tm2(tm);
     time_t timet = mktime(&tm2);
 
-    if ( timet == (time_t)(-1) )
+    if ( timet == (time_t)-1 )
     {
-        wxFAIL_MSG(_T("Invalid time"));
+        // mktime() rather unintuitively fails for Jan 1, 1970 if the hour is
+        // less than timezone - try to make it work for this case
+        if ( tm2.tm_year == 70 && tm2.tm_mon == 0 && tm2.tm_mday == 1 )
+        {
+            // add timezone to make sure that date is in range
+            tm2.tm_sec -= GetTimeZone();
+
+            timet = mktime(&tm2);
+            if ( timet != (time_t)-1 )
+            {
+                timet += GetTimeZone();
+
+                return Set(timet);
+            }
+        }
+
+        wxFAIL_MSG( _T("mktime() failed") );
 
         return ms_InvDateTime;
     }
diff --git a/src/msw/dir.cpp b/src/msw/dir.cpp
index 8e993552a5..06e86573f5 100644
--- a/src/msw/dir.cpp
+++ b/src/msw/dir.cpp
@@ -91,15 +91,6 @@ wxDirData::wxDirData(const wxString& dirname)
          : m_dirname(dirname)
 {
     m_handle = INVALID_HANDLE_VALUE;
-
-    // throw away the trailing slashes
-    size_t n = m_dirname.length();
-    wxCHECK_RET( n, _T("empty dir name in wxDir") );
-
-    while ( n > 0 && wxIsPathSeparator(m_dirname[--n]) )
-        ;
-
-    m_dirname.Truncate(n + 1);
 }
 
 wxDirData::~wxDirData()
@@ -115,6 +106,8 @@ void wxDirData::Close()
         {
             wxLogLastError(_T("FindClose"));
         }
+
+        m_handle = INVALID_HANDLE_VALUE;
     }
 }
 
@@ -131,8 +124,11 @@ bool wxDirData::Read(wxString *filename)
     if ( m_handle == INVALID_HANDLE_VALUE )
     {
         // open first
-        m_handle = ::FindFirstFile(!m_filespec ? _T("*.*") : m_filespec.c_str(),
-                                   &finddata);
+        wxString filespec;
+        filespec << m_dirname << _T('\\')
+                 << (!m_filespec ? _T("*.*") : m_filespec.c_str());
+
+        m_handle = ::FindFirstFile(filespec, &finddata);
 
         first = TRUE;
     }
@@ -141,7 +137,7 @@ bool wxDirData::Read(wxString *filename)
     {
         DWORD err = ::GetLastError();
 
-        if ( err != ERROR_NO_MORE_FILES )
+        if ( err != ERROR_FILE_NOT_FOUND )
         {
             wxLogSysError(err, _("Can not enumerate files in directory '%s'"),
                           m_dirname.c_str());
@@ -151,12 +147,10 @@ bool wxDirData::Read(wxString *filename)
         return FALSE;
     }
 
-    bool matches = FALSE;
-
     const wxChar *name;
     DWORD attr;
 
-    while ( !matches )
+    for ( ;; )
     {
         if ( first )
         {
@@ -205,11 +199,17 @@ bool wxDirData::Read(wxString *filename)
         // finally, check whether it's a hidden file
         if ( !(m_flags & wxDIR_HIDDEN) )
         {
-            matches = !(attr & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM));
+            if ( attr & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM) )
+            {
+                // it's a hidden file, skip it
+                continue;
+            }
         }
-    }
 
-    *filename = name;
+        *filename = name;
+
+        break;
+    }
 
     return TRUE;
 }
diff --git a/src/msw/radiobox.cpp b/src/msw/radiobox.cpp
index 5daf5146d3..20ce47a197 100644
--- a/src/msw/radiobox.cpp
+++ b/src/msw/radiobox.cpp
@@ -182,7 +182,7 @@ bool wxRadioBox::Create(wxWindow *parent,
 {
     // initialize members
     m_selectedButton = -1;
-    m_noItems = n;
+    m_noItems = 0;
 
     m_majorDim =  majorDim == 0 ? n : majorDim;
     m_noRowsOrCols = majorDim;
@@ -196,6 +196,7 @@ bool wxRadioBox::Create(wxWindow *parent,
         return FALSE;
 
     // and now create the buttons
+    m_noItems = n;
 #if RADIOBTN_PARENT_IS_RADIOBOX
     HWND hwndParent = GetHwnd();
 #else
@@ -658,7 +659,7 @@ bool wxRadioBox::ContainsHWND(WXHWND hWnd) const
     return FALSE;
 }
 
-void wxRadioBox::Command (wxCommandEvent & event)
+void wxRadioBox::Command(wxCommandEvent & event)
 {
     SetSelection (event.m_commandInt);
     ProcessCommand (event);
@@ -687,6 +688,24 @@ void wxRadioBox::SendNotificationEvent()
     ProcessCommand(event);
 }
 
+bool wxRadioBox::SetFont(const wxFont& font)
+{
+    if ( !wxControl::SetFont(font) )
+    {
+        // nothing to do
+        return FALSE;
+    }
+
+    // also set the font of our radio buttons
+    WXHFONT hfont = wxFont(font).GetResourceHandle();
+    for ( int n = 0; n < m_noItems; n++ )
+    {
+        ::SendMessage((HWND)m_radioButtons[n], WM_SETFONT, (WPARAM)hfont, 0L);
+    }
+
+    return TRUE;
+}
+
 long wxRadioBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
 {
     // This is required for the radiobox to be sensitive to mouse input,
-- 
2.45.2

