]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/fswatcher.cpp
Preserve client data pointers when setting bitmaps in wxBitmapComboBox.
[wxWidgets.git] / src / msw / fswatcher.cpp
index cfe3bfc224bf7451edd7140035505e75b49add31..1c33ebac6e7d4b7f04f09231c6eeae817c2bca00 100644 (file)
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        msw/fswatcher.cpp
+// Name:        src/msw/fswatcher.cpp
 // Purpose:     wxMSWFileSystemWatcher
 // Author:      Bartosz Bekier
 // Created:     2009-05-26
@@ -107,9 +107,10 @@ bool wxFSWatcherImplMSW::DoAdd(wxSharedPtr<wxFSWatchEntryMSW> watch)
     return m_iocp.Add(watch);
 }
 
-bool wxFSWatcherImplMSW::DoRemove(wxSharedPtr<wxFSWatchEntryMSW> watch)
+bool
+wxFSWatcherImplMSW::DoRemove(wxSharedPtr<wxFSWatchEntryMSW> watch)
 {
-    return true;
+    return m_iocp.ScheduleForRemoval(watch);
 }
 
 // TODO ensuring that we have not already set watch for this handle/dir?
@@ -135,9 +136,32 @@ void wxFSWatcherImplMSW::SendEvent(wxFileSystemWatcherEvent& evt)
 
 bool wxFSWatcherImplMSW::DoSetUpWatch(wxFSWatchEntryMSW& watch)
 {
+    BOOL bWatchSubtree = FALSE;
+
+    switch ( watch.GetType() )
+    {
+        case wxFSWPath_File:
+            wxLogError(_("Monitoring individual files for changes is not "
+                         "supported currently."));
+            return false;
+
+        case wxFSWPath_Dir:
+            bWatchSubtree = FALSE;
+            break;
+
+        case wxFSWPath_Tree:
+            bWatchSubtree = TRUE;
+            break;
+
+        case wxFSWPath_None:
+            wxFAIL_MSG( "Invalid watch type." );
+            return false;
+    }
+
     int flags = Watcher2NativeFlags(watch.GetFlags());
     int ret = ReadDirectoryChangesW(watch.GetHandle(), watch.GetBuffer(),
-                                    wxFSWatchEntryMSW::BUFFER_SIZE, TRUE,
+                                    wxFSWatchEntryMSW::BUFFER_SIZE,
+                                    bWatchSubtree,
                                     flags, NULL,
                                     watch.GetOverlapped(), NULL);
     if (!ret)
@@ -215,6 +239,11 @@ bool wxIOCPThread::ReadEvents()
     wxLogTrace( wxTRACE_FSWATCHER, "[iocp] Read entry: path='%s'",
                 watch->GetPath());
 
+    // First check if we're still interested in this watch, we could have
+    // removed it in the meanwhile.
+    if ( m_iocp->CompleteRemoval(watch) )
+        return true;
+
     // extract events from buffer info our vector container
     wxVector<wxEventProcessingData> events;
     const char* memory = static_cast<const char*>(watch->GetBuffer());
@@ -287,8 +316,12 @@ void wxIOCPThread::ProcessNativeEvents(wxVector<wxEventProcessingData>& events)
             // CHECK I heard that returned path can be either in short on long
             // form...need to account for that!
             wxFileName path = GetEventPath(*watch, e);
-            wxFileSystemWatcherEvent event(flags, path, path);
-            SendEvent(event);
+            // For files, check that it matches any filespec
+            if ( m_service->MatchesFilespec(path, watch->GetFilespec()) )
+            {
+                wxFileSystemWatcherEvent event(flags, path, path);
+                SendEvent(event);
+            }
         }
     }
 }
@@ -379,4 +412,30 @@ bool wxMSWFileSystemWatcher::Init()
     return ret;
 }
 
+bool
+wxMSWFileSystemWatcher::AddTree(const wxFileName& path,
+                                int events,
+                                const wxString& filter)
+{
+    if ( !filter.empty() )
+    {
+        // Use the inefficient generic version as we can only monitor
+        // everything under the given directory.
+        //
+        // Notice that it would probably be better to still monitor everything
+        // natively and filter out the changes we're not interested in.
+        return wxFileSystemWatcherBase::AddTree(path, events, filter);
+    }
+
+
+    if ( !path.DirExists() )
+    {
+        wxLogError(_("Can't monitor non-existent directory \"%s\" for changes."),
+                   path.GetFullPath());
+        return false;
+    }
+
+    return AddAny(path, events, wxFSWPath_Tree);
+}
+
 #endif // wxUSE_FSWATCHER