SparkleShare/SparkleShare/Mac/Controller.cs

237 lines
7.5 KiB
C#
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// SparkleShare, a collaboration and sharing tool.
// Copyright (C) 2010 Hylke Bons <hi@planetpeanut.uk>
//
// 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 <http://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using Foundation;
using AppKit;
using Sparkles;
using Sparkles.Git;
namespace SparkleShare {
public class Controller : BaseController {
public override string PresetsPath {
get {
return Path.Combine (NSBundle.MainBundle.ResourcePath, "Presets");
}
}
public Controller (Configuration config)
: base (config)
{
NSApplication.Init ();
GitCommand.GitPath = Path.Combine (NSBundle.MainBundle.ResourcePath, "git", "libexec", "git-core", "git");
GitCommand.ExecPath = Path.Combine (NSBundle.MainBundle.ResourcePath, "git", "libexec", "git-core");
bool overwite = true;
File.Copy (
Path.Combine (GitCommand.ExecPath, "git-lfs"),
Path.Combine (Config.BinPath, "git-lfs"),
overwite);
}
public override void Initialize ()
{
base.Initialize ();
BaseRepository.UseCustomWatcher = true;
this.watcher = new SparkleMacWatcher (SparkleShare.Controller.FoldersPath);
this.watcher.Changed += OnFilesChanged;
}
public override void CreateSparkleShareFolder ()
{
if (Directory.Exists (SparkleShare.Controller.FoldersPath))
return;
Directory.CreateDirectory (SparkleShare.Controller.FoldersPath);
// TODO: Use proper API
var chmod = new Command ("chmod", "700 " + SparkleShare.Controller.FoldersPath);
chmod.StartAndWaitForExit ();
}
public override void SetFolderIcon ()
{
string folder_icon_name = "sparkleshare-folder.icns";
if (Environment.OSVersion.Version.Major >= 14)
folder_icon_name = "sparkleshare-folder-yosemite.icns";
NSWorkspace.SharedWorkspace.SetIconforFile (NSImage.ImageNamed (folder_icon_name), SparkleShare.Controller.FoldersPath, 0);
}
// There aren't any bindings in Xamarin.Mac to support this yet, so
// we call out to an applescript to do the job
public override void CreateStartupItem ()
{
string args = "-e 'tell application \"System Events\" to " +
"make login item at end with properties " +
"{path:\"" + NSBundle.MainBundle.BundlePath + "\", hidden:false}'";
var process = new Command ("osascript", args);
process.StartAndWaitForExit ();
Logger.LogInfo ("Controller", "Added " + NSBundle.MainBundle.BundlePath + " to login items");
}
public override void InstallProtocolHandler ()
{
}
public override void CopyToClipboard (string text)
{
NSPasteboard.GeneralPasteboard.ClearContents ();
NSPasteboard.GeneralPasteboard.SetStringForType (text, "NSStringPboardType");
}
public override void OpenFolder (string path)
{
path = Uri.UnescapeDataString (path);
NSWorkspace.SharedWorkspace.OpenFile (path);
}
public override void OpenFile (string path)
{
path = Uri.UnescapeDataString (path);
NSWorkspace.SharedWorkspace.OpenFile (path);
}
public override void OpenWebsite (string url)
{
NSWorkspace.SharedWorkspace.OpenUrl (new NSUrl (url));
}
string event_log_html;
public override string EventLogHTML
{
get {
if (string.IsNullOrEmpty (this.event_log_html)) {
string html_file_path = Path.Combine (NSBundle.MainBundle.ResourcePath, "HTML", "event-log.html");
string jquery_file_path = Path.Combine (NSBundle.MainBundle.ResourcePath, "HTML", "jquery.js");
string html = File.ReadAllText (html_file_path);
string jquery = File.ReadAllText (jquery_file_path);
this.event_log_html = html.Replace ("<!-- $jquery -->", jquery);
}
return this.event_log_html;
}
}
string day_entry_html;
public override string DayEntryHTML
{
get {
if (string.IsNullOrEmpty (this.day_entry_html)) {
string html_file_path = Path.Combine (NSBundle.MainBundle.ResourcePath, "HTML", "day-entry.html");
this.day_entry_html = File.ReadAllText (html_file_path);
}
return this.day_entry_html;
}
}
string event_entry_html;
public override string EventEntryHTML
{
get {
if (string.IsNullOrEmpty (this.event_entry_html)) {
string html_file_path = Path.Combine (NSBundle.MainBundle.ResourcePath, "HTML", "event-entry.html");
this.event_entry_html = File.ReadAllText (html_file_path);
}
return this.event_entry_html;
}
}
// We have to use our own custom made folder watcher, as
// System.IO.FileSystemWatcher fails watching subfolders on Mac
SparkleMacWatcher watcher;
delegate void FileActivityTask ();
FileActivityTask MacFileActivityTask (BaseRepository repo, FileSystemEventArgs fse_args)
{
return delegate { new Thread (() => { repo.OnFileActivity (fse_args); }).Start (); };
}
void OnFilesChanged (List<string> changed_files_in_basedir)
{
var triggered_repos = new List<string> ();
foreach (string file_path in changed_files_in_basedir) {
string [] paths = file_path.Split (Path.DirectorySeparatorChar);
if (paths.Length < 2)
continue;
BaseRepository repo = GetRepoByName (paths [1]);
if (repo != null && !triggered_repos.Contains (repo.Name)) {
FileActivityTask task = MacFileActivityTask (repo,
new FileSystemEventArgs (WatcherChangeTypes.Changed, file_path, "Unknown"));
task ();
triggered_repos.Add (repo.Name);
}
}
}
public delegate void Code ();
public void Invoke (Code code)
{
using (var a = new NSAutoreleasePool ())
{
new NSObject ().InvokeOnMainThread (() => code ());
}
}
public override void PlatformQuit ()
{
watcher.Dispose ();
NSRunningApplication.CurrentApplication.Terminate ();
}
}
}