1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/fswatcher.h
3 // Purpose: wxFileSystemWatcherBase
4 // Author: Bartosz Bekier
6 // Copyright: (c) 2009 Bartosz Bekier <bartosz.bekier@gmail.com>
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 #ifndef _WX_FSWATCHER_BASE_H_
11 #define _WX_FSWATCHER_BASE_H_
19 #include "wx/evtloop.h"
20 #include "wx/filename.h"
22 #include "wx/hashmap.h"
24 #define wxTRACE_FSWATCHER "fswatcher"
26 // ----------------------------------------------------------------------------
27 // wxFileSystemWatcherEventType & wxFileSystemWatcherEvent
28 // ----------------------------------------------------------------------------
31 * Possible types of file system events.
32 * This is a subset that will work fine an all platforms (actually, we will
33 * see how it works on Mac).
35 * We got 2 types of error events:
36 * - warning: these are not fatal and further events can still be generated
37 * - error: indicates fatal error and causes that no more events will happen
41 wxFSW_EVENT_CREATE
= 0x01,
42 wxFSW_EVENT_DELETE
= 0x02,
43 wxFSW_EVENT_RENAME
= 0x04,
44 wxFSW_EVENT_MODIFY
= 0x08,
45 wxFSW_EVENT_ACCESS
= 0x10,
46 wxFSW_EVENT_ATTRIB
= 0x20, // Currently this is wxGTK-only
49 wxFSW_EVENT_WARNING
= 0x40,
50 wxFSW_EVENT_ERROR
= 0x80,
51 wxFSW_EVENT_ALL
= wxFSW_EVENT_CREATE
| wxFSW_EVENT_DELETE
|
52 wxFSW_EVENT_RENAME
| wxFSW_EVENT_MODIFY
|
53 wxFSW_EVENT_ACCESS
| wxFSW_EVENT_ATTRIB
|
54 wxFSW_EVENT_WARNING
| wxFSW_EVENT_ERROR
56 ,wxFSW_EVENT_UNMOUNT
= 0x2000
60 // Type of the path watched, used only internally for now.
63 wxFSWPath_None
, // Invalid value for an initialized watch.
64 wxFSWPath_File
, // Plain file.
65 wxFSWPath_Dir
, // Watch a directory and the files in it.
66 wxFSWPath_Tree
// Watch a directory and all its children recursively.
71 * Event containing information about file system change.
73 class WXDLLIMPEXP_FWD_BASE wxFileSystemWatcherEvent
;
74 wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_BASE
, wxEVT_FSWATCHER
,
75 wxFileSystemWatcherEvent
);
77 class WXDLLIMPEXP_BASE wxFileSystemWatcherEvent
: public wxEvent
80 wxFileSystemWatcherEvent(int changeType
= 0, int watchid
= wxID_ANY
) :
81 wxEvent(watchid
, wxEVT_FSWATCHER
),
82 m_changeType(changeType
)
86 wxFileSystemWatcherEvent(int changeType
, const wxString
& errorMsg
,
87 int watchid
= wxID_ANY
) :
88 wxEvent(watchid
, wxEVT_FSWATCHER
),
89 m_changeType(changeType
), m_errorMsg(errorMsg
)
93 wxFileSystemWatcherEvent(int changeType
,
94 const wxFileName
& path
, const wxFileName
& newPath
,
95 int watchid
= wxID_ANY
) :
96 wxEvent(watchid
, wxEVT_FSWATCHER
),
97 m_changeType(changeType
), m_path(path
), m_newPath(newPath
)
102 * Returns the path at which the event occurred.
104 const wxFileName
& GetPath() const
110 * Sets the path at which the event occurred
112 void SetPath(const wxFileName
& path
)
118 * In case of rename(move?) events, returns the new path related to the
119 * event. The "new" means newer in the sense of time. In case of other
120 * events it returns the same path as GetPath().
122 const wxFileName
& GetNewPath() const
128 * Sets the new path related to the event. See above.
130 void SetNewPath(const wxFileName
& path
)
136 * Returns the type of file system event that occurred.
138 int GetChangeType() const
143 virtual wxEvent
* Clone() const
145 wxFileSystemWatcherEvent
* evt
= new wxFileSystemWatcherEvent(*this);
146 evt
->m_errorMsg
= m_errorMsg
.Clone();
147 evt
->m_path
= wxFileName(m_path
.GetFullPath().Clone());
148 evt
->m_newPath
= wxFileName(m_newPath
.GetFullPath().Clone());
152 virtual wxEventCategory
GetEventCategory() const
154 // TODO this has to be merged with "similar" categories and changed
155 return wxEVT_CATEGORY_UNKNOWN
;
159 * Returns if this error is an error event
163 return (m_changeType
& (wxFSW_EVENT_ERROR
| wxFSW_EVENT_WARNING
)) != 0;
166 wxString
GetErrorDescription() const
172 * Returns a wxString describing an event useful for debugging or testing
174 wxString
ToString() const;
179 wxFileName m_newPath
;
182 DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxFileSystemWatcherEvent
)
185 typedef void (wxEvtHandler::*wxFileSystemWatcherEventFunction
)
186 (wxFileSystemWatcherEvent
&);
188 #define wxFileSystemWatcherEventHandler(func) \
189 wxEVENT_HANDLER_CAST(wxFileSystemWatcherEventFunction, func)
191 #define EVT_FSWATCHER(winid, func) \
192 wx__DECLARE_EVT1(wxEVT_FSWATCHER, winid, wxFileSystemWatcherEventHandler(func))
194 // ----------------------------------------------------------------------------
195 // wxFileSystemWatcherBase: interface for wxFileSystemWatcher
196 // ----------------------------------------------------------------------------
198 // Simple container to store information about one watched path.
203 m_events(-1), m_type(wxFSWPath_None
), m_refcount(-1)
207 wxFSWatchInfo(const wxString
& path
,
210 const wxString
& filespec
= wxString()) :
211 m_path(path
), m_filespec(filespec
), m_events(events
), m_type(type
),
216 const wxString
& GetPath() const
221 const wxString
& GetFilespec() const { return m_filespec
; }
228 wxFSWPathType
GetType() const
233 // Reference counting of watch entries is used to avoid watching the same
234 // file system path multiple times (this can happen even accidentally, e.g.
235 // when you have a recursive watch and then decide to watch some file or
236 // directory under it separately).
244 wxASSERT_MSG( m_refcount
> 0, wxS("Trying to decrement a zero count") );
250 wxString m_filespec
; // For tree watches, holds any filespec to apply
252 wxFSWPathType m_type
;
256 WX_DECLARE_STRING_HASH_MAP(wxFSWatchInfo
, wxFSWatchInfoMap
);
259 * Encapsulation of platform-specific file system event mechanism
261 class wxFSWatcherImpl
;
264 * Main entry point for clients interested in file system events.
265 * Defines interface that can be used to receive that kind of events.
267 class WXDLLIMPEXP_BASE wxFileSystemWatcherBase
: public wxEvtHandler
270 wxFileSystemWatcherBase();
272 virtual ~wxFileSystemWatcherBase();
275 * Adds path to currently watched files. Any events concerning this
276 * particular path will be sent to handler. Optionally a filter can be
277 * specified to receive only events of particular type.
279 * Please note that when adding a dir, immediate children will be watched
282 virtual bool Add(const wxFileName
& path
, int events
= wxFSW_EVENT_ALL
);
285 * Like above, but recursively adds every file/dir in the tree rooted in
286 * path. Additionally a file mask can be specified to include only files
287 * of particular type.
289 virtual bool AddTree(const wxFileName
& path
, int events
= wxFSW_EVENT_ALL
,
290 const wxString
& filespec
= wxEmptyString
);
293 * Removes path from the list of watched paths.
295 virtual bool Remove(const wxFileName
& path
);
298 * Same as above, but also removes every file belonging to the tree rooted
301 virtual bool RemoveTree(const wxFileName
& path
);
304 * Clears the list of currently watched paths.
306 virtual bool RemoveAll();
309 * Returns the number of watched paths
311 int GetWatchedPathsCount() const;
314 * Retrevies all watched paths and places them in wxArrayString. Returns
315 * the number of paths.
317 * TODO think about API here: we need to return more information (like is
318 * the path watched recursively)
320 int GetWatchedPaths(wxArrayString
* paths
) const;
322 wxEvtHandler
* GetOwner() const
327 void SetOwner(wxEvtHandler
* handler
)
336 // This is a semi-private function used by wxWidgets itself only.
338 // Delegates the real work of adding the path to wxFSWatcherImpl::Add() and
339 // updates m_watches if the new path was successfully added.
340 bool AddAny(const wxFileName
& path
, int events
, wxFSWPathType type
,
341 const wxString
& filespec
= wxString());
345 static wxString
GetCanonicalPath(const wxFileName
& path
)
347 wxFileName path_copy
= wxFileName(path
);
348 if ( !path_copy
.Normalize() )
350 wxFAIL_MSG(wxString::Format("Unable to normalize path '%s'",
351 path
.GetFullPath()));
352 return wxEmptyString
;
355 return path_copy
.GetFullPath();
359 wxFSWatchInfoMap m_watches
; // path=>wxFSWatchInfo map
360 wxFSWatcherImpl
* m_service
; // file system events service
361 wxEvtHandler
* m_owner
; // handler for file system events
363 friend class wxFSWatcherImpl
;
366 // include the platform specific file defining wxFileSystemWatcher
367 // inheriting from wxFileSystemWatcherBase
370 #include "wx/unix/fswatcher_inotify.h"
371 #define wxFileSystemWatcher wxInotifyFileSystemWatcher
372 #elif defined(wxHAS_KQUEUE)
373 #include "wx/unix/fswatcher_kqueue.h"
374 #define wxFileSystemWatcher wxKqueueFileSystemWatcher
375 #elif defined(__WINDOWS__)
376 #include "wx/msw/fswatcher.h"
377 #define wxFileSystemWatcher wxMSWFileSystemWatcher
379 #include "wx/generic/fswatcher.h"
380 #define wxFileSystemWatcher wxPollingFileSystemWatcher
383 #endif // wxUSE_FSWATCHER
385 #endif /* _WX_FSWATCHER_BASE_H_ */