From 350777b68f3cbc6c51d8fdbb29151ee36247563e Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 24 Jan 2003 00:32:17 +0000 Subject: [PATCH] added and documented wxDirTraverser::OnOpenError git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@18895 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 1 + docs/latex/wx/dirtrav.tex | 27 ++++++++--- include/wx/dir.h | 14 +++++- src/common/dircmn.cpp | 94 +++++++++++++++++++++++++++++++-------- 4 files changed, 110 insertions(+), 26 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 155f56d89f..fa5ab9811c 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -16,6 +16,7 @@ All: - added wxDateSpan::operator==() and !=() (Lukasz Michalski) - use true/false throughout the library instead of TRUE/FALSE - wxStopWatch::Start() resumes the stop watch if paused, as per the docs +- added wxDirTraverser::OnOpenError() to customize the error handling wxBase: diff --git a/docs/latex/wx/dirtrav.tex b/docs/latex/wx/dirtrav.tex index bf7ef9df13..f8fbbee806 100644 --- a/docs/latex/wx/dirtrav.tex +++ b/docs/latex/wx/dirtrav.tex @@ -71,6 +71,17 @@ enum wxDirTraverseResult \latexignore{\rtfignore{\wxheading{Members}}} +\membersection{wxDirTraverser::OnDir}\label{wxdirtraverserondir} + +\func{virtual wxDirTraverseResult}{OnDir}{\param{const wxString\& }{dirname}} + +This function is called for each directory. It may return {\tt wxSIR\_STOP} +to abort traversing completely, {\tt wxDIR\_IGNORE} to skip this directory but +continue with others or {\tt wxDIR\_CONTINUE} to enumerate all files and +subdirectories in this directory. + +This is a pure virtual function and must be implemented in the derived class. + \membersection{wxDirTraverser::OnFile}\label{wxdirtraverseronfile} \func{virtual wxDirTraverseResult}{OnFile}{\param{const wxString\& }{filename}} @@ -79,13 +90,17 @@ This function is called for each file. It may return {\tt wxDIR\_STOP} to abort traversing (for example, if the file being searched is found) or {\tt wxDIR\_CONTINUE} to proceed. -\membersection{wxDirTraverser::OnDir}\label{wxdirtraverserondir} +This is a pure virtual function and must be implemented in the derived class. -\func{virtual wxDirTraverseResult}{OnDir}{\param{const wxString\& }{dirname}} +\membersection{wxOpenErrorTraverser::OnOpenError}\label{wxopenerrortraverseronopenerror} -This function is called for each directory. It may return {\tt wxSIR\_STOP} -to abort traversing completely, {\tt wxDIR\_IGNORE} to skip this directory but -continue with others or {\tt wxDIR\_CONTINUE} to enumerate all files and -subdirectories in this directory. +\func{virtual wxOpenErrorTraverseResult}{OnOpenError}{\param{const wxString\& }{openerrorname}} + +This function is called for each directory which we failed to open for +enumerating. It may return {\tt wxSIR\_STOP} to abort traversing completely, +{\tt wxDIR\_IGNORE} to skip this directory but continue with others or +{\tt wxDIR\_CONTINUE} to retry opening this directory once again. + +The base class version always returns {\tt wxDIR\_IGNORE}. diff --git a/include/wx/dir.h b/include/wx/dir.h index 1e32ce38a5..32c6c014fc 100644 --- a/include/wx/dir.h +++ b/include/wx/dir.h @@ -54,13 +54,25 @@ class WXDLLEXPORT wxDirTraverser public: // called for each file found by wxDir::Traverse() // - // return wxDIR_STOP or wxDIR_CONTINUE from here + // return wxDIR_STOP or wxDIR_CONTINUE from here (wxDIR_IGNORE doesn't + // make sense) virtual wxDirTraverseResult OnFile(const wxString& filename) = 0; // called for each directory found by wxDir::Traverse() // // return one of the enum elements defined above virtual wxDirTraverseResult OnDir(const wxString& dirname) = 0; + + // called for each directory which we couldn't open during our traversal + // of the directory tyree + // + // this method can also return either wxDIR_STOP, wxDIR_IGNORE or + // wxDIR_CONTINUE but the latter is treated specially: it means to retry + // opening the directory and so may lead to infinite loop if it is + // returned unconditionally, be careful with this! + // + // the base class version always returns wxDIR_IGNORE + virtual wxDirTraverseResult OnOpenError(const wxString& dirname); }; // ---------------------------------------------------------------------------- diff --git a/src/common/dircmn.cpp b/src/common/dircmn.cpp index dc0b24bbc1..2012e5560a 100644 --- a/src/common/dircmn.cpp +++ b/src/common/dircmn.cpp @@ -43,6 +43,16 @@ // implementation // ============================================================================ +// ---------------------------------------------------------------------------- +// wxDirTraverser +// ---------------------------------------------------------------------------- + +wxDirTraverseResult +wxDirTraverser::OnOpenError(const wxString& WXUNUSED(dirname)) +{ + return wxDIR_IGNORE; +} + // ---------------------------------------------------------------------------- // wxDir::HasFiles() and HasSubDirs() // ---------------------------------------------------------------------------- @@ -88,29 +98,75 @@ size_t wxDir::Traverse(wxDirTraverser& sink, if ( flags & wxDIR_DIRS ) { wxString dirname; - bool cont = GetFirst(&dirname, _T(""), wxDIR_DIRS | wxDIR_HIDDEN); - while ( cont ) + for ( bool cont = GetFirst(&dirname, _T(""), wxDIR_DIRS | wxDIR_HIDDEN); + cont; + cont = GetNext(&dirname) ) { - wxDirTraverseResult res = sink.OnDir(prefix + dirname); + const wxString fulldirname = prefix + dirname; - if ( res == wxDIR_STOP ) - break; - - if ( res == wxDIR_CONTINUE ) + switch ( sink.OnDir(fulldirname) ) { - wxDir subdir(prefix + dirname); - if ( subdir.IsOpened() ) - { - nFiles += subdir.Traverse(sink, filespec, flags); - } + default: + wxFAIL_MSG(_T("unexpected OnDir() return value") ); + // fall through + + case wxDIR_STOP: + cont = false; + break; + + case wxDIR_CONTINUE: + { + wxDir subdir; + + // don't give the error messages for the directories + // which we can't open: there can be all sorts of good + // reason for this (e.g. insufficient privileges) and + // this shouldn't be treated as an error -- instead + // let the user code decide what to do + bool ok; + do + { + wxLogNull noLog; + ok = subdir.Open(fulldirname); + if ( !ok ) + { + // ask the user code what to do + bool tryagain; + switch ( sink.OnOpenError(fulldirname) ) + { + default: + wxFAIL_MSG(_T("unexpected OnOpenError() return value") ); + // fall through + + case wxDIR_STOP: + cont = false; + // fall through + + case wxDIR_IGNORE: + tryagain = false; + break; + + case wxDIR_CONTINUE: + tryagain = true; + } + + if ( !tryagain ) + break; + } + } + while ( !ok ); + + if ( ok ) + { + nFiles += subdir.Traverse(sink, filespec, flags); + } + } + break; + + case wxDIR_IGNORE: + // nothing to do + ; } - else - { - wxASSERT_MSG( res == wxDIR_IGNORE, - _T("unexpected OnDir() return value") ); - } - - cont = GetNext(&dirname); } } -- 2.47.2