PageRenderTime 16ms CodeModel.GetById 1ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/SparkleShare/Mac/SparkleController.cs

http://github.com/hbons/SparkleShare
C# | 241 lines | 157 code | 62 blank | 22 comment | 10 complexity | 7bc6b94b06d4d53d168dba5d2525fbd1 MD5 | raw file
  1//   SparkleShare, a collaboration and sharing tool.
  2//   Copyright (C) 2010  Hylke Bons <hylkebons@gmail.com>
  3//
  4//   This program is free software: you can redistribute it and/or modify
  5//   it under the terms of the GNU General Public License as published by
  6//   the Free Software Foundation, either version 3 of the License, or
  7//   (at your option) any later version.
  8//
  9//   This program is distributed in the hope that it will be useful,
 10//   but WITHOUT ANY WARRANTY; without even the implied warranty of
 11//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 12//   GNU General Public License for more details.
 13//
 14//   You should have received a copy of the GNU General Public License
 15//   along with this program. If not, see <http://www.gnu.org/licenses/>.
 16
 17
 18using System;
 19using System.Diagnostics;
 20using System.IO;
 21using System.Threading;
 22
 23using MonoMac.Foundation;
 24using MonoMac.AppKit;
 25
 26using Mono.Unix.Native;
 27using SparkleLib;
 28using System.Collections.Generic;
 29
 30namespace SparkleShare {
 31
 32    public class SparkleController : SparkleControllerBase {
 33
 34        public override string PluginsPath {
 35            get {
 36                return Path.Combine (NSBundle.MainBundle.ResourcePath, "Plugins");
 37            }
 38        }
 39
 40        // We have to use our own custom made folder watcher, as
 41        // System.IO.FileSystemWatcher fails watching subfolders on Mac
 42        private SparkleMacWatcher watcher;
 43
 44        
 45        public SparkleController () : base ()
 46        {
 47            NSApplication.Init ();
 48
 49            // Let's use the bundled git first
 50            SparkleLib.Git.SparkleGit.GitPath  = Path.Combine (NSBundle.MainBundle.ResourcePath, "git", "libexec", "git-core", "git");
 51            SparkleLib.Git.SparkleGit.ExecPath = Path.Combine (NSBundle.MainBundle.ResourcePath, "git", "libexec", "git-core");
 52        }
 53
 54        
 55        public override void Initialize ()
 56        {
 57            base.Initialize ();
 58
 59            SparkleRepoBase.UseCustomWatcher = true;
 60            this.watcher = new SparkleMacWatcher (Program.Controller.FoldersPath);
 61
 62            this.watcher.Changed += OnFilesChanged;
 63        }
 64
 65
 66        private void OnFilesChanged (List<string> changed_files_in_basedir)
 67        {
 68            List<string> triggered_repos = new List<string> ();
 69
 70            foreach (string file in changed_files_in_basedir) {
 71                string repo_name;
 72                int path_sep_index = file.IndexOf (Path.DirectorySeparatorChar);
 73
 74                if (path_sep_index >= 0)
 75                    repo_name = file.Substring (0, path_sep_index);
 76                else
 77                    repo_name = file;
 78
 79                repo_name = Path.GetFileNameWithoutExtension (repo_name);
 80                SparkleRepoBase repo = GetRepoByName (repo_name);
 81
 82                if (repo == null)
 83                    continue;
 84
 85                if (!triggered_repos.Contains (repo_name)) {
 86                    triggered_repos.Add (repo_name);
 87
 88                    FileActivityTask task = MacActivityTask (repo,
 89                        new FileSystemEventArgs (WatcherChangeTypes.Changed, file, "Unknown"));
 90                    
 91                    task ();
 92                }
 93
 94            }
 95        }
 96
 97        private delegate void FileActivityTask ();
 98
 99        private FileActivityTask MacActivityTask (SparkleRepoBase repo, FileSystemEventArgs fse_args) {
100            return delegate { new Thread (() => { repo.OnFileActivity (fse_args); }).Start (); };
101        }
102
103
104        public override void CreateStartupItem ()
105        {
106            // There aren't any bindings in MonoMac to support this yet, so
107            // we call out to an applescript to do the job
108            Process process = new Process ();
109            process.StartInfo.FileName        = "osascript";
110            process.StartInfo.UseShellExecute = false;
111            process.StartInfo.Arguments       = "-e 'tell application \"System Events\" to " +
112                "make login item at end with properties {path:\"" + NSBundle.MainBundle.BundlePath + "\", hidden:false}'";
113
114            process.Start ();
115            process.WaitForExit ();
116
117            SparkleLogger.LogInfo ("Controller", "Added " + NSBundle.MainBundle.BundlePath + " to login items");
118        }
119
120
121        public override void InstallProtocolHandler ()
122        {
123             // We ship SparkleShareInviteHandler.app in the bundle
124        }
125
126
127        public override void AddToBookmarks ()
128        {
129            // TODO
130        }
131
132
133        public override bool CreateSparkleShareFolder ()
134        {
135            if (!Directory.Exists (Program.Controller.FoldersPath)) {
136                Directory.CreateDirectory (Program.Controller.FoldersPath);
137
138                if (Environment.OSVersion.Version.Major >= 14) {
139                    NSWorkspace.SharedWorkspace.SetIconforFile (
140                        NSImage.ImageNamed ("sparkleshare-folder-yosemite.icns"),
141                        Program.Controller.FoldersPath, 0);
142
143                } else {
144                    NSWorkspace.SharedWorkspace.SetIconforFile (
145                        NSImage.ImageNamed ("sparkleshare-folder.icns"),
146                        Program.Controller.FoldersPath, 0);
147                }
148
149                Syscall.chmod (Program.Controller.FoldersPath, (FilePermissions) 448); // 448 -> 700
150
151                return true;
152            }
153
154            return false;
155        }
156
157
158        public override void OpenFolder (string path)
159        {
160            path = Uri.UnescapeDataString (path);
161            NSWorkspace.SharedWorkspace.OpenFile (path);
162        }
163        
164        
165        public override void OpenFile (string path)
166        {
167            path = Uri.UnescapeDataString (path);
168            NSWorkspace.SharedWorkspace.OpenFile (path);
169        }
170
171        
172        public override void OpenWebsite (string url)
173        {
174            NSWorkspace.SharedWorkspace.OpenUrl (new NSUrl (url));
175        }
176
177
178        public override void CopyToClipboard (string text)
179        {
180            NSPasteboard.GeneralPasteboard.ClearContents ();
181            NSPasteboard.GeneralPasteboard.SetStringForType (text, "NSStringPboardType");
182        }
183
184
185        private string event_log_html;
186        public override string EventLogHTML
187        {
188            get {
189                if (string.IsNullOrEmpty (this.event_log_html)) {
190                    string html_file_path   = Path.Combine (NSBundle.MainBundle.ResourcePath, "HTML", "event-log.html");
191                    string jquery_file_path = Path.Combine (NSBundle.MainBundle.ResourcePath, "HTML", "jquery.js");
192                    string html             = File.ReadAllText (html_file_path);
193                    string jquery           = File.ReadAllText (jquery_file_path);
194                    this.event_log_html     = html.Replace ("<!-- $jquery -->", jquery);
195                }
196
197                return this.event_log_html;
198            }
199        }
200
201
202        private string day_entry_html;
203        public override string DayEntryHTML
204        {
205            get {
206                if (string.IsNullOrEmpty (this.day_entry_html)) {
207                    string html_file_path = Path.Combine (NSBundle.MainBundle.ResourcePath, "HTML", "day-entry.html");
208                    this.day_entry_html   = File.ReadAllText (html_file_path);
209                }
210
211                return this.day_entry_html;
212            }
213        }
214        
215
216        private string event_entry_html;
217        public override string EventEntryHTML
218        {
219            get {
220               if (string.IsNullOrEmpty (this.event_entry_html)) {
221                   string html_file_path = Path.Combine (NSBundle.MainBundle.ResourcePath, "HTML", "event-entry.html");
222                   this.event_entry_html = File.ReadAllText (html_file_path);
223               }
224
225               return this.event_entry_html;
226            }
227        }
228
229
230        public delegate void Code ();
231        private NSObject obj = new NSObject ();
232
233        public void Invoke (Code code)
234        {
235            using (var a = new NSAutoreleasePool ())
236            {
237                obj.InvokeOnMainThread (() => code ());
238            }
239        }
240    }
241}