diff --git a/SparkleLib/SparkleRepoBase.cs b/SparkleLib/SparkleRepoBase.cs index 5539ed58..e48230cc 100644 --- a/SparkleLib/SparkleRepoBase.cs +++ b/SparkleLib/SparkleRepoBase.cs @@ -298,9 +298,9 @@ namespace SparkleLib { // Starts a timer when something changes - private void OnFileActivity (object o, FileSystemEventArgs args) + public void OnFileActivity (object o, FileSystemEventArgs args) { - if (args.FullPath.Contains ("/.git") || args.FullPath.Contains ("/.hg")) + if (args.FullPath.Contains ("/.")) return; WatcherChangeTypes wct = args.ChangeType; diff --git a/SparkleShare/Mac/SparkleMacController.cs b/SparkleShare/Mac/SparkleMacController.cs index f22010ef..6ea521f3 100644 --- a/SparkleShare/Mac/SparkleMacController.cs +++ b/SparkleShare/Mac/SparkleMacController.cs @@ -28,6 +28,33 @@ namespace SparkleShare { public class SparkleMacController : SparkleController { + // We have to use our own custom made folder watcher, as + // System.IO.FileSystemWatcher fails watching subfolders on Mac + private SparkleMacWatcher watcher = new SparkleMacWatcher (SparklePaths.SparklePath); + + + public SparkleMacController () : base () + { + watcher.Changed += delegate (string path) { + string repo_name; + + if (path.Contains ("/")) + repo_name = path.Substring (0, path.IndexOf ("/")); + else + repo_name = path; + + repo_name = repo_name.Trim ("/".ToCharArray ()); + FileSystemEventArgs args = new FileSystemEventArgs (WatcherChangeTypes.Changed, + Path.Combine (SparklePaths.SparklePath, path), Path.GetFileName (path)); + + foreach (SparkleRepoBase repo in Repositories) { + if (repo.Name.Equals (repo_name)) + repo.OnFileActivity (this, args); + } + }; + } + + public override void EnableSystemAutostart () { // N/A diff --git a/SparkleShare/Mac/SparkleMacWatcher.cs b/SparkleShare/Mac/SparkleMacWatcher.cs new file mode 100644 index 00000000..70a1c265 --- /dev/null +++ b/SparkleShare/Mac/SparkleMacWatcher.cs @@ -0,0 +1,78 @@ +// SparkleShare, an instant update workflow to Git. +// Copyright (C) 2010 Hylke Bons +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + + +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading; +using System.Timers; + +namespace SparkleShare { + + public class SparkleMacWatcher { + + public delegate void ChangedEventHandler (string path); + public event ChangedEventHandler Changed; + + private DirectoryInfo last_changed; + + public SparkleMacWatcher (string path) + { + Thread thread = new Thread (new ThreadStart (delegate { + DateTime timestamp; + DirectoryInfo parent = new DirectoryInfo (path); + this.last_changed = new DirectoryInfo (path); + + while (true) { + timestamp = this.last_changed.LastWriteTime; + GetLastChange (parent); + + if (DateTime.Compare (this.last_changed.LastWriteTime, timestamp) != 0) { + string relative_path = this.last_changed.FullName.Substring (path.Length + 1); + + if (Changed != null) + Changed (relative_path); + } + + Thread.Sleep (5000); + } + })); + + thread.Start (); + } + + + private void GetLastChange (DirectoryInfo parent) + { + try { + if (DateTime.Compare (parent.LastWriteTime, this.last_changed.LastWriteTime) > 0) + this.last_changed = parent; + + foreach (DirectoryInfo info in parent.GetDirectories ()) { + if (!info.FullName.Contains ("/.")) { + if (DateTime.Compare (info.LastWriteTime, this.last_changed.LastWriteTime) > 0) + this.last_changed = info; + + GetLastChange (info); + } + } + + } catch (Exception) { } + } + } +} +