]> git.saurik.com Git - wxWidgets.git/blame - include/wx/fswatcher.h
Better name for wxXmlResource::GetDirection() argument.
[wxWidgets.git] / include / wx / fswatcher.h
CommitLineData
6b8ef0b3
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: wx/fswatcher.h
3// Purpose: wxFileSystemWatcherBase
4// Author: Bartosz Bekier
5// Created: 2009-05-23
6b8ef0b3
VZ
6// Copyright: (c) 2009 Bartosz Bekier <bartosz.bekier@gmail.com>
7// Licence: wxWindows licence
8/////////////////////////////////////////////////////////////////////////////
9
10#ifndef _WX_FSWATCHER_BASE_H_
11#define _WX_FSWATCHER_BASE_H_
12
13#include "wx/defs.h"
14
15#if wxUSE_FSWATCHER
16
17#include "wx/log.h"
18#include "wx/event.h"
19#include "wx/evtloop.h"
20#include "wx/filename.h"
21#include "wx/dir.h"
22#include "wx/hashmap.h"
23
24#define wxTRACE_FSWATCHER "fswatcher"
25
26// ----------------------------------------------------------------------------
27// wxFileSystemWatcherEventType & wxFileSystemWatcherEvent
28// ----------------------------------------------------------------------------
29
30/**
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).
34 *
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
38 */
39enum
40{
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,
f31f9900 46 wxFSW_EVENT_ATTRIB = 0x20, // Currently this is wxGTK-only
6b8ef0b3
VZ
47
48 // error events
f31f9900
VZ
49 wxFSW_EVENT_WARNING = 0x40,
50 wxFSW_EVENT_ERROR = 0x80,
6b8ef0b3
VZ
51 wxFSW_EVENT_ALL = wxFSW_EVENT_CREATE | wxFSW_EVENT_DELETE |
52 wxFSW_EVENT_RENAME | wxFSW_EVENT_MODIFY |
f31f9900 53 wxFSW_EVENT_ACCESS | wxFSW_EVENT_ATTRIB |
6b8ef0b3 54 wxFSW_EVENT_WARNING | wxFSW_EVENT_ERROR
092e08a8
VZ
55#ifdef wxHAS_INOTIFY
56 ,wxFSW_EVENT_UNMOUNT = 0x2000
57#endif
6b8ef0b3
VZ
58};
59
f8d37148
VZ
60// Type of the path watched, used only internally for now.
61enum wxFSWPathType
62{
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.
67};
68
69
6b8ef0b3
VZ
70/**
71 * Event containing information about file system change.
72 */
73class WXDLLIMPEXP_FWD_BASE wxFileSystemWatcherEvent;
74wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_BASE, wxEVT_FSWATCHER,
75 wxFileSystemWatcherEvent);
76
77class WXDLLIMPEXP_BASE wxFileSystemWatcherEvent: public wxEvent
78{
79public:
3fc2ee04 80 wxFileSystemWatcherEvent(int changeType = 0, int watchid = wxID_ANY) :
6b8ef0b3
VZ
81 wxEvent(watchid, wxEVT_FSWATCHER),
82 m_changeType(changeType)
83 {
84 }
85
86 wxFileSystemWatcherEvent(int changeType, const wxString& errorMsg,
87 int watchid = wxID_ANY) :
88 wxEvent(watchid, wxEVT_FSWATCHER),
89 m_changeType(changeType), m_errorMsg(errorMsg)
90 {
91 }
92
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)
98 {
99 }
100
101 /**
102 * Returns the path at which the event occurred.
103 */
104 const wxFileName& GetPath() const
105 {
106 return m_path;
107 }
108
109 /**
110 * Sets the path at which the event occurred
111 */
112 void SetPath(const wxFileName& path)
113 {
114 m_path = path;
115 }
116
117 /**
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().
121 */
122 const wxFileName& GetNewPath() const
123 {
124 return m_newPath;
125 }
126
127 /**
128 * Sets the new path related to the event. See above.
129 */
130 void SetNewPath(const wxFileName& path)
131 {
132 m_newPath = path;
133 }
134
135 /**
136 * Returns the type of file system event that occurred.
137 */
138 int GetChangeType() const
139 {
140 return m_changeType;
141 }
142
143 virtual wxEvent* Clone() const
144 {
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());
149 return evt;
150 }
151
152 virtual wxEventCategory GetEventCategory() const
153 {
05e66a70 154 // TODO this has to be merged with "similar" categories and changed
6b8ef0b3
VZ
155 return wxEVT_CATEGORY_UNKNOWN;
156 }
157
158 /**
159 * Returns if this error is an error event
160 */
161 bool IsError() const
162 {
163 return (m_changeType & (wxFSW_EVENT_ERROR | wxFSW_EVENT_WARNING)) != 0;
164 }
165
166 wxString GetErrorDescription() const
167 {
168 return m_errorMsg;
169 }
170
171 /**
172 * Returns a wxString describing an event useful for debugging or testing
173 */
174 wxString ToString() const;
175
176protected:
177 int m_changeType;
178 wxFileName m_path;
179 wxFileName m_newPath;
180 wxString m_errorMsg;
3fc2ee04
RD
181private:
182 DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxFileSystemWatcherEvent)
6b8ef0b3
VZ
183};
184
185typedef void (wxEvtHandler::*wxFileSystemWatcherEventFunction)
186 (wxFileSystemWatcherEvent&);
187
188#define wxFileSystemWatcherEventHandler(func) \
189 wxEVENT_HANDLER_CAST(wxFileSystemWatcherEventFunction, func)
190
70ef16f4
VZ
191#define EVT_FSWATCHER(winid, func) \
192 wx__DECLARE_EVT1(wxEVT_FSWATCHER, winid, wxFileSystemWatcherEventHandler(func))
6b8ef0b3
VZ
193
194// ----------------------------------------------------------------------------
195// wxFileSystemWatcherBase: interface for wxFileSystemWatcher
196// ----------------------------------------------------------------------------
197
f8d37148 198// Simple container to store information about one watched path.
6b8ef0b3
VZ
199class wxFSWatchInfo
200{
201public:
202 wxFSWatchInfo() :
76cfd1bf 203 m_events(-1), m_type(wxFSWPath_None), m_refcount(-1)
6b8ef0b3
VZ
204 {
205 }
206
227dee95
VZ
207 wxFSWatchInfo(const wxString& path,
208 int events,
209 wxFSWPathType type,
210 const wxString& filespec = wxString()) :
76cfd1bf
VZ
211 m_path(path), m_filespec(filespec), m_events(events), m_type(type),
212 m_refcount(1)
6b8ef0b3
VZ
213 {
214 }
215
216 const wxString& GetPath() const
217 {
218 return m_path;
219 }
220
227dee95
VZ
221 const wxString& GetFilespec() const { return m_filespec; }
222
6b8ef0b3
VZ
223 int GetFlags() const
224 {
225 return m_events;
226 }
227
f8d37148
VZ
228 wxFSWPathType GetType() const
229 {
230 return m_type;
231 }
232
76cfd1bf
VZ
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).
237 int IncRef()
238 {
239 return ++m_refcount;
240 }
241
242 int DecRef()
243 {
244 wxASSERT_MSG( m_refcount > 0, wxS("Trying to decrement a zero count") );
245 return --m_refcount;
246 }
247
6b8ef0b3
VZ
248protected:
249 wxString m_path;
227dee95 250 wxString m_filespec; // For tree watches, holds any filespec to apply
6b8ef0b3 251 int m_events;
f8d37148 252 wxFSWPathType m_type;
76cfd1bf 253 int m_refcount;
6b8ef0b3
VZ
254};
255
256WX_DECLARE_STRING_HASH_MAP(wxFSWatchInfo, wxFSWatchInfoMap);
257
258/**
259 * Encapsulation of platform-specific file system event mechanism
260 */
261class wxFSWatcherImpl;
262
263/**
264 * Main entry point for clients interested in file system events.
265 * Defines interface that can be used to receive that kind of events.
266 */
267class WXDLLIMPEXP_BASE wxFileSystemWatcherBase: public wxEvtHandler
268{
269public:
270 wxFileSystemWatcherBase();
271
272 virtual ~wxFileSystemWatcherBase();
273
274 /**
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.
278 *
279 * Please note that when adding a dir, immediate children will be watched
280 * as well.
281 */
282 virtual bool Add(const wxFileName& path, int events = wxFSW_EVENT_ALL);
283
284 /**
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.
288 */
289 virtual bool AddTree(const wxFileName& path, int events = wxFSW_EVENT_ALL,
227dee95 290 const wxString& filespec = wxEmptyString);
6b8ef0b3
VZ
291
292 /**
293 * Removes path from the list of watched paths.
294 */
295 virtual bool Remove(const wxFileName& path);
296
297 /**
298 * Same as above, but also removes every file belonging to the tree rooted
299 * at path.
300 */
301 virtual bool RemoveTree(const wxFileName& path);
302
303 /**
304 * Clears the list of currently watched paths.
305 */
306 virtual bool RemoveAll();
307
308 /**
309 * Returns the number of watched paths
310 */
311 int GetWatchedPathsCount() const;
312
313 /**
314 * Retrevies all watched paths and places them in wxArrayString. Returns
315 * the number of paths.
316 *
317 * TODO think about API here: we need to return more information (like is
318 * the path watched recursively)
319 */
320 int GetWatchedPaths(wxArrayString* paths) const;
321
322 wxEvtHandler* GetOwner() const
323 {
324 return m_owner;
325 }
326
327 void SetOwner(wxEvtHandler* handler)
328 {
329 if (!handler)
330 m_owner = this;
331 else
332 m_owner = handler;
333 }
334
3a2b3701
VZ
335
336 // This is a semi-private function used by wxWidgets itself only.
337 //
338 // Delegates the real work of adding the path to wxFSWatcherImpl::Add() and
339 // updates m_watches if the new path was successfully added.
227dee95
VZ
340 bool AddAny(const wxFileName& path, int events, wxFSWPathType type,
341 const wxString& filespec = wxString());
3a2b3701 342
6b8ef0b3
VZ
343protected:
344
345 static wxString GetCanonicalPath(const wxFileName& path)
346 {
347 wxFileName path_copy = wxFileName(path);
348 if ( !path_copy.Normalize() )
349 {
350 wxFAIL_MSG(wxString::Format("Unable to normalize path '%s'",
351 path.GetFullPath()));
352 return wxEmptyString;
353 }
354
355 return path_copy.GetFullPath();
356 }
357
f8d37148 358
6b8ef0b3
VZ
359 wxFSWatchInfoMap m_watches; // path=>wxFSWatchInfo map
360 wxFSWatcherImpl* m_service; // file system events service
361 wxEvtHandler* m_owner; // handler for file system events
362
363 friend class wxFSWatcherImpl;
364};
365
366// include the platform specific file defining wxFileSystemWatcher
367// inheriting from wxFileSystemWatcherBase
368
369#ifdef wxHAS_INOTIFY
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
d98a58c5 375#elif defined(__WINDOWS__)
6b8ef0b3
VZ
376 #include "wx/msw/fswatcher.h"
377 #define wxFileSystemWatcher wxMSWFileSystemWatcher
378#else
379 #include "wx/generic/fswatcher.h"
380 #define wxFileSystemWatcher wxPollingFileSystemWatcher
381#endif
382
383#endif // wxUSE_FSWATCHER
384
385#endif /* _WX_FSWATCHER_BASE_H_ */