]> git.saurik.com Git - wxWidgets.git/blame - src/common/fswatchercmn.cpp
Correct bug in the wxSpinCtrlGeneric sub-controls resizing.
[wxWidgets.git] / src / common / fswatchercmn.cpp
CommitLineData
6b8ef0b3
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: common/fswatchercmn.cpp
3// Purpose: wxMswFileSystemWatcher
4// Author: Bartosz Bekier
5// Created: 2009-05-26
6// RCS-ID: $Id$
7// Copyright: (c) 2009 Bartosz Bekier <bartosz.bekier@gmail.com>
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11// For compilers that support precompilation, includes "wx.h".
12#include "wx/wxprec.h"
13
14#ifdef __BORLANDC__
15 #pragma hdrstop
16#endif
17
18#if wxUSE_FSWATCHER
19
20#include "wx/fswatcher.h"
21#include "wx/private/fswatcher.h"
22
23// ============================================================================
24// helpers
25// ============================================================================
26
27wxDEFINE_EVENT(wxEVT_FSWATCHER, wxFileSystemWatcherEvent);
28
29static wxString GetFSWEventChangeTypeName(int type)
30{
31 switch (type)
32 {
33 case wxFSW_EVENT_CREATE:
34 return "CREATE";
35 case wxFSW_EVENT_DELETE:
36 return "DELETE";
37 case wxFSW_EVENT_RENAME:
38 return "RENAME";
39 case wxFSW_EVENT_MODIFY:
40 return "MODIFY";
41 case wxFSW_EVENT_ACCESS:
42 return "ACCESS";
43 }
44
45 // should never be reached!
46 wxFAIL_MSG("Unknown change type");
47 return "INVALID_TYPE";
48}
49
50
51// ============================================================================
52// wxFileSystemWatcherEvent implementation
53// ============================================================================
54
55wxString wxFileSystemWatcherEvent::ToString() const
56{
57 return wxString::Format("FSW_EVT type=%d (%s) path='%s'", m_changeType,
58 GetFSWEventChangeTypeName(m_changeType), GetPath().GetFullPath());
59}
60
61
62// ============================================================================
63// wxFileSystemWatcherEvent implementation
64// ============================================================================
65
66wxFileSystemWatcherBase::wxFileSystemWatcherBase() :
67 m_service(0), m_owner(this)
68{
69}
70
71wxFileSystemWatcherBase::~wxFileSystemWatcherBase()
72{
73 RemoveAll();
74 if (m_service)
75 {
76 delete m_service;
77 }
78}
79
80bool wxFileSystemWatcherBase::Add(const wxFileName& path, int events)
81{
82 // args validation & consistency checks
83 if (!path.FileExists() && !path.DirExists())
84 return false;
85
86 wxString canonical = GetCanonicalPath(path);
87 if (canonical.IsEmpty())
88 return false;
89
90 wxCHECK_MSG(m_watches.find(canonical) == m_watches.end(), false,
91 wxString::Format("Path '%s' is already watched", canonical));
92
93 // adding a path in a platform specific way
94 wxFSWatchInfo watch(canonical, events);
95 if ( !m_service->Add(watch) )
96 return false;
97
98 // on success, add path to our 'watch-list'
99 wxFSWatchInfoMap::value_type val(canonical, watch);
100 return m_watches.insert(val).second;
101}
102
103bool wxFileSystemWatcherBase::Remove(const wxFileName& path)
104{
105 // args validation & consistency checks
106 wxString canonical = GetCanonicalPath(path);
107 if (canonical.IsEmpty())
108 return false;
109
110 wxFSWatchInfoMap::iterator it = m_watches.find(canonical);
111 wxCHECK_MSG(it != m_watches.end(), false,
112 wxString::Format("Path '%s' is not watched", canonical));
113
114 // remove from watch-list
115 wxFSWatchInfo watch = it->second;
116 m_watches.erase(it);
117
118 // remove in a platform specific way
119 return m_service->Remove(watch);
120}
121
122bool wxFileSystemWatcherBase::AddTree(const wxFileName& path, int events,
123 const wxString& filter)
124{
125 if (!path.DirExists())
126 return false;
127
128 // OPT could be optimised if we stored information about relationships
129 // between paths
130 class AddTraverser : public wxDirTraverser
131 {
132 public:
133 AddTraverser(wxFileSystemWatcherBase* watcher, int events) :
134 m_watcher(watcher), m_events(events)
135 {
136 }
137
138 // CHECK we choose which files to delegate to Add(), maybe we should pass
139 // all of them to Add() and let it choose? this is useful when adding a
140 // file to a dir that is already watched, then not only should we know
141 // about that, but Add() should also behave well then
142 virtual wxDirTraverseResult OnFile(const wxString& WXUNUSED(filename))
143 {
144 return wxDIR_CONTINUE;
145 }
146
147 virtual wxDirTraverseResult OnDir(const wxString& dirname)
148 {
149 wxLogTrace(wxTRACE_FSWATCHER, "--- AddTree adding '%s' ---",
150 dirname);
151 // we add as much as possible and ignore errors
152 m_watcher->Add(wxFileName(dirname), m_events);
153 return wxDIR_CONTINUE;
154 }
155
156 private:
157 wxFileSystemWatcherBase* m_watcher;
158 int m_events;
159 wxString m_filter;
160 };
161
162 wxDir dir(path.GetFullPath());
163 AddTraverser traverser(this, events);
164 dir.Traverse(traverser, filter);
165
166 return true;
167}
168
169bool wxFileSystemWatcherBase::RemoveTree(const wxFileName& path)
170{
171 if (!path.DirExists())
172 return false;
173
174 // OPT could be optimised if we stored information about relationships
175 // between paths
176 class RemoveTraverser : public wxDirTraverser
177 {
178 public:
179 RemoveTraverser(wxFileSystemWatcherBase* watcher) :
180 m_watcher(watcher)
181 {
182 }
183
184 virtual wxDirTraverseResult OnFile(const wxString& filename)
185 {
186 m_watcher->Remove(wxFileName(filename));
187 return wxDIR_CONTINUE;
188 }
189
190 virtual wxDirTraverseResult OnDir(const wxString& dirname)
191 {
192 m_watcher->RemoveTree(wxFileName(dirname));
193 return wxDIR_CONTINUE;
194 }
195
196 private:
197 wxFileSystemWatcherBase* m_watcher;
198 };
199
200 wxDir dir(path.GetFullPath());
201 RemoveTraverser traverser(this);
202 dir.Traverse(traverser);
203
204 return true;
205}
206
207bool wxFileSystemWatcherBase::RemoveAll()
208{
209 m_service->RemoveAll();
210 m_watches.clear();
211 return true;
212}
213
214int wxFileSystemWatcherBase::GetWatchedPathsCount() const
215{
216 return m_watches.size();
217}
218
219int wxFileSystemWatcherBase::GetWatchedPaths(wxArrayString* paths) const
220{
221 wxCHECK_MSG( paths != NULL, -1, "Null array passed to retrieve paths");
222
223 wxFSWatchInfoMap::const_iterator it = m_watches.begin();
224 for ( ; it != m_watches.end(); ++it)
225 {
226 paths->push_back(it->first);
227 }
228
229 return m_watches.size();
230}
231
232#endif // wxUSE_FSWATCHER