]>
git.saurik.com Git - wxWidgets.git/blob - src/common/fswatchercmn.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/fswatchercmn.cpp
3 // Purpose: wxMswFileSystemWatcher
4 // Author: Bartosz Bekier
7 // Copyright: (c) 2009 Bartosz Bekier <bartosz.bekier@gmail.com>
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
20 #include "wx/fswatcher.h"
21 #include "wx/private/fswatcher.h"
23 // ============================================================================
25 // ============================================================================
27 wxDEFINE_EVENT(wxEVT_FSWATCHER
, wxFileSystemWatcherEvent
);
29 static wxString
GetFSWEventChangeTypeName(int type
)
33 case wxFSW_EVENT_CREATE
:
35 case wxFSW_EVENT_DELETE
:
37 case wxFSW_EVENT_RENAME
:
39 case wxFSW_EVENT_MODIFY
:
41 case wxFSW_EVENT_ACCESS
:
45 // should never be reached!
46 wxFAIL_MSG("Unknown change type");
47 return "INVALID_TYPE";
51 // ============================================================================
52 // wxFileSystemWatcherEvent implementation
53 // ============================================================================
55 wxString
wxFileSystemWatcherEvent::ToString() const
57 return wxString::Format("FSW_EVT type=%d (%s) path='%s'", m_changeType
,
58 GetFSWEventChangeTypeName(m_changeType
), GetPath().GetFullPath());
62 // ============================================================================
63 // wxFileSystemWatcherEvent implementation
64 // ============================================================================
66 wxFileSystemWatcherBase::wxFileSystemWatcherBase() :
67 m_service(0), m_owner(this)
71 wxFileSystemWatcherBase::~wxFileSystemWatcherBase()
80 bool wxFileSystemWatcherBase::Add(const wxFileName
& path
, int events
)
82 wxFSWPathType type
= wxFSWPath_None
;
83 if ( path
.FileExists() )
85 type
= wxFSWPath_File
;
87 else if ( path
.DirExists() )
93 wxLogError(_("Can't monitor non-existent path \"%s\" for changes."),
98 return DoAdd(path
, events
, type
);
102 wxFileSystemWatcherBase::DoAdd(const wxFileName
& path
,
106 wxString canonical
= GetCanonicalPath(path
);
107 if (canonical
.IsEmpty())
110 wxCHECK_MSG(m_watches
.find(canonical
) == m_watches
.end(), false,
111 wxString::Format("Path '%s' is already watched", canonical
));
113 // adding a path in a platform specific way
114 wxFSWatchInfo
watch(canonical
, events
, type
);
115 if ( !m_service
->Add(watch
) )
118 // on success, add path to our 'watch-list'
119 wxFSWatchInfoMap::value_type
val(canonical
, watch
);
120 return m_watches
.insert(val
).second
;
123 bool wxFileSystemWatcherBase::Remove(const wxFileName
& path
)
125 // args validation & consistency checks
126 wxString canonical
= GetCanonicalPath(path
);
127 if (canonical
.IsEmpty())
130 wxFSWatchInfoMap::iterator it
= m_watches
.find(canonical
);
131 wxCHECK_MSG(it
!= m_watches
.end(), false,
132 wxString::Format("Path '%s' is not watched", canonical
));
134 // remove from watch-list
135 wxFSWatchInfo watch
= it
->second
;
138 // remove in a platform specific way
139 return m_service
->Remove(watch
);
142 bool wxFileSystemWatcherBase::AddTree(const wxFileName
& path
, int events
,
143 const wxString
& filter
)
145 if (!path
.DirExists())
148 // OPT could be optimised if we stored information about relationships
150 class AddTraverser
: public wxDirTraverser
153 AddTraverser(wxFileSystemWatcherBase
* watcher
, int events
) :
154 m_watcher(watcher
), m_events(events
)
158 // CHECK we choose which files to delegate to Add(), maybe we should pass
159 // all of them to Add() and let it choose? this is useful when adding a
160 // file to a dir that is already watched, then not only should we know
161 // about that, but Add() should also behave well then
162 virtual wxDirTraverseResult
OnFile(const wxString
& WXUNUSED(filename
))
164 return wxDIR_CONTINUE
;
167 virtual wxDirTraverseResult
OnDir(const wxString
& dirname
)
169 wxLogTrace(wxTRACE_FSWATCHER
, "--- AddTree adding '%s' ---",
171 // we add as much as possible and ignore errors
172 m_watcher
->Add(wxFileName(dirname
), m_events
);
173 return wxDIR_CONTINUE
;
177 wxFileSystemWatcherBase
* m_watcher
;
182 wxDir
dir(path
.GetFullPath());
183 AddTraverser
traverser(this, events
);
184 dir
.Traverse(traverser
, filter
);
189 bool wxFileSystemWatcherBase::RemoveTree(const wxFileName
& path
)
191 if (!path
.DirExists())
194 // OPT could be optimised if we stored information about relationships
196 class RemoveTraverser
: public wxDirTraverser
199 RemoveTraverser(wxFileSystemWatcherBase
* watcher
) :
204 virtual wxDirTraverseResult
OnFile(const wxString
& filename
)
206 m_watcher
->Remove(wxFileName(filename
));
207 return wxDIR_CONTINUE
;
210 virtual wxDirTraverseResult
OnDir(const wxString
& dirname
)
212 m_watcher
->RemoveTree(wxFileName(dirname
));
213 return wxDIR_CONTINUE
;
217 wxFileSystemWatcherBase
* m_watcher
;
220 wxDir
dir(path
.GetFullPath());
221 RemoveTraverser
traverser(this);
222 dir
.Traverse(traverser
);
227 bool wxFileSystemWatcherBase::RemoveAll()
229 m_service
->RemoveAll();
234 int wxFileSystemWatcherBase::GetWatchedPathsCount() const
236 return m_watches
.size();
239 int wxFileSystemWatcherBase::GetWatchedPaths(wxArrayString
* paths
) const
241 wxCHECK_MSG( paths
!= NULL
, -1, "Null array passed to retrieve paths");
243 wxFSWatchInfoMap::const_iterator it
= m_watches
.begin();
244 for ( ; it
!= m_watches
.end(); ++it
)
246 paths
->push_back(it
->first
);
249 return m_watches
.size();
252 #endif // wxUSE_FSWATCHER