// Purpose: wxMswFileSystemWatcher
// Author: Bartosz Bekier
// Created: 2009-05-26
-// RCS-ID: $Id$
// Copyright: (c) 2009 Bartosz Bekier <bartosz.bekier@gmail.com>
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
return "MODIFY";
case wxFSW_EVENT_ACCESS:
return "ACCESS";
+ case wxFSW_EVENT_ATTRIB: // Currently this is wxGTK-only
+ return "ATTRIBUTE";
+#ifdef wxHAS_INOTIFY
+ case wxFSW_EVENT_UNMOUNT: // Currently this is wxGTK-only
+ return "UNMOUNT";
+#endif
+ case wxFSW_EVENT_WARNING:
+ return "WARNING";
+ case wxFSW_EVENT_ERROR:
+ return "ERROR";
}
// should never be reached!
// wxFileSystemWatcherEvent implementation
// ============================================================================
+IMPLEMENT_DYNAMIC_CLASS(wxFileSystemWatcherEvent, wxEvent);
+
wxString wxFileSystemWatcherEvent::ToString() const
{
return wxString::Format("FSW_EVT type=%d (%s) path='%s'", m_changeType,
}
else
{
- wxLogError(_("Can't monitor non-existent path \"%s\" for changes."),
+ // Don't overreact to being passed a non-existent item. It may have
+ // only just been deleted, in which case doing nothing is correct
+ wxLogTrace(wxTRACE_FSWATCHER,
+ "Can't monitor non-existent path \"%s\" for changes.",
path.GetFullPath());
return false;
}
if ( it == m_watches.end() )
{
wxFSWatchInfoMap::value_type val(canonical, watch);
- m_watches.insert(val).second;
+ m_watches.insert(val);
}
else
{
{
}
- // CHECK we choose which files to delegate to Add(), maybe we should pass
- // all of them to Add() and let it choose? this is useful when adding a
- // file to a dir that is already watched, then not only should we know
- // about that, but Add() should also behave well then
- virtual wxDirTraverseResult OnFile(const wxString& filename)
+ virtual wxDirTraverseResult OnFile(const wxString& WXUNUSED(filename))
{
- if ( m_watcher->AddAny(wxFileName::FileName(filename),
- m_events, wxFSWPath_File) )
- {
- wxLogTrace(wxTRACE_FSWATCHER,
- "--- AddTree adding file '%s' ---", filename);
- }
+ // There is no need to watch individual files as we watch the
+ // parent directory which will notify us about any changes in them.
return wxDIR_CONTINUE;
}
virtual wxDirTraverseResult OnDir(const wxString& dirname)
{
- // We can't currently watch only the files with the given filespec
- // in the subdirectories so we only watch subdirectories at all if
- // we want to watch everything.
- if ( m_filespec.empty() )
+ if ( m_watcher->AddAny(wxFileName::DirName(dirname),
+ m_events, wxFSWPath_Tree, m_filespec) )
{
- if ( m_watcher->AddAny(wxFileName::DirName(dirname),
- m_events, wxFSWPath_Dir) )
- {
- wxLogTrace(wxTRACE_FSWATCHER,
- "--- AddTree adding directory '%s' ---", dirname);
- }
+ wxLogTrace(wxTRACE_FSWATCHER,
+ "--- AddTree adding directory '%s' ---", dirname);
}
return wxDIR_CONTINUE;
}
};
wxDir dir(path.GetFullPath());
+ // Prevent asserts or infinite loops in trees containing symlinks
+ int flags = wxDIR_DIRS;
+ if ( !path.ShouldFollowLink() )
+ {
+ flags |= wxDIR_NO_FOLLOW;
+ }
AddTraverser traverser(this, events, filespec);
- dir.Traverse(traverser, filespec);
+ dir.Traverse(traverser, filespec, flags);
// Add the path itself explicitly as Traverse() doesn't return it.
- AddAny(path.GetPathWithSep(), events, wxFSWPath_Dir, filespec);
+ AddAny(path.GetPathWithSep(), events, wxFSWPath_Tree, filespec);
return true;
}
{
}
- virtual wxDirTraverseResult OnFile(const wxString& filename)
+ virtual wxDirTraverseResult OnFile(const wxString& WXUNUSED(filename))
{
- m_watcher->Remove(wxFileName(filename));
+ // We never watch the individual files when watching the tree, so
+ // nothing to do here.
return wxDIR_CONTINUE;
}
virtual wxDirTraverseResult OnDir(const wxString& dirname)
{
- // Currently the subdirectories would have been added only if there
- // is no filespec.
- //
- // Notice that we still need to recurse into them even if we're
- // using a filespec because they can contain files matching it.
- if ( m_filespec.empty() )
- {
- m_watcher->Remove(wxFileName::DirName(dirname));
- }
-
+ m_watcher->Remove(wxFileName::DirName(dirname));
return wxDIR_CONTINUE;
}
#endif // __WINDOWS__
wxDir dir(path.GetFullPath());
+ // AddTree() might have used the wxDIR_NO_FOLLOW to prevent asserts or
+ // infinite loops in trees containing symlinks. We need to do the same
+ // or we'll try to remove unwatched items. Let's hope the caller used
+ // the same ShouldFollowLink() setting as in AddTree()...
+ int flags = wxDIR_DIRS;
+ if ( !path.ShouldFollowLink() )
+ {
+ flags |= wxDIR_NO_FOLLOW;
+ }
RemoveTraverser traverser(this, filespec);
- dir.Traverse(traverser, filespec);
+ dir.Traverse(traverser, filespec, flags);
// As in AddTree() above, handle the path itself explicitly.
Remove(path);