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