Merge branch 'osx'
6
.gitmodules
vendored
|
@ -4,9 +4,3 @@
|
||||||
[submodule "GitSharp"]
|
[submodule "GitSharp"]
|
||||||
path = GitSharp
|
path = GitSharp
|
||||||
url = http://github.com/henon/GitSharp.git
|
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
|
|
||||||
|
|
1
MacCore
|
@ -1 +0,0 @@
|
||||||
Subproject commit da3e017ccda1ce1c21777246151a5d7f21a3ffa5
|
|
1
MonoMac
|
@ -1 +0,0 @@
|
||||||
Subproject commit 433483a484b8637b379265c38ebab643a8cfcc6a
|
|
8
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):
|
0.2-beta1 (Sun Sep 5, 2010):
|
||||||
|
|
||||||
Hylke: Aside from the usual bug fixes and behind the scenes work I mainly
|
Hylke: Aside from the usual bug fixes and behind the scenes work I mainly
|
||||||
|
|
50
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.
|
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
|
see the LICENSE file or visit http://www.gnu.org/licenses/gpl-3.0.html
|
||||||
|
|
||||||
|
|
||||||
Run
|
Run on Linux:
|
||||||
===
|
=============
|
||||||
|
|
||||||
SparkleShare currently requires:
|
SparkleShare currently requires:
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ SparkleShare currently requires:
|
||||||
- webkitgtk
|
- webkitgtk
|
||||||
- webkit-sharp
|
- webkit-sharp
|
||||||
|
|
||||||
Run the service:
|
Run the service, either click the SparkleShare launcher or:
|
||||||
|
|
||||||
$ sparkleshare start
|
$ sparkleshare start
|
||||||
|
|
||||||
|
@ -62,8 +62,8 @@ Note:
|
||||||
by hand.
|
by hand.
|
||||||
|
|
||||||
|
|
||||||
Build
|
Build on Linux:
|
||||||
=====
|
===============
|
||||||
|
|
||||||
To build SparkleShare you need:
|
To build SparkleShare you need:
|
||||||
|
|
||||||
|
@ -97,13 +97,40 @@ Note:
|
||||||
Use './configure --prefix=/usr' if you want the Nautilus extension to work.
|
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'.
|
Install git-core, automake and intltool using 'port install'.
|
||||||
Make sure that git or a symbolic link to git is in /usr/bin.
|
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
|
Frequently Asked Question
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
|
@ -118,18 +145,19 @@ Official website:
|
||||||
http://www.sparkleshare.org/
|
http://www.sparkleshare.org/
|
||||||
|
|
||||||
Project page:
|
Project page:
|
||||||
http://github.com/SparkleShare
|
http://github.com/SparkleShare/
|
||||||
|
|
||||||
IRC Channel:
|
IRC Channel:
|
||||||
#sparkleshare on irc.gnome.org
|
#sparkleshare on irc.gnome.org
|
||||||
|
|
||||||
Wiki:
|
Wiki:
|
||||||
http://github.com/hbons/SparkleShare/wiki
|
http://github.com/hbons/SparkleShare/wiki/
|
||||||
|
|
||||||
Issue tracker:
|
Issue tracker:
|
||||||
http://github.com/hbons/SparkleShare/issues
|
http://github.com/hbons/SparkleShare/issues/
|
||||||
|
|
||||||
Translation project:
|
Translation project:
|
||||||
http://www.transifex.net/projects/p/sparkleshare/
|
http://www.transifex.net/projects/p/sparkleshare/
|
||||||
|
|
||||||
|
|
||||||
Now have fun and create cool things together! :)
|
Now have fun and create cool things together! :)
|
||||||
|
|
|
@ -8,6 +8,7 @@ SOURCES = \
|
||||||
SparkleCommit.cs \
|
SparkleCommit.cs \
|
||||||
SparkleEvents.cs \
|
SparkleEvents.cs \
|
||||||
SparkleFetcher.cs \
|
SparkleFetcher.cs \
|
||||||
|
SparkleGit.cs \
|
||||||
SparkleHelpers.cs \
|
SparkleHelpers.cs \
|
||||||
SparkleListener.cs \
|
SparkleListener.cs \
|
||||||
SparkleOptions.cs \
|
SparkleOptions.cs \
|
||||||
|
|
|
@ -130,21 +130,42 @@ namespace SparkleLib {
|
||||||
private void InstallExcludeRules ()
|
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);
|
TextWriter writer = new StreamWriter (exlude_rules_file_path);
|
||||||
|
|
||||||
// Ignore gedit swap files
|
// gedit and emacs
|
||||||
writer.WriteLine ("*~");
|
writer.WriteLine ("*~");
|
||||||
|
|
||||||
// Ignore vi swap files
|
// vi(m)
|
||||||
writer.WriteLine (".*.sw?");
|
writer.WriteLine (".*.sw[a-z]");
|
||||||
|
writer.WriteLine ("*.un~");
|
||||||
|
writer.WriteLine ("*.swp");
|
||||||
|
writer.WriteLine ("*.swo");
|
||||||
|
|
||||||
// Ignore OSX's invisible directories
|
// KDE
|
||||||
|
writer.WriteLine (".directory");
|
||||||
|
|
||||||
|
// Mac OSX
|
||||||
writer.WriteLine (".DS_Store");
|
writer.WriteLine (".DS_Store");
|
||||||
|
writer.WriteLine ("Icon?");
|
||||||
|
writer.WriteLine ("._*");
|
||||||
|
writer.WriteLine (".Spotlight-V100");
|
||||||
|
writer.WriteLine (".Trashes");
|
||||||
|
|
||||||
// Ignore Windows cache files
|
// Windows
|
||||||
writer.WriteLine ("Thumbs.db");
|
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 ();
|
writer.Close ();
|
||||||
|
|
||||||
|
|
|
@ -16,47 +16,22 @@
|
||||||
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Diagnostics;
|
||||||
using System.Drawing;
|
|
||||||
using System.Timers;
|
|
||||||
using MonoMac.Foundation;
|
|
||||||
using MonoMac.AppKit;
|
|
||||||
using MonoMac.ObjCRuntime;
|
|
||||||
using MonoMac.WebKit;
|
|
||||||
|
|
||||||
namespace SparkleShare {
|
namespace SparkleLib {
|
||||||
|
|
||||||
public partial class AppDelegate : NSApplicationDelegate {
|
public class SparkleGit : Process {
|
||||||
// Workaround to be able to work with SparkleUI as the main class
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public SparkleGit (string path, string args) : base ()
|
||||||
public class SparkleUI : AppDelegate
|
|
||||||
{
|
{
|
||||||
|
|
||||||
public static SparkleStatusIcon StatusIcon;
|
EnableRaisingEvents = true;
|
||||||
public static List <SparkleLog> OpenLogs;
|
|
||||||
|
|
||||||
|
StartInfo.FileName = SparklePaths.GitPath;
|
||||||
|
StartInfo.Arguments = args;
|
||||||
public SparkleUI ()
|
StartInfo.RedirectStandardOutput = true;
|
||||||
{
|
StartInfo.UseShellExecute = false;
|
||||||
|
StartInfo.WorkingDirectory = path;
|
||||||
NSApplication.Init ();
|
|
||||||
|
|
||||||
NSApplication.SharedApplication.ApplicationIconImage
|
|
||||||
= NSImage.ImageNamed ("sparkleshare.icns");
|
|
||||||
|
|
||||||
OpenLogs = new List <SparkleLog> ();
|
|
||||||
StatusIcon = new SparkleStatusIcon ();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void Run ()
|
|
||||||
{
|
|
||||||
|
|
||||||
NSApplication.Main (new string [0]);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,7 @@
|
||||||
<Compile Include="SparkleOptions.cs" />
|
<Compile Include="SparkleOptions.cs" />
|
||||||
<Compile Include="SparkleCommit.cs" />
|
<Compile Include="SparkleCommit.cs" />
|
||||||
<Compile Include="SparkleListener.cs" />
|
<Compile Include="SparkleListener.cs" />
|
||||||
|
<Compile Include="SparkleGit.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
<ProjectExtensions>
|
<ProjectExtensions>
|
||||||
|
|
|
@ -14,62 +14,60 @@
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
using Meebey.SmartIrc4net;
|
using Meebey.SmartIrc4net;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
namespace SparkleLib {
|
namespace SparkleLib {
|
||||||
|
|
||||||
// A persistent connection to the server that
|
// A persistent connection to the server that
|
||||||
// listens for change notifications
|
// listens for change notifications
|
||||||
public class SparkleListener
|
public class SparkleListener {
|
||||||
{
|
|
||||||
|
|
||||||
// FIXME: The IrcClient is a public property because
|
// FIXME: The IrcClient is a public property because
|
||||||
// extending it causes crashes
|
// extending it causes crashes
|
||||||
public IrcClient Client;
|
public IrcClient Client;
|
||||||
private Thread Thread;
|
private Thread Thread;
|
||||||
public readonly string Server;
|
public readonly string Server;
|
||||||
|
public readonly string FallbackServer;
|
||||||
public readonly string Channel;
|
public readonly string Channel;
|
||||||
public readonly string Nick;
|
public readonly string Nick;
|
||||||
|
|
||||||
|
|
||||||
public SparkleListener (string server, string channel, string nick)
|
public SparkleListener (string server, string folder_name, string user_email)
|
||||||
{
|
{
|
||||||
|
|
||||||
Server = server;
|
// This is SparkleShare's centralized notification service.
|
||||||
Channel = channel;
|
// Don't worry, we only use this server as a backup if you
|
||||||
Nick = nick;
|
// 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 (!Nick.Equals (""))
|
if (!user_email.Equals ("") && user_email != null)
|
||||||
Nick = nick.Replace ("@", "_at_").Replace (".", "_dot_");
|
Nick = GetSHA1 (folder_name + user_email + "sparkles");
|
||||||
else
|
else
|
||||||
Nick = "anonymous";
|
Nick = GetSHA1 (DateTime.Now.ToString () + "sparkles");
|
||||||
|
|
||||||
// Keep the nick short
|
Nick = "s" + Nick.Substring (0, 7);
|
||||||
if (Nick.Length > 9)
|
// Channel = "#" + GetSHA1 (server + folder_name);
|
||||||
Nick = Nick.Substring (0, 9);
|
|
||||||
|
|
||||||
// TODO: Remove these hardcoded values
|
|
||||||
Channel = "#sparkletest";
|
|
||||||
Server = "irc.gnome.org";
|
Server = "irc.gnome.org";
|
||||||
|
Channel = "#sparkletest";
|
||||||
|
|
||||||
Client = new IrcClient () {
|
Client = new IrcClient () {
|
||||||
PingTimeout = 120,
|
PingTimeout = 180,
|
||||||
SocketSendTimeout = 120,
|
PingInterval = 90
|
||||||
SocketReceiveTimeout = 120,
|
|
||||||
AutoRetry = true,
|
|
||||||
AutoReconnect = true,
|
|
||||||
AutoRejoin = true
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Starts a new thread and listens to the channel
|
// Starts a new thread and listens to the channel
|
||||||
public void ListenForChanges ()
|
public void Listen ()
|
||||||
{
|
{
|
||||||
|
|
||||||
Thread = new Thread (
|
Thread = new Thread (
|
||||||
|
@ -104,6 +102,14 @@ namespace SparkleLib {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Announce (string message)
|
||||||
|
{
|
||||||
|
|
||||||
|
Client.SendMessage (SendType.Message, Channel, message);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Frees all resources for this Listener
|
// Frees all resources for this Listener
|
||||||
public void Dispose ()
|
public void Dispose ()
|
||||||
{
|
{
|
||||||
|
@ -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 ("-", "");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace SparkleLib {
|
||||||
public static class SparklePaths
|
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;
|
public static string HomePath = new UnixUserInfo (UnixEnvironment.UserName).HomeDirectory;
|
||||||
|
|
||||||
|
@ -44,9 +44,11 @@ namespace SparkleLib {
|
||||||
"icons");
|
"icons");
|
||||||
|
|
||||||
|
|
||||||
private static string GetGitPath ()
|
private static string SystemGitPath
|
||||||
{
|
{
|
||||||
|
|
||||||
|
get {
|
||||||
|
|
||||||
Process process = new Process ();
|
Process process = new Process ();
|
||||||
|
|
||||||
process.StartInfo.RedirectStandardOutput = true;
|
process.StartInfo.RedirectStandardOutput = true;
|
||||||
|
@ -55,11 +57,18 @@ namespace SparkleLib {
|
||||||
process.StartInfo.Arguments = "git";
|
process.StartInfo.Arguments = "git";
|
||||||
process.Start ();
|
process.Start ();
|
||||||
|
|
||||||
string git_path = process.StandardOutput.ReadToEnd ().Trim ();
|
string git_path = process.StandardOutput.ReadToEnd ();
|
||||||
|
git_path = git_path.Trim ();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty (git_path)) {
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty (git_path))
|
|
||||||
return git_path;
|
return git_path;
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
Console.WriteLine ("Sorry, SparkleShare needs Git to run, but it wasn't found.");
|
||||||
|
Environment.Exit (-1);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -67,3 +76,7 @@ namespace SparkleLib {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
using GitSharp;
|
using GitSharp;
|
||||||
using GitSharp.Commands;
|
using GitSharp.Commands;
|
||||||
using GitSharp.Core.Transport;
|
using GitSharp.Core.Transport;
|
||||||
|
@ -30,15 +31,15 @@ namespace SparkleLib {
|
||||||
|
|
||||||
public class SparkleRepo : Repository {
|
public class SparkleRepo : Repository {
|
||||||
|
|
||||||
private Process Process;
|
|
||||||
private Timer RemoteTimer;
|
private Timer RemoteTimer;
|
||||||
private Timer LocalTimer;
|
private Timer LocalTimer;
|
||||||
private FileSystemWatcher Watcher;
|
private FileSystemWatcher Watcher;
|
||||||
private bool HasChanged;
|
|
||||||
private DateTime LastChange;
|
|
||||||
private System.Object ChangeLock;
|
private System.Object ChangeLock;
|
||||||
private int FetchRequests;
|
private int FetchRequests;
|
||||||
private SparkleListener Listener;
|
private SparkleListener Listener;
|
||||||
|
private bool HasChanged;
|
||||||
|
private List <double> SizeBuffer;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The folder name the repository resides in locally
|
/// The folder name the repository resides in locally
|
||||||
|
@ -254,20 +255,10 @@ namespace SparkleLib {
|
||||||
LocalPath = path;
|
LocalPath = path;
|
||||||
Name = Path.GetFileName (LocalPath);
|
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);
|
RemoteName = Path.GetFileNameWithoutExtension (RemoteOriginUrl);
|
||||||
RemoteOriginUrl = Config ["remote.origin.url"];
|
RemoteOriginUrl = Config ["remote.origin.url"];
|
||||||
Domain = GetDomain (RemoteOriginUrl);
|
Domain = GetDomain (RemoteOriginUrl);
|
||||||
Description = GetDescription ();
|
Description = GetDescription ();
|
||||||
|
|
||||||
UserName = Config ["user.name"];
|
UserName = Config ["user.name"];
|
||||||
UserEmail = Config ["user.email"];
|
UserEmail = Config ["user.email"];
|
||||||
|
|
||||||
|
@ -283,6 +274,11 @@ namespace SparkleLib {
|
||||||
_IsPushing = false;
|
_IsPushing = false;
|
||||||
_ServerOnline = true;
|
_ServerOnline = true;
|
||||||
|
|
||||||
|
HasChanged = false;
|
||||||
|
ChangeLock = new Object ();
|
||||||
|
FetchRequests = 0;
|
||||||
|
|
||||||
|
|
||||||
string unsynced_file_path = SparkleHelpers.CombineMore (LocalPath ,
|
string unsynced_file_path = SparkleHelpers.CombineMore (LocalPath ,
|
||||||
".git", "has_unsynced_changes");
|
".git", "has_unsynced_changes");
|
||||||
|
|
||||||
|
@ -295,10 +291,6 @@ namespace SparkleLib {
|
||||||
if (_CurrentHash == null)
|
if (_CurrentHash == null)
|
||||||
CreateInitialCommit ();
|
CreateInitialCommit ();
|
||||||
|
|
||||||
HasChanged = false;
|
|
||||||
ChangeLock = new System.Object ();
|
|
||||||
FetchRequests = 0;
|
|
||||||
|
|
||||||
|
|
||||||
// Watch the repository's folder
|
// Watch the repository's folder
|
||||||
Watcher = new FileSystemWatcher (LocalPath) {
|
Watcher = new FileSystemWatcher (LocalPath) {
|
||||||
|
@ -312,35 +304,41 @@ namespace SparkleLib {
|
||||||
Watcher.Deleted += new FileSystemEventHandler (OnFileActivity);
|
Watcher.Deleted += new FileSystemEventHandler (OnFileActivity);
|
||||||
Watcher.Renamed += new RenamedEventHandler (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 () {
|
RemoteTimer = new Timer () {
|
||||||
Interval = 60000
|
Interval = 60000
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Listen to the irc channel on the server
|
|
||||||
Listener = new SparkleListener (Domain, "#" + RemoteName, UserEmail);
|
|
||||||
|
|
||||||
RemoteTimer.Elapsed += delegate {
|
RemoteTimer.Elapsed += delegate {
|
||||||
|
|
||||||
if (_IsPolling)
|
if (_IsPolling) {
|
||||||
CheckForRemoteChanges ();
|
|
||||||
|
|
||||||
if (_HasUnsyncedChanges)
|
CheckForRemoteChanges ();
|
||||||
Push ();
|
|
||||||
|
|
||||||
if (!Listener.Client.IsConnected) {
|
if (!Listener.Client.IsConnected) {
|
||||||
|
|
||||||
SparkleHelpers.DebugInfo ("Irc", "[" + Name + "] Trying to reconnect...");
|
SparkleHelpers.DebugInfo ("Irc", "[" + Name + "] Trying to reconnect...");
|
||||||
Listener.Client.Reconnect (true, true);
|
Listener.Listen ();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_HasUnsyncedChanges)
|
||||||
|
Push ();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Stop polling when the connection to the irc channel is succesful
|
// Stop polling when the connection to the irc channel is succesful
|
||||||
Listener.Client.OnConnected += delegate {
|
Listener.Client.OnConnected += delegate {
|
||||||
|
|
||||||
|
_IsPolling = false;
|
||||||
|
|
||||||
// Check for changes manually one more time
|
// Check for changes manually one more time
|
||||||
CheckForRemoteChanges ();
|
CheckForRemoteChanges ();
|
||||||
|
|
||||||
|
@ -348,9 +346,15 @@ namespace SparkleLib {
|
||||||
if (_HasUnsyncedChanges)
|
if (_HasUnsyncedChanges)
|
||||||
Push ();
|
Push ();
|
||||||
|
|
||||||
SparkleHelpers.DebugInfo ("Irc", "[" + Name + "] Connected. Now listening...");
|
SparkleHelpers.DebugInfo ("Irc", "[" + Name + "] Connected. Now listening... (" + Listener.Server + ")");
|
||||||
|
|
||||||
_IsPolling = false;
|
};
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -358,9 +362,6 @@ namespace SparkleLib {
|
||||||
Listener.Client.OnDisconnected += delegate {
|
Listener.Client.OnDisconnected += delegate {
|
||||||
|
|
||||||
SparkleHelpers.DebugInfo ("Irc", "[" + Name + "] Lost connection. Falling back to polling...");
|
SparkleHelpers.DebugInfo ("Irc", "[" + Name + "] Lost connection. Falling back to polling...");
|
||||||
|
|
||||||
CheckForRemoteChanges ();
|
|
||||||
|
|
||||||
_IsPolling = true;
|
_IsPolling = true;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -369,8 +370,9 @@ namespace SparkleLib {
|
||||||
Listener.Client.OnChannelMessage += delegate (object o, IrcEventArgs args) {
|
Listener.Client.OnChannelMessage += delegate (object o, IrcEventArgs args) {
|
||||||
|
|
||||||
SparkleHelpers.DebugInfo ("Irc", "[" + Name + "] Was notified of a remote change.");
|
SparkleHelpers.DebugInfo ("Irc", "[" + Name + "] Was notified of a remote change.");
|
||||||
|
string message = args.Data.Message.Trim ();
|
||||||
|
|
||||||
if (!args.Data.Message.Equals (_CurrentHash)) {
|
if (!message.Equals (_CurrentHash) && message.Length == 40) {
|
||||||
|
|
||||||
FetchRequests++;
|
FetchRequests++;
|
||||||
|
|
||||||
|
@ -389,6 +391,7 @@ namespace SparkleLib {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
// Not really needed as we won't be notified about our own messages
|
||||||
SparkleHelpers.DebugInfo ("Irc",
|
SparkleHelpers.DebugInfo ("Irc",
|
||||||
"[" + Name + "] False alarm, already up to date. (" + _CurrentHash + ")");
|
"[" + Name + "] False alarm, already up to date. (" + _CurrentHash + ")");
|
||||||
|
|
||||||
|
@ -397,13 +400,15 @@ namespace SparkleLib {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Start listening
|
// Start listening
|
||||||
Listener.ListenForChanges ();
|
Listener.Listen ();
|
||||||
|
|
||||||
|
|
||||||
|
SizeBuffer = new List <double> ();
|
||||||
|
|
||||||
// Keep a timer that checks if there are changes and
|
// Keep a timer that checks if there are changes and
|
||||||
// whether they have settled
|
// whether they have settled
|
||||||
LocalTimer = new Timer () {
|
LocalTimer = new Timer () {
|
||||||
Interval = 4000
|
Interval = 250
|
||||||
};
|
};
|
||||||
|
|
||||||
LocalTimer.Elapsed += delegate (object o, ElapsedEventArgs args) {
|
LocalTimer.Elapsed += delegate (object o, ElapsedEventArgs args) {
|
||||||
|
@ -411,9 +416,7 @@ namespace SparkleLib {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
if (_IsPolling)
|
|
||||||
RemoteTimer.Start ();
|
RemoteTimer.Start ();
|
||||||
|
|
||||||
LocalTimer.Start ();
|
LocalTimer.Start ();
|
||||||
|
|
||||||
// Add everything that changed
|
// Add everything that changed
|
||||||
|
@ -430,23 +433,14 @@ namespace SparkleLib {
|
||||||
{
|
{
|
||||||
|
|
||||||
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Checking for remote changes...");
|
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Checking for remote changes...");
|
||||||
|
SparkleGit git = new SparkleGit (LocalPath, "ls-remote origin master");
|
||||||
|
|
||||||
Process process = new Process () {
|
git.Exited += delegate {
|
||||||
EnableRaisingEvents = true
|
|
||||||
};
|
|
||||||
|
|
||||||
process.StartInfo.FileName = SparklePaths.GitPath;
|
if (git.ExitCode != 0)
|
||||||
process.StartInfo.RedirectStandardOutput = true;
|
|
||||||
process.StartInfo.UseShellExecute = false;
|
|
||||||
process.StartInfo.WorkingDirectory = LocalPath;
|
|
||||||
process.StartInfo.Arguments = "ls-remote origin master";
|
|
||||||
|
|
||||||
process.Exited += delegate {
|
|
||||||
|
|
||||||
if (process.ExitCode != 0)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
string remote_hash = process.StandardOutput.ReadToEnd ();
|
string remote_hash = git.StandardOutput.ReadToEnd ();
|
||||||
|
|
||||||
if (!remote_hash.StartsWith (_CurrentHash)) {
|
if (!remote_hash.StartsWith (_CurrentHash)) {
|
||||||
|
|
||||||
|
@ -458,32 +452,9 @@ namespace SparkleLib {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
process.Start ();
|
|
||||||
|
|
||||||
/* FIXME: LsRemoteCommand is not yet implemented by GitSharp
|
git.Start ();
|
||||||
|
git.WaitForExit ();
|
||||||
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 ();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -495,14 +466,17 @@ namespace SparkleLib {
|
||||||
|
|
||||||
if (HasChanged) {
|
if (HasChanged) {
|
||||||
|
|
||||||
SparkleHelpers.DebugInfo ("Local", "[" + Name + "] Changes found, checking if settled.");
|
if (SizeBuffer.Count >= 4)
|
||||||
|
SizeBuffer.RemoveAt (0);
|
||||||
|
|
||||||
DateTime now = DateTime.UtcNow;
|
DirectoryInfo dir_info = new DirectoryInfo (LocalPath);
|
||||||
TimeSpan changed = new TimeSpan (now.Ticks - LastChange.Ticks);
|
SizeBuffer.Add (CalculateFolderSize (dir_info));
|
||||||
|
|
||||||
if (changed.TotalMilliseconds > 5000) {
|
if (SizeBuffer [0].Equals (SizeBuffer [1]) &&
|
||||||
|
SizeBuffer [1].Equals (SizeBuffer [2]) &&
|
||||||
|
SizeBuffer [2].Equals (SizeBuffer [3])) {
|
||||||
|
|
||||||
SparkleHelpers.DebugInfo ("Local", "[" + Name + "] Changes have settled, adding files...");
|
SparkleHelpers.DebugInfo ("Local", "[" + Name + "] Changes have settled.");
|
||||||
|
|
||||||
_IsBuffering = false;
|
_IsBuffering = false;
|
||||||
|
|
||||||
|
@ -524,7 +498,11 @@ namespace SparkleLib {
|
||||||
|
|
||||||
WatcherChangeTypes wct = fse_args.ChangeType;
|
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;
|
_IsBuffering = true;
|
||||||
|
|
||||||
|
@ -540,12 +518,12 @@ namespace SparkleLib {
|
||||||
}
|
}
|
||||||
|
|
||||||
SparkleHelpers.DebugInfo ("Event", "[" + Name + "] " + wct.ToString () + " '" + fse_args.Name + "'");
|
SparkleHelpers.DebugInfo ("Event", "[" + Name + "] " + wct.ToString () + " '" + fse_args.Name + "'");
|
||||||
|
SparkleHelpers.DebugInfo ("Local", "[" + Name + "] Changes found, checking if settled.");
|
||||||
|
|
||||||
RemoteTimer.Stop ();
|
RemoteTimer.Stop ();
|
||||||
|
|
||||||
lock (ChangeLock) {
|
lock (ChangeLock) {
|
||||||
|
|
||||||
LastChange = DateTime.UtcNow;
|
|
||||||
HasChanged = true;
|
HasChanged = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -565,14 +543,13 @@ namespace SparkleLib {
|
||||||
LocalTimer.Stop ();
|
LocalTimer.Stop ();
|
||||||
RemoteTimer.Stop ();
|
RemoteTimer.Stop ();
|
||||||
|
|
||||||
|
if (Status.AnyDifferences) {
|
||||||
|
|
||||||
Add ();
|
Add ();
|
||||||
|
|
||||||
string message = FormatCommitMessage ();
|
string message = FormatCommitMessage ();
|
||||||
|
|
||||||
if (message != null) {
|
|
||||||
|
|
||||||
Commit (message);
|
Commit (message);
|
||||||
CheckForRemoteChanges ();
|
|
||||||
Push ();
|
Push ();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -586,9 +563,7 @@ namespace SparkleLib {
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
|
|
||||||
if (_IsPolling)
|
|
||||||
RemoteTimer.Start ();
|
RemoteTimer.Start ();
|
||||||
|
|
||||||
LocalTimer.Start ();
|
LocalTimer.Start ();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -604,9 +579,10 @@ namespace SparkleLib {
|
||||||
|
|
||||||
// FIXME: this GitSharp method seems to block...
|
// FIXME: this GitSharp method seems to block...
|
||||||
// Index.AddAll ();
|
// Index.AddAll ();
|
||||||
Process.StartInfo.Arguments = "add --all";
|
|
||||||
Process.Start ();
|
SparkleGit git = new SparkleGit (LocalPath, "add --all");
|
||||||
Process.WaitForExit ();
|
git.Start ();
|
||||||
|
git.WaitForExit ();
|
||||||
|
|
||||||
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Changes staged.");
|
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
|
// Commits the made changes
|
||||||
new public void Commit (string message)
|
new public void Commit (string message)
|
||||||
{
|
{
|
||||||
|
@ -626,15 +617,21 @@ namespace SparkleLib {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
base.Commit (message);
|
base.Commit (message);
|
||||||
|
_CurrentHash = Head.CurrentCommit.Hash;
|
||||||
|
|
||||||
SparkleHelpers.DebugInfo ("Commit", "[" + Name + "] " + message);
|
SparkleHelpers.DebugInfo ("Commit", "[" + Name + "] " + message + " (" + _CurrentHash);
|
||||||
|
|
||||||
SparkleEventArgs args = new SparkleEventArgs ("Commited");
|
SparkleEventArgs args = new SparkleEventArgs ("Commited") {
|
||||||
args.Message = message;
|
Message = message
|
||||||
|
};
|
||||||
|
|
||||||
if (Commited != null)
|
if (Commited != null)
|
||||||
Commited (this, args);
|
Commited (this, args);
|
||||||
|
|
||||||
|
// Collect garbage pseudo-randomly
|
||||||
|
if (DateTime.Now.Second % 10 == 0)
|
||||||
|
CollectGarbage ();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -647,32 +644,9 @@ namespace SparkleLib {
|
||||||
|
|
||||||
RemoteTimer.Stop ();
|
RemoteTimer.Stop ();
|
||||||
|
|
||||||
|
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Fetching changes...");
|
||||||
|
|
||||||
/* FIXME: SSH transport doesn't work with GitSharp
|
SparkleGit git = new SparkleGit (LocalPath, "fetch -v origin master");
|
||||||
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;
|
|
||||||
|
|
||||||
SparkleEventArgs args;
|
SparkleEventArgs args;
|
||||||
args = new SparkleEventArgs ("FetchingStarted");
|
args = new SparkleEventArgs ("FetchingStarted");
|
||||||
|
@ -680,28 +654,22 @@ namespace SparkleLib {
|
||||||
if (FetchingStarted != null)
|
if (FetchingStarted != null)
|
||||||
FetchingStarted (this, args);
|
FetchingStarted (this, args);
|
||||||
|
|
||||||
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Fetching changes...");
|
|
||||||
|
|
||||||
process.StartInfo.Arguments = "fetch -v origin master";
|
git.Exited += delegate {
|
||||||
|
|
||||||
process.Exited += delegate {
|
|
||||||
|
|
||||||
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Changes fetched.");
|
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Changes fetched.");
|
||||||
|
|
||||||
args = new SparkleEventArgs ("FetchingFinished");
|
|
||||||
|
|
||||||
_IsSyncing = false;
|
_IsSyncing = false;
|
||||||
_IsFetching = false;
|
_IsFetching = false;
|
||||||
|
|
||||||
if (_IsPolling)
|
|
||||||
RemoteTimer.Start ();
|
|
||||||
|
|
||||||
_CurrentHash = Head.CurrentCommit.Hash;
|
_CurrentHash = Head.CurrentCommit.Hash;
|
||||||
|
|
||||||
if (process.ExitCode != 0) {
|
if (git.ExitCode != 0) {
|
||||||
|
|
||||||
_ServerOnline = false;
|
_ServerOnline = false;
|
||||||
|
|
||||||
|
args = new SparkleEventArgs ("FetchingFailed");
|
||||||
|
|
||||||
if (FetchingFailed != null)
|
if (FetchingFailed != null)
|
||||||
FetchingFailed (this, args);
|
FetchingFailed (this, args);
|
||||||
|
|
||||||
|
@ -709,15 +677,20 @@ namespace SparkleLib {
|
||||||
|
|
||||||
_ServerOnline = true;
|
_ServerOnline = true;
|
||||||
|
|
||||||
|
args = new SparkleEventArgs ("FetchingFinished");
|
||||||
|
|
||||||
if (FetchingFinished != null)
|
if (FetchingFinished != null)
|
||||||
FetchingFinished (this, args);
|
FetchingFinished (this, args);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RemoteTimer.Start ();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
process.Start ();
|
|
||||||
process.WaitForExit ();
|
git.Start ();
|
||||||
|
git.WaitForExit ();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -726,49 +699,42 @@ namespace SparkleLib {
|
||||||
public void Rebase ()
|
public void Rebase ()
|
||||||
{
|
{
|
||||||
|
|
||||||
Add ();
|
|
||||||
|
|
||||||
Watcher.EnableRaisingEvents = false;
|
Watcher.EnableRaisingEvents = false;
|
||||||
|
|
||||||
|
if (Status.AnyDifferences) {
|
||||||
|
|
||||||
|
Add ();
|
||||||
|
|
||||||
|
string commit_message = FormatCommitMessage ();
|
||||||
|
Commit (commit_message);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Rebasing changes...");
|
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Rebasing changes...");
|
||||||
|
SparkleGit git = new SparkleGit (LocalPath, "rebase -v FETCH_HEAD");
|
||||||
|
|
||||||
Process.StartInfo.Arguments = "rebase -v FETCH_HEAD";
|
git.Exited += delegate {
|
||||||
Process.WaitForExit ();
|
|
||||||
Process.Start ();
|
|
||||||
|
|
||||||
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Changes rebased.");
|
if (Status.MergeConflict.Count > 0) {
|
||||||
|
|
||||||
string output = Process.StandardOutput.ReadToEnd ().Trim ();
|
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Conflict detected...");
|
||||||
|
|
||||||
if (!output.Contains ("up to date")) {
|
foreach (string problem_file_name in Status.MergeConflict) {
|
||||||
|
|
||||||
if (output.Contains ("Failed to merge")) {
|
SparkleGit git_ours = new SparkleGit (LocalPath,
|
||||||
|
"checkout --ours " + problem_file_name);
|
||||||
|
git_ours.Start ();
|
||||||
|
git_ours.WaitForExit ();
|
||||||
|
|
||||||
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Resolving conflict...");
|
string timestamp = DateTime.Now.ToString ("H:mm d MMM");
|
||||||
|
|
||||||
Process.StartInfo.Arguments = "status";
|
string new_file_name = problem_file_name + " (" + UserName + ", " + timestamp + ")";
|
||||||
Process.WaitForExit ();
|
File.Move (problem_file_name, new_file_name);
|
||||||
Process.Start ();
|
|
||||||
output = Process.StandardOutput.ReadToEnd ().Trim ();
|
|
||||||
string [] lines = Regex.Split (output, "\n");
|
|
||||||
|
|
||||||
foreach (string line in lines) {
|
SparkleGit git_theirs = new SparkleGit (LocalPath,
|
||||||
|
"checkout --theirs " + problem_file_name);
|
||||||
if (line.Contains ("needs merge")) {
|
git_theirs.Start ();
|
||||||
|
git_theirs.WaitForExit ();
|
||||||
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");
|
SparkleEventArgs args = new SparkleEventArgs ("ConflictDetected");
|
||||||
|
|
||||||
|
@ -777,13 +743,11 @@ namespace SparkleLib {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Add ();
|
Add ();
|
||||||
|
|
||||||
Process.StartInfo.Arguments = "rebase --continue";
|
SparkleGit git_continue = new SparkleGit (LocalPath, "rebase --continue");
|
||||||
Process.WaitForExit ();
|
git_continue.Start ();
|
||||||
Process.Start ();
|
git_continue.WaitForExit ();
|
||||||
|
|
||||||
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Conflict resolved.");
|
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Conflict resolved.");
|
||||||
|
|
||||||
|
@ -791,13 +755,18 @@ namespace SparkleLib {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
List <SparkleCommit> commits = GetCommits (1);
|
|
||||||
|
git.Start ();
|
||||||
|
git.WaitForExit ();
|
||||||
|
|
||||||
|
_CurrentHash = Head.CurrentCommit.Hash;
|
||||||
|
|
||||||
if (NewCommit != null)
|
if (NewCommit != null)
|
||||||
NewCommit (commits [0], LocalPath);
|
NewCommit (GetCommits (2) [0], LocalPath); // FIXME: GetCommits doesn't like 1
|
||||||
|
|
||||||
}
|
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Changes rebased.");
|
||||||
|
|
||||||
Watcher.EnableRaisingEvents = true;
|
Watcher.EnableRaisingEvents = true;
|
||||||
|
|
||||||
|
@ -811,40 +780,22 @@ namespace SparkleLib {
|
||||||
_IsSyncing = true;
|
_IsSyncing = true;
|
||||||
_IsPushing = true;
|
_IsPushing = true;
|
||||||
|
|
||||||
|
SparkleGit git = new SparkleGit (LocalPath, "push origin master");
|
||||||
|
|
||||||
|
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Pushing changes...");
|
||||||
|
|
||||||
SparkleEventArgs args = new SparkleEventArgs ("PushingStarted");
|
SparkleEventArgs args = new SparkleEventArgs ("PushingStarted");
|
||||||
|
|
||||||
if (PushingStarted != null)
|
if (PushingStarted != null)
|
||||||
PushingStarted (this, args);
|
PushingStarted (this, args);
|
||||||
|
|
||||||
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Pushing changes...");
|
|
||||||
|
|
||||||
/* FIXME: SSH transport doesn't work with GitSharp
|
git.Exited += delegate {
|
||||||
try {
|
|
||||||
|
|
||||||
PushCommand push_command = new PushCommand () {
|
|
||||||
Remote = "origin",
|
|
||||||
Repository = this
|
|
||||||
};
|
|
||||||
|
|
||||||
push_command.Execute ();
|
|
||||||
|
|
||||||
} catch (GitSharp.Core.Exceptions.TransportException e) {
|
|
||||||
|
|
||||||
Console.WriteLine (e.Message);
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
Process.StartInfo.Arguments = "push origin master";
|
|
||||||
|
|
||||||
Process.WaitForExit ();
|
|
||||||
|
|
||||||
Process.Exited += delegate {
|
|
||||||
|
|
||||||
_IsSyncing = false;
|
_IsSyncing = false;
|
||||||
_IsPushing = false;
|
_IsPushing = false;
|
||||||
|
|
||||||
if (Process.ExitCode != 0) {
|
if (git.ExitCode != 0) {
|
||||||
|
|
||||||
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Pushing failed.");
|
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Pushing failed.");
|
||||||
|
|
||||||
|
@ -861,6 +812,8 @@ namespace SparkleLib {
|
||||||
if (PushingFailed != null)
|
if (PushingFailed != null)
|
||||||
PushingFailed (this, args);
|
PushingFailed (this, args);
|
||||||
|
|
||||||
|
CheckForChanges ();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Changes pushed.");
|
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Changes pushed.");
|
||||||
|
@ -878,32 +831,16 @@ namespace SparkleLib {
|
||||||
if (PushingFinished != null)
|
if (PushingFinished != null)
|
||||||
PushingFinished (this, args);
|
PushingFinished (this, args);
|
||||||
|
|
||||||
|
if (!_IsPolling)
|
||||||
|
Listener.Announce (_CurrentHash);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
Process.Start ();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Ignores repos, dotfiles, swap files and the like
|
git.Start ();
|
||||||
private bool ShouldIgnore (string file_path)
|
git.WaitForExit ();
|
||||||
{
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -948,6 +885,37 @@ namespace SparkleLib {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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
|
// Create a first commit in case the user has cloned
|
||||||
// an empty repository
|
// an empty repository
|
||||||
private void CreateInitialCommit ()
|
private void CreateInitialCommit ()
|
||||||
|
@ -964,48 +932,90 @@ namespace SparkleLib {
|
||||||
public List <SparkleCommit> GetCommits (int count)
|
public List <SparkleCommit> GetCommits (int count)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (count <= 0)
|
if (count < 1)
|
||||||
return null;
|
count = 30;
|
||||||
|
|
||||||
List <SparkleCommit> commits = new List <SparkleCommit> ();
|
List <SparkleCommit> commits = new List <SparkleCommit> ();
|
||||||
|
|
||||||
string commit_ref = "HEAD";
|
SparkleGit git_log = new SparkleGit (LocalPath, "log -" + count + " --raw --date=iso");
|
||||||
|
git_log.Start ();
|
||||||
|
git_log.WaitForExit ();
|
||||||
|
|
||||||
try {
|
string output = git_log.StandardOutput.ReadToEnd ();
|
||||||
|
string [] lines = output.Split ("\n".ToCharArray ());
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
List <string> entries = new List <string> ();
|
||||||
|
|
||||||
Commit commit = new Commit (this, commit_ref);
|
int j = 0;
|
||||||
|
string entry = "";
|
||||||
|
foreach (string line in lines) {
|
||||||
|
|
||||||
SparkleCommit sparkle_commit = new SparkleCommit ();
|
if (line.StartsWith ("commit") && j > 0) {
|
||||||
|
|
||||||
sparkle_commit.UserName = commit.Author.Name;
|
entries.Add (entry);
|
||||||
sparkle_commit.UserEmail = commit.Author.EmailAddress;
|
entry = "";
|
||||||
sparkle_commit.DateTime = commit.CommitDate.DateTime;
|
|
||||||
sparkle_commit.Hash = commit.Hash;
|
|
||||||
|
|
||||||
foreach (Change change in commit.Changes) {
|
|
||||||
|
|
||||||
if (change.ChangeType.ToString ().Equals ("Added"))
|
|
||||||
sparkle_commit.Added.Add (change.Path);
|
|
||||||
|
|
||||||
if (change.ChangeType.ToString ().Equals ("Modified"))
|
|
||||||
sparkle_commit.Edited.Add (change.Path);
|
|
||||||
|
|
||||||
if (change.ChangeType.ToString ().Equals ("Deleted"))
|
|
||||||
sparkle_commit.Deleted.Add (change.Path);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
commits.Add (sparkle_commit);
|
entry += line + "\n";
|
||||||
commit_ref += "^";
|
j++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (System.NullReferenceException) {
|
|
||||||
|
|
||||||
// FIXME: Doesn't show the first commit because it throws
|
foreach (string log_entry in entries) {
|
||||||
// this exception before getting to it. Seems to be a bug in GitSharp
|
|
||||||
|
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 (commit);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
21
SparkleShare/Mac/AppDelegate.cs
Normal file
|
@ -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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,26 +2,19 @@
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string></string>
|
||||||
<key>CFBundleIconFile</key>
|
<key>CFBundleIconFile</key>
|
||||||
<string>sparkleshare.icns</string>
|
<string>sparkleshare</string>
|
||||||
<key>LSEnvironment</key>
|
|
||||||
<dict>
|
|
||||||
<key>PATH</key>
|
|
||||||
<string>/opt/local/bin</string>
|
|
||||||
</dict>
|
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
<string>org.sparkleshare.sparkleshare</string>
|
<string>org.sparkleshare.sparkleshare</string>
|
||||||
<key>CFBundleName</key>
|
<key>CFBundleName</key>
|
||||||
<string>SparkleShare</string>
|
<string>SparkleShare</string>
|
||||||
<key>CFBundleVersion</key>
|
|
||||||
<string>1</string>
|
|
||||||
<key>LSMinimumSystemVersion</key>
|
<key>LSMinimumSystemVersion</key>
|
||||||
<string>10.6</string>
|
<string>10.6</string>
|
||||||
<key>NSMainNibFile</key>
|
<key>NSMainNibFile</key>
|
||||||
<string>MainMenu</string>
|
<string>MainMenu</string>
|
||||||
<key>NSPrincipalClass</key>
|
<key>NSPrincipalClass</key>
|
||||||
<string>NSApplication</string>
|
<string>NSApplication</string>
|
||||||
<key>LSBackgroundOnly</key>
|
|
||||||
<false/>
|
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
2245
SparkleShare/Mac/MainMenu.xib
Normal file
558
SparkleShare/Mac/SparkleIntro.cs
Normal file
|
@ -0,0 +1,558 @@
|
||||||
|
// SparkleShare, an instant update workflow to Git.
|
||||||
|
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.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 ();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
181
SparkleShare/Mac/SparkleLog.cs
Normal file
|
@ -0,0 +1,181 @@
|
||||||
|
// SparkleShare, an instant update workflow to Git.
|
||||||
|
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.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 ("<!-- $body-font-family -->", "Lucida Grande");
|
||||||
|
html = html.Replace ("<!-- $body-font-size -->", "13.4px");
|
||||||
|
html = html.Replace ("<!-- $secondary-font-color -->", "#bbb");
|
||||||
|
html = html.Replace ("<!-- $small-color -->", "#ddd");
|
||||||
|
html = html.Replace ("<!-- $day-entry-header-background-color -->", "#f5f5f5");
|
||||||
|
html = html.Replace ("<!-- $a-color -->", "#0085cf");
|
||||||
|
html = html.Replace ("<!-- $no-buddy-icon-background-image -->",
|
||||||
|
"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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -50,7 +50,7 @@ namespace SparkleShare {
|
||||||
public override void AddToBookmarks ()
|
public override void AddToBookmarks ()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,9 +63,6 @@ namespace SparkleShare {
|
||||||
|
|
||||||
Directory.CreateDirectory (SparklePaths.SparklePath);
|
Directory.CreateDirectory (SparklePaths.SparklePath);
|
||||||
|
|
||||||
NSWorkspace.SharedWorkspace.SetIconforFile (NSImage.ImageNamed ("sparkleshare.icns"),
|
|
||||||
SparklePaths.SparklePath, 0);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -82,11 +79,69 @@ namespace SparkleShare {
|
||||||
{
|
{
|
||||||
|
|
||||||
string folder = Path.Combine (SparklePaths.SparklePath, subfolder);
|
string folder = Path.Combine (SparklePaths.SparklePath, subfolder);
|
||||||
|
folder.Replace (" ", "\\ "); // Escape space-characters
|
||||||
|
|
||||||
Process process = new Process ();
|
NSWorkspace.SharedWorkspace.OpenFile (folder);
|
||||||
process.StartInfo.Arguments = folder.Replace (" ", "\\ "); // Escape space-characters
|
|
||||||
process.StartInfo.FileName = "open";
|
}
|
||||||
process.Start ();
|
|
||||||
|
|
||||||
|
public override string EventLogHTML
|
||||||
|
{
|
||||||
|
|
||||||
|
get {
|
||||||
|
|
||||||
|
string resource_path = NSBundle.MainBundle.ResourcePath;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
161
SparkleShare/Mac/SparkleShare.csproj
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProductVersion>10.0.0</ProductVersion>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
<ProjectGuid>{CF5BC8DB-A633-4FCC-8A3E-E3AC9B59FABC}</ProjectGuid>
|
||||||
|
<ProjectTypeGuids>{1C533B1C-72DD-4CB1-9F6B-BF11D93BCFBE};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<RootNamespace>SparkleShare</RootNamespace>
|
||||||
|
<AssemblyName>SparkleShare</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||||
|
<ReleaseVersion>0.2</ReleaseVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug</OutputPath>
|
||||||
|
<DefineConstants>DEBUG</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<ConsolePause>false</ConsolePause>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>none</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Release</OutputPath>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<ConsolePause>false</ConsolePause>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Xml">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Core">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Xml.Linq">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Drawing">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="MonoMac">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="SparkleLib, Version=0.2.0.0, Culture=neutral, PublicKeyToken=null">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\..\bin\SparkleLib.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Mono.Posix">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="DiffieHellman, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\..\bin\DiffieHellman.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="GitSharp.Core, Version=0.3.0.0, Culture=neutral, PublicKeyToken=null">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\..\bin\GitSharp.Core.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="GitSharp, Version=0.3.0.0, Culture=neutral, PublicKeyToken=null">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\..\bin\GitSharp.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Meebey.SmartIrc4net, Version=0.4.5.0, Culture=neutral, PublicKeyToken=7868485fbf407e0f">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\..\bin\Meebey.SmartIrc4net.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Org.Mentalis.Security, Version=1.0.13.715, Culture=neutral, PublicKeyToken=null">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\..\bin\Org.Mentalis.Security.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Tamir.SharpSSH, Version=1.1.1.13, Culture=neutral, PublicKeyToken=null">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\..\bin\Tamir.SharpSSH.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="AppDelegate.cs">
|
||||||
|
<DependentUpon>MainMenu.xib</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="MainMenu.xib.designer.cs">
|
||||||
|
<DependentUpon>MainMenu.xib</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="..\SparkleController.cs">
|
||||||
|
<Link>SparkleController.cs</Link>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="SparkleWindow.cs" />
|
||||||
|
<Compile Include="SparkleIntro.cs" />
|
||||||
|
<Compile Include="SparkleLog.cs" />
|
||||||
|
<Compile Include="SparkleMacController.cs" />
|
||||||
|
<Compile Include="SparkleStatusIcon.cs" />
|
||||||
|
<Compile Include="SparkleUI.cs" />
|
||||||
|
<Compile Include="..\SparkleShare.cs">
|
||||||
|
<Link>SparkleShare.cs</Link>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Include="MainMenu.xib" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="Info.plist" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\Mono\MonoMac\v0.0\Mono.MonoMac.targets" />
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="..\..\data\html\day-entry.html">
|
||||||
|
<Link>HTML\day-entry.html</Link>
|
||||||
|
</Content>
|
||||||
|
<Content Include="..\..\data\html\event-entry.html">
|
||||||
|
<Link>HTML\event-entry.html</Link>
|
||||||
|
</Content>
|
||||||
|
<Content Include="..\..\data\html\event-log.html">
|
||||||
|
<Link>HTML\event-log.html</Link>
|
||||||
|
</Content>
|
||||||
|
<Content Include="..\..\data\side-splash.png">
|
||||||
|
<Link>Pixmaps\side-splash.png</Link>
|
||||||
|
</Content>
|
||||||
|
<Content Include="..\..\data\avatar-default.png">
|
||||||
|
<Link>Pixmaps\avatar-default.png</Link>
|
||||||
|
</Content>
|
||||||
|
<Content Include="..\..\data\sparkleshare-mac.icns">
|
||||||
|
<Link>sparkleshare-mac.icns</Link>
|
||||||
|
</Content>
|
||||||
|
<Content Include="..\..\data\sparkleshare.icns">
|
||||||
|
<Link>sparkleshare.icns</Link>
|
||||||
|
</Content>
|
||||||
|
<Content Include="..\..\data\idle-active.png">
|
||||||
|
<Link>Pixmaps\idle-active.png</Link>
|
||||||
|
</Content>
|
||||||
|
<Content Include="..\..\data\idle.png">
|
||||||
|
<Link>Pixmaps\idle.png</Link>
|
||||||
|
</Content>
|
||||||
|
<Content Include="..\..\data\idle0.png">
|
||||||
|
<Link>Pixmaps\idle0.png</Link>
|
||||||
|
</Content>
|
||||||
|
<Content Include="..\..\data\idle1.png">
|
||||||
|
<Link>Pixmaps\idle1.png</Link>
|
||||||
|
</Content>
|
||||||
|
<Content Include="..\..\data\idle2.png">
|
||||||
|
<Link>Pixmaps\idle2.png</Link>
|
||||||
|
</Content>
|
||||||
|
<Content Include="..\..\data\idle3.png">
|
||||||
|
<Link>Pixmaps\idle3.png</Link>
|
||||||
|
</Content>
|
||||||
|
<Content Include="..\..\data\idle4.png">
|
||||||
|
<Link>Pixmaps\idle4.png</Link>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Pixmaps\" />
|
||||||
|
<Folder Include="HTML\" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
21
SparkleShare/Mac/SparkleShare.sln
Normal file
|
@ -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
|
|
@ -1,298 +0,0 @@
|
||||||
//
|
|
||||||
// Layout.cs
|
|
||||||
//
|
|
||||||
// Author:
|
|
||||||
// Michael Hutchinson <mhutchinson@novell.com>
|
|
||||||
//
|
|
||||||
// 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>, ILayout
|
|
||||||
{
|
|
||||||
List<ILayout> children = new List<ILayout> ();
|
|
||||||
|
|
||||||
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<ILayout> 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<LayoutRequest> ChildRequests = new List<LayoutRequest> ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,190 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.10">
|
|
||||||
<data>
|
|
||||||
<int key="IBDocument.SystemTarget">1060</int>
|
|
||||||
<string key="IBDocument.SystemVersion">10D573</string>
|
|
||||||
<string key="IBDocument.InterfaceBuilderVersion">762</string>
|
|
||||||
<string key="IBDocument.AppKitVersion">1038.29</string>
|
|
||||||
<string key="IBDocument.HIToolboxVersion">460.00</string>
|
|
||||||
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
|
|
||||||
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
|
|
||||||
<string key="NS.object.0">762</string>
|
|
||||||
</object>
|
|
||||||
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
<integer value="2"/>
|
|
||||||
</object>
|
|
||||||
<object class="NSArray" key="IBDocument.PluginDependencies">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
|
||||||
</object>
|
|
||||||
<object class="NSMutableDictionary" key="IBDocument.Metadata">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
<object class="NSArray" key="dict.sortedKeys" id="0">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
</object>
|
|
||||||
<object class="NSMutableArray" key="dict.values">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
<object class="NSCustomObject" id="1001">
|
|
||||||
<string key="NSClassName">MainWindowController</string>
|
|
||||||
</object>
|
|
||||||
<object class="NSCustomObject" id="1003">
|
|
||||||
<string key="NSClassName">FirstResponder</string>
|
|
||||||
</object>
|
|
||||||
<object class="NSCustomObject" id="1004">
|
|
||||||
<string key="NSClassName">NSApplication</string>
|
|
||||||
</object>
|
|
||||||
<object class="NSWindowTemplate" id="748157544">
|
|
||||||
<int key="NSWindowStyleMask">15</int>
|
|
||||||
<int key="NSWindowBacking">2</int>
|
|
||||||
<string key="NSWindowRect">{{131, 74}, {606, 354}}</string>
|
|
||||||
<int key="NSWTFlags">611844096</int>
|
|
||||||
<string key="NSWindowTitle">Window</string>
|
|
||||||
<string key="NSWindowClass">MainWindow</string>
|
|
||||||
<nil key="NSViewClass"/>
|
|
||||||
<string key="NSWindowContentMaxSize">{1.79769e+308, 1.79769e+308}</string>
|
|
||||||
<object class="NSView" key="NSWindowView" id="312036702">
|
|
||||||
<reference key="NSNextResponder"/>
|
|
||||||
<int key="NSvFlags">256</int>
|
|
||||||
<string key="NSFrameSize">{606, 354}</string>
|
|
||||||
<reference key="NSSuperview"/>
|
|
||||||
</object>
|
|
||||||
<string key="NSScreenRect">{{0, 0}, {1280, 778}}</string>
|
|
||||||
<string key="NSMaxSize">{1.79769e+308, 1.79769e+308}</string>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<object class="IBObjectContainer" key="IBDocument.Objects">
|
|
||||||
<object class="NSMutableArray" key="connectionRecords">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
<object class="IBConnectionRecord">
|
|
||||||
<object class="IBOutletConnection" key="connection">
|
|
||||||
<string key="label">window</string>
|
|
||||||
<reference key="source" ref="1001"/>
|
|
||||||
<reference key="destination" ref="748157544"/>
|
|
||||||
</object>
|
|
||||||
<int key="connectionID">6</int>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<object class="IBMutableOrderedSet" key="objectRecords">
|
|
||||||
<object class="NSArray" key="orderedObjects">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
<object class="IBObjectRecord">
|
|
||||||
<int key="objectID">0</int>
|
|
||||||
<reference key="object" ref="0"/>
|
|
||||||
<reference key="children" ref="1000"/>
|
|
||||||
<nil key="parent"/>
|
|
||||||
</object>
|
|
||||||
<object class="IBObjectRecord">
|
|
||||||
<int key="objectID">-2</int>
|
|
||||||
<reference key="object" ref="1001"/>
|
|
||||||
<reference key="parent" ref="0"/>
|
|
||||||
<string key="objectName">File's Owner</string>
|
|
||||||
</object>
|
|
||||||
<object class="IBObjectRecord">
|
|
||||||
<int key="objectID">-1</int>
|
|
||||||
<reference key="object" ref="1003"/>
|
|
||||||
<reference key="parent" ref="0"/>
|
|
||||||
<string key="objectName">First Responder</string>
|
|
||||||
</object>
|
|
||||||
<object class="IBObjectRecord">
|
|
||||||
<int key="objectID">-3</int>
|
|
||||||
<reference key="object" ref="1004"/>
|
|
||||||
<reference key="parent" ref="0"/>
|
|
||||||
<string key="objectName">Application</string>
|
|
||||||
</object>
|
|
||||||
<object class="IBObjectRecord">
|
|
||||||
<int key="objectID">2</int>
|
|
||||||
<reference key="object" ref="748157544"/>
|
|
||||||
<object class="NSMutableArray" key="children">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
<reference ref="312036702"/>
|
|
||||||
</object>
|
|
||||||
<reference key="parent" ref="0"/>
|
|
||||||
</object>
|
|
||||||
<object class="IBObjectRecord">
|
|
||||||
<int key="objectID">3</int>
|
|
||||||
<reference key="object" ref="312036702"/>
|
|
||||||
<reference key="parent" ref="748157544"/>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<object class="NSMutableDictionary" key="flattenedProperties">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
<object class="NSArray" key="dict.sortedKeys">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
<string>-1.IBPluginDependency</string>
|
|
||||||
<string>-2.IBPluginDependency</string>
|
|
||||||
<string>-3.IBPluginDependency</string>
|
|
||||||
<string>2.IBEditorWindowLastContentRect</string>
|
|
||||||
<string>2.IBPluginDependency</string>
|
|
||||||
<string>2.IBWindowTemplateEditedContentRect</string>
|
|
||||||
<string>2.NSWindowTemplate.visibleAtLaunch</string>
|
|
||||||
<string>3.IBPluginDependency</string>
|
|
||||||
</object>
|
|
||||||
<object class="NSMutableArray" key="dict.values">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
|
||||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
|
||||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
|
||||||
<string>{{319, 371}, {606, 354}}</string>
|
|
||||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
|
||||||
<string>{{319, 371}, {606, 354}}</string>
|
|
||||||
<boolean value="YES"/>
|
|
||||||
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<object class="NSMutableDictionary" key="unlocalizedProperties">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
<reference key="dict.sortedKeys" ref="0"/>
|
|
||||||
<object class="NSMutableArray" key="dict.values">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<nil key="activeLocalization"/>
|
|
||||||
<object class="NSMutableDictionary" key="localizations">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
<reference key="dict.sortedKeys" ref="0"/>
|
|
||||||
<object class="NSMutableArray" key="dict.values">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<nil key="sourceID"/>
|
|
||||||
<int key="maxID">6</int>
|
|
||||||
</object>
|
|
||||||
<object class="IBClassDescriber" key="IBDocument.Classes">
|
|
||||||
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
|
|
||||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
|
||||||
<object class="IBPartialClassDescription">
|
|
||||||
<string key="className">MainWindow</string>
|
|
||||||
<string key="superclassName">NSWindow</string>
|
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
|
||||||
<string key="majorKey">IBUserSource</string>
|
|
||||||
<string key="minorKey"/>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<object class="IBPartialClassDescription">
|
|
||||||
<string key="className">MainWindowController</string>
|
|
||||||
<string key="superclassName">NSWindowController</string>
|
|
||||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
|
||||||
<string key="majorKey">IBUserSource</string>
|
|
||||||
<string key="minorKey"/>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
</object>
|
|
||||||
<int key="IBDocument.localizationMode">0</int>
|
|
||||||
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
|
|
||||||
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
|
|
||||||
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3</string>
|
|
||||||
<integer value="3000" key="NS.object.0"/>
|
|
||||||
</object>
|
|
||||||
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
|
|
||||||
<nil key="IBDocument.LastKnownRelativeProjectPath"/>
|
|
||||||
<int key="IBDocument.defaultPropertyAccessControl">3</int>
|
|
||||||
</data>
|
|
||||||
</archive>
|
|
||||||
|
|
|
@ -1,128 +0,0 @@
|
||||||
// SparkleShare, an instant update workflow to Git.
|
|
||||||
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.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);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,98 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" ToolsVersion="3.5" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<PropertyGroup>
|
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
|
||||||
<ProductVersion>9.0.21022</ProductVersion>
|
|
||||||
<SchemaVersion>2.0</SchemaVersion>
|
|
||||||
<ProjectGuid>{709CB8F4-F82F-4C94-B4E2-DC502087525B}</ProjectGuid>
|
|
||||||
<ProjectTypeGuids>{1C533B1C-72DD-4CB1-9F6B-BF11D93BCFBE};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<RootNamespace>SparkleShare</RootNamespace>
|
|
||||||
<AssemblyName>SparkleShare</AssemblyName>
|
|
||||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
|
||||||
<DebugSymbols>true</DebugSymbols>
|
|
||||||
<DebugType>full</DebugType>
|
|
||||||
<Optimize>false</Optimize>
|
|
||||||
<OutputPath>bin\Debug</OutputPath>
|
|
||||||
<DefineConstants>DEBUG</DefineConstants>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<WarningLevel>4</WarningLevel>
|
|
||||||
<ConsolePause>false</ConsolePause>
|
|
||||||
<EnvironmentVariables>
|
|
||||||
<EnvironmentVariables>
|
|
||||||
<Variable name="PATH" value="/opt/local/bin" />
|
|
||||||
</EnvironmentVariables>
|
|
||||||
</EnvironmentVariables>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
|
||||||
<DebugType>none</DebugType>
|
|
||||||
<Optimize>false</Optimize>
|
|
||||||
<OutputPath>bin\Release</OutputPath>
|
|
||||||
<ErrorReport>prompt</ErrorReport>
|
|
||||||
<WarningLevel>4</WarningLevel>
|
|
||||||
<ConsolePause>false</ConsolePause>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Reference Include="System" />
|
|
||||||
<Reference Include="System.Xml" />
|
|
||||||
<Reference Include="System.Core" />
|
|
||||||
<Reference Include="System.Xml.Linq" />
|
|
||||||
<Reference Include="System.Drawing" />
|
|
||||||
<Reference Include="MonoMac">
|
|
||||||
<SpecificVersion>False</SpecificVersion>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Mono.Posix" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Compile Include="MainMenu.xib.designer.cs">
|
|
||||||
<DependentUpon>MainMenu.xib</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="Layout.cs" />
|
|
||||||
<Compile Include="SparkleLog.cs" />
|
|
||||||
<Compile Include="SparkleStatusIcon.cs" />
|
|
||||||
<Compile Include="..\..\SparkleShare.cs">
|
|
||||||
<Link>SparkleShare.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\..\SparkleController.cs">
|
|
||||||
<Link>SparkleController.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="SparkleMacController.cs" />
|
|
||||||
<Compile Include="SparkleUI.cs" />
|
|
||||||
<Compile Include="SparkleWindow.cs" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Page Include="MainMenu.xib" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="Info.plist" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
|
||||||
<Import Project="$(MSBuildExtensionsPath)\Mono\MonoMac\v0.0\Mono.MonoMac.targets" />
|
|
||||||
<ItemGroup>
|
|
||||||
<Content Include="Pixmaps\idle.png" />
|
|
||||||
<Content Include="Pixmaps\idle0.png" />
|
|
||||||
<Content Include="Pixmaps\idle2.png" />
|
|
||||||
<Content Include="Pixmaps\idle-active.png" />
|
|
||||||
<Content Include="Pixmaps\idle1.png" />
|
|
||||||
<Content Include="Pixmaps\idle4.png" />
|
|
||||||
<Content Include="Pixmaps\idle3.png" />
|
|
||||||
<Content Include="Pixmaps\sparkleshare-idle.png" />
|
|
||||||
<Content Include="Pixmaps\sparkleshare-idle-focus.png" />
|
|
||||||
<Content Include="..\..\..\data\side-splash.png">
|
|
||||||
<Link>Pixmaps\side-splash.png</Link>
|
|
||||||
</Content>
|
|
||||||
<Content Include="sparkleshare.icns" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\..\..\SparkleLib\SparkleLib.csproj">
|
|
||||||
<Project>{2C914413-B31C-4362-93C7-1AE34F09112A}</Project>
|
|
||||||
<Name>SparkleLib</Name>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Folder Include="Pixmaps\" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
|
@ -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
|
|
|
@ -1,70 +0,0 @@
|
||||||
// SparkleShare, an instant update workflow to Git.
|
|
||||||
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.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);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
using System.Timers;
|
using System.Timers;
|
||||||
using MonoMac.Foundation;
|
using MonoMac.Foundation;
|
||||||
using MonoMac.AppKit;
|
using MonoMac.AppKit;
|
||||||
|
@ -39,7 +40,6 @@ namespace SparkleShare {
|
||||||
private NSMenuItem [] FolderMenuItems;
|
private NSMenuItem [] FolderMenuItems;
|
||||||
private NSMenuItem SyncMenuItem;
|
private NSMenuItem SyncMenuItem;
|
||||||
private NSMenuItem NotificationsMenuItem;
|
private NSMenuItem NotificationsMenuItem;
|
||||||
private NSMenuItem AboutMenuItem;
|
|
||||||
|
|
||||||
private delegate void Task ();
|
private delegate void Task ();
|
||||||
private EventHandler [] Tasks;
|
private EventHandler [] Tasks;
|
||||||
|
@ -69,7 +69,12 @@ namespace SparkleShare {
|
||||||
|
|
||||||
SparkleShare.Controller.FolderSizeChanged += delegate {
|
SparkleShare.Controller.FolderSizeChanged += delegate {
|
||||||
InvokeOnMainThread (delegate {
|
InvokeOnMainThread (delegate {
|
||||||
|
|
||||||
|
if (!Animation.Enabled)
|
||||||
|
SetNormalState ();
|
||||||
|
|
||||||
UpdateMenu ();
|
UpdateMenu ();
|
||||||
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -123,12 +128,21 @@ namespace SparkleShare {
|
||||||
|
|
||||||
InvokeOnMainThread (delegate {
|
InvokeOnMainThread (delegate {
|
||||||
|
|
||||||
StatusItem.AlternateImage = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/idle" + FrameNumber + ".png");
|
string image_path =
|
||||||
StatusItem.AlternateImage.Size = new SizeF (16, 16);
|
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);
|
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);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -161,8 +175,11 @@ namespace SparkleShare {
|
||||||
SparkleShare.Controller.OpenSparkleShareFolder ();
|
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);
|
FolderMenuItem.Image.Size = new SizeF (16, 16);
|
||||||
|
|
||||||
Menu.AddItem (FolderMenuItem);
|
Menu.AddItem (FolderMenuItem);
|
||||||
|
@ -177,6 +194,7 @@ namespace SparkleShare {
|
||||||
|
|
||||||
foreach (string path in SparkleShare.Controller.Folders) {
|
foreach (string path in SparkleShare.Controller.Folders) {
|
||||||
|
|
||||||
|
// TODO
|
||||||
// if (repo.HasUnsyncedChanges)
|
// if (repo.HasUnsyncedChanges)
|
||||||
// folder_action.IconName = "dialog-error";
|
// folder_action.IconName = "dialog-error";
|
||||||
|
|
||||||
|
@ -198,7 +216,13 @@ namespace SparkleShare {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// TODO: No Remote Folders Yet
|
FolderMenuItems = new NSMenuItem [1];
|
||||||
|
|
||||||
|
FolderMenuItems [0] = new NSMenuItem () {
|
||||||
|
Title = "No Remote Folders Yet"
|
||||||
|
};
|
||||||
|
|
||||||
|
Menu.AddItem (FolderMenuItems [0]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,59 +230,68 @@ namespace SparkleShare {
|
||||||
|
|
||||||
|
|
||||||
SyncMenuItem = new NSMenuItem () {
|
SyncMenuItem = new NSMenuItem () {
|
||||||
Title = "Add Remote Folder..."
|
Title = "Add Remote Folder…"
|
||||||
};
|
};
|
||||||
|
|
||||||
if (SparkleShare.Controller.FirstRun)
|
if (!SparkleShare.Controller.FirstRun) {
|
||||||
SyncMenuItem.Enabled = false;
|
|
||||||
|
|
||||||
SyncMenuItem.Activated += delegate {
|
SyncMenuItem.Activated += delegate {
|
||||||
new SparkleWindow ();
|
|
||||||
|
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 (SyncMenuItem);
|
||||||
|
|
||||||
|
|
||||||
Menu.AddItem (NSMenuItem.SeparatorItem);
|
Menu.AddItem (NSMenuItem.SeparatorItem);
|
||||||
|
|
||||||
|
|
||||||
NotificationsMenuItem = new NSMenuItem () {
|
NotificationsMenuItem = new NSMenuItem ();
|
||||||
Title = "Show Notifications"
|
|
||||||
};
|
|
||||||
|
|
||||||
if (SparkleShare.Controller.NotificationsEnabled)
|
if (SparkleShare.Controller.NotificationsEnabled)
|
||||||
NotificationsMenuItem.State = NSCellStateValue.On;
|
NotificationsMenuItem.Title = "Turn Notifications Off";
|
||||||
|
else
|
||||||
|
NotificationsMenuItem.Title = "Turn Notifications On";
|
||||||
|
|
||||||
NotificationsMenuItem.Activated += delegate {
|
NotificationsMenuItem.Activated += delegate {
|
||||||
|
|
||||||
SparkleShare.Controller.ToggleNotifications ();
|
SparkleShare.Controller.ToggleNotifications ();
|
||||||
|
|
||||||
|
InvokeOnMainThread (delegate {
|
||||||
|
|
||||||
if (SparkleShare.Controller.NotificationsEnabled)
|
if (SparkleShare.Controller.NotificationsEnabled)
|
||||||
NotificationsMenuItem.State = NSCellStateValue.On;
|
NotificationsMenuItem.Title = "Turn Notifications Off";
|
||||||
else
|
else
|
||||||
NotificationsMenuItem.State = NSCellStateValue.Off;
|
NotificationsMenuItem.Title = "Turn Notifications On";
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Menu.AddItem (NotificationsMenuItem);
|
Menu.AddItem (NotificationsMenuItem);
|
||||||
|
|
||||||
|
|
||||||
Menu.AddItem (NSMenuItem.SeparatorItem);
|
|
||||||
|
|
||||||
|
|
||||||
AboutMenuItem = new NSMenuItem () {
|
|
||||||
Title = "About"
|
|
||||||
};
|
|
||||||
|
|
||||||
AboutMenuItem.Activated += delegate {
|
|
||||||
// TODO
|
|
||||||
};
|
|
||||||
|
|
||||||
Menu.AddItem (AboutMenuItem);
|
|
||||||
|
|
||||||
StatusItem.Menu = Menu;
|
StatusItem.Menu = Menu;
|
||||||
StatusItem.Menu.Update ();
|
StatusItem.Menu.Update ();
|
||||||
Console.WriteLine ("MENU UPDATED");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,6 +303,10 @@ namespace SparkleShare {
|
||||||
|
|
||||||
return delegate {
|
return delegate {
|
||||||
|
|
||||||
|
InvokeOnMainThread (delegate {
|
||||||
|
|
||||||
|
NSApplication.SharedApplication.ActivateIgnoringOtherApps (true);
|
||||||
|
|
||||||
SparkleLog log = SparkleUI.OpenLogs.Find (delegate (SparkleLog l) {
|
SparkleLog log = SparkleUI.OpenLogs.Find (delegate (SparkleLog l) {
|
||||||
return l.LocalPath.Equals (path);
|
return l.LocalPath.Equals (path);
|
||||||
});
|
});
|
||||||
|
@ -278,18 +315,18 @@ namespace SparkleShare {
|
||||||
// that's not the case or present it to the user if it is
|
// that's not the case or present it to the user if it is
|
||||||
if (log == null) {
|
if (log == null) {
|
||||||
|
|
||||||
InvokeOnMainThread (delegate {
|
|
||||||
SparkleUI.OpenLogs.Add (new SparkleLog (path));
|
SparkleUI.OpenLogs.Add (new SparkleLog (path));
|
||||||
});
|
SparkleUI.OpenLogs [SparkleUI.OpenLogs.Count - 1].MakeKeyAndOrderFront (this);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
InvokeOnMainThread (delegate {
|
|
||||||
log.OrderFrontRegardless ();
|
log.OrderFrontRegardless ();
|
||||||
});
|
log.MakeKeyAndOrderFront (this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -381,12 +418,10 @@ namespace SparkleShare {
|
||||||
public override void MenuWillOpen (NSMenu menu)
|
public override void MenuWillOpen (NSMenu menu)
|
||||||
{
|
{
|
||||||
|
|
||||||
Console.WriteLine ("OPENED");
|
|
||||||
|
|
||||||
InvokeOnMainThread (delegate {
|
InvokeOnMainThread (delegate {
|
||||||
|
|
||||||
foreach (SparkleLog log in SparkleUI.OpenLogs)
|
SparkleUI.NewEvents = 0;
|
||||||
log.OrderFrontRegardless ();
|
NSApplication.SharedApplication.DockTile.BadgeLabel = null;
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
148
SparkleShare/Mac/SparkleUI.cs
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
// SparkleShare, an instant update workflow to Git.
|
||||||
|
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.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 <SparkleLog> 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 <SparkleLog> ();
|
||||||
|
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]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
168
SparkleShare/Mac/SparkleWindow.cs
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
// SparkleShare, an instant update workflow to Git.
|
||||||
|
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.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 <NSButton> 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 <NSButton> ();
|
||||||
|
|
||||||
|
|
||||||
|
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 <NSButton> ();
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -25,7 +25,6 @@ using System.Net;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
|
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
@ -37,6 +36,8 @@ namespace SparkleShare {
|
||||||
public string FolderSize;
|
public string FolderSize;
|
||||||
public bool FirstRun;
|
public bool FirstRun;
|
||||||
|
|
||||||
|
public readonly string SparklePath;
|
||||||
|
|
||||||
|
|
||||||
public event OnQuitWhileSyncingEventHandler OnQuitWhileSyncing;
|
public event OnQuitWhileSyncingEventHandler OnQuitWhileSyncing;
|
||||||
public delegate void OnQuitWhileSyncingEventHandler ();
|
public delegate void OnQuitWhileSyncingEventHandler ();
|
||||||
|
@ -53,6 +54,9 @@ namespace SparkleShare {
|
||||||
public event FolderSizeChangedEventHandler FolderSizeChanged;
|
public event FolderSizeChangedEventHandler FolderSizeChanged;
|
||||||
public delegate void FolderSizeChangedEventHandler (string folder_size);
|
public delegate void FolderSizeChangedEventHandler (string folder_size);
|
||||||
|
|
||||||
|
public event AvatarFetchedEventHandler AvatarFetched;
|
||||||
|
public delegate void AvatarFetchedEventHandler ();
|
||||||
|
|
||||||
public event OnIdleEventHandler OnIdle;
|
public event OnIdleEventHandler OnIdle;
|
||||||
public delegate void OnIdleEventHandler ();
|
public delegate void OnIdleEventHandler ();
|
||||||
|
|
||||||
|
@ -85,6 +89,8 @@ namespace SparkleShare {
|
||||||
FolderSize = GetFolderSize ();
|
FolderSize = GetFolderSize ();
|
||||||
|
|
||||||
|
|
||||||
|
SparklePath = SparklePaths.SparklePath;
|
||||||
|
|
||||||
string global_config_file_path = SparkleHelpers.CombineMore (SparklePaths.SparkleConfigPath, "config");
|
string global_config_file_path = SparkleHelpers.CombineMore (SparklePaths.SparkleConfigPath, "config");
|
||||||
|
|
||||||
// Show the introduction screen if SparkleShare isn't configured
|
// Show the introduction screen if SparkleShare isn't configured
|
||||||
|
@ -158,7 +164,7 @@ namespace SparkleShare {
|
||||||
|
|
||||||
// The location of the user's public key for SparkleShare
|
// The location of the user's public key for SparkleShare
|
||||||
string public_key_file_path = SparkleHelpers.CombineMore (SparklePaths.HomePath, ".ssh",
|
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))
|
if (!File.Exists (public_key_file_path))
|
||||||
return false;
|
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)
|
public string GetHTMLLog (string name)
|
||||||
{
|
{
|
||||||
|
|
||||||
List <SparkleCommit> commits = GetLog (name);
|
List <SparkleCommit> commits = GetLog (name);
|
||||||
|
|
||||||
List <ActivityDay> activity_days = new List <ActivityDay> ();
|
List <ActivityDay> activity_days = new List <ActivityDay> ();
|
||||||
|
|
||||||
foreach (SparkleCommit commit in commits) {
|
foreach (SparkleCommit commit in commits) {
|
||||||
|
|
||||||
GetAvatar (commit.UserEmail, 32);
|
GetAvatar (commit.UserEmail, 36);
|
||||||
|
|
||||||
bool commit_inserted = false;
|
bool commit_inserted = false;
|
||||||
foreach (ActivityDay stored_activity_day in activity_days) {
|
foreach (ActivityDay stored_activity_day in activity_days) {
|
||||||
|
@ -270,23 +280,9 @@ namespace SparkleShare {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string event_log_html = EventLogHTML;
|
||||||
|
string day_entry_html = DayEntryHTML;
|
||||||
StreamReader reader;
|
string event_entry_html = EventEntryHTML;
|
||||||
|
|
||||||
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 = "";
|
string event_log = "";
|
||||||
|
@ -305,13 +301,16 @@ namespace SparkleShare {
|
||||||
|
|
||||||
foreach (string file_path in change_set.Edited) {
|
foreach (string file_path in change_set.Edited) {
|
||||||
|
|
||||||
if (File.Exists (SparkleHelpers.CombineMore (SparklePaths.SparklePath ,name , file_path))) {
|
string absolute_file_path = SparkleHelpers.CombineMore (SparklePaths.SparklePath,
|
||||||
|
name, file_path);
|
||||||
|
|
||||||
event_entry += "<dd><a href='#'>" + file_path + "</a></dd>";
|
if (File.Exists (absolute_file_path)) {
|
||||||
|
|
||||||
|
event_entry += "<dd><a href='" + absolute_file_path + "'>" + file_path + "</a></dd>";
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
event_entry += "<dd>" + SparkleHelpers.CombineMore (SparklePaths.SparklePath, name, file_path) + "</dd>";
|
event_entry += "<dd>" + file_path + "</dd>";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,14 +324,16 @@ namespace SparkleShare {
|
||||||
event_entry += "<dt>Added</dt>";
|
event_entry += "<dt>Added</dt>";
|
||||||
|
|
||||||
foreach (string file_path in change_set.Added) {
|
foreach (string file_path in change_set.Added) {
|
||||||
|
string absolute_file_path = SparkleHelpers.CombineMore (SparklePaths.SparklePath,
|
||||||
|
name, file_path);
|
||||||
|
|
||||||
if (File.Exists (SparkleHelpers.CombineMore (SparklePaths.SparklePath ,name , file_path))) {
|
if (File.Exists (absolute_file_path)) {
|
||||||
|
|
||||||
event_entry += "<dd><a href='#'>" + file_path + "</a></dd>";
|
event_entry += "<dd><a href='" + absolute_file_path + "'>" + file_path + "</a></dd>";
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
event_entry += "<dd>" + SparkleHelpers.CombineMore (SparklePaths.SparklePath ,name , file_path) + "</dd>";
|
event_entry += "<dd>" + file_path + "</dd>";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,30 +347,33 @@ namespace SparkleShare {
|
||||||
|
|
||||||
foreach (string file_path in change_set.Deleted) {
|
foreach (string file_path in change_set.Deleted) {
|
||||||
|
|
||||||
if (File.Exists (SparkleHelpers.CombineMore (SparklePaths.SparklePath ,name , file_path))) {
|
string absolute_file_path = SparkleHelpers.CombineMore (SparklePaths.SparklePath,
|
||||||
|
name, file_path);
|
||||||
|
|
||||||
event_entry += "<dd><a href='#'>" + file_path + "</a></dd>";
|
if (File.Exists (absolute_file_path)) {
|
||||||
|
|
||||||
|
event_entry += "<dd><a href='" + absolute_file_path + "'>" + file_path + "</a></dd>";
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
event_entry += "<dd>" + SparkleHelpers.CombineMore (SparklePaths.SparklePath ,name , file_path) + "</dd>";
|
event_entry += "<dd>" + file_path + "</dd>";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Console.WriteLine(GetAvatar (change_set.UserEmail, 32));
|
|
||||||
event_entry += "</dl>";
|
event_entry += "</dl>";
|
||||||
|
|
||||||
event_entries += event_entry_html.Replace ("<!-- $event-entry-content -->", event_entry)
|
event_entries += event_entry_html.Replace ("<!-- $event-entry-content -->", event_entry)
|
||||||
.Replace ("<!-- $event-user-name -->", change_set.UserName)
|
.Replace ("<!-- $event-user-name -->", change_set.UserName)
|
||||||
.Replace ("<!-- $event-avatar-url -->", "file://" +GetAvatar (change_set.UserEmail, 32) )
|
.Replace ("<!-- $event-avatar-url -->", "file://" + GetAvatar (change_set.UserEmail, 36) )
|
||||||
.Replace ("<!-- $event-time -->", change_set.DateTime.ToString ("H:mm"));
|
.Replace ("<!-- $event-time -->", change_set.DateTime.ToString ("H:mm"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
string day_entry = "";
|
string day_entry = "";
|
||||||
|
|
||||||
DateTime today = DateTime.Now;
|
DateTime today = DateTime.Now;
|
||||||
|
@ -399,6 +403,7 @@ Console.WriteLine(GetAvatar (change_set.UserEmail, 32));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string html = event_log_html.Replace ("<!-- $event-log-content -->", event_log);
|
string html = event_log_html.Replace ("<!-- $event-log-content -->", event_log);
|
||||||
|
|
||||||
return html;
|
return html;
|
||||||
|
@ -553,6 +558,12 @@ Console.WriteLine(GetAvatar (change_set.UserEmail, 32));
|
||||||
if (FolderListChanged != null)
|
if (FolderListChanged != null)
|
||||||
FolderListChanged ();
|
FolderListChanged ();
|
||||||
|
|
||||||
|
|
||||||
|
FolderSize = GetFolderSize ();
|
||||||
|
|
||||||
|
if (FolderSizeChanged != null)
|
||||||
|
FolderSizeChanged (FolderSize);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -582,6 +593,12 @@ Console.WriteLine(GetAvatar (change_set.UserEmail, 32));
|
||||||
if (FolderListChanged != null)
|
if (FolderListChanged != null)
|
||||||
FolderListChanged ();
|
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)
|
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
|
// Write the user's information to a text file
|
||||||
TextWriter writer = new StreamWriter (global_config_file_path);
|
TextWriter writer = new StreamWriter (global_config_file_path);
|
||||||
|
@ -831,7 +848,7 @@ Console.WriteLine(GetAvatar (change_set.UserEmail, 32));
|
||||||
"\temail = " + user_email);
|
"\temail = " + user_email);
|
||||||
writer.Close ();
|
writer.Close ();
|
||||||
|
|
||||||
SparkleHelpers.DebugInfo ("Config", "Created '" + global_config_file_path + "'");
|
SparkleHelpers.DebugInfo ("Config", "Updated '" + global_config_file_path + "'");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -842,16 +859,27 @@ Console.WriteLine(GetAvatar (change_set.UserEmail, 32));
|
||||||
|
|
||||||
string keys_path = SparklePaths.SparkleKeysPath;
|
string keys_path = SparklePaths.SparkleKeysPath;
|
||||||
string key_file_name = "sparkleshare." + UserEmail + ".key";
|
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))
|
if (!Directory.Exists (keys_path))
|
||||||
Directory.CreateDirectory (keys_path);
|
Directory.CreateDirectory (keys_path);
|
||||||
|
|
||||||
if (!File.Exists (key_file_name)) {
|
if (!File.Exists (key_file_name)) {
|
||||||
|
|
||||||
|
Process process = new Process () {
|
||||||
|
EnableRaisingEvents = true
|
||||||
|
};
|
||||||
|
|
||||||
process.StartInfo.WorkingDirectory = keys_path;
|
process.StartInfo.WorkingDirectory = keys_path;
|
||||||
process.StartInfo.UseShellExecute = false;
|
process.StartInfo.UseShellExecute = false;
|
||||||
process.StartInfo.RedirectStandardOutput = true;
|
process.StartInfo.RedirectStandardOutput = true;
|
||||||
|
@ -866,8 +894,11 @@ Console.WriteLine(GetAvatar (change_set.UserEmail, 32));
|
||||||
|
|
||||||
process.Exited += delegate {
|
process.Exited += delegate {
|
||||||
|
|
||||||
SparkleHelpers.DebugInfo ("Config", "Created key '" + key_file_name + "'");
|
SparkleHelpers.DebugInfo ("Config", "Created private key '" + key_file_name + "'");
|
||||||
SparkleHelpers.DebugInfo ("Config", "Created key '" + key_file_name + ".pub'");
|
SparkleHelpers.DebugInfo ("Config", "Created public key '" + key_file_name + ".pub'");
|
||||||
|
|
||||||
|
File.Copy (key_file_path + ".pub",
|
||||||
|
Path.Combine (SparklePath, "Your key.txt"));
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -902,8 +933,11 @@ Console.WriteLine(GetAvatar (change_set.UserEmail, 32));
|
||||||
private void EnableHostKeyCheckingForHost (string host)
|
private void EnableHostKeyCheckingForHost (string host)
|
||||||
{
|
{
|
||||||
|
|
||||||
string ssh_config_file_path = SparkleHelpers.CombineMore (SparklePaths.HomePath, ".ssh", "config");
|
string ssh_config_file_path = SparkleHelpers.CombineMore
|
||||||
string ssh_config = "Host " + host + "\n\tStrictHostKeyChecking no";
|
(SparklePaths.HomePath, ".ssh", "config");
|
||||||
|
|
||||||
|
string ssh_config = "Host " + host + "\n" +
|
||||||
|
"\tStrictHostKeyChecking no";
|
||||||
|
|
||||||
if (File.Exists (ssh_config_file_path)) {
|
if (File.Exists (ssh_config_file_path)) {
|
||||||
|
|
||||||
|
@ -911,15 +945,15 @@ Console.WriteLine(GetAvatar (change_set.UserEmail, 32));
|
||||||
string current_ssh_config = reader.ReadToEnd ();
|
string current_ssh_config = reader.ReadToEnd ();
|
||||||
reader.Close ();
|
reader.Close ();
|
||||||
|
|
||||||
if (current_ssh_config.Equals (ssh_config)) {
|
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);
|
File.Delete (ssh_config_file_path);
|
||||||
|
|
||||||
} else {
|
} 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);
|
TextWriter writer = new StreamWriter (ssh_config_file_path);
|
||||||
writer.WriteLine (current_ssh_config);
|
writer.WriteLine (current_ssh_config);
|
||||||
writer.Close ();
|
writer.Close ();
|
||||||
|
@ -931,6 +965,67 @@ Console.WriteLine(GetAvatar (change_set.UserEmail, 32));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void FetchFolder (string url, string name)
|
public void FetchFolder (string url, string name)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -1013,7 +1108,8 @@ Console.WriteLine(GetAvatar (change_set.UserEmail, 32));
|
||||||
SparkleHelpers.ClearAttributes (tmp_folder);
|
SparkleHelpers.ClearAttributes (tmp_folder);
|
||||||
Directory.Delete (tmp_folder, true);
|
Directory.Delete (tmp_folder, true);
|
||||||
|
|
||||||
SparkleHelpers.DebugInfo ("Config", "Deleted temporary directory: " + tmp_folder);
|
SparkleHelpers.DebugInfo ("Config",
|
||||||
|
"Deleted temporary directory: " + tmp_folder);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
// Creates an MD5 hash of input
|
||||||
public static string GetMD5 (string s)
|
public static string GetMD5 (string s)
|
||||||
{
|
{
|
||||||
MD5 md5 = new MD5CryptoServiceProvider ();
|
MD5 md5 = new MD5CryptoServiceProvider ();
|
||||||
Byte[] bytes = ASCIIEncoding.Default.GetBytes (s);
|
Byte[] bytes = ASCIIEncoding.Default.GetBytes (s);
|
||||||
Byte[] encodedBytes = md5.ComputeHash (bytes);
|
Byte[] encoded_bytes = md5.ComputeHash (bytes);
|
||||||
return BitConverter.ToString (encodedBytes).ToLower ().Replace ("-", "");
|
return BitConverter.ToString (encoded_bytes).ToLower ().Replace ("-", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1136,6 +1174,16 @@ Console.WriteLine(GetAvatar (change_set.UserEmail, 32));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -89,11 +89,11 @@ namespace SparkleShare {
|
||||||
|
|
||||||
case PlatformID.Unix:
|
case PlatformID.Unix:
|
||||||
SetProcessName ("sparkleshare");
|
SetProcessName ("sparkleshare");
|
||||||
Controller = new SparkleLinController ();
|
//Controller = new SparkleLinController ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PlatformID.MacOSX:
|
case PlatformID.MacOSX:
|
||||||
//Controller = new SparkleMacController ();
|
Controller = new SparkleMacController ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PlatformID.Win32NT:
|
case PlatformID.Win32NT:
|
||||||
|
|
BIN
data/avatar-default.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
|
@ -4,7 +4,11 @@
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td><img src='<!-- $event-avatar-url -->'></td>
|
<td>
|
||||||
|
<div class='no-buddy-icon'>
|
||||||
|
<div class='buddy-icon' style='background-image: url("<!-- $event-avatar-url -->")'></div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
<td width='100%'>
|
<td width='100%'>
|
||||||
<b><!-- $event-user-name --></b><br>
|
<b><!-- $event-user-name --></b><br>
|
||||||
<!-- $event-entry-content -->
|
<!-- $event-entry-content -->
|
||||||
|
|
|
@ -8,12 +8,13 @@
|
||||||
<style>
|
<style>
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background-color: <!-- $body-background-color -->;
|
background-color: #f1f1f1;
|
||||||
color: <!-- $body-color -->;
|
color: <!-- $body-color -->;
|
||||||
font-size: <!-- $body-font-size -->;
|
font-size: <!-- $body-font-size -->;
|
||||||
font-family: <!-- $body-font-family -->;
|
font-family: <!-- $body-font-family -->;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
margin-top: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
small {
|
small {
|
||||||
|
@ -22,15 +23,36 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.day-entry-header {
|
.day-entry-header {
|
||||||
background-color: <!-- $day-entry-header-background-color -->;
|
background-color: #ccc;
|
||||||
padding: 9px;
|
color: #fff;
|
||||||
|
padding: 3px;
|
||||||
|
text-align: center;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
-webkit-border-radius: 25px;
|
||||||
|
width: 128px;
|
||||||
|
font-weight: lighter;
|
||||||
|
-webkit-box-shadow: 0px 1px 0px #aaa;
|
||||||
}
|
}
|
||||||
|
|
||||||
.day-entry-content {
|
.day-entry-content {
|
||||||
padding: 12px;
|
padding: 9px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dd {
|
dl {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
padding-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
dt {
|
||||||
|
padding-bottom: 9px;
|
||||||
|
padding-top: 9px;
|
||||||
|
}
|
||||||
|
|
||||||
|
dd {
|
||||||
|
padding-left: 0;
|
||||||
|
margin-left: 12px;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,6 +74,28 @@
|
||||||
color: <!-- $secondary-font-color -->;
|
color: <!-- $secondary-font-color -->;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.no-buddy-icon {
|
||||||
|
margin-right: 12px;
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
background-image: url('<!-- $no-buddy-icon-background-image -->');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buddy-icon {
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event-entry-content {
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 12px;
|
||||||
|
padding: 12px;
|
||||||
|
-webkit-border-radius: 6px;
|
||||||
|
border: <!-- $small-color --> 1px solid;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
Before Width: | Height: | Size: 732 B After Width: | Height: | Size: 732 B |
Before Width: | Height: | Size: 797 B After Width: | Height: | Size: 797 B |
Before Width: | Height: | Size: 803 B After Width: | Height: | Size: 803 B |
Before Width: | Height: | Size: 822 B After Width: | Height: | Size: 822 B |
Before Width: | Height: | Size: 818 B After Width: | Height: | Size: 818 B |
Before Width: | Height: | Size: 831 B After Width: | Height: | Size: 831 B |
Before Width: | Height: | Size: 826 B After Width: | Height: | Size: 826 B |
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 79 KiB |
Before Width: | Height: | Size: 283 B After Width: | Height: | Size: 283 B |
Before Width: | Height: | Size: 216 B After Width: | Height: | Size: 216 B |
BIN
data/sparkleshare-mac.icns
Normal file
1087
data/sparkleshare-mac.svg
Normal file
After Width: | Height: | Size: 53 KiB |