diff --git a/.gitmodules b/.gitmodules index f588b95e..64b6fac6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,9 +4,3 @@ [submodule "GitSharp"] path = GitSharp url = http://github.com/henon/GitSharp.git -[submodule "MonoMac"] - path = MonoMac - url = https://github.com/mono/monomac.git -[submodule "MacCore"] - path = MacCore - url = https://github.com/mono/maccore.git diff --git a/MacCore b/MacCore deleted file mode 160000 index da3e017c..00000000 --- a/MacCore +++ /dev/null @@ -1 +0,0 @@ -Subproject commit da3e017ccda1ce1c21777246151a5d7f21a3ffa5 diff --git a/MonoMac b/MonoMac deleted file mode 160000 index 433483a4..00000000 --- a/MonoMac +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 433483a484b8637b379265c38ebab643a8cfcc6a diff --git a/NEWS b/NEWS index 5eb17caa..3d345607 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,11 @@ +0.2-beta2 for Mac (Sat Feb, 2011): + + Hylke: Mac version! Massive restructure of the code to an MVC-like model + to make building different front-ends easier. Ported the event logs to + Webkit, so users can style it to their liking. It also reduces the amount + of UI-porting that needs to be done between toolkits. + + 0.2-beta1 (Sun Sep 5, 2010): Hylke: Aside from the usual bug fixes and behind the scenes work I mainly diff --git a/README b/README index de34b5f8..cf08d555 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -SparkleShare 0.2 Beta 1 +SparkleShare 0.2 Beta 2 ======================= SparkleShare is a file sharing and collaboration tool inspired by Dropbox. @@ -25,8 +25,8 @@ to change and redistribute it under certain conditions. For more information see the LICENSE file or visit http://www.gnu.org/licenses/gpl-3.0.html -Run -=== +Run on Linux: +============= SparkleShare currently requires: @@ -43,7 +43,7 @@ SparkleShare currently requires: - webkitgtk - webkit-sharp -Run the service: +Run the service, either click the SparkleShare launcher or: $ sparkleshare start @@ -62,8 +62,8 @@ Note: by hand. -Build -===== +Build on Linux: +=============== To build SparkleShare you need: @@ -97,13 +97,40 @@ Note: Use './configure --prefix=/usr' if you want the Nautilus extension to work. -Build on OSX: +Run on Mac: +=========== + +You will need to have the Mac version of git installed. + +SparkleShare will look for git in /usr/bin, so you may need to create a symbolic +link to git, depending on where it was installed: + + $ sudo ln -s /path/to/your/git /usr/bin/git + +Now just double-click the SparkleShare.app. + + +Build on Mac: ============= -Get the Mono Framework, Monodevelop, and MacPorts. +Install the Mono Framework, Monodevelop (plus the MonoMac plugin), and MacPorts. + Install git-core, automake and intltool using 'port install'. Make sure that git or a symbolic link to git is in /usr/bin. +Note: + + You may need to adjust some environment variables to find mono: + + $ export PATH=/Library/Frameworks/Mono.framework/Versions/Current/bin:$PATH + $ export PKG_CONFIG=/Library/Frameworks/Mono.framework/Versions/Current/bin/pkg-config + $ export PKG_CONFIG_PATH=/Library/Frameworks/Mono.framework/Versions/Current/lib/pkgconfig + $ ./autogen.sh + +The last step will give you some errors, but you only need the libraries to be compiled. +Open 'SparkleShare/Mac/SparkleShare.sln' in MonoDevelop and start the build. + + Frequently Asked Question ========================= @@ -118,18 +145,19 @@ Official website: http://www.sparkleshare.org/ Project page: -http://github.com/SparkleShare +http://github.com/SparkleShare/ IRC Channel: #sparkleshare on irc.gnome.org Wiki: -http://github.com/hbons/SparkleShare/wiki +http://github.com/hbons/SparkleShare/wiki/ Issue tracker: -http://github.com/hbons/SparkleShare/issues +http://github.com/hbons/SparkleShare/issues/ Translation project: http://www.transifex.net/projects/p/sparkleshare/ + Now have fun and create cool things together! :) diff --git a/SparkleLib/Makefile.am b/SparkleLib/Makefile.am index 69d6c2ef..adb8db7a 100644 --- a/SparkleLib/Makefile.am +++ b/SparkleLib/Makefile.am @@ -8,6 +8,7 @@ SOURCES = \ SparkleCommit.cs \ SparkleEvents.cs \ SparkleFetcher.cs \ + SparkleGit.cs \ SparkleHelpers.cs \ SparkleListener.cs \ SparkleOptions.cs \ diff --git a/SparkleLib/SparkleFetcher.cs b/SparkleLib/SparkleFetcher.cs index a305649c..ebbe97d0 100644 --- a/SparkleLib/SparkleFetcher.cs +++ b/SparkleLib/SparkleFetcher.cs @@ -130,21 +130,42 @@ namespace SparkleLib { private void InstallExcludeRules () { - string exlude_rules_file_path = SparkleHelpers.CombineMore (TargetFolder, ".git", "info", "exclude"); + string exlude_rules_file_path = SparkleHelpers.CombineMore + (TargetFolder, ".git", "info", "exclude"); TextWriter writer = new StreamWriter (exlude_rules_file_path); - // Ignore gedit swap files + // gedit and emacs writer.WriteLine ("*~"); - // Ignore vi swap files - writer.WriteLine (".*.sw?"); - - // Ignore OSX's invisible directories - writer.WriteLine (".DS_Store"); + // vi(m) + writer.WriteLine (".*.sw[a-z]"); + writer.WriteLine ("*.un~"); + writer.WriteLine ("*.swp"); + writer.WriteLine ("*.swo"); - // Ignore Windows cache files + // KDE + writer.WriteLine (".directory"); + + // Mac OSX + writer.WriteLine (".DS_Store"); + writer.WriteLine ("Icon?"); + writer.WriteLine ("._*"); + writer.WriteLine (".Spotlight-V100"); + writer.WriteLine (".Trashes"); + + // Windows writer.WriteLine ("Thumbs.db"); + writer.WriteLine ("Desktop.ini"); + + // CVS + writer.WriteLine ("*/CVS/*"); + writer.WriteLine (".cvsignore"); + writer.WriteLine ("*/.cvsignore"); + + // Subversion + writer.WriteLine ("/.svn/*"); + writer.WriteLine ("*/.svn/*"); writer.Close (); diff --git a/SparkleShare/Mac/SparkleShare/SparkleUI.cs b/SparkleLib/SparkleGit.cs similarity index 51% rename from SparkleShare/Mac/SparkleShare/SparkleUI.cs rename to SparkleLib/SparkleGit.cs index 68171528..46799474 100644 --- a/SparkleShare/Mac/SparkleShare/SparkleUI.cs +++ b/SparkleLib/SparkleGit.cs @@ -14,52 +14,27 @@ // 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.Drawing; -using System.Timers; -using MonoMac.Foundation; -using MonoMac.AppKit; -using MonoMac.ObjCRuntime; -using MonoMac.WebKit; +using System.Diagnostics; -namespace SparkleShare { +namespace SparkleLib { - public partial class AppDelegate : NSApplicationDelegate { - // Workaround to be able to work with SparkleUI as the main class - } + public class SparkleGit : Process { - - public class SparkleUI : AppDelegate - { - - public static SparkleStatusIcon StatusIcon; - public static List OpenLogs; - - - - public SparkleUI () - { - - NSApplication.Init (); - - NSApplication.SharedApplication.ApplicationIconImage - = NSImage.ImageNamed ("sparkleshare.icns"); - - OpenLogs = new List (); - StatusIcon = new SparkleStatusIcon (); - - } - - - public void Run () + public SparkleGit (string path, string args) : base () { - NSApplication.Main (new string [0]); + EnableRaisingEvents = true; + + StartInfo.FileName = SparklePaths.GitPath; + StartInfo.Arguments = args; + StartInfo.RedirectStandardOutput = true; + StartInfo.UseShellExecute = false; + StartInfo.WorkingDirectory = path; } } -} +} \ No newline at end of file diff --git a/SparkleLib/SparkleLib.csproj b/SparkleLib/SparkleLib.csproj index ab73c7d0..9e286ba7 100644 --- a/SparkleLib/SparkleLib.csproj +++ b/SparkleLib/SparkleLib.csproj @@ -76,6 +76,7 @@ + diff --git a/SparkleLib/SparkleListener.cs b/SparkleLib/SparkleListener.cs index f37745d2..6aa9b850 100644 --- a/SparkleLib/SparkleListener.cs +++ b/SparkleLib/SparkleListener.cs @@ -14,62 +14,60 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . + using Meebey.SmartIrc4net; using System; using System.Collections.Generic; using System.Text; using System.Threading; +using System.Security.Cryptography; namespace SparkleLib { // A persistent connection to the server that // listens for change notifications - public class SparkleListener - { + public class SparkleListener { // FIXME: The IrcClient is a public property because // extending it causes crashes public IrcClient Client; private Thread Thread; public readonly string Server; + public readonly string FallbackServer; public readonly string Channel; public readonly string Nick; - public SparkleListener (string server, string channel, string nick) + public SparkleListener (string server, string folder_name, string user_email) { - Server = server; - Channel = channel; - Nick = nick; - - if (!Nick.Equals ("")) - Nick = nick.Replace ("@", "_at_").Replace (".", "_dot_"); + // This is SparkleShare's centralized notification service. + // Don't worry, we only use this server as a backup if you + // don't have your own. All data needed to connect is hashed and + // we don't store any personal information ever. + // Server = "204.62.14.135"; + + if (!user_email.Equals ("") && user_email != null) + Nick = GetSHA1 (folder_name + user_email + "sparkles"); else - Nick = "anonymous"; + Nick = GetSHA1 (DateTime.Now.ToString () + "sparkles"); - // Keep the nick short - if (Nick.Length > 9) - Nick = Nick.Substring (0, 9); - - // TODO: Remove these hardcoded values + Nick = "s" + Nick.Substring (0, 7); + // Channel = "#" + GetSHA1 (server + folder_name); + + Server = "irc.gnome.org"; Channel = "#sparkletest"; - Server = "irc.gnome.org"; - + Client = new IrcClient () { - PingTimeout = 120, - SocketSendTimeout = 120, - SocketReceiveTimeout = 120, - AutoRetry = true, - AutoReconnect = true, - AutoRejoin = true + PingTimeout = 180, + PingInterval = 90 }; } // Starts a new thread and listens to the channel - public void ListenForChanges () + public void Listen () { Thread = new Thread ( @@ -102,6 +100,14 @@ namespace SparkleLib { Thread.Start (); } + + + public void Announce (string message) + { + + Client.SendMessage (SendType.Message, Channel, message); + + } // Frees all resources for this Listener @@ -113,6 +119,16 @@ namespace SparkleLib { } + + // Creates an SHA-1 hash of input + private static string GetSHA1 (string s) + { + SHA1 sha1 = new SHA1CryptoServiceProvider (); + Byte[] bytes = ASCIIEncoding.Default.GetBytes (s); + Byte[] encoded_bytes = sha1.ComputeHash (bytes); + return BitConverter.ToString (encoded_bytes).ToLower ().Replace ("-", ""); + } + } } diff --git a/SparkleLib/SparklePaths.cs b/SparkleLib/SparklePaths.cs index 138379f6..051e7514 100644 --- a/SparkleLib/SparklePaths.cs +++ b/SparkleLib/SparklePaths.cs @@ -24,7 +24,7 @@ namespace SparkleLib { public static class SparklePaths { - public static string GitPath = "/usr/bin/git"; // TODO: Don't hardcode this + public static string GitPath = SystemGitPath; public static string HomePath = new UnixUserInfo (UnixEnvironment.UserName).HomeDirectory; @@ -44,24 +44,37 @@ namespace SparkleLib { "icons"); - private static string GetGitPath () + private static string SystemGitPath { - - Process process = new Process (); - process.StartInfo.RedirectStandardOutput = true; - process.StartInfo.UseShellExecute = false; - process.StartInfo.FileName = "which"; - process.StartInfo.Arguments = "git"; - process.Start (); - - string git_path = process.StandardOutput.ReadToEnd ().Trim (); + get { - if (!string.IsNullOrEmpty (git_path)) - return git_path; - else - return null; - + Process process = new Process (); + + process.StartInfo.RedirectStandardOutput = true; + process.StartInfo.UseShellExecute = false; + process.StartInfo.FileName = "which"; + process.StartInfo.Arguments = "git"; + process.Start (); + + string git_path = process.StandardOutput.ReadToEnd (); + git_path = git_path.Trim (); + + if (!string.IsNullOrEmpty (git_path)) { + + return git_path; + + } else { + + Console.WriteLine ("Sorry, SparkleShare needs Git to run, but it wasn't found."); + Environment.Exit (-1); + + return null; + + } + + } + } } diff --git a/SparkleLib/SparkleRepo.cs b/SparkleLib/SparkleRepo.cs index 56bb02ae..da8a10ec 100644 --- a/SparkleLib/SparkleRepo.cs +++ b/SparkleLib/SparkleRepo.cs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . + using GitSharp; using GitSharp.Commands; using GitSharp.Core.Transport; @@ -30,15 +31,15 @@ namespace SparkleLib { public class SparkleRepo : Repository { - private Process Process; private Timer RemoteTimer; private Timer LocalTimer; private FileSystemWatcher Watcher; - private bool HasChanged; - private DateTime LastChange; private System.Object ChangeLock; private int FetchRequests; private SparkleListener Listener; + private bool HasChanged; + private List SizeBuffer; + /// /// The folder name the repository resides in locally @@ -251,37 +252,32 @@ namespace SparkleLib { public SparkleRepo (string path) : base (path) { - LocalPath = path; - Name = Path.GetFileName (LocalPath); + LocalPath = path; + Name = Path.GetFileName (LocalPath); - Process = new Process () { - EnableRaisingEvents = true - }; - - Process.StartInfo.FileName = SparklePaths.GitPath; - Process.StartInfo.RedirectStandardOutput = true; - Process.StartInfo.UseShellExecute = false; - Process.StartInfo.WorkingDirectory = LocalPath; - - RemoteName = Path.GetFileNameWithoutExtension (RemoteOriginUrl); - RemoteOriginUrl = Config ["remote.origin.url"]; - Domain = GetDomain (RemoteOriginUrl); - Description = GetDescription (); - - UserName = Config ["user.name"]; - UserEmail = Config ["user.email"]; + RemoteName = Path.GetFileNameWithoutExtension (RemoteOriginUrl); + RemoteOriginUrl = Config ["remote.origin.url"]; + Domain = GetDomain (RemoteOriginUrl); + Description = GetDescription (); + UserName = Config ["user.name"]; + UserEmail = Config ["user.email"]; if (Head.CurrentCommit == null) - _CurrentHash = null; + _CurrentHash = null; else - _CurrentHash = Head.CurrentCommit.Hash; + _CurrentHash = Head.CurrentCommit.Hash; - _IsSyncing = false; - _IsBuffering = false; - _IsPolling = true; - _IsFetching = false; - _IsPushing = false; - _ServerOnline = true; + _IsSyncing = false; + _IsBuffering = false; + _IsPolling = true; + _IsFetching = false; + _IsPushing = false; + _ServerOnline = true; + + HasChanged = false; + ChangeLock = new Object (); + FetchRequests = 0; + string unsynced_file_path = SparkleHelpers.CombineMore (LocalPath , ".git", "has_unsynced_changes"); @@ -295,10 +291,6 @@ namespace SparkleLib { if (_CurrentHash == null) CreateInitialCommit (); - HasChanged = false; - ChangeLock = new System.Object (); - FetchRequests = 0; - // Watch the repository's folder Watcher = new FileSystemWatcher (LocalPath) { @@ -312,35 +304,41 @@ namespace SparkleLib { Watcher.Deleted += new FileSystemEventHandler (OnFileActivity); Watcher.Renamed += new RenamedEventHandler (OnFileActivity); - // Fetch remote changes every minute + + // Listen to the irc channel on the server... + Listener = new SparkleListener (Domain, "#" + RemoteName, UserEmail); + + // ...fetch remote changes every 60 seconds if that fails RemoteTimer = new Timer () { Interval = 60000 }; - - // Listen to the irc channel on the server - Listener = new SparkleListener (Domain, "#" + RemoteName, UserEmail); - + RemoteTimer.Elapsed += delegate { - - if (_IsPolling) + + if (_IsPolling) { + CheckForRemoteChanges (); + + if (!Listener.Client.IsConnected) { + + SparkleHelpers.DebugInfo ("Irc", "[" + Name + "] Trying to reconnect..."); + Listener.Listen (); + + } + + } if (_HasUnsyncedChanges) Push (); - if (!Listener.Client.IsConnected) { - - SparkleHelpers.DebugInfo ("Irc", "[" + Name + "] Trying to reconnect..."); - Listener.Client.Reconnect (true, true); - - } - }; // Stop polling when the connection to the irc channel is succesful Listener.Client.OnConnected += delegate { - + + _IsPolling = false; + // Check for changes manually one more time CheckForRemoteChanges (); @@ -348,19 +346,22 @@ namespace SparkleLib { if (_HasUnsyncedChanges) Push (); - SparkleHelpers.DebugInfo ("Irc", "[" + Name + "] Connected. Now listening..."); - - _IsPolling = false; + SparkleHelpers.DebugInfo ("Irc", "[" + Name + "] Connected. Now listening... (" + Listener.Server + ")"); }; + // Start polling when the connection to the irc channel is lost + Listener.Client.OnConnectionError += delegate { + + SparkleHelpers.DebugInfo ("Irc", "[" + Name + "] Lost connection. Falling back to polling..."); + _IsPolling = true; + + }; + // Start polling when the connection to the irc channel is lost Listener.Client.OnDisconnected += delegate { SparkleHelpers.DebugInfo ("Irc", "[" + Name + "] Lost connection. Falling back to polling..."); - - CheckForRemoteChanges (); - _IsPolling = true; }; @@ -369,8 +370,9 @@ namespace SparkleLib { Listener.Client.OnChannelMessage += delegate (object o, IrcEventArgs args) { SparkleHelpers.DebugInfo ("Irc", "[" + Name + "] Was notified of a remote change."); - - if (!args.Data.Message.Equals (_CurrentHash)) { + string message = args.Data.Message.Trim (); + + if (!message.Equals (_CurrentHash) && message.Length == 40) { FetchRequests++; @@ -388,7 +390,8 @@ namespace SparkleLib { } } else { - + + // Not really needed as we won't be notified about our own messages SparkleHelpers.DebugInfo ("Irc", "[" + Name + "] False alarm, already up to date. (" + _CurrentHash + ")"); @@ -397,13 +400,15 @@ namespace SparkleLib { }; // Start listening - Listener.ListenForChanges (); + Listener.Listen (); + + SizeBuffer = new List (); // Keep a timer that checks if there are changes and // whether they have settled LocalTimer = new Timer () { - Interval = 4000 + Interval = 250 }; LocalTimer.Elapsed += delegate (object o, ElapsedEventArgs args) { @@ -411,9 +416,7 @@ namespace SparkleLib { }; - if (_IsPolling) - RemoteTimer.Start (); - + RemoteTimer.Start (); LocalTimer.Start (); // Add everything that changed @@ -430,23 +433,14 @@ namespace SparkleLib { { SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Checking for remote changes..."); - - Process process = new Process () { - EnableRaisingEvents = true - }; - - process.StartInfo.FileName = SparklePaths.GitPath; - process.StartInfo.RedirectStandardOutput = true; - process.StartInfo.UseShellExecute = false; - process.StartInfo.WorkingDirectory = LocalPath; - process.StartInfo.Arguments = "ls-remote origin master"; - - process.Exited += delegate { + SparkleGit git = new SparkleGit (LocalPath, "ls-remote origin master"); + + git.Exited += delegate { - if (process.ExitCode != 0) + if (git.ExitCode != 0) return; - string remote_hash = process.StandardOutput.ReadToEnd (); + string remote_hash = git.StandardOutput.ReadToEnd (); if (!remote_hash.StartsWith (_CurrentHash)) { @@ -457,33 +451,10 @@ namespace SparkleLib { } }; + - process.Start (); - -/* FIXME: LsRemoteCommand is not yet implemented by GitSharp - - LsRemoteCommand ls_remote = new LsRemoteCommand () { - Repository = this - }; - - ls_remote.Execute (); - - using (StreamReader reader = new StreamReader (ls_remote.OutputStream.BaseStream)) - { - - string remote_hash = reader.ReadLine ()); - - if (!remote_hash.StartsWith (_CurrentHash)) { - - SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Remote changes found."); - - Fetch (); - Rebase (); - - } - - } -*/ + git.Start (); + git.WaitForExit (); } @@ -494,15 +465,18 @@ namespace SparkleLib { lock (ChangeLock) { if (HasChanged) { + + if (SizeBuffer.Count >= 4) + SizeBuffer.RemoveAt (0); + + DirectoryInfo dir_info = new DirectoryInfo (LocalPath); + SizeBuffer.Add (CalculateFolderSize (dir_info)); - SparkleHelpers.DebugInfo ("Local", "[" + Name + "] Changes found, checking if settled."); + if (SizeBuffer [0].Equals (SizeBuffer [1]) && + SizeBuffer [1].Equals (SizeBuffer [2]) && + SizeBuffer [2].Equals (SizeBuffer [3])) { - DateTime now = DateTime.UtcNow; - TimeSpan changed = new TimeSpan (now.Ticks - LastChange.Ticks); - - if (changed.TotalMilliseconds > 5000) { - - SparkleHelpers.DebugInfo ("Local", "[" + Name + "] Changes have settled, adding files..."); + SparkleHelpers.DebugInfo ("Local", "[" + Name + "] Changes have settled."); _IsBuffering = false; @@ -523,8 +497,12 @@ namespace SparkleLib { { WatcherChangeTypes wct = fse_args.ChangeType; - - if (!ShouldIgnore (fse_args.FullPath)) { + + int number_of_changes = Status.Untracked.Count + + Status.Missing.Count + + Status.Modified.Count; + + if (number_of_changes > 0) { _IsBuffering = true; @@ -540,12 +518,12 @@ namespace SparkleLib { } SparkleHelpers.DebugInfo ("Event", "[" + Name + "] " + wct.ToString () + " '" + fse_args.Name + "'"); - + SparkleHelpers.DebugInfo ("Local", "[" + Name + "] Changes found, checking if settled."); + RemoteTimer.Stop (); lock (ChangeLock) { - LastChange = DateTime.UtcNow; HasChanged = true; } @@ -565,14 +543,13 @@ namespace SparkleLib { LocalTimer.Stop (); RemoteTimer.Stop (); - Add (); - - string message = FormatCommitMessage (); - - if (message != null) { - + if (Status.AnyDifferences) { + + Add (); + + string message = FormatCommitMessage (); Commit (message); - CheckForRemoteChanges (); + Push (); } else { @@ -586,9 +563,7 @@ namespace SparkleLib { } finally { - if (_IsPolling) - RemoteTimer.Start (); - + RemoteTimer.Start (); LocalTimer.Start (); } @@ -604,9 +579,10 @@ namespace SparkleLib { // FIXME: this GitSharp method seems to block... // Index.AddAll (); - Process.StartInfo.Arguments = "add --all"; - Process.Start (); - Process.WaitForExit (); + + SparkleGit git = new SparkleGit (LocalPath, "add --all"); + git.Start (); + git.WaitForExit (); SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Changes staged."); @@ -618,6 +594,21 @@ namespace SparkleLib { } + // Removes unneeded objects + private void CollectGarbage () + { + + SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Collecting garbage..."); + + SparkleGit git = new SparkleGit (LocalPath, "gc"); + git.Start (); + git.WaitForExit (); + + SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Garbage collected.."); + + } + + // Commits the made changes new public void Commit (string message) { @@ -626,14 +617,20 @@ namespace SparkleLib { return; base.Commit (message); + _CurrentHash = Head.CurrentCommit.Hash; + + SparkleHelpers.DebugInfo ("Commit", "[" + Name + "] " + message + " (" + _CurrentHash); - SparkleHelpers.DebugInfo ("Commit", "[" + Name + "] " + message); - - SparkleEventArgs args = new SparkleEventArgs ("Commited"); - args.Message = message; + SparkleEventArgs args = new SparkleEventArgs ("Commited") { + Message = message + }; if (Commited != null) Commited (this, args); + + // Collect garbage pseudo-randomly + if (DateTime.Now.Second % 10 == 0) + CollectGarbage (); } @@ -647,32 +644,9 @@ namespace SparkleLib { RemoteTimer.Stop (); + SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Fetching changes..."); -/* FIXME: SSH transport doesn't work with GitSharp - try { - - FetchCommand fetch_command = new FetchCommand () { - Remote = "origin", - Repository = this - }; - - fetch_command.Execute (); - - } catch (GitSharp.Core.Exceptions.TransportException e) { - - Console.WriteLine ("Nothing to fetch: " + e.Message); - - } -*/ - - Process process = new Process () { - EnableRaisingEvents = true - }; - - process.StartInfo.FileName = SparklePaths.GitPath; - process.StartInfo.RedirectStandardOutput = true; - process.StartInfo.UseShellExecute = false; - process.StartInfo.WorkingDirectory = LocalPath; + SparkleGit git = new SparkleGit (LocalPath, "fetch -v origin master"); SparkleEventArgs args; args = new SparkleEventArgs ("FetchingStarted"); @@ -680,44 +654,43 @@ namespace SparkleLib { if (FetchingStarted != null) FetchingStarted (this, args); - SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Fetching changes..."); - process.StartInfo.Arguments = "fetch -v origin master"; - - process.Exited += delegate { + git.Exited += delegate { SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Changes fetched."); - args = new SparkleEventArgs ("FetchingFinished"); - _IsSyncing = false; _IsFetching = false; - if (_IsPolling) - RemoteTimer.Start (); - _CurrentHash = Head.CurrentCommit.Hash; - if (process.ExitCode != 0) { + if (git.ExitCode != 0) { _ServerOnline = false; - + + args = new SparkleEventArgs ("FetchingFailed"); + if (FetchingFailed != null) FetchingFailed (this, args); } else { _ServerOnline = true; + + args = new SparkleEventArgs ("FetchingFinished"); if (FetchingFinished != null) FetchingFinished (this, args); } + RemoteTimer.Start (); + }; - process.Start (); - process.WaitForExit (); + + git.Start (); + git.WaitForExit (); } @@ -726,79 +699,75 @@ namespace SparkleLib { public void Rebase () { - Add (); - Watcher.EnableRaisingEvents = false; - - SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Rebasing changes..."); - - Process.StartInfo.Arguments = "rebase -v FETCH_HEAD"; - Process.WaitForExit (); - Process.Start (); - - SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Changes rebased."); - - string output = Process.StandardOutput.ReadToEnd ().Trim (); - - if (!output.Contains ("up to date")) { - - if (output.Contains ("Failed to merge")) { - - SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Resolving conflict..."); - - Process.StartInfo.Arguments = "status"; - Process.WaitForExit (); - Process.Start (); - output = Process.StandardOutput.ReadToEnd ().Trim (); - string [] lines = Regex.Split (output, "\n"); - - foreach (string line in lines) { - - if (line.Contains ("needs merge")) { - - string problem_file_name = line.Substring (line.IndexOf (": needs merge")); - - Process.StartInfo.Arguments = "checkout --ours " + problem_file_name; - Process.WaitForExit (); - Process.Start (); - - string timestamp = DateTime.Now.ToString ("H:mm d MMM yyyy"); - - File.Move (problem_file_name, problem_file_name + " (" + UserName + ", " + timestamp + ")"); - - Process.StartInfo.Arguments = "checkout --theirs " + problem_file_name; - Process.WaitForExit (); - Process.Start (); - - SparkleEventArgs args = new SparkleEventArgs ("ConflictDetected"); - - if (ConflictDetected != null) - ConflictDetected (this, args); - - } - - } - - Add (); - - Process.StartInfo.Arguments = "rebase --continue"; - Process.WaitForExit (); - Process.Start (); - - SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Conflict resolved."); - - Push (); - } + if (Status.AnyDifferences) { + + Add (); + + string commit_message = FormatCommitMessage (); + Commit (commit_message); - - List commits = GetCommits (1); - - if (NewCommit != null) - NewCommit (commits [0], LocalPath); - } + SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Rebasing changes..."); + SparkleGit git = new SparkleGit (LocalPath, "rebase -v FETCH_HEAD"); + + git.Exited += delegate { + + if (Status.MergeConflict.Count > 0) { + + SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Conflict detected..."); + + foreach (string problem_file_name in Status.MergeConflict) { + + SparkleGit git_ours = new SparkleGit (LocalPath, + "checkout --ours " + problem_file_name); + git_ours.Start (); + git_ours.WaitForExit (); + + string timestamp = DateTime.Now.ToString ("H:mm d MMM"); + + string new_file_name = problem_file_name + " (" + UserName + ", " + timestamp + ")"; + File.Move (problem_file_name, new_file_name); + + SparkleGit git_theirs = new SparkleGit (LocalPath, + "checkout --theirs " + problem_file_name); + git_theirs.Start (); + git_theirs.WaitForExit (); + + SparkleEventArgs args = new SparkleEventArgs ("ConflictDetected"); + + if (ConflictDetected != null) + ConflictDetected (this, args); + + } + + Add (); + + SparkleGit git_continue = new SparkleGit (LocalPath, "rebase --continue"); + git_continue.Start (); + git_continue.WaitForExit (); + + SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Conflict resolved."); + + Push (); + + } + + }; + + + git.Start (); + git.WaitForExit (); + + _CurrentHash = Head.CurrentCommit.Hash; + + if (NewCommit != null) + NewCommit (GetCommits (2) [0], LocalPath); // FIXME: GetCommits doesn't like 1 + + SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Changes rebased."); + Watcher.EnableRaisingEvents = true; } @@ -810,41 +779,23 @@ namespace SparkleLib { _IsSyncing = true; _IsPushing = true; - - SparkleEventArgs args = new SparkleEventArgs ("PushingStarted"); - - if (PushingStarted != null) - PushingStarted (this, args); + + SparkleGit git = new SparkleGit (LocalPath, "push origin master"); SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Pushing changes..."); -/* FIXME: SSH transport doesn't work with GitSharp - try { - - PushCommand push_command = new PushCommand () { - Remote = "origin", - Repository = this - }; - - push_command.Execute (); - - } catch (GitSharp.Core.Exceptions.TransportException e) { - - Console.WriteLine (e.Message); + SparkleEventArgs args = new SparkleEventArgs ("PushingStarted"); - } -*/ + if (PushingStarted != null) + PushingStarted (this, args); - Process.StartInfo.Arguments = "push origin master"; - - Process.WaitForExit (); - - Process.Exited += delegate { + + git.Exited += delegate { _IsSyncing = false; _IsPushing = false; - if (Process.ExitCode != 0) { + if (git.ExitCode != 0) { SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Pushing failed."); @@ -859,7 +810,9 @@ namespace SparkleLib { args = new SparkleEventArgs ("PushingFailed"); if (PushingFailed != null) - PushingFailed (this, args); + PushingFailed (this, args); + + CheckForChanges (); } else { @@ -877,33 +830,17 @@ namespace SparkleLib { if (PushingFinished != null) PushingFinished (this, args); + + if (!_IsPolling) + Listener.Announce (_CurrentHash); } }; - Process.Start (); - } - - - // Ignores repos, dotfiles, swap files and the like - private bool ShouldIgnore (string file_path) - { - - if (file_path.EndsWith (".lock") || - file_path.EndsWith ("~") || - file_path.Contains (".git") || - file_path.Contains ("/.") || - file_path.EndsWith (".swp") || - System.IO.Directory.Exists (Path.Combine (LocalPath, file_path))) { - - return true; // Yes, ignore it - - } else { - - return false; - - } + + git.Start (); + git.WaitForExit (); } @@ -946,6 +883,37 @@ namespace SparkleLib { return description; } + + + // Recursively gets a folder's size in bytes + private double CalculateFolderSize (DirectoryInfo parent) + { + + if (!System.IO.Directory.Exists (parent.ToString ())) + return 0; + + double size = 0; + + // Ignore the temporary 'rebase-apply' directory. This prevents potential + // crashes when files are being queried whilst the files have already been deleted. + if (parent.Name.Equals ("rebase-apply")) + return 0; + + foreach (FileInfo file in parent.GetFiles()) { + + if (!file.Exists) + return 0; + + size += file.Length; + + } + + foreach (DirectoryInfo directory in parent.GetDirectories()) + size += CalculateFolderSize (directory); + + return size; + + } // Create a first commit in case the user has cloned @@ -964,49 +932,91 @@ namespace SparkleLib { public List GetCommits (int count) { - if (count <= 0) - return null; - + if (count < 1) + count = 30; + List commits = new List (); - string commit_ref = "HEAD"; + SparkleGit git_log = new SparkleGit (LocalPath, "log -" + count + " --raw --date=iso"); + git_log.Start (); + git_log.WaitForExit (); + + string output = git_log.StandardOutput.ReadToEnd (); + string [] lines = output.Split ("\n".ToCharArray ()); + + List entries = new List (); - try { - - for (int i = 0; i < count; i++) { - - Commit commit = new Commit (this, commit_ref); - - SparkleCommit sparkle_commit = new SparkleCommit (); - - sparkle_commit.UserName = commit.Author.Name; - sparkle_commit.UserEmail = commit.Author.EmailAddress; - sparkle_commit.DateTime = commit.CommitDate.DateTime; - sparkle_commit.Hash = commit.Hash; + int j = 0; + string entry = ""; + foreach (string line in lines) { + + if (line.StartsWith ("commit") && j > 0) { - foreach (Change change in commit.Changes) { + entries.Add (entry); + entry = ""; + + } + + entry += line + "\n"; + j++; - if (change.ChangeType.ToString ().Equals ("Added")) - sparkle_commit.Added.Add (change.Path); + } + - if (change.ChangeType.ToString ().Equals ("Modified")) - sparkle_commit.Edited.Add (change.Path); + foreach (string log_entry in entries) { - if (change.ChangeType.ToString ().Equals ("Deleted")) - sparkle_commit.Deleted.Add (change.Path); + Regex regex = new Regex (@"commit ([a-z0-9]{40})\n" + + "Author: (.+) <(.+)>\n" + + "Date: ([0-9]{4})-([0-9]{2})-([0-9]{2}) " + + "([0-9]{2}):([0-9]{2}):([0-9]{2}) \\+([0-9]{4})\n" + + "*"); + + Match match = regex.Match (log_entry); + if (match.Success) { + + SparkleCommit commit = new SparkleCommit (); + + commit.Hash = match.Groups [1].Value; + commit.UserName = match.Groups [2].Value; + commit.UserEmail = match.Groups [3].Value; + + commit.DateTime = new DateTime (int.Parse (match.Groups [4].Value), + int.Parse (match.Groups [5].Value), int.Parse (match.Groups [6].Value), + int.Parse (match.Groups [7].Value), int.Parse (match.Groups [8].Value), + int.Parse (match.Groups [9].Value)); + + string [] entry_lines = log_entry.Split ("\n".ToCharArray ()); + foreach (string entry_line in entry_lines) { + + if (entry_line.StartsWith (":")) { + + string change_type = entry_line [37].ToString (); + string file_path = entry_line.Substring (39); + + if (change_type.Equals ("A")) { + + commit.Added.Add (file_path); + + } else if (change_type.Equals ("M")) { + + commit.Edited.Add (file_path); + + } else if (change_type.Equals ("D")) { + + commit.Deleted.Add (file_path); + + } + + + } + } - - commits.Add (sparkle_commit); - commit_ref += "^"; - - } - - } catch (System.NullReferenceException) { - - // FIXME: Doesn't show the first commit because it throws - // this exception before getting to it. Seems to be a bug in GitSharp - + + commits.Add (commit); + + } + } return commits; diff --git a/SparkleShare/Mac/AppDelegate.cs b/SparkleShare/Mac/AppDelegate.cs new file mode 100644 index 00000000..061449d4 --- /dev/null +++ b/SparkleShare/Mac/AppDelegate.cs @@ -0,0 +1,21 @@ +using System; +using System.Drawing; +using MonoMac.Foundation; +using MonoMac.AppKit; +using MonoMac.ObjCRuntime; + +namespace test2 +{ + public partial class AppDelegate : NSApplicationDelegate + { + + public AppDelegate () + { + } + + public override void FinishedLaunching (NSObject notification) + { + } + } +} + diff --git a/SparkleShare/Mac/SparkleShare/Info.plist b/SparkleShare/Mac/Info.plist similarity index 70% rename from SparkleShare/Mac/SparkleShare/Info.plist rename to SparkleShare/Mac/Info.plist index 4431992a..8117ef38 100644 --- a/SparkleShare/Mac/SparkleShare/Info.plist +++ b/SparkleShare/Mac/Info.plist @@ -2,26 +2,19 @@ + CFBundleExecutable + CFBundleIconFile - sparkleshare.icns - LSEnvironment - - PATH - /opt/local/bin - + sparkleshare CFBundleIdentifier org.sparkleshare.sparkleshare CFBundleName SparkleShare - CFBundleVersion - 1 LSMinimumSystemVersion 10.6 NSMainNibFile MainMenu NSPrincipalClass NSApplication - LSBackgroundOnly - diff --git a/SparkleShare/Mac/MainMenu.xib b/SparkleShare/Mac/MainMenu.xib new file mode 100644 index 00000000..472b3d05 --- /dev/null +++ b/SparkleShare/Mac/MainMenu.xib @@ -0,0 +1,2245 @@ + + + + 1060 + 10D2162 + 762 + 1038.29 + 460.00 + + com.apple.InterfaceBuilder.CocoaPlugin + 762 + + + YES + + + + YES + com.apple.InterfaceBuilder.CocoaPlugin + + + YES + + YES + + + YES + + + + YES + + NSApplication + + + FirstResponder + + + NSApplication + + + AMainMenu + + YES + + + SparkleShare + + 1048576 + 2147483647 + + NSImage + NSMenuCheckmark + + + NSImage + NSMenuMixedState + + submenuAction: + + SparkleShare + + YES + + + About SparkleShare + + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Services + + 1048576 + 2147483647 + + + submenuAction: + + Services + + YES + + _NSServicesMenu + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Hide SparkleShare + h + 1048576 + 2147483647 + + + + + + Hide Others + h + 1572864 + 2147483647 + + + + + + Show All + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Quit SparkleShare + q + 1048576 + 2147483647 + + + + + _NSAppleMenu + + + + + Edit + + 1048576 + 2147483647 + + + submenuAction: + + Edit + + YES + + + Undo + z + 1048576 + 2147483647 + + + + + + Redo + Z + 1179648 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Cut + x + 1048576 + 2147483647 + + + + + + Copy + c + 1048576 + 2147483647 + + + + + + Paste + v + 1048576 + 2147483647 + + + + + + Paste and Match Style + V + 1572864 + 2147483647 + + + + + + Delete + + 1048576 + 2147483647 + + + + + + Select All + a + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Find + + 1048576 + 2147483647 + + + submenuAction: + + Find + + YES + + + Find… + f + 1048576 + 2147483647 + + + 1 + + + + Find Next + g + 1048576 + 2147483647 + + + 2 + + + + Find Previous + G + 1179648 + 2147483647 + + + 3 + + + + Use Selection for Find + e + 1048576 + 2147483647 + + + 7 + + + + Jump to Selection + j + 1048576 + 2147483647 + + + + + + + + + Spelling and Grammar + + 1048576 + 2147483647 + + + submenuAction: + + Spelling and Grammar + + YES + + + Show Spelling and Grammar + : + 1048576 + 2147483647 + + + + + + Check Document Now + ; + 1048576 + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Check Spelling While Typing + + 1048576 + 2147483647 + + + + + + Check Grammar With Spelling + + 1048576 + 2147483647 + + + + + + Correct Spelling Automatically + + 2147483647 + + + + + + + + + Substitutions + + 1048576 + 2147483647 + + + submenuAction: + + Substitutions + + YES + + + Show Substitutions + + 2147483647 + + + + + + YES + YES + + + 2147483647 + + + + + + Smart Copy/Paste + f + 1048576 + 2147483647 + + + 1 + + + + Smart Quotes + g + 1048576 + 2147483647 + + + 2 + + + + Smart Dashes + + 2147483647 + + + + + + Smart Links + G + 1179648 + 2147483647 + + + 3 + + + + Text Replacement + + 2147483647 + + + + + + + + + Transformations + + 2147483647 + + + submenuAction: + + Transformations + + YES + + + Make Upper Case + + 2147483647 + + + + + + Make Lower Case + + 2147483647 + + + + + + Capitalize + + 2147483647 + + + + + + + + + Speech + + 1048576 + 2147483647 + + + submenuAction: + + Speech + + YES + + + Start Speaking + + 1048576 + 2147483647 + + + + + + Stop Speaking + + 1048576 + 2147483647 + + + + + + + + + + + + Window + + 1048576 + 2147483647 + + + submenuAction: + + Window + + YES + + + Minimize + m + 1048576 + 2147483647 + + + + + + Zoom + + 1048576 + 2147483647 + + + + + + YES + YES + + + 1048576 + 2147483647 + + + + + + Bring All to Front + + 1048576 + 2147483647 + + + + + _NSWindowsMenu + + + + + Help + + 2147483647 + + + submenuAction: + + Help + + YES + + + SparkleShare Help + ? + 1048576 + 2147483647 + + + + + _NSHelpMenu + + + + _NSMainMenu + + + NSFontManager + + + AppDelegate + + + + + YES + + + performMiniaturize: + + + + 37 + + + + arrangeInFront: + + + + 39 + + + + orderFrontStandardAboutPanel: + + + + 142 + + + + toggleContinuousSpellChecking: + + + + 222 + + + + undo: + + + + 223 + + + + copy: + + + + 224 + + + + checkSpelling: + + + + 225 + + + + paste: + + + + 226 + + + + stopSpeaking: + + + + 227 + + + + cut: + + + + 228 + + + + showGuessPanel: + + + + 230 + + + + redo: + + + + 231 + + + + selectAll: + + + + 232 + + + + startSpeaking: + + + + 233 + + + + delete: + + + + 235 + + + + performZoom: + + + + 240 + + + + performFindPanelAction: + + + + 241 + + + + centerSelectionInVisibleArea: + + + + 245 + + + + toggleGrammarChecking: + + + + 347 + + + + toggleSmartInsertDelete: + + + + 355 + + + + toggleAutomaticQuoteSubstitution: + + + + 356 + + + + toggleAutomaticLinkDetection: + + + + 357 + + + + hide: + + + + 367 + + + + hideOtherApplications: + + + + 368 + + + + unhideAllApplications: + + + + 370 + + + + terminate: + + + + 449 + + + + toggleAutomaticSpellingCorrection: + + + + 456 + + + + orderFrontSubstitutionsPanel: + + + + 458 + + + + toggleAutomaticDashSubstitution: + + + + 461 + + + + toggleAutomaticTextReplacement: + + + + 463 + + + + uppercaseWord: + + + + 464 + + + + capitalizeWord: + + + + 467 + + + + lowercaseWord: + + + + 468 + + + + pasteAsPlainText: + + + + 486 + + + + performFindPanelAction: + + + + 487 + + + + performFindPanelAction: + + + + 488 + + + + performFindPanelAction: + + + + 489 + + + + showHelp: + + + + 493 + + + + delegate + + + + 534 + + + + + YES + + 0 + + + + + + -2 + + + File's Owner + + + -1 + + + First Responder + + + -3 + + + Application + + + 29 + + + YES + + + + + + + + + 19 + + + YES + + + + + + 56 + + + YES + + + + + + 217 + + + YES + + + + + + 205 + + + YES + + + + + + + + + + + + + + + + + + + + 202 + + + + + 198 + + + + + 207 + + + + + 214 + + + + + 199 + + + + + 203 + + + + + 197 + + + + + 206 + + + + + 215 + + + + + 218 + + + YES + + + + + + 216 + + + YES + + + + + + 200 + + + YES + + + + + + + + + + + 219 + + + + + 201 + + + + + 204 + + + + + 220 + + + YES + + + + + + + + + + 213 + + + + + 210 + + + + + 221 + + + + + 208 + + + + + 209 + + + + + 57 + + + YES + + + + + + + + + + + + + + 58 + + + + + 134 + + + + + 150 + + + + + 136 + + + + + 144 + + + + + 236 + + + + + 131 + + + YES + + + + + + 149 + + + + + 145 + + + + + 130 + + + + + 24 + + + YES + + + + + + + + + 92 + + + + + 5 + + + + + 239 + + + + + 23 + + + + + 211 + + + YES + + + + + + 212 + + + YES + + + + + + + 195 + + + + + 196 + + + + + 346 + + + + + 348 + + + YES + + + + + + 349 + + + YES + + + + + + + + + + + + 350 + + + + + 351 + + + + + 354 + + + + + 420 + + + + + 450 + + + YES + + + + + + 451 + + + YES + + + + + + + + 452 + + + + + 453 + + + + + 454 + + + + + 457 + + + + + 459 + + + + + 460 + + + + + 462 + + + + + 465 + + + + + 466 + + + + + 485 + + + + + 490 + + + YES + + + + + + 491 + + + YES + + + + + + 492 + + + + + 533 + + + + + + + YES + + YES + -3.IBPluginDependency + 130.IBEditorWindowLastContentRect + 130.IBPluginDependency + 130.ImportedFromIB2 + 130.editorWindowContentRectSynchronizationRect + 131.IBPluginDependency + 131.ImportedFromIB2 + 134.IBPluginDependency + 134.ImportedFromIB2 + 136.IBPluginDependency + 136.ImportedFromIB2 + 144.IBPluginDependency + 144.ImportedFromIB2 + 145.IBPluginDependency + 145.ImportedFromIB2 + 149.IBPluginDependency + 149.ImportedFromIB2 + 150.IBPluginDependency + 150.ImportedFromIB2 + 19.IBPluginDependency + 19.ImportedFromIB2 + 195.IBPluginDependency + 195.ImportedFromIB2 + 196.IBPluginDependency + 196.ImportedFromIB2 + 197.IBPluginDependency + 197.ImportedFromIB2 + 198.IBPluginDependency + 198.ImportedFromIB2 + 199.IBPluginDependency + 199.ImportedFromIB2 + 200.IBEditorWindowLastContentRect + 200.IBPluginDependency + 200.ImportedFromIB2 + 200.editorWindowContentRectSynchronizationRect + 201.IBPluginDependency + 201.ImportedFromIB2 + 202.IBPluginDependency + 202.ImportedFromIB2 + 203.IBPluginDependency + 203.ImportedFromIB2 + 204.IBPluginDependency + 204.ImportedFromIB2 + 205.IBEditorWindowLastContentRect + 205.IBPluginDependency + 205.ImportedFromIB2 + 205.editorWindowContentRectSynchronizationRect + 206.IBPluginDependency + 206.ImportedFromIB2 + 207.IBPluginDependency + 207.ImportedFromIB2 + 208.IBPluginDependency + 208.ImportedFromIB2 + 209.IBPluginDependency + 209.ImportedFromIB2 + 210.IBPluginDependency + 210.ImportedFromIB2 + 211.IBPluginDependency + 211.ImportedFromIB2 + 212.IBPluginDependency + 212.ImportedFromIB2 + 212.editorWindowContentRectSynchronizationRect + 213.IBPluginDependency + 213.ImportedFromIB2 + 214.IBPluginDependency + 214.ImportedFromIB2 + 215.IBPluginDependency + 215.ImportedFromIB2 + 216.IBPluginDependency + 216.ImportedFromIB2 + 217.IBPluginDependency + 217.ImportedFromIB2 + 218.IBPluginDependency + 218.ImportedFromIB2 + 219.IBPluginDependency + 219.ImportedFromIB2 + 220.IBEditorWindowLastContentRect + 220.IBPluginDependency + 220.ImportedFromIB2 + 220.editorWindowContentRectSynchronizationRect + 221.IBPluginDependency + 221.ImportedFromIB2 + 23.IBPluginDependency + 23.ImportedFromIB2 + 236.IBPluginDependency + 236.ImportedFromIB2 + 239.IBPluginDependency + 239.ImportedFromIB2 + 24.IBEditorWindowLastContentRect + 24.IBPluginDependency + 24.ImportedFromIB2 + 24.editorWindowContentRectSynchronizationRect + 29.IBEditorWindowLastContentRect + 29.IBPluginDependency + 29.ImportedFromIB2 + 29.WindowOrigin + 29.editorWindowContentRectSynchronizationRect + 346.IBPluginDependency + 346.ImportedFromIB2 + 348.IBPluginDependency + 348.ImportedFromIB2 + 349.IBEditorWindowLastContentRect + 349.IBPluginDependency + 349.ImportedFromIB2 + 349.editorWindowContentRectSynchronizationRect + 350.IBPluginDependency + 350.ImportedFromIB2 + 351.IBPluginDependency + 351.ImportedFromIB2 + 354.IBPluginDependency + 354.ImportedFromIB2 + 450.IBPluginDependency + 451.IBEditorWindowLastContentRect + 451.IBPluginDependency + 452.IBPluginDependency + 453.IBPluginDependency + 454.IBPluginDependency + 457.IBPluginDependency + 459.IBPluginDependency + 460.IBPluginDependency + 462.IBPluginDependency + 465.IBPluginDependency + 466.IBPluginDependency + 485.IBPluginDependency + 490.IBPluginDependency + 491.IBEditorWindowLastContentRect + 491.IBPluginDependency + 492.IBPluginDependency + 5.IBPluginDependency + 5.ImportedFromIB2 + 56.IBPluginDependency + 56.ImportedFromIB2 + 57.IBEditorWindowLastContentRect + 57.IBPluginDependency + 57.ImportedFromIB2 + 57.editorWindowContentRectSynchronizationRect + 58.IBPluginDependency + 58.ImportedFromIB2 + 92.IBPluginDependency + 92.ImportedFromIB2 + + + YES + com.apple.InterfaceBuilder.CocoaPlugin + {{529, 686}, {64, 6}} + com.apple.InterfaceBuilder.CocoaPlugin + + {{436, 809}, {64, 6}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{753, 187}, {275, 113}} + com.apple.InterfaceBuilder.CocoaPlugin + + {{608, 612}, {275, 83}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{470, 439}, {254, 283}} + com.apple.InterfaceBuilder.CocoaPlugin + + {{187, 434}, {243, 243}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{608, 612}, {167, 43}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{753, 217}, {238, 103}} + com.apple.InterfaceBuilder.CocoaPlugin + + {{608, 612}, {241, 103}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{514, 649}, {194, 73}} + com.apple.InterfaceBuilder.CocoaPlugin + + {{525, 802}, {197, 73}} + {{346, 722}, {300, 20}} + com.apple.InterfaceBuilder.CocoaPlugin + + {74, 862} + {{6, 978}, {478, 20}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{746, 287}, {220, 133}} + com.apple.InterfaceBuilder.CocoaPlugin + + {{608, 612}, {215, 63}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + {{724, 419}, {170, 63}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{585, 699}, {194, 23}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{358, 569}, {223, 153}} + com.apple.InterfaceBuilder.CocoaPlugin + + {{23, 794}, {245, 183}} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + + + + YES + + + YES + + + + + YES + + + YES + + + + 534 + + + + YES + + AppDelegate + NSResponder + + IBUserSource + + + + + + YES + + NSApplication + NSResponder + + IBFrameworkSource + AppKit.framework/Headers/NSApplication.h + + + + NSApplication + + IBFrameworkSource + AppKit.framework/Headers/NSApplicationScripting.h + + + + NSApplication + + IBFrameworkSource + AppKit.framework/Headers/NSColorPanel.h + + + + NSApplication + + IBFrameworkSource + AppKit.framework/Headers/NSHelpManager.h + + + + NSApplication + + IBFrameworkSource + AppKit.framework/Headers/NSPageLayout.h + + + + NSApplication + + IBFrameworkSource + AppKit.framework/Headers/NSUserInterfaceItemSearching.h + + + + NSBrowser + NSControl + + IBFrameworkSource + AppKit.framework/Headers/NSBrowser.h + + + + NSControl + NSView + + IBFrameworkSource + AppKit.framework/Headers/NSControl.h + + + + NSFontManager + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSFontManager.h + + + + NSFormatter + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFormatter.h + + + + NSMatrix + NSControl + + IBFrameworkSource + AppKit.framework/Headers/NSMatrix.h + + + + NSMenu + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSMenu.h + + + + NSMenuItem + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSMenuItem.h + + + + NSMovieView + NSView + + IBFrameworkSource + AppKit.framework/Headers/NSMovieView.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSAccessibility.h + + + + NSObject + + + + NSObject + + + + NSObject + + + + NSObject + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSDictionaryController.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSDragging.h + + + + NSObject + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSFontPanel.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSKeyValueBinding.h + + + + NSObject + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSNibLoading.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSOutlineView.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSPasteboard.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSSavePanel.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSTableView.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSToolbarItem.h + + + + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSView.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSClassDescription.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObjectScripting.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPortCoder.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSScriptClassDescription.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSScriptKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSScriptObjectSpecifiers.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSScriptWhoseTests.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLDownload.h + + + + NSResponder + + IBFrameworkSource + AppKit.framework/Headers/NSInterfaceStyle.h + + + + NSResponder + NSObject + + IBFrameworkSource + AppKit.framework/Headers/NSResponder.h + + + + NSTableView + NSControl + + + + NSText + NSView + + IBFrameworkSource + AppKit.framework/Headers/NSText.h + + + + NSTextView + NSText + + IBFrameworkSource + AppKit.framework/Headers/NSTextView.h + + + + NSView + + IBFrameworkSource + AppKit.framework/Headers/NSClipView.h + + + + NSView + + + + NSView + + IBFrameworkSource + AppKit.framework/Headers/NSRulerView.h + + + + NSView + NSResponder + + + + NSWindow + + IBFrameworkSource + AppKit.framework/Headers/NSDrawer.h + + + + NSWindow + NSResponder + + IBFrameworkSource + AppKit.framework/Headers/NSWindow.h + + + + NSWindow + + IBFrameworkSource + AppKit.framework/Headers/NSWindowScripting.h + + + + + 0 + IBCocoaFramework + + com.apple.InterfaceBuilder.CocoaPlugin.macosx + + + + com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 + + + YES + ../MacCocoaApp.xcodeproj + 3 + + YES + + YES + NSMenuCheckmark + NSMenuMixedState + + + YES + {9, 8} + {7, 2} + + + + diff --git a/SparkleShare/Mac/SparkleShare/MainMenu.xib.designer.cs b/SparkleShare/Mac/MainMenu.xib.designer.cs similarity index 100% rename from SparkleShare/Mac/SparkleShare/MainMenu.xib.designer.cs rename to SparkleShare/Mac/MainMenu.xib.designer.cs diff --git a/SparkleShare/Mac/SparkleIntro.cs b/SparkleShare/Mac/SparkleIntro.cs new file mode 100644 index 00000000..7f15022b --- /dev/null +++ b/SparkleShare/Mac/SparkleIntro.cs @@ -0,0 +1,558 @@ +// 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.Drawing; +using System.IO; +using System.Timers; +using MonoMac.Foundation; +using MonoMac.AppKit; +using MonoMac.ObjCRuntime; +using MonoMac.WebKit; +using Mono.Unix; + +namespace SparkleShare { + + public class SparkleIntro : SparkleWindow { + + private NSButton ContinueButton; + private NSButton SyncButton; + private NSButton TryAgainButton; + private NSButton CancelButton; + private NSButton SkipButton; + private NSButton OpenFolderButton; + private NSButton FinishButton; + private NSForm UserInfoForm; + private NSProgressIndicator ProgressIndicator; + private NSTextField AddressTextField; + private NSTextField FolderNameTextField; + private NSTextField ServerTypeLabel; + private NSTextField AddressLabel; + private NSTextField FolderNameLabel; + private NSTextField FolderNameHelpLabel; + private NSButtonCell ButtonCellProto; + private NSMatrix Matrix; + private int ServerType; + + private bool ServerFormOnly; + + + public SparkleIntro () : base () + { + + ServerFormOnly = false; + + } + + + public void ShowAccountForm () + { + + Reset (); + + Header = "Welcome to SparkleShare!"; + Description = "Before we can create a SparkleShare folder on this " + + "computer, we need some information from you."; + + + UserInfoForm = new NSForm (new RectangleF (250, 115, 350, 64)); + UserInfoForm.AddEntry ("Full Name:"); + UserInfoForm.AddEntry ("Email Address:"); + UserInfoForm.CellSize = new SizeF (280, 22); + UserInfoForm.IntercellSpacing = new SizeF (4, 4); + + string full_name = new UnixUserInfo (UnixEnvironment.UserName).RealName; + UserInfoForm.Cells [0].StringValue = full_name; + UserInfoForm.Cells [1].StringValue = SparkleShare.Controller.UserEmail; + + + ContinueButton = new NSButton () { + Title = "Continue", + Enabled = false + }; + + ContinueButton.Activated += delegate { + + SparkleShare.Controller.UserName = UserInfoForm.Cells [0].StringValue.Trim (); + SparkleShare.Controller.UserEmail = UserInfoForm.Cells [1].StringValue.Trim (); + SparkleShare.Controller.GenerateKeyPair (); + SparkleShare.Controller.FirstRun = false; + + InvokeOnMainThread (delegate { + ShowServerForm (); + }); + + }; + + + // TODO: Ugly hack, do properly with events + Timer timer = new Timer () { + Interval = 50 + }; + + timer.Elapsed += delegate { + + InvokeOnMainThread (delegate { + + bool name_is_correct = + !UserInfoForm.Cells [0].StringValue.Trim ().Equals (""); + + bool email_is_correct = SparkleShare.Controller.IsValidEmail + (UserInfoForm.Cells [1].StringValue.Trim ()); + + ContinueButton.Enabled = (name_is_correct && email_is_correct); + + }); + + }; + + timer.Start (); + + ContentView.AddSubview (UserInfoForm); + Buttons.Add (ContinueButton); + + ShowAll (); + + } + + + public void ShowServerForm (bool server_form_only) + { + + ServerFormOnly = server_form_only; + ShowServerForm (); + + } + + + public void ShowServerForm () + { + + Reset (); + + Header = "Where is your remote folder?"; + Description = ""; + + + ServerTypeLabel = new NSTextField () { + Alignment = (uint) NSTextAlignment.Right, + BackgroundColor = NSColor.WindowBackground, + Bordered = false, + Editable = false, + Frame = new RectangleF (150, Frame.Height - 139 , 160, 17), + StringValue = "Server Type:", + Font = SparkleUI.Font + }; + + AddressLabel = new NSTextField () { + Alignment = (uint) NSTextAlignment.Right, + BackgroundColor = NSColor.WindowBackground, + Bordered = false, + Editable = false, + Frame = new RectangleF (150, Frame.Height - 237 , 160, 17), + StringValue = "Address:", + Font = SparkleUI.Font + }; + + FolderNameLabel = new NSTextField () { + Alignment = (uint) NSTextAlignment.Right, + BackgroundColor = NSColor.WindowBackground, + Bordered = false, + Editable = false, + Frame = new RectangleF (150, Frame.Height - 264 , 160, 17), + StringValue = "Folder Name:", + Font = SparkleUI.Font + }; + + + AddressTextField = new NSTextField () { + Frame = new RectangleF (320, Frame.Height - 240 , 256, 22), + Font = SparkleUI.Font + }; + + FolderNameTextField = new NSTextField () { + Frame = new RectangleF (320, Frame.Height - (240 + 22 + 4) , 256, 22), + StringValue = "" + }; + + + FolderNameHelpLabel = new NSTextField () { + BackgroundColor = NSColor.WindowBackground, + Bordered = false, + TextColor = NSColor.DisabledControlText, + Editable = false, + Frame = new RectangleF (320, Frame.Height - 285 , 200, 17), + StringValue = "e.g. ‘rupert/website-design’" + }; + + + ServerType = 0; + + ButtonCellProto = new NSButtonCell (); + ButtonCellProto.SetButtonType (NSButtonType.Radio) ; + + Matrix = new NSMatrix (new RectangleF (315, 180, 256, 78), + NSMatrixMode.Radio, ButtonCellProto, 4, 1); + + Matrix.CellSize = new SizeF (256, 18); + + Matrix.Cells [0].Title = "My own server"; + Matrix.Cells [1].Title = "Github"; + Matrix.Cells [2].Title = "Gitorious"; + Matrix.Cells [3].Title = "The GNOME Project"; + + foreach (NSCell cell in Matrix.Cells) + cell.Font = SparkleUI.Font; + + // TODO: Ugly hack, do properly with events + Timer timer = new Timer () { + Interval = 50 + }; + + timer.Elapsed += delegate { + + InvokeOnMainThread (delegate { + + if (Matrix.SelectedRow != ServerType) { + ServerType = Matrix.SelectedRow; + + AddressTextField.Enabled = (ServerType == 0); + + switch (ServerType) { + + case 0: + AddressTextField.StringValue = ""; + FolderNameHelpLabel.StringValue = "e.g. ‘rupert/website-design’"; + break; + + case 1: + AddressTextField.StringValue = "ssh://git@github.com/"; + FolderNameHelpLabel.StringValue = "e.g. ‘rupert/website-design’"; + break; + + case 2: + AddressTextField.StringValue = "ssh://git@gitorious.org/"; + FolderNameHelpLabel.StringValue = "e.g. ‘project/website-design’"; + break; + + case 3: + AddressTextField.StringValue = "ssh://git@gnome.org/git/"; + FolderNameHelpLabel.StringValue = "e.g. ‘gnome-icon-theme’"; + break; + + } + + } + + + if (ServerType == 0 && !AddressTextField.StringValue.Trim ().Equals ("") + && !FolderNameTextField.StringValue.Trim ().Equals ("")) { + + SyncButton.Enabled = true; + + } else if (ServerType != 0 && + !FolderNameTextField.StringValue.Trim ().Equals ("")) { + + SyncButton.Enabled = true; + + } else { + + SyncButton.Enabled = false; + + } + + }); + + }; + + timer.Start (); + + + ContentView.AddSubview (ServerTypeLabel); + ContentView.AddSubview (Matrix); + + ContentView.AddSubview (AddressLabel); + ContentView.AddSubview (AddressTextField); + + ContentView.AddSubview (FolderNameLabel); + ContentView.AddSubview (FolderNameTextField); + ContentView.AddSubview (FolderNameHelpLabel); + + + SyncButton = new NSButton () { + Title = "Sync", + Enabled = false + }; + + + SyncButton.Activated += delegate { + + string name = FolderNameTextField.StringValue; + + // Remove the starting slash if there is one + if (name.StartsWith ("/")) + name = name.Substring (1); + + string server = AddressTextField.StringValue; + + if (name.EndsWith ("/")) + name = name.TrimEnd ("/".ToCharArray ()); + + if (name.StartsWith ("/")) + name = name.TrimStart ("/".ToCharArray ()); + + if (server.StartsWith ("ssh://")) + server = server.Substring (6); + + if (ServerType == 0) { + + // Use the default user 'git' if no username is specified + if (!server.Contains ("@")) + server = "git@" + server; + + // Prepend the Secure Shell protocol when it isn't specified + if (!server.StartsWith ("ssh://")) + server = "ssh://" + server; + + // Remove the trailing slash if there is one + if (server.EndsWith ("/")) + server = server.TrimEnd ("/".ToCharArray ()); + + } + + if (ServerType == 2) { + + server = "ssh://git@gitorious.org"; + + if (!name.EndsWith (".git")) { + + if (!name.Contains ("/")) + name = name + "/" + name; + + name += ".git"; + + } + + } + + if (ServerType == 1) + server = "ssh://git@github.com"; + + if (ServerType == 3) + server = "ssh://git@gnome.org/git/"; + + string url = server + "/" + name; + string canonical_name = Path.GetFileNameWithoutExtension (name); + + + ShowSyncingPage (canonical_name); + + + SparkleShare.Controller.FolderFetched += delegate { + + InvokeOnMainThread (delegate { + ShowSuccessPage (canonical_name); + }); + + }; + + SparkleShare.Controller.FolderFetchError += delegate { + + InvokeOnMainThread (delegate { + ShowErrorPage (); + }); + + }; + + + SparkleShare.Controller.FetchFolder (url, name); + + }; + + + Buttons.Add (SyncButton); + + + if (ServerFormOnly) { + + CancelButton = new NSButton () { + Title = "Cancel" + }; + + CancelButton.Activated += delegate { + InvokeOnMainThread (delegate { + Close (); + }); + }; + + Buttons.Add (CancelButton); + + } else { + + SkipButton = new NSButton () { + Title = "Skip" + }; + + SkipButton.Activated += delegate { + InvokeOnMainThread (delegate { + ShowCompletedPage (); + }); + }; + + Buttons.Add (SkipButton); + + } + + ShowAll (); + + } + + + public void ShowErrorPage () + { + + Reset (); + + Header = "Something went wrong…"; + Description = ""; + + + TryAgainButton = new NSButton () { + Title = "Try again…" + }; + + TryAgainButton.Activated += delegate { + InvokeOnMainThread (delegate { + ShowServerForm (); + }); + }; + + + Buttons.Add (TryAgainButton); + + ShowAll (); + + } + + + private void ShowSyncingPage (string name) + { + + Reset (); + + Header = "Syncing folder ‘" + name + "’…"; + Description = "This may take a while.\n" + + "You sure it’s not coffee o-clock?"; + + + ProgressIndicator = new NSProgressIndicator () { + Frame = new RectangleF (190, Frame.Height - 200, 640 - 150 - 80, 20), + Style = NSProgressIndicatorStyle.Bar + }; + + ProgressIndicator.StartAnimation (this); + + ContentView.AddSubview (ProgressIndicator); + + + FinishButton = new NSButton () { + Title = "Finish", + Enabled = false + }; + + Buttons.Add (FinishButton); + + ShowAll (); + + } + + + public void ShowSuccessPage (string folder_name) + { + + Reset (); + + Header = "Folder synced succesfully!"; + Description = "Now you can access the synced files from ‘" + folder_name + "’ in " + + "your SparkleShare folder."; + + + FinishButton = new NSButton () { + Title = "Finish" + }; + + FinishButton.Activated += delegate { + InvokeOnMainThread (delegate { + SparkleUI.StatusIcon.CreateMenu (); + Close (); + }); + }; + + + OpenFolderButton = new NSButton () { + Title = "Open Folder" + }; + + OpenFolderButton.Activated += delegate { + SparkleShare.Controller.OpenSparkleShareFolder (folder_name); + }; + + + Buttons.Add (FinishButton); + Buttons.Add (OpenFolderButton); + + ShowAll (); + + NSApplication.SharedApplication.RequestUserAttention + (NSRequestUserAttentionType.CriticalRequest); + + } + + + private void ShowCompletedPage () + { + + Reset (); + + Header = "SparkleShare is ready to go!"; + Description = "Now you can start accepting invitations from others. " + + "Just click on invitations you get by email and " + + "we will take care of the rest."; + + + FinishButton = new NSButton () { + Title = "Finish" + }; + + FinishButton.Activated += delegate { + InvokeOnMainThread (delegate { + SparkleUI.StatusIcon.CreateMenu (); + Close (); + }); + + }; + + Buttons.Add (FinishButton); + + ShowAll (); + + } + + } + + +} \ No newline at end of file diff --git a/SparkleShare/Mac/SparkleLog.cs b/SparkleShare/Mac/SparkleLog.cs new file mode 100644 index 00000000..559ffc1c --- /dev/null +++ b/SparkleShare/Mac/SparkleLog.cs @@ -0,0 +1,181 @@ +// 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.Drawing; +using MonoMac.Foundation; +using MonoMac.AppKit; +using MonoMac.ObjCRuntime; +using MonoMac.WebKit; + +using System.IO; + +namespace SparkleShare { + + public class SparkleLog : NSWindow { + + public readonly string LocalPath; + + private WebView WebView; + private NSButton CloseButton; + private NSButton OpenFolderButton; + private NSBox Separator; + + public SparkleLog (IntPtr handle) : base (handle) { } + + public SparkleLog (string path) : base () + { + + LocalPath = path; + + Delegate = new SparkleLogDelegate (); + + SetFrame (new RectangleF (0, 0, 480, 640), true); + Center (); + + // Open slightly off center for each consecutive window + if (SparkleUI.OpenLogs.Count > 0) { + + RectangleF offset = new RectangleF (Frame.X + (SparkleUI.OpenLogs.Count * 20), + Frame.Y - (SparkleUI.OpenLogs.Count * 20), Frame.Width, Frame.Height); + + SetFrame (offset, true); + + } + + StyleMask = (NSWindowStyle.Closable | + NSWindowStyle.Miniaturizable | + NSWindowStyle.Titled); + + MaxSize = new SizeF (480, 640); + MinSize = new SizeF (480, 640); + HasShadow = true; + BackingType = NSBackingStore.Buffered; + + CreateEventLog (); + UpdateEventLog (); + + ContentView.AddSubview (WebView); + + OpenFolderButton = new NSButton (new RectangleF (16, 12, 120, 32)) { + Title = "Open Folder", + BezelStyle = NSBezelStyle.Rounded , + Font = SparkleUI.Font + }; + + OpenFolderButton.Activated += delegate { + SparkleShare.Controller.OpenSparkleShareFolder (LocalPath); + }; + + ContentView.AddSubview (OpenFolderButton); + + + CloseButton = new NSButton (new RectangleF (480 - 120 - 16, 12, 120, 32)) { + Title = "Close", + BezelStyle = NSBezelStyle.Rounded, + Font = SparkleUI.Font + }; + + CloseButton.Activated += delegate { + InvokeOnMainThread (delegate { + PerformClose (this); + }); + }; + + ContentView.AddSubview (CloseButton); + + + string name = Path.GetFileName (LocalPath); + Title = String.Format ("Events in ‘{0}’", name); + + Separator = new NSBox (new RectangleF (0, 58, 480, 1)) { + BorderColor = NSColor.LightGray, + BoxType = NSBoxType.NSBoxCustom + }; + + ContentView.AddSubview (Separator); + + OrderFrontRegardless (); + + } + + + public void UpdateEventLog () + { + + string folder_name = Path.GetFileName (LocalPath); + string html = SparkleShare.Controller.GetHTMLLog (folder_name); + + html = html.Replace ("", "Lucida Grande"); + html = html.Replace ("", "13.4px"); + html = html.Replace ("", "#bbb"); + html = html.Replace ("", "#ddd"); + html = html.Replace ("", "#f5f5f5"); + html = html.Replace ("", "#0085cf"); + html = html.Replace ("", + "file://" + Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "avatar-default.png")); + + WebView.MainFrame.LoadHtmlString (html, new NSUrl ("")); + + Update (); + + } + + + private WebView CreateEventLog () + { + + WebView = new WebView (new RectangleF (0, 59, 480, 559), "", ""){ + PolicyDelegate = new SparkleWebPolicyDelegate () + }; + + return WebView; + + } + + } + + + public class SparkleLogDelegate : NSWindowDelegate { + + public override bool WindowShouldClose (NSObject sender) + { + + (sender as SparkleLog).OrderOut (this); + return false; + + } + + } + + + public class SparkleWebPolicyDelegate : WebPolicyDelegate { + + public override void DecidePolicyForNavigation (WebView web_view, NSDictionary action_info, + NSUrlRequest request, WebFrame frame, NSObject decision_token) + { + + string file_path = request.Url.ToString (); + file_path = file_path.Replace ("%20", " "); + + NSWorkspace.SharedWorkspace.OpenFile (file_path); + + } + + } + +} \ No newline at end of file diff --git a/SparkleShare/Mac/SparkleShare/SparkleMacController.cs b/SparkleShare/Mac/SparkleMacController.cs similarity index 59% rename from SparkleShare/Mac/SparkleShare/SparkleMacController.cs rename to SparkleShare/Mac/SparkleMacController.cs index 3937009b..d08692a6 100644 --- a/SparkleShare/Mac/SparkleShare/SparkleMacController.cs +++ b/SparkleShare/Mac/SparkleMacController.cs @@ -49,8 +49,8 @@ namespace SparkleShare { // list of bookmarked places public override void AddToBookmarks () { - + // TODO } @@ -61,11 +61,8 @@ namespace SparkleShare { if (!Directory.Exists (SparklePaths.SparklePath)) { - Directory.CreateDirectory (SparklePaths.SparklePath); - - NSWorkspace.SharedWorkspace.SetIconforFile (NSImage.ImageNamed ("sparkleshare.icns"), - SparklePaths.SparklePath, 0); - + Directory.CreateDirectory (SparklePaths.SparklePath); + return true; } else { @@ -82,14 +79,72 @@ namespace SparkleShare { { string folder = Path.Combine (SparklePaths.SparklePath, subfolder); + folder.Replace (" ", "\\ "); // Escape space-characters + + NSWorkspace.SharedWorkspace.OpenFile (folder); + + } + + + public override string EventLogHTML + { + + get { + + string resource_path = NSBundle.MainBundle.ResourcePath; - Process process = new Process (); - process.StartInfo.Arguments = folder.Replace (" ", "\\ "); // Escape space-characters - process.StartInfo.FileName = "open"; - process.Start (); + string html_path = Path.Combine (resource_path, "HTML", "event-log.html"); + + StreamReader reader = new StreamReader (html_path); + string html = reader.ReadToEnd (); + reader.Close (); + + return html; + + } } + + public override string DayEntryHTML + { + + get { + + string resource_path = NSBundle.MainBundle.ResourcePath; + + string html_path = Path.Combine (resource_path, "HTML", "day-entry.html"); + + StreamReader reader = new StreamReader (html_path); + string html = reader.ReadToEnd (); + reader.Close (); + + return html; + + } + + } + + + public override string EventEntryHTML + { + + get { + + string resource_path = NSBundle.MainBundle.ResourcePath; + + string html_path = Path.Combine (resource_path, "HTML", "event-entry.html"); + + StreamReader reader = new StreamReader (html_path); + string html = reader.ReadToEnd (); + reader.Close (); + + return html; + + } + + } + } } \ No newline at end of file diff --git a/SparkleShare/Mac/SparkleShare.csproj b/SparkleShare/Mac/SparkleShare.csproj new file mode 100644 index 00000000..dcb392ce --- /dev/null +++ b/SparkleShare/Mac/SparkleShare.csproj @@ -0,0 +1,161 @@ + + + + Debug + AnyCPU + 10.0.0 + 2.0 + {CF5BC8DB-A633-4FCC-8A3E-E3AC9B59FABC} + {1C533B1C-72DD-4CB1-9F6B-BF11D93BCFBE};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Exe + SparkleShare + SparkleShare + v4.0 + 0.2 + + + true + full + false + bin\Debug + DEBUG + prompt + 4 + false + + + none + false + bin\Release + prompt + 4 + false + + + + False + + + False + + + False + + + False + + + False + + + False + + + False + ..\..\bin\SparkleLib.dll + + + False + + + False + ..\..\bin\DiffieHellman.dll + + + False + ..\..\bin\GitSharp.Core.dll + + + False + ..\..\bin\GitSharp.dll + + + False + ..\..\bin\Meebey.SmartIrc4net.dll + + + False + ..\..\bin\Org.Mentalis.Security.dll + + + False + ..\..\bin\Tamir.SharpSSH.dll + + + + + MainMenu.xib + + + MainMenu.xib + + + SparkleController.cs + + + + + + + + + SparkleShare.cs + + + + + + + + + + + + + HTML\day-entry.html + + + HTML\event-entry.html + + + HTML\event-log.html + + + Pixmaps\side-splash.png + + + Pixmaps\avatar-default.png + + + sparkleshare-mac.icns + + + sparkleshare.icns + + + Pixmaps\idle-active.png + + + Pixmaps\idle.png + + + Pixmaps\idle0.png + + + Pixmaps\idle1.png + + + Pixmaps\idle2.png + + + Pixmaps\idle3.png + + + Pixmaps\idle4.png + + + + + + + diff --git a/SparkleShare/Mac/SparkleShare.sln b/SparkleShare/Mac/SparkleShare.sln new file mode 100644 index 00000000..a3404e29 --- /dev/null +++ b/SparkleShare/Mac/SparkleShare.sln @@ -0,0 +1,21 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SparkleShare", "SparkleShare.csproj", "{CF5BC8DB-A633-4FCC-8A3E-E3AC9B59FABC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CF5BC8DB-A633-4FCC-8A3E-E3AC9B59FABC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CF5BC8DB-A633-4FCC-8A3E-E3AC9B59FABC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CF5BC8DB-A633-4FCC-8A3E-E3AC9B59FABC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CF5BC8DB-A633-4FCC-8A3E-E3AC9B59FABC}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(MonoDevelopProperties) = preSolution + StartupItem = SparkleShare.csproj + version = 0.2 + EndGlobalSection +EndGlobal diff --git a/SparkleShare/Mac/SparkleShare/Layout.cs b/SparkleShare/Mac/SparkleShare/Layout.cs deleted file mode 100644 index 56bccafd..00000000 --- a/SparkleShare/Mac/SparkleShare/Layout.cs +++ /dev/null @@ -1,298 +0,0 @@ -// -// Layout.cs -// -// Author: -// Michael Hutchinson -// -// Copyright (c) 2010 Novell, Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using System; -using System.Collections.Generic; -using System.Drawing; -using MonoMac.AppKit; -using System.Linq; -namespace MonoDevelop.Platform.Mac -{ - interface ILayout - { - LayoutRequest BeginLayout (); - void EndLayout (LayoutRequest request, PointF origin, SizeF allocation); - } - - class LayoutRequest - { - public SizeF Size { get; set; } - public bool Visible { get; set; } - public bool ExpandWidth { get; set; } - public bool ExpandHeight { get; set; } - } - - abstract class LayoutBox : IEnumerable, ILayout - { - List children = new List (); - - public float Spacing { get; set; } - public float PadLeft { get; set; } - public float PadRight { get; set; } - public float PadTop { get; set; } - public float PadBottom { get; set; } - public LayoutAlign Align { get; set; } - - public LayoutDirection Direction { get; set; } - - public LayoutBox (LayoutDirection direction, float spacing) : this (direction, spacing, 0) - { - } - - public LayoutBox (LayoutDirection direction, float spacing, float padding) - { - PadLeft = PadRight = PadTop = PadBottom = padding; - this.Direction = direction; - this.Spacing = spacing; - this.Align = LayoutAlign.Center; - } - - public int Count { get { return children.Count; } } - - bool IsHorizontal { get { return Direction == LayoutDirection.Horizontal; } } - - public IEnumerator GetEnumerator () - { - return children.GetEnumerator (); - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator () - { - return children.GetEnumerator (); - } - - public void Add (ILayout child) - { - children.Add (child); - OnChildAdded (child); - } - - ContainerLayoutRequest request = new ContainerLayoutRequest (); - - public virtual LayoutRequest BeginLayout () - { - float width = 0; - float height = 0; - - request.ChildRequests.Clear (); - request.ChildRequests.AddRange (children.Select (c => c.BeginLayout ())); - - foreach (var r in request.ChildRequests) { - if (!r.Visible) - continue; - request.Visible = true; - if (r.ExpandWidth) - request.ExpandWidth = true; - if (r.ExpandHeight) - request.ExpandHeight = true; - - if (IsHorizontal) { - if (width != 0) - width += Spacing; - width += r.Size.Width; - height = Math.Max (height, r.Size.Height); - } else { - if (height != 0) - height += Spacing; - height += r.Size.Height; - width = Math.Max (width, r.Size.Width); - } - } - - request.Size = new SizeF (width + PadLeft + PadRight, height + PadTop + PadBottom); - return request; - } - - public virtual void EndLayout (LayoutRequest request, PointF origin, SizeF allocation) - { - var childRequests = ((ContainerLayoutRequest) request).ChildRequests; - - allocation = new SizeF (allocation.Width - PadLeft - PadRight, allocation.Height - PadBottom - PadTop); - origin = new PointF (origin.X + PadLeft, origin.Y + PadBottom); - - var size = request.Size; - size.Height -= (PadTop + PadBottom); - size.Width -= (PadLeft + PadRight); - - int wExpandCount = 0; - int hExpandCount = 0; - int visibleCount = 0; - foreach (var childRequest in childRequests) { - if (childRequest.Visible) - visibleCount++; - else - continue; - if (childRequest.ExpandWidth) - wExpandCount++; - if (childRequest.ExpandHeight) - hExpandCount++; - } - - float wExpand = 0; - if (allocation.Width > size.Width) { - wExpand = allocation.Width - size.Width; - if (wExpandCount > 0) - wExpand /= wExpandCount; - } - float hExpand = 0; - if (allocation.Height > size.Height) { - hExpand = allocation.Height - size.Height; - if (hExpandCount > 0) - hExpand /= hExpandCount; - } - - if (Direction == LayoutDirection.Horizontal) { - float pos = PadLeft; - if (wExpandCount == 0) { - if (Align == LayoutAlign.End) - pos += wExpand; - else if (Align == LayoutAlign.Center) - pos += wExpand / 2; - } - for (int i = 0; i < childRequests.Count; i++) { - var child = children[i]; - var childReq = childRequests[i]; - if (!childReq.Visible) - continue; - - var childSize = new SizeF (childReq.Size.Width, allocation.Height); - if (childReq.ExpandWidth) { - childSize.Width += wExpand; - } else if (hExpandCount == 0 && Align == LayoutAlign.Fill) { - childSize.Width += wExpand / visibleCount; - } - - child.EndLayout (childReq, new PointF (pos, origin.Y), childSize); - pos += childSize.Width + Spacing; - } - } else { - float pos = PadBottom; - if (hExpandCount == 0) { - if (Align == LayoutAlign.End) - pos += hExpand; - else if (Align == LayoutAlign.Center) - pos += hExpand / 2; - } - for (int i = 0; i < childRequests.Count; i++) { - var child = children[i]; - var childReq = childRequests[i]; - if (!childReq.Visible) - continue; - - var childSize = new SizeF (allocation.Width, childReq.Size.Height); - if (childReq.ExpandHeight) { - childSize.Height += hExpand; - } else if (hExpandCount == 0 && Align == LayoutAlign.Fill) { - childSize.Height += hExpand / visibleCount; - } - - child.EndLayout (childReq, new PointF (origin.X, pos), childSize); - pos += childSize.Height + Spacing; - } - } - } - - protected abstract void OnChildAdded (ILayout child); - - class ContainerLayoutRequest : LayoutRequest - { - public List ChildRequests = new List (); - } - } - - public enum LayoutAlign - { - Begin, Center, End, Fill - } - - public enum LayoutDirection - { - Horizontal, Vertical - } - - abstract class LayoutAlignment : ILayout - { - public LayoutAlignment () - { - XAlign = YAlign = LayoutAlign.Center; - } - - public LayoutAlign XAlign { get; set; } - public LayoutAlign YAlign { get; set; } - public bool ExpandHeight { get; set; } - public bool ExpandWidth { get; set; } - public float MinHeight { get; set; } - public float MinWidth { get; set; } - public float PadLeft { get; set; } - public float PadRight { get; set; } - public float PadTop { get; set; } - public float PadBottom { get; set; } - public bool Visible { get; set; } - - LayoutRequest request = new LayoutRequest (); - - public virtual LayoutRequest BeginLayout () - { - request.Size = new SizeF (MinWidth + PadLeft + PadRight, MinHeight + PadTop + PadBottom); - request.ExpandHeight = this.ExpandHeight; - request.ExpandWidth = this.ExpandWidth; - request.Visible = this.Visible; - return request; - } - - public virtual void EndLayout (LayoutRequest request, PointF origin, SizeF allocation) - { - var frame = new RectangleF (origin.X + PadLeft, origin.Y + PadBottom, - allocation.Width - PadLeft - PadRight, allocation.Height - PadTop - PadBottom); - - if (allocation.Height > request.Size.Height) { - if (YAlign != LayoutAlign.Fill) { - frame.Height = request.Size.Height - PadTop - PadBottom; - if (YAlign == LayoutAlign.Center) { - frame.Y += (allocation.Height - request.Size.Height) / 2; - } else if (YAlign == LayoutAlign.End) { - frame.Y += (allocation.Height - request.Size.Height); - } - } - } - - if (allocation.Width > request.Size.Width) { - if (XAlign != LayoutAlign.Fill) { - frame.Width = request.Size.Width - PadLeft - PadRight; - if (XAlign == LayoutAlign.Center) { - frame.X += (allocation.Width - request.Size.Width) / 2; - } else if (XAlign == LayoutAlign.End) { - frame.X += (allocation.Width - request.Size.Width); - } - } - } - - OnLayoutEnded (frame); - } - - protected abstract void OnLayoutEnded (RectangleF frame); - } -} \ No newline at end of file diff --git a/SparkleShare/Mac/SparkleShare/MainMenu.xib b/SparkleShare/Mac/SparkleShare/MainMenu.xib deleted file mode 100644 index ed428a77..00000000 --- a/SparkleShare/Mac/SparkleShare/MainMenu.xib +++ /dev/null @@ -1,1028 +0,0 @@ - - - - 1060 - 10D2162 - 762 - 1038.29 - 460.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 762 - - - YES - - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - - - YES - - YES - - - YES - - - - YES - - NSApplication - - - FirstResponder - - - NSApplication - - - AMainMenu - - YES - - - SparkleShare - - 1048576 - 2147483647 - - NSImage - NSMenuCheckmark - - - NSImage - NSMenuMixedState - - submenuAction: - - MacCocoaApp - - YES - - - Services - - 1048576 - 2147483647 - - - submenuAction: - - Services - - YES - - _NSServicesMenu - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Hide SparkleShare - h - 1048576 - 2147483647 - - - - - - Hide Others - h - 1572864 - 2147483647 - - - - - - Show All - - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Quit SparkleShare - q - 1048576 - 2147483647 - - - - - _NSAppleMenu - - - - - Window - - 1048576 - 2147483647 - - - submenuAction: - - Window - - YES - - - Minimize - m - 1048576 - 2147483647 - - - - - - Zoom - - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Bring All to Front - - 1048576 - 2147483647 - - - - - _NSWindowsMenu - - - - - Help - - 2147483647 - - - submenuAction: - - Help - - YES - - - SparkleShare Help - ? - 1048576 - 2147483647 - - - - - _NSHelpMenu - - - - _NSMainMenu - - - NSFontManager - - - AppDelegate - - - - - YES - - - performMiniaturize: - - - - 37 - - - - arrangeInFront: - - - - 39 - - - - performZoom: - - - - 240 - - - - hide: - - - - 367 - - - - hideOtherApplications: - - - - 368 - - - - unhideAllApplications: - - - - 370 - - - - terminate: - - - - 449 - - - - showHelp: - - - - 493 - - - - delegate - - - - 534 - - - - - YES - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 29 - - - YES - - - - - - - - 56 - - - YES - - - - - - 57 - - - YES - - - - - - - - - - - - 136 - - - - - 420 - - - - - 533 - - - - - 149 - - - - - 131 - - - YES - - - - - - 144 - - - - - 150 - - - - - 145 - - - - - 134 - - - - - 130 - - - - - 490 - - - YES - - - - - - 19 - - - YES - - - - - - 24 - - - YES - - - - - - - - - 23 - - - - - 239 - - - - - 5 - - - - - 92 - - - - - 491 - - - YES - - - - - - 492 - - - - - - - YES - - YES - -3.IBPluginDependency - 130.IBEditorWindowLastContentRect - 130.IBPluginDependency - 130.ImportedFromIB2 - 130.editorWindowContentRectSynchronizationRect - 131.IBPluginDependency - 131.ImportedFromIB2 - 134.IBPluginDependency - 134.ImportedFromIB2 - 136.IBPluginDependency - 136.ImportedFromIB2 - 144.IBPluginDependency - 144.ImportedFromIB2 - 145.IBPluginDependency - 145.ImportedFromIB2 - 149.IBPluginDependency - 149.ImportedFromIB2 - 150.IBPluginDependency - 150.ImportedFromIB2 - 19.IBPluginDependency - 19.ImportedFromIB2 - 23.IBPluginDependency - 23.ImportedFromIB2 - 239.IBPluginDependency - 239.ImportedFromIB2 - 24.IBEditorWindowLastContentRect - 24.IBPluginDependency - 24.ImportedFromIB2 - 24.editorWindowContentRectSynchronizationRect - 29.IBEditorWindowLastContentRect - 29.IBPluginDependency - 29.ImportedFromIB2 - 29.WindowOrigin - 29.editorWindowContentRectSynchronizationRect - 490.IBPluginDependency - 491.IBEditorWindowLastContentRect - 491.IBPluginDependency - 492.IBPluginDependency - 5.IBPluginDependency - 5.ImportedFromIB2 - 56.IBPluginDependency - 56.ImportedFromIB2 - 57.IBEditorWindowLastContentRect - 57.IBPluginDependency - 57.ImportedFromIB2 - 57.editorWindowContentRectSynchronizationRect - 92.IBPluginDependency - 92.ImportedFromIB2 - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - {{581, 686}, {64, 6}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{436, 809}, {64, 6}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{470, 649}, {194, 73}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{525, 802}, {197, 73}} - {{346, 722}, {256, 20}} - com.apple.InterfaceBuilder.CocoaPlugin - - {74, 862} - {{6, 978}, {478, 20}} - com.apple.InterfaceBuilder.CocoaPlugin - {{541, 699}, {194, 23}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{358, 599}, {213, 123}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{23, 794}, {245, 183}} - com.apple.InterfaceBuilder.CocoaPlugin - - - - - YES - - - YES - - - - - YES - - - YES - - - - 534 - - - - YES - - AppDelegate - NSResponder - - IBUserSource - - - - - - YES - - NSApplication - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSApplication.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSApplicationScripting.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSColorPanel.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSHelpManager.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSPageLayout.h - - - - NSApplication - - IBFrameworkSource - AppKit.framework/Headers/NSUserInterfaceItemSearching.h - - - - NSFontManager - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontManager.h - - - - NSMenu - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenu.h - - - - NSMenuItem - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSMenuItem.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSAccessibility.h - - - - NSObject - - - - NSObject - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSControl.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDictionaryController.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSDragging.h - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSFontPanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSKeyValueBinding.h - - - - NSObject - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSNibLoading.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSOutlineView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSPasteboard.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSSavePanel.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSTableView.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSToolbarItem.h - - - - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSView.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSError.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFileManager.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyValueObserving.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSKeyedArchiver.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObject.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSObjectScripting.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSPortCoder.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSRunLoop.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptClassDescription.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptKeyValueCoding.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptObjectSpecifiers.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSScriptWhoseTests.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSThread.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURL.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLConnection.h - - - - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSURLDownload.h - - - - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSInterfaceStyle.h - - - - NSResponder - NSObject - - IBFrameworkSource - AppKit.framework/Headers/NSResponder.h - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSClipView.h - - - - NSView - - - - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSRulerView.h - - - - NSView - NSResponder - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSDrawer.h - - - - NSWindow - NSResponder - - IBFrameworkSource - AppKit.framework/Headers/NSWindow.h - - - - NSWindow - - IBFrameworkSource - AppKit.framework/Headers/NSWindowScripting.h - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.macosx - - - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - ../MacCocoaApp.xcodeproj - 3 - - YES - - YES - NSMenuCheckmark - NSMenuMixedState - - - YES - {9, 8} - {7, 2} - - - - diff --git a/SparkleShare/Mac/SparkleShare/MainWindow.xib b/SparkleShare/Mac/SparkleShare/MainWindow.xib deleted file mode 100644 index 877e588b..00000000 --- a/SparkleShare/Mac/SparkleShare/MainWindow.xib +++ /dev/null @@ -1,190 +0,0 @@ - - - - 1060 - 10D573 - 762 - 1038.29 - 460.00 - - com.apple.InterfaceBuilder.CocoaPlugin - 762 - - - YES - - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - - - YES - - YES - - - YES - - - - YES - - MainWindowController - - - FirstResponder - - - NSApplication - - - 15 - 2 - {{131, 74}, {606, 354}} - 611844096 - Window - MainWindow - - {1.79769e+308, 1.79769e+308} - - - 256 - {606, 354} - - - {{0, 0}, {1280, 778}} - {1.79769e+308, 1.79769e+308} - - - - - YES - - - window - - - - 6 - - - - - YES - - 0 - - - - - - -2 - - - File's Owner - - - -1 - - - First Responder - - - -3 - - - Application - - - 2 - - - YES - - - - - - 3 - - - - - - - YES - - YES - -1.IBPluginDependency - -2.IBPluginDependency - -3.IBPluginDependency - 2.IBEditorWindowLastContentRect - 2.IBPluginDependency - 2.IBWindowTemplateEditedContentRect - 2.NSWindowTemplate.visibleAtLaunch - 3.IBPluginDependency - - - YES - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{319, 371}, {606, 354}} - com.apple.InterfaceBuilder.CocoaPlugin - {{319, 371}, {606, 354}} - - com.apple.InterfaceBuilder.CocoaPlugin - - - - YES - - - YES - - - - - YES - - - YES - - - - 6 - - - - YES - - MainWindow - NSWindow - - IBUserSource - - - - - MainWindowController - NSWindowController - - IBUserSource - - - - - - 0 - IBCocoaFramework - - com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 - - - YES - - 3 - - - diff --git a/SparkleShare/Mac/SparkleShare/SparkleLog.cs b/SparkleShare/Mac/SparkleShare/SparkleLog.cs deleted file mode 100644 index 4052ce8b..00000000 --- a/SparkleShare/Mac/SparkleShare/SparkleLog.cs +++ /dev/null @@ -1,128 +0,0 @@ -// 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.Drawing; -using MonoMac.Foundation; -using MonoMac.AppKit; -using MonoMac.ObjCRuntime; -using MonoMac.WebKit; - -namespace SparkleShare { - - public class SparkleLog : NSWindow { - - public readonly string LocalPath; - - private WebView WebView; - private NSButton CloseButton; - private NSButton OpenFolderButton; - - public SparkleLog (IntPtr handle) : base (handle) { } - - public SparkleLog (string path) : base () - { - - LocalPath = path; - - Delegate = new LogDelegate (); - - SetFrame (new RectangleF (0, 0, 480, 640), true); - - Center (); - - StyleMask = (NSWindowStyle.Closable | - NSWindowStyle.Miniaturizable | - NSWindowStyle.Titled); - - MaxSize = new SizeF (480, 640); - MinSize = new SizeF (480, 640); - HasShadow = true; - BackingType = NSBackingStore.Buffered; - - - ContentView.AddSubview (CreateEventLog ()); - - OpenFolderButton = new NSButton (new RectangleF (16, 12, 120, 31)) { - Title = "Open Folder", - BezelStyle = NSBezelStyle.Rounded - }; - - OpenFolderButton.Activated += delegate { - SparkleShare.Controller.OpenSparkleShareFolder (LocalPath); - }; - - ContentView.AddSubview (OpenFolderButton); - - - CloseButton = new NSButton (new RectangleF (480 - 120 - 16, 12, 120, 31)) { - Title = "Close", - BezelStyle = NSBezelStyle.Rounded - }; - - CloseButton.Activated += delegate { - InvokeOnMainThread (delegate { - PerformClose (this); - }); - }; - - ContentView.AddSubview (CloseButton); - - - string name = System.IO.Path.GetFileName (LocalPath); - Title = String.Format ("Recent Events in ‘{0}’", name); - - OrderFrontRegardless (); - - } - - - public void UpdateEventLog () - { - - } - - - private WebView CreateEventLog () - { - - RectangleF frame = new RectangleF (0, 12 + 31 + 16, 480, 640 - (12 + 31 + 16)); - - WebView = new WebView (frame, "", ""); - WebView.MainFrameUrl = "http://www.google.nl/"; - - return WebView; - - } - - } - - - public class LogDelegate : NSWindowDelegate { - - public override void WillClose (NSNotification notification) - { - - InvokeOnMainThread (delegate { - SparkleUI.OpenLogs.Remove ((SparkleLog) notification.Object); - }); - - } - - } - -} diff --git a/SparkleShare/Mac/SparkleShare/SparkleShare.csproj b/SparkleShare/Mac/SparkleShare/SparkleShare.csproj deleted file mode 100644 index 50a86364..00000000 --- a/SparkleShare/Mac/SparkleShare/SparkleShare.csproj +++ /dev/null @@ -1,98 +0,0 @@ - - - - Debug - AnyCPU - 9.0.21022 - 2.0 - {709CB8F4-F82F-4C94-B4E2-DC502087525B} - {1C533B1C-72DD-4CB1-9F6B-BF11D93BCFBE};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - Exe - SparkleShare - SparkleShare - v3.5 - - - true - full - false - bin\Debug - DEBUG - prompt - 4 - false - - - - - - - - none - false - bin\Release - prompt - 4 - false - - - - - - - - - False - - - - - - MainMenu.xib - - - - - - SparkleShare.cs - - - SparkleController.cs - - - - - - - - - - - - - - - - - - - - - - - - - Pixmaps\side-splash.png - - - - - - {2C914413-B31C-4362-93C7-1AE34F09112A} - SparkleLib - - - - - - \ No newline at end of file diff --git a/SparkleShare/Mac/SparkleShare/SparkleShare.sln b/SparkleShare/Mac/SparkleShare/SparkleShare.sln deleted file mode 100644 index 925a0eda..00000000 --- a/SparkleShare/Mac/SparkleShare/SparkleShare.sln +++ /dev/null @@ -1,26 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SparkleShare", "SparkleShare.csproj", "{709CB8F4-F82F-4C94-B4E2-DC502087525B}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SparkleLib", "..\..\..\SparkleLib\SparkleLib.csproj", "{2C914413-B31C-4362-93C7-1AE34F09112A}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {2C914413-B31C-4362-93C7-1AE34F09112A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2C914413-B31C-4362-93C7-1AE34F09112A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2C914413-B31C-4362-93C7-1AE34F09112A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2C914413-B31C-4362-93C7-1AE34F09112A}.Release|Any CPU.Build.0 = Release|Any CPU - {709CB8F4-F82F-4C94-B4E2-DC502087525B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {709CB8F4-F82F-4C94-B4E2-DC502087525B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {709CB8F4-F82F-4C94-B4E2-DC502087525B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {709CB8F4-F82F-4C94-B4E2-DC502087525B}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(MonoDevelopProperties) = preSolution - StartupItem = SparkleShare.csproj - EndGlobalSection -EndGlobal diff --git a/SparkleShare/Mac/SparkleShare/SparkleWindow.cs b/SparkleShare/Mac/SparkleShare/SparkleWindow.cs deleted file mode 100644 index 21f1cbde..00000000 --- a/SparkleShare/Mac/SparkleShare/SparkleWindow.cs +++ /dev/null @@ -1,70 +0,0 @@ -// 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.Drawing; -using MonoMac.Foundation; -using MonoMac.AppKit; -using MonoMac.ObjCRuntime; -using MonoMac.WebKit; - -namespace SparkleShare { - - public class SparkleWindow : NSWindow { - - public readonly string LocalPath; - - private NSImage SideSplash; - - public SparkleWindow () : base () - { - - SetFrame (new RectangleF (0, 0, 640, 480), true); - - Center (); - - StyleMask = (NSWindowStyle.Closable | - NSWindowStyle.Miniaturizable | - NSWindowStyle.Titled); - - MaxSize = new SizeF (640, 480); - MinSize = new SizeF (640, 480); - HasShadow = true; - BackingType = NSBackingStore.Buffered; - - SideSplash = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/side-splash.png"); - SideSplash.Size = new SizeF (150, 480); - - - NSText tv = new NSText (new RectangleF (200, 200, 200, 200)) { - Value = "TEST" - }; - - ContentView.AddSubview (new NSImageView (new RectangleF (0, 0, 150, 480)) { Image = SideSplash}); - ContentView.AddSubview (new NSTextField (new RectangleF (200, 100, 128, 31)) { BezelStyle = NSTextFieldBezelStyle.Rounded}); - ContentView.AddSubview (tv); - - - - NSApplication.SharedApplication.ActivateIgnoringOtherApps (true); - MakeKeyAndOrderFront (this); - - } - - } - -} diff --git a/SparkleShare/Mac/SparkleShare/SparkleStatusIcon.cs b/SparkleShare/Mac/SparkleStatusIcon.cs similarity index 74% rename from SparkleShare/Mac/SparkleShare/SparkleStatusIcon.cs rename to SparkleShare/Mac/SparkleStatusIcon.cs index b1907cab..356f2b17 100644 --- a/SparkleShare/Mac/SparkleShare/SparkleStatusIcon.cs +++ b/SparkleShare/Mac/SparkleStatusIcon.cs @@ -16,6 +16,7 @@ using System; using System.Drawing; +using System.IO; using System.Timers; using MonoMac.Foundation; using MonoMac.AppKit; @@ -39,7 +40,6 @@ namespace SparkleShare { private NSMenuItem [] FolderMenuItems; private NSMenuItem SyncMenuItem; private NSMenuItem NotificationsMenuItem; - private NSMenuItem AboutMenuItem; private delegate void Task (); private EventHandler [] Tasks; @@ -53,7 +53,7 @@ namespace SparkleShare { public SparkleStatusIcon () : base () - { + { Animation = CreateAnimation (); @@ -69,7 +69,12 @@ namespace SparkleShare { SparkleShare.Controller.FolderSizeChanged += delegate { InvokeOnMainThread (delegate { + + if (!Animation.Enabled) + SetNormalState (); + UpdateMenu (); + }); }; @@ -123,11 +128,20 @@ namespace SparkleShare { InvokeOnMainThread (delegate { - StatusItem.AlternateImage = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/idle" + FrameNumber + ".png"); - StatusItem.AlternateImage.Size = new SizeF (16, 16); + string image_path = + Path.Combine (NSBundle.MainBundle.ResourcePath, + "Pixmaps", "idle" + FrameNumber + ".png"); - StatusItem.Image = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/idle" + FrameNumber + ".png"); + StatusItem.Image = new NSImage (image_path); StatusItem.Image.Size = new SizeF (16, 16); + + + string alternate_image_path = + Path.Combine (NSBundle.MainBundle.ResourcePath, + "Pixmaps", "idle" + FrameNumber + ".png"); + + StatusItem.AlternateImage = new NSImage (alternate_image_path); + StatusItem.AlternateImage.Size = new SizeF (16, 16); }); @@ -160,23 +174,27 @@ namespace SparkleShare { FolderMenuItem.Activated += delegate { SparkleShare.Controller.OpenSparkleShareFolder (); }; + - //FolderMenuItem.Image = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/sparkleshare.icns"); - FolderMenuItem.Image = NSImage.ImageNamed ("NSFolder"); + string folder_icon_path = Path.Combine (NSBundle.MainBundle.ResourcePath, + "sparkleshare-mac.icns"); + + FolderMenuItem.Image = new NSImage (folder_icon_path); FolderMenuItem.Image.Size = new SizeF (16, 16); Menu.AddItem (FolderMenuItem); if (SparkleShare.Controller.Folders.Count > 0) { - + FolderMenuItems = new NSMenuItem [SparkleShare.Controller.Folders.Count]; Tasks = new EventHandler [SparkleShare.Controller.Folders.Count]; int i = 0; foreach (string path in SparkleShare.Controller.Folders) { - + + // TODO // if (repo.HasUnsyncedChanges) // folder_action.IconName = "dialog-error"; @@ -198,67 +216,82 @@ namespace SparkleShare { } else { - // TODO: No Remote Folders Yet + FolderMenuItems = new NSMenuItem [1]; + + FolderMenuItems [0] = new NSMenuItem () { + Title = "No Remote Folders Yet" + }; + + Menu.AddItem (FolderMenuItems [0]); } - + Menu.AddItem (NSMenuItem.SeparatorItem); SyncMenuItem = new NSMenuItem () { - Title = "Add Remote Folder..." + Title = "Add Remote Folder…" }; - if (SparkleShare.Controller.FirstRun) - SyncMenuItem.Enabled = false; + if (!SparkleShare.Controller.FirstRun) { - SyncMenuItem.Activated += delegate { - new SparkleWindow (); - }; + SyncMenuItem.Activated += delegate { + + InvokeOnMainThread (delegate { + + NSApplication.SharedApplication.ActivateIgnoringOtherApps (true); + + if (SparkleUI.Intro == null) { + + SparkleUI.Intro = new SparkleIntro (); + SparkleUI.Intro.ShowServerForm (true); + + } + if (!SparkleUI.Intro.IsVisible) + SparkleUI.Intro.ShowServerForm (true); + + SparkleUI.Intro.OrderFrontRegardless (); + SparkleUI.Intro.MakeKeyAndOrderFront (this); + + }); + + }; + + } + Menu.AddItem (SyncMenuItem); Menu.AddItem (NSMenuItem.SeparatorItem); - NotificationsMenuItem = new NSMenuItem () { - Title = "Show Notifications" - }; + NotificationsMenuItem = new NSMenuItem (); if (SparkleShare.Controller.NotificationsEnabled) - NotificationsMenuItem.State = NSCellStateValue.On; - + NotificationsMenuItem.Title = "Turn Notifications Off"; + else + NotificationsMenuItem.Title = "Turn Notifications On"; + NotificationsMenuItem.Activated += delegate { SparkleShare.Controller.ToggleNotifications (); + + InvokeOnMainThread (delegate { - if (SparkleShare.Controller.NotificationsEnabled) - NotificationsMenuItem.State = NSCellStateValue.On; - else - NotificationsMenuItem.State = NSCellStateValue.Off; + if (SparkleShare.Controller.NotificationsEnabled) + NotificationsMenuItem.Title = "Turn Notifications Off"; + else + NotificationsMenuItem.Title = "Turn Notifications On"; + + }); }; Menu.AddItem (NotificationsMenuItem); - - - Menu.AddItem (NSMenuItem.SeparatorItem); - - - AboutMenuItem = new NSMenuItem () { - Title = "About" - }; - - AboutMenuItem.Activated += delegate { - // TODO - }; - - Menu.AddItem (AboutMenuItem); StatusItem.Menu = Menu; StatusItem.Menu.Update (); - Console.WriteLine ("MENU UPDATED"); } @@ -269,27 +302,31 @@ namespace SparkleShare { { return delegate { - - SparkleLog log = SparkleUI.OpenLogs.Find (delegate (SparkleLog l) { - return l.LocalPath.Equals (path); - }); + + InvokeOnMainThread (delegate { - // Check whether the log is already open, create a new one if - // that's not the case or present it to the user if it is - if (log == null) { + NSApplication.SharedApplication.ActivateIgnoringOtherApps (true); - InvokeOnMainThread (delegate { + SparkleLog log = SparkleUI.OpenLogs.Find (delegate (SparkleLog l) { + return l.LocalPath.Equals (path); + }); + + // Check whether the log is already open, create a new one if + // that's not the case or present it to the user if it is + if (log == null) { + SparkleUI.OpenLogs.Add (new SparkleLog (path)); - }); - - } else { - - InvokeOnMainThread (delegate { - log.OrderFrontRegardless (); - }); + SparkleUI.OpenLogs [SparkleUI.OpenLogs.Count - 1].MakeKeyAndOrderFront (this); + + } else { + + log.OrderFrontRegardless (); + log.MakeKeyAndOrderFront (this); + + } + + }); - } - }; } @@ -380,13 +417,11 @@ namespace SparkleShare { public override void MenuWillOpen (NSMenu menu) { - - Console.WriteLine ("OPENED"); - - InvokeOnMainThread (delegate { - foreach (SparkleLog log in SparkleUI.OpenLogs) - log.OrderFrontRegardless (); + InvokeOnMainThread (delegate { + + SparkleUI.NewEvents = 0; + NSApplication.SharedApplication.DockTile.BadgeLabel = null; }); diff --git a/SparkleShare/Mac/SparkleUI.cs b/SparkleShare/Mac/SparkleUI.cs new file mode 100644 index 00000000..46d348a6 --- /dev/null +++ b/SparkleShare/Mac/SparkleUI.cs @@ -0,0 +1,148 @@ +// 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.Drawing; +using System.IO; +using System.Timers; +using MonoMac.Foundation; +using MonoMac.AppKit; +using MonoMac.ObjCRuntime; +using MonoMac.WebKit; + +namespace SparkleShare { + + public partial class AppDelegate : NSApplicationDelegate { + + public override void WillBecomeActive (NSNotification notification) + { + + SparkleUI.NewEvents = 0; + NSApplication.SharedApplication.DockTile.BadgeLabel = null; + + } + + } + + + public class SparkleUI : AppDelegate + { + + public static SparkleStatusIcon StatusIcon; + public static List OpenLogs; + public static int NewEvents; + public static SparkleIntro Intro; + public static NSFont Font; + + + public SparkleUI () + { + + NSApplication.Init (); + + SetSparkleIcon (); + + // TODO: Getting crashes when I remove this + NSApplication.SharedApplication.ApplicationIconImage + = NSImage.ImageNamed ("sparkleshare.icns"); + + + Font = NSFontManager.SharedFontManager.FontWithFamily + ("Lucida Grande", NSFontTraitMask.Condensed, 0, 13); + + + OpenLogs = new List (); + StatusIcon = new SparkleStatusIcon (); + + NewEvents = 0; + + SparkleShare.Controller.NotificationRaised += delegate { + + InvokeOnMainThread (delegate { + + NewEvents++; + NSApplication.SharedApplication.DockTile.BadgeLabel = NewEvents.ToString (); + + foreach (SparkleLog log in SparkleUI.OpenLogs) + log.UpdateEventLog (); + + NSApplication.SharedApplication.RequestUserAttention + (NSRequestUserAttentionType.InformationalRequest); + + }); + + }; + + + SparkleShare.Controller.AvatarFetched += delegate { + + InvokeOnMainThread (delegate { + + foreach (SparkleLog log in SparkleUI.OpenLogs) + log.UpdateEventLog (); + + }); + + }; + + SparkleShare.Controller.OnIdle += delegate { + + InvokeOnMainThread (delegate { + + foreach (SparkleLog log in SparkleUI.OpenLogs) + log.UpdateEventLog (); + + }); + + }; + + + if (SparkleShare.Controller.FirstRun) { + + Intro = new SparkleIntro (); + Intro.ShowAccountForm (); + + } + + } + + + public void SetSparkleIcon () + { + + string folder_icon_path = Path.Combine (NSBundle.MainBundle.ResourcePath, + "sparkleshare-mac.icns"); + + NSImage folder_icon = new NSImage (folder_icon_path); + + NSWorkspace.SharedWorkspace.SetIconforFile (folder_icon, + SparkleShare.Controller.SparklePath, 0); + + } + + + public void Run () + { + + NSApplication.Main (new string [0]); + + } + + } + +} diff --git a/SparkleShare/Mac/SparkleWindow.cs b/SparkleShare/Mac/SparkleWindow.cs new file mode 100644 index 00000000..c2fb6742 --- /dev/null +++ b/SparkleShare/Mac/SparkleWindow.cs @@ -0,0 +1,168 @@ +// 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.Drawing; +using System.IO; +using MonoMac.Foundation; +using MonoMac.AppKit; +using MonoMac.ObjCRuntime; +using MonoMac.WebKit; +using Mono.Unix; + +namespace SparkleShare { + + public class SparkleWindow : NSWindow { + + private NSImage SideSplash; + private NSImageView SideSplashView; + + public List Buttons; + public string Header; + public string Description; + + private NSTextField HeaderTextField; + private NSTextField DescriptionTextField; + + + public SparkleWindow () : base () + { + + SetFrame (new RectangleF (0, 0, 640, 380), true); + + StyleMask = NSWindowStyle.Titled; + MaxSize = new SizeF (640, 380); + MinSize = new SizeF (640, 380); + HasShadow = true; + BackingType = NSBackingStore.Buffered; + + Center (); + + string side_splash_path = Path.Combine (NSBundle.MainBundle.ResourcePath, + "Pixmaps", "side-splash.png"); + + SideSplash = new NSImage (side_splash_path) { + Size = new SizeF (150, 480) + }; + + SideSplashView = new NSImageView () { + Image = SideSplash, + Frame = new RectangleF (0, 0, 150, 480) + }; + + + Buttons = new List (); + + + HeaderTextField = new NSTextField () { + Frame = new RectangleF (190, Frame.Height - 100, 318, 48), + BackgroundColor = NSColor.WindowBackground, + Bordered = false, + Editable = false, + Font = NSFontManager.SharedFontManager.FontWithFamily + ("Lucida Grande", NSFontTraitMask.Bold, 0, 15) + }; + + DescriptionTextField = new NSTextField () { + Frame = new RectangleF (190, Frame.Height - 155 , 640 - 240, 64), + BackgroundColor = NSColor.WindowBackground, + Bordered = false, + Editable = false, + Font = SparkleUI.Font + }; + + + NSApplication.SharedApplication.ActivateIgnoringOtherApps (true); + MakeKeyAndOrderFront (this); + + OrderFrontRegardless (); + + } + + + public void Reset () { + + ContentView.Subviews = new NSView [0]; + Buttons = new List (); + + Header = ""; + Description = ""; + + } + + + public void ShowAll () { + + HeaderTextField.StringValue = Header; + DescriptionTextField.StringValue = Description; + + ContentView.AddSubview (HeaderTextField); + + if (!Description.Equals ("")) + ContentView.AddSubview (DescriptionTextField); + + ContentView.AddSubview (SideSplashView); + + int i = 1; + + if (Buttons.Count > 0) { + + DefaultButtonCell = Buttons [0].Cell; + + foreach (NSButton button in Buttons) { + + button.BezelStyle = NSBezelStyle.Rounded; + button.Frame = new RectangleF (Frame.Width - 15 - (105 * i) , 12, 105, 32); + + if (button.Title.Contains (" ")) + button.Frame = new RectangleF (Frame.Width - 30 - (105 * i) , 12, 120, 32); + + button.Font = SparkleUI.Font; + + ContentView.AddSubview (button); + + i++; + + } + + } + + } + + + public override void OrderFrontRegardless () + { + + NSApplication.SharedApplication.AddWindowsItem (this, "SparkleShare Setup", false); + base.OrderFrontRegardless (); + + } + + + public override void Close () + { + + OrderOut (this); + NSApplication.SharedApplication.RemoveWindowsItem (this); + return; + + } + + } + +} diff --git a/SparkleShare/SparkleController.cs b/SparkleShare/SparkleController.cs index 8cc2ffd4..7eb2a4fb 100644 --- a/SparkleShare/SparkleController.cs +++ b/SparkleShare/SparkleController.cs @@ -25,7 +25,6 @@ using System.Net; using System.Threading; using System.Text.RegularExpressions; using System.Xml; - using System.Security.Cryptography; using System.Text; @@ -36,6 +35,8 @@ namespace SparkleShare { public List Repositories; public string FolderSize; public bool FirstRun; + + public readonly string SparklePath; public event OnQuitWhileSyncingEventHandler OnQuitWhileSyncing; @@ -52,6 +53,9 @@ namespace SparkleShare { public event FolderSizeChangedEventHandler FolderSizeChanged; public delegate void FolderSizeChangedEventHandler (string folder_size); + + public event AvatarFetchedEventHandler AvatarFetched; + public delegate void AvatarFetchedEventHandler (); public event OnIdleEventHandler OnIdle; public delegate void OnIdleEventHandler (); @@ -83,7 +87,9 @@ namespace SparkleShare { AddToBookmarks (); FolderSize = GetFolderSize (); - + + + SparklePath = SparklePaths.SparklePath; string global_config_file_path = SparkleHelpers.CombineMore (SparklePaths.SparkleConfigPath, "config"); @@ -151,14 +157,14 @@ namespace SparkleShare { } - + // Uploads the user's public key to the server public bool AcceptInvitation (string server, string folder, string token) { // The location of the user's public key for SparkleShare string public_key_file_path = SparkleHelpers.CombineMore (SparklePaths.HomePath, ".ssh", - "sparkleshare." + SparkleShare.Controller.UserEmail + ".key.pub"); + "sparkleshare." + UserEmail + ".key.pub"); if (!File.Exists (public_key_file_path)) return false; @@ -233,16 +239,20 @@ namespace SparkleShare { } + public abstract string EventLogHTML { get; } + public abstract string DayEntryHTML { get; } + public abstract string EventEntryHTML { get; } + + public string GetHTMLLog (string name) { - List commits = GetLog (name); - - List activity_days = new List (); + List commits = GetLog (name); + List activity_days = new List (); foreach (SparkleCommit commit in commits) { - GetAvatar (commit.UserEmail, 32); + GetAvatar (commit.UserEmail, 36); bool commit_inserted = false; foreach (ActivityDay stored_activity_day in activity_days) { @@ -261,34 +271,20 @@ namespace SparkleShare { if (!commit_inserted) { - ActivityDay activity_day = new ActivityDay (commit.DateTime); - activity_day.Add (commit); - activity_days.Add (activity_day); + ActivityDay activity_day = new ActivityDay (commit.DateTime); + activity_day.Add (commit); + activity_days.Add (activity_day); } } - - - StreamReader reader; - - reader = new StreamReader (Defines.PREFIX + "/share/sparkleshare/html/event-log.html"); - string event_log_html = reader.ReadToEnd (); - reader.Close (); - - reader = new StreamReader (Defines.PREFIX + "/share/sparkleshare/html/day-entry.html"); - string day_entry_html = reader.ReadToEnd (); - reader.Close (); - - reader = new StreamReader (Defines.PREFIX + "/share/sparkleshare/html/event-entry.html"); - string event_entry_html = reader.ReadToEnd (); - reader.Close (); - - + string event_log_html = EventLogHTML; + string day_entry_html = DayEntryHTML; + string event_entry_html = EventEntryHTML; + - string event_log = ""; foreach (ActivityDay activity_day in activity_days) { @@ -304,14 +300,17 @@ namespace SparkleShare { event_entry += "
Edited
"; foreach (string file_path in change_set.Edited) { + + string absolute_file_path = SparkleHelpers.CombineMore (SparklePaths.SparklePath, + name, file_path); + + if (File.Exists (absolute_file_path)) { - if (File.Exists (SparkleHelpers.CombineMore (SparklePaths.SparklePath ,name , file_path))) { - - event_entry += "
" + file_path + "
"; + event_entry += "
" + file_path + "
"; } else { - event_entry += "
" + SparkleHelpers.CombineMore (SparklePaths.SparklePath, name, file_path) + "
"; + event_entry += "
" + file_path + "
"; } @@ -325,14 +324,16 @@ namespace SparkleShare { event_entry += "
Added
"; foreach (string file_path in change_set.Added) { + string absolute_file_path = SparkleHelpers.CombineMore (SparklePaths.SparklePath, + name, file_path); + + if (File.Exists (absolute_file_path)) { - if (File.Exists (SparkleHelpers.CombineMore (SparklePaths.SparklePath ,name , file_path))) { - - event_entry += "
" + file_path + "
"; - + event_entry += "
" + file_path + "
"; + } else { - event_entry += "
" + SparkleHelpers.CombineMore (SparklePaths.SparklePath ,name , file_path) + "
"; + event_entry += "
" + file_path + "
"; } @@ -346,33 +347,36 @@ namespace SparkleShare { foreach (string file_path in change_set.Deleted) { - if (File.Exists (SparkleHelpers.CombineMore (SparklePaths.SparklePath ,name , file_path))) { - - event_entry += "
" + file_path + "
"; + string absolute_file_path = SparkleHelpers.CombineMore (SparklePaths.SparklePath, + name, file_path); + + if (File.Exists (absolute_file_path)) { + event_entry += "
" + file_path + "
"; + } else { - event_entry += "
" + SparkleHelpers.CombineMore (SparklePaths.SparklePath ,name , file_path) + "
"; + event_entry += "
" + file_path + "
"; } } } -Console.WriteLine(GetAvatar (change_set.UserEmail, 32)); + event_entry += ""; + event_entries += event_entry_html.Replace ("", event_entry) .Replace ("", change_set.UserName) - .Replace ("", "file://" +GetAvatar (change_set.UserEmail, 32) ) + .Replace ("", "file://" + GetAvatar (change_set.UserEmail, 36) ) .Replace ("", change_set.DateTime.ToString ("H:mm")); - + } - - - + + string day_entry = ""; - DateTime today = DateTime.Now; + DateTime today = DateTime.Now; DateTime yesterday = DateTime.Now.AddDays (-1); if (today.Day == activity_day.DateTime.Day && @@ -398,7 +402,8 @@ Console.WriteLine(GetAvatar (change_set.UserEmail, 32)); } - + + string html = event_log_html.Replace ("", event_log); return html; @@ -553,6 +558,12 @@ Console.WriteLine(GetAvatar (change_set.UserEmail, 32)); if (FolderListChanged != null) FolderListChanged (); + + FolderSize = GetFolderSize (); + + if (FolderSizeChanged != null) + FolderSizeChanged (FolderSize); + } @@ -582,6 +593,12 @@ Console.WriteLine(GetAvatar (change_set.UserEmail, 32)); if (FolderListChanged != null) FolderListChanged (); + + FolderSize = GetFolderSize (); + + if (FolderSizeChanged != null) + FolderSizeChanged (FolderSize); + } @@ -822,7 +839,7 @@ Console.WriteLine(GetAvatar (change_set.UserEmail, 32)); private void WriteUserInfo (string user_name, string user_email) { - string global_config_file_path = SparkleHelpers.CombineMore (SparklePaths.SparkleConfigPath, "config"); + string global_config_file_path = Path.Combine (SparklePaths.SparkleConfigPath, "config"); // Write the user's information to a text file TextWriter writer = new StreamWriter (global_config_file_path); @@ -831,7 +848,7 @@ Console.WriteLine(GetAvatar (change_set.UserEmail, 32)); "\temail = " + user_email); writer.Close (); - SparkleHelpers.DebugInfo ("Config", "Created '" + global_config_file_path + "'"); + SparkleHelpers.DebugInfo ("Config", "Updated '" + global_config_file_path + "'"); } @@ -840,18 +857,29 @@ Console.WriteLine(GetAvatar (change_set.UserEmail, 32)); public void GenerateKeyPair () { - string keys_path = SparklePaths.SparkleKeysPath; + string keys_path = SparklePaths.SparkleKeysPath; string key_file_name = "sparkleshare." + UserEmail + ".key"; + string key_file_path = Path.Combine (keys_path, key_file_name); + + + if (File.Exists (key_file_path)) { + + SparkleHelpers.DebugInfo ("Config", "Key already exists ('" + key_file_name + "'), " + + "leaving it untouched"); + return; + + } - Process process = new Process () { - EnableRaisingEvents = true - }; if (!Directory.Exists (keys_path)) Directory.CreateDirectory (keys_path); if (!File.Exists (key_file_name)) { + Process process = new Process () { + EnableRaisingEvents = true + }; + process.StartInfo.WorkingDirectory = keys_path; process.StartInfo.UseShellExecute = false; process.StartInfo.RedirectStandardOutput = true; @@ -866,8 +894,11 @@ Console.WriteLine(GetAvatar (change_set.UserEmail, 32)); process.Exited += delegate { - SparkleHelpers.DebugInfo ("Config", "Created key '" + key_file_name + "'"); - SparkleHelpers.DebugInfo ("Config", "Created key '" + key_file_name + ".pub'"); + SparkleHelpers.DebugInfo ("Config", "Created private key '" + key_file_name + "'"); + SparkleHelpers.DebugInfo ("Config", "Created public key '" + key_file_name + ".pub'"); + + File.Copy (key_file_path + ".pub", + Path.Combine (SparklePath, "Your key.txt")); }; @@ -890,10 +921,10 @@ Console.WriteLine(GetAvatar (change_set.UserEmail, 32)); } else { - TextWriter writer = new StreamWriter (ssh_config_file_path); + TextWriter writer = new StreamWriter (ssh_config_file_path); writer.WriteLine (ssh_config); writer.Close (); - + } } @@ -902,30 +933,94 @@ Console.WriteLine(GetAvatar (change_set.UserEmail, 32)); private void EnableHostKeyCheckingForHost (string host) { - string ssh_config_file_path = SparkleHelpers.CombineMore (SparklePaths.HomePath, ".ssh", "config"); - string ssh_config = "Host " + host + "\n\tStrictHostKeyChecking no"; + string ssh_config_file_path = SparkleHelpers.CombineMore + (SparklePaths.HomePath, ".ssh", "config"); + + string ssh_config = "Host " + host + "\n" + + "\tStrictHostKeyChecking no"; if (File.Exists (ssh_config_file_path)) { StreamReader reader = new StreamReader (ssh_config_file_path); string current_ssh_config = reader.ReadToEnd (); reader.Close (); - - if (current_ssh_config.Equals (ssh_config)) { - - File.Delete (ssh_config_file_path); + + current_ssh_config = current_ssh_config.Remove (current_ssh_config.IndexOf (ssh_config), + ssh_config.Length); + + if (current_ssh_config.Trim ().Equals ("")) { + + File.Delete (ssh_config_file_path); } else { - - current_ssh_config = current_ssh_config.Remove (current_ssh_config.IndexOf (ssh_config), - ssh_config.Length); - + TextWriter writer = new StreamWriter (ssh_config_file_path); writer.WriteLine (current_ssh_config); writer.Close (); + + } + + } + + } + + + // Gets the avatar for a specific email address and size + public string GetAvatar (string email, int size) + { + + string avatar_path = SparkleHelpers.CombineMore (SparklePaths.SparkleLocalIconPath, + size + "x" + size, "status"); + + if (!Directory.Exists (avatar_path)) { + + Directory.CreateDirectory (avatar_path); + SparkleHelpers.DebugInfo ("Config", "Created '" + avatar_path + "'"); + + } + + string avatar_file_path = SparkleHelpers.CombineMore (avatar_path, "avatar-" + email); + + if (File.Exists (avatar_file_path)) { + + return avatar_file_path; + + } else { + + // Let's try to get the person's gravatar for next time + WebClient web_client = new WebClient (); + Uri uri = new Uri ("http://www.gravatar.com/avatar/" + GetMD5 (email) + + ".jpg?s=" + size + "&d=404"); + + string tmp_file_path = SparkleHelpers.CombineMore (SparklePaths.SparkleTmpPath, email + size); + + if (!File.Exists (tmp_file_path)) { + + web_client.DownloadFileAsync (uri, tmp_file_path); + + web_client.DownloadFileCompleted += delegate { + + if (File.Exists (avatar_file_path)) + File.Delete (avatar_file_path); + + FileInfo tmp_file_info = new FileInfo (tmp_file_path); + + if (tmp_file_info.Length > 255) + File.Move (tmp_file_path, avatar_file_path); + + if (AvatarFetched != null) + AvatarFetched (); + + }; } + // Fall back to a generic icon if there is no gravatar + if (File.Exists (avatar_file_path)) + return avatar_file_path; + else + return null; + } } @@ -991,7 +1086,7 @@ Console.WriteLine(GetAvatar (change_set.UserEmail, 32)); } catch (Exception e) { SparkleHelpers.DebugInfo ("Controller", "Error moving folder: " + e.Message); - + } @@ -1013,11 +1108,12 @@ Console.WriteLine(GetAvatar (change_set.UserEmail, 32)); SparkleHelpers.ClearAttributes (tmp_folder); Directory.Delete (tmp_folder, true); - SparkleHelpers.DebugInfo ("Config", "Deleted temporary directory: " + tmp_folder); + SparkleHelpers.DebugInfo ("Config", + "Deleted temporary directory: " + tmp_folder); } - + if (FolderFetchError != null) FolderFetchError (); @@ -1029,71 +1125,13 @@ Console.WriteLine(GetAvatar (change_set.UserEmail, 32)); } - // Gets the avatar for a specific email address and size - public static string GetAvatar (string email, int size) - { - - string avatar_path = SparkleHelpers.CombineMore (SparklePaths.SparkleLocalIconPath, - size + "x" + size, "status"); - - if (!Directory.Exists (avatar_path)) { - - Directory.CreateDirectory (avatar_path); - SparkleHelpers.DebugInfo ("Config", "Created '" + avatar_path + "'"); - - } - - string avatar_file_path = SparkleHelpers.CombineMore (avatar_path, "avatar-" + email); - - if (File.Exists (avatar_file_path)) { - - return avatar_file_path; - - } else { - - // Let's try to get the person's gravatar for next time - WebClient web_client = new WebClient (); - Uri uri = new Uri ("http://www.gravatar.com/avatar/" + GetMD5 (email) + - ".jpg?s=" + size + "&d=404"); - - string tmp_file_path = SparkleHelpers.CombineMore (SparklePaths.SparkleTmpPath, email + size); - - if (!File.Exists (tmp_file_path)) { - - web_client.DownloadFileAsync (uri, tmp_file_path); - - web_client.DownloadFileCompleted += delegate { - - if (File.Exists (avatar_file_path)) - File.Delete (avatar_file_path); - - FileInfo tmp_file_info = new FileInfo (tmp_file_path); - - if (tmp_file_info.Length > 255) - File.Move (tmp_file_path, avatar_file_path); - - }; - - } - - // Fall back to a generic icon if there is no gravatar - if (File.Exists (avatar_file_path)) - return avatar_file_path; - else - return null; - - } - - } - - // Creates an MD5 hash of input public static string GetMD5 (string s) { MD5 md5 = new MD5CryptoServiceProvider (); Byte[] bytes = ASCIIEncoding.Default.GetBytes (s); - Byte[] encodedBytes = md5.ComputeHash (bytes); - return BitConverter.ToString (encodedBytes).ToLower ().Replace ("-", ""); + Byte[] encoded_bytes = md5.ComputeHash (bytes); + return BitConverter.ToString (encoded_bytes).ToLower ().Replace ("-", ""); } @@ -1118,7 +1156,7 @@ Console.WriteLine(GetAvatar (change_set.UserEmail, 32)); Quit (); } - + public void Quit () { @@ -1134,7 +1172,17 @@ Console.WriteLine(GetAvatar (change_set.UserEmail, 32)); Environment.Exit (0); - } + } + + + // Checks to see if an email address is valid + public bool IsValidEmail (string email) + { + + Regex regex = new Regex (@"^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$", RegexOptions.IgnoreCase); + return regex.IsMatch (email); + + } } @@ -1142,7 +1190,7 @@ Console.WriteLine(GetAvatar (change_set.UserEmail, 32)); public class ChangeSet : SparkleCommit { } - + // All commits that happened on a day public class ActivityDay : List @@ -1158,6 +1206,6 @@ Console.WriteLine(GetAvatar (change_set.UserEmail, 32)); } - } - + } + } \ No newline at end of file diff --git a/SparkleShare/SparkleShare.cs b/SparkleShare/SparkleShare.cs index 8aa9cbe8..fa180f50 100644 --- a/SparkleShare/SparkleShare.cs +++ b/SparkleShare/SparkleShare.cs @@ -89,11 +89,11 @@ namespace SparkleShare { case PlatformID.Unix: SetProcessName ("sparkleshare"); - Controller = new SparkleLinController (); + //Controller = new SparkleLinController (); break; case PlatformID.MacOSX: - //Controller = new SparkleMacController (); + Controller = new SparkleMacController (); break; case PlatformID.Win32NT: diff --git a/data/avatar-default.png b/data/avatar-default.png new file mode 100644 index 00000000..b4f31d43 Binary files /dev/null and b/data/avatar-default.png differ diff --git a/data/html/event-entry.html b/data/html/event-entry.html index 73e0afd7..5b321499 100644 --- a/data/html/event-entry.html +++ b/data/html/event-entry.html @@ -4,7 +4,11 @@ - +
+
+
+
+

diff --git a/data/html/event-log.html b/data/html/event-log.html index 304a0d86..b5a9bc39 100644 --- a/data/html/event-log.html +++ b/data/html/event-log.html @@ -8,12 +8,13 @@ diff --git a/SparkleShare/Mac/SparkleShare/Pixmaps/idle-active.png b/data/idle-active.png similarity index 100% rename from SparkleShare/Mac/SparkleShare/Pixmaps/idle-active.png rename to data/idle-active.png diff --git a/SparkleShare/Mac/SparkleShare/Pixmaps/idle.png b/data/idle.png similarity index 100% rename from SparkleShare/Mac/SparkleShare/Pixmaps/idle.png rename to data/idle.png diff --git a/SparkleShare/Mac/SparkleShare/Pixmaps/idle0.png b/data/idle0.png similarity index 100% rename from SparkleShare/Mac/SparkleShare/Pixmaps/idle0.png rename to data/idle0.png diff --git a/SparkleShare/Mac/SparkleShare/Pixmaps/idle1.png b/data/idle1.png similarity index 100% rename from SparkleShare/Mac/SparkleShare/Pixmaps/idle1.png rename to data/idle1.png diff --git a/SparkleShare/Mac/SparkleShare/Pixmaps/idle2.png b/data/idle2.png similarity index 100% rename from SparkleShare/Mac/SparkleShare/Pixmaps/idle2.png rename to data/idle2.png diff --git a/SparkleShare/Mac/SparkleShare/Pixmaps/idle3.png b/data/idle3.png similarity index 100% rename from SparkleShare/Mac/SparkleShare/Pixmaps/idle3.png rename to data/idle3.png diff --git a/SparkleShare/Mac/SparkleShare/Pixmaps/idle4.png b/data/idle4.png similarity index 100% rename from SparkleShare/Mac/SparkleShare/Pixmaps/idle4.png rename to data/idle4.png diff --git a/data/side-splash.png b/data/side-splash.png index 21de89e0..47ae13ec 100644 Binary files a/data/side-splash.png and b/data/side-splash.png differ diff --git a/SparkleShare/Mac/SparkleShare/Pixmaps/sparkleshare-idle-focus.png b/data/sparkleshare-idle-focus.png similarity index 100% rename from SparkleShare/Mac/SparkleShare/Pixmaps/sparkleshare-idle-focus.png rename to data/sparkleshare-idle-focus.png diff --git a/SparkleShare/Mac/SparkleShare/Pixmaps/sparkleshare-idle.png b/data/sparkleshare-idle.png similarity index 100% rename from SparkleShare/Mac/SparkleShare/Pixmaps/sparkleshare-idle.png rename to data/sparkleshare-idle.png diff --git a/data/sparkleshare-mac.icns b/data/sparkleshare-mac.icns new file mode 100644 index 00000000..7d6c0371 Binary files /dev/null and b/data/sparkleshare-mac.icns differ diff --git a/data/sparkleshare-mac.svg b/data/sparkleshare-mac.svg new file mode 100644 index 00000000..2d408bd2 --- /dev/null +++ b/data/sparkleshare-mac.svg @@ -0,0 +1,1087 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SparkleShare/Mac/SparkleShare/sparkleshare.icns b/data/sparkleshare.icns similarity index 100% rename from SparkleShare/Mac/SparkleShare/sparkleshare.icns rename to data/sparkleshare.icns