Merge branch 'disconnect'. Fixes #508

Conflicts:
	SparkleLib/SparkleListenerBase.cs
	SparkleLib/SparkleListenerTcp.cs
This commit is contained in:
Hylke Bons 2012-02-08 02:24:02 +01:00
commit 9f55680a6a
17 changed files with 327 additions and 1387 deletions

View file

@ -16,6 +16,7 @@
using System;
using System.IO;
using System.Diagnostics;
namespace SparkleLib {
@ -23,28 +24,58 @@ namespace SparkleLib {
public class SparkleGit : Process {
public static string ExecPath = null;
public static string Path = null;
public SparkleGit (string path, string args) : base ()
{
Path = LocateGit ();
EnableRaisingEvents = true;
StartInfo.FileName = SparkleBackend.DefaultBackend.Path;
StartInfo.FileName = Path;
StartInfo.RedirectStandardOutput = true;
StartInfo.UseShellExecute = false;
StartInfo.WorkingDirectory = path;
StartInfo.CreateNoWindow = true;
if (!string.IsNullOrEmpty (ExecPath))
StartInfo.Arguments = "--exec-path=\"" + ExecPath + "\" " + args;
else
if (string.IsNullOrEmpty (ExecPath))
StartInfo.Arguments = args;
else
StartInfo.Arguments = "--exec-path=\"" + ExecPath + "\" " + args;
}
new public void Start ()
{
SparkleHelpers.DebugInfo ("Cmd", "git " + StartInfo.Arguments);
base.Start ();
try {
base.Start ();
} catch (Exception e) {
SparkleHelpers.DebugInfo ("Cmd", "There's a problem running Git: " + e.Message);
Environment.Exit (-1);
}
}
private string LocateGit ()
{
if (!string.IsNullOrEmpty (Path))
return Path;
string [] possible_git_paths = new string [] {
"/usr/bin/git",
"/usr/local/bin/git",
"/opt/local/bin/git",
"/usr/local/git/bin/git"
};
foreach (string path in possible_git_paths)
if (File.Exists (path))
return path;
return "git";
}
}
}

View file

@ -17,10 +17,8 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
using System.Xml;
namespace SparkleLib {
@ -167,25 +165,29 @@ namespace SparkleLib {
}
public override bool CheckForRemoteChanges ()
public override bool HasRemoteChanges
{
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Checking for remote changes...");
SparkleGit git = new SparkleGit (LocalPath, "ls-remote " + Url + " master");
get {
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Checking for remote changes...");
SparkleGit git = new SparkleGit (LocalPath, "ls-remote " + Url + " master");
git.Start ();
git.WaitForExit ();
if (git.ExitCode != 0)
return false;
string remote_revision = git.StandardOutput.ReadToEnd ().TrimEnd ();
if (!remote_revision.StartsWith (CurrentRevision)) {
SparkleHelpers.DebugInfo ("Git",
"[" + Name + "] Remote changes found. (" + remote_revision + ")");
git.Start ();
git.WaitForExit ();
return true;
if (git.ExitCode != 0)
return false;
string remote_revision = git.StandardOutput.ReadToEnd ().TrimEnd ();
if (!remote_revision.StartsWith (CurrentRevision)) {
SparkleHelpers.DebugInfo ("Git", "[" + Name + "] Remote changes found. (" + remote_revision + ")");
return true;
} else {
return false;
} else {
return false;
}
}
}

View file

@ -6,6 +6,7 @@ SOURCES = \
Git/SparkleFetcherGit.cs \
Git/SparkleGit.cs \
Git/SparkleRepoGit.cs \
SparkleAnnouncement.cs \
SparkleBackend.cs \
SparkleChangeSet.cs \
SparkleConfig.cs \
@ -13,6 +14,7 @@ SOURCES = \
SparkleFetcherBase.cs \
SparkleHelpers.cs \
SparkleListenerBase.cs \
SparkleListenerFactory.cs \
SparkleListenerTcp.cs \
SparkleRepoBase.cs \
SparkleWatcher.cs

View file

@ -0,0 +1,34 @@
// SparkleShare, a collaboration and sharing tool.
// 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;
namespace SparkleLib {
public class SparkleAnnouncement {
public readonly string FolderIdentifier;
public readonly string Message;
public SparkleAnnouncement (string folder_identifier, string message)
{
FolderIdentifier = folder_identifier;
Message = message;
}
}
}

View file

@ -21,40 +21,7 @@ using System.Runtime.InteropServices;
namespace SparkleLib {
public class SparkleBackend {
public static SparkleBackend DefaultBackend = new SparkleBackendGit ();
public string Name;
public string Path;
public SparkleBackend (string name, string [] paths)
{
Name = name;
Path = "git";
foreach (string path in paths) {
if (File.Exists (path)) {
Path = path;
break;
}
}
}
public bool IsPresent {
get {
return (Path != null);
}
}
public bool IsUsablePath (string path)
{
return (path.Length > 0);
}
public static class SparkleBackend {
public static string Version {
get {
@ -65,7 +32,7 @@ namespace SparkleLib {
// Strange magic needed by Platform ()
[DllImport ("libc")]
static extern int uname (IntPtr buf);
private static extern int uname (IntPtr buf);
// This fixes the PlatformID enumeration for MacOSX in Environment.OSVersion.Platform,
@ -90,44 +57,4 @@ namespace SparkleLib {
}
}
}
public class SparkleBackendGit : SparkleBackend {
private static string name = "Git";
private static string [] paths = new string [] {
"/opt/local/bin/git",
"/usr/bin/git",
"/usr/local/bin/git",
"/usr/local/git/bin/git"
};
public SparkleBackendGit () : base (name, paths) { }
}
public class SparkleBackendHg : SparkleBackend {
private static string name = "Hg";
private static string [] paths = new string [] {
"/opt/local/bin/hg",
"/usr/bin/hg"
};
public SparkleBackendHg () : base (name, paths) { }
}
public class SparkleBackendScp : SparkleBackend {
private static string name = "Scp";
private static string [] paths = new string [] {
"/usr/bin/scp"
};
public SparkleBackendScp () : base (name, paths) { }
}
}

View file

@ -29,6 +29,7 @@ namespace SparkleLib {
Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData),
"sparkleshare");
// TODO: declare elsewhere
public static SparkleConfig DefaultConfig = new SparkleConfig (default_config_path, "config.xml");
public static bool DebugMode = true;

View file

@ -16,9 +16,7 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Security.AccessControl;
using System.Text.RegularExpressions;
using System.Threading;

View file

@ -40,12 +40,14 @@
<Compile Include="Git/SparkleFetcherGit.cs" />
<Compile Include="Hg/SparkleFetcherHg.cs" />
<Compile Include="Defines.cs" />
<Compile Include="SparkleAnnouncement.cs" />
<Compile Include="SparkleHelpers.cs" />
<Compile Include="SparklePaths.cs" />
<Compile Include="SparkleOptions.cs" />
<Compile Include="SparkleChangeSet.cs" />
<Compile Include="SparkleListenerBase.cs" />
<Compile Include="SparkleListenerIrc.cs" />
<Compile Include="SparkleListenerFactory.cs" />
<Compile Include="SparkleListenerTcp.cs" />
<Compile Include="SparkleBackend.cs" />
<Compile Include="SparkleConfig.cs" />
<Compile Include="SparkleWatcher.cs" />

View file

@ -16,76 +16,11 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Timers;
using System.Linq;
namespace SparkleLib {
public class SparkleAnnouncement {
public readonly string FolderIdentifier;
public readonly string Message;
public SparkleAnnouncement (string folder_identifier, string message)
{
FolderIdentifier = folder_identifier;
Message = message;
}
}
public static class SparkleListenerFactory {
private static List<SparkleListenerBase> listeners = new List<SparkleListenerBase> ();
public static SparkleListenerBase CreateListener (string folder_name, string folder_identifier)
{
string uri = SparkleConfig.DefaultConfig.GetFolderOptionalAttribute (
folder_name, "announcements_url");
if (uri == null) {
// This is SparkleShare's centralized notification service.
// Don't worry, we only use this server as a backup if you
// don't have your own. All data needed to connect is hashed and
// we don't store any personal information ever
uri = "tcp://notifications.sparkleshare.org:1986";
}
Uri announce_uri = new Uri (uri);
// We use only one listener per server to keep
// the number of connections as low as possible
foreach (SparkleListenerBase listener in listeners) {
if (listener.Server.Equals (announce_uri)) {
SparkleHelpers.DebugInfo ("ListenerFactory",
"Refered to existing listener for " + announce_uri);
listener.AlsoListenToBase (folder_identifier);
return (SparkleListenerBase) listener;
}
}
// Create a new listener with the appropriate
// type if one doesn't exist yet for that server
switch (announce_uri.Scheme) {
case "tcp":
listeners.Add (new SparkleListenerTcp (announce_uri, folder_identifier));
break;
default:
listeners.Add (new SparkleListenerTcp (announce_uri, folder_identifier));
break;
}
SparkleHelpers.DebugInfo ("ListenerFactory", "Issued new listener for " + announce_uri);
return (SparkleListenerBase) listeners [listeners.Count - 1];
}
}
// A persistent connection to the server that
// listens for change notifications
public abstract class SparkleListenerBase {
@ -170,6 +105,7 @@ namespace SparkleLib {
}
// TODO: rename override method instead?
public void AlsoListenToBase (string channel)
{
if (!this.channels.Contains (channel) && IsConnected) {
@ -210,9 +146,9 @@ namespace SparkleLib {
}
public void OnDisconnected ()
public void OnDisconnected (string message)
{
SparkleHelpers.DebugInfo ("Listener", "Signal of " + Server + " lost");
SparkleHelpers.DebugInfo ("Listener", "Disconnected from " + Server + ": " + message);
if (Disconnected != null)
Disconnected ();
@ -294,4 +230,3 @@ namespace SparkleLib {
}
}
}

View file

@ -0,0 +1,89 @@
// SparkleShare, a collaboration and sharing tool.
// 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;
namespace SparkleLib {
public static class SparkleListenerFactory {
private static List<SparkleListenerBase> listeners = new List<SparkleListenerBase> ();
public static SparkleListenerBase CreateListener (string folder_name, string folder_identifier)
{
// Check if the user wants to use a global custom notification service
string uri = SparkleConfig.DefaultConfig.GetConfigOption ("announcements_url");
// Check if the user wants a use a custom notification service for this folder
if (string.IsNullOrEmpty (uri))
uri = SparkleConfig.DefaultConfig.GetFolderOptionalAttribute (
folder_name, "announcements_url");
// Fall back to the fallback service is neither is the case
if (string.IsNullOrEmpty (uri)) {
// This is SparkleShare's centralized notification service.
// It communicates "It's time to sync!" signals between clients.
//
// Here's how it works: the client listens to a channel (the
// folder identifier, a SHA-1 hash) for when it's time to sync.
// Clients also send the current revision hash to the channel
// for other clients to pick up when you've synced up any
// changes.
//
// Please see the SparkleShare wiki if you wish to run
// your own service instead
uri = "tcp://notifications.sparkleshare.org:1986";
}
Uri announce_uri = new Uri (uri);
// We use only one listener per notification service to keep
// the number of connections as low as possible
foreach (SparkleListenerBase listener in listeners) {
if (listener.Server.Equals (announce_uri)) {
SparkleHelpers.DebugInfo ("ListenerFactory",
"Refered to existing " + announce_uri.Scheme +
" listener for " + announce_uri);
// We already seem to have a listener for this server,
// refer to the existing one instead
listener.AlsoListenToBase (folder_identifier);
return (SparkleListenerBase) listener;
}
}
// Create a new listener with the appropriate
// type if one doesn't exist yet for that server
switch (announce_uri.Scheme) {
case "tcp":
listeners.Add (new SparkleListenerTcp (announce_uri, folder_identifier));
break;
default:
listeners.Add (new SparkleListenerTcp (announce_uri, folder_identifier));
break;
}
SparkleHelpers.DebugInfo ("ListenerFactory",
"Issued new " + announce_uri.Scheme + " listener for " + announce_uri);
return (SparkleListenerBase) listeners [listeners.Count - 1];
}
}
}

View file

@ -16,23 +16,20 @@
using System;
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Collections.Generic;
using System.Xml.Serialization;
namespace SparkleLib {
public class SparkleListenerTcp : SparkleListenerBase {
private Socket socket;
private Object socket_lock = new Object ();
private Thread thread;
private bool is_connected = false;
private bool is_connecting = false;
private Object socket_lock = new Object ();
private bool is_connected = false;
private bool is_connecting = false;
private int receive_timeout = 180 * 1000;
public SparkleListenerTcp (Uri server, string folder_identifier) :
@ -60,83 +57,133 @@ namespace SparkleLib {
// Starts a new thread and listens to the channel
public override void Connect ()
{
SparkleHelpers.DebugInfo ("ListenerTcp", "Connecting to " + Server.Host);
this.is_connecting = true;
this.thread = new Thread (
new ThreadStart (delegate {
int port = Server.Port;
if (port < 0)
port = 1986;
try {
// Connect and subscribe to the channel
int port = Server.Port;
if (port < 0)
port = 9999;
lock (this.socket_lock) {
this.socket = new Socket (AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp) {
ReceiveTimeout = 30 * 1000
ReceiveTimeout = this.receive_timeout,
SendTimeout = 10 * 1000
};
// Try to connect to the server
this.socket.Connect (Server.Host, port);
this.is_connecting = false;
this.is_connected = true;
this.is_connected = true;
OnConnected ();
// Subscribe to channels of interest to us
foreach (string channel in base.channels) {
SparkleHelpers.DebugInfo ("ListenerTcp", "Subscribing to channel " + channel);
this.socket.Send (Encoding.UTF8.GetBytes ("subscribe " + channel + "\n"));
SparkleHelpers.DebugInfo ("ListenerTcp",
"Subscribing to channel " + channel + " on " + Server);
byte [] subscribe_bytes =
Encoding.UTF8.GetBytes ("subscribe " + channel + "\n");
this.socket.Send (subscribe_bytes);
}
}
byte [] bytes = new byte [4096];
// List to the channels, this blocks the thread
while (this.socket.Connected) {
int bytes_read = this.socket.Receive (bytes);
if (bytes_read > 0) {
string received = Encoding.UTF8.GetString (bytes);
string line = received.Substring (0, received.IndexOf ("\n"));
if (!line.Contains ("!"))
continue;
string folder_identifier = line.Substring (0, line.IndexOf ("!"));
string message = CleanMessage (line.Substring (line.IndexOf ("!") + 1));
if (!folder_identifier.Equals ("debug") &&
!String.IsNullOrEmpty (message)) {
OnAnnouncement (new SparkleAnnouncement (folder_identifier, message));
}
} else {
SparkleHelpers.DebugInfo ("ListenerTcp", "Error on socket");
lock (this.socket_lock) {
this.socket.Close ();
this.is_connected = false;
OnDisconnected ();
}
}
}
SparkleHelpers.DebugInfo ("ListenerTcp", "Disconnected from " + Server.Host);
} catch (SocketException e) {
SparkleHelpers.DebugInfo ("ListenerTcp", "Could not connect to " + Server + ": " + e.Message);
this.is_connected = false;
this.is_connected = false;
this.is_connecting = false;
OnDisconnected ();
OnDisconnected (e.Message);
return;
}
byte [] bytes = new byte [4096];
int bytes_read = 0;
DateTime last_ping = DateTime.Now;
// Wait for messages
while (this.is_connected) {
try {
// This blocks the thread
bytes_read = this.socket.Receive (bytes);
// We've timed out, let's ping the server to
// see if the connection is still up
} catch (SocketException) {
try {
// Check when the last ping occured. If it's
// significantly longer than our regular interval the
// system likely woke up from sleep and we want to
// simulate a disconnect
int sleepiness = DateTime.Compare (
last_ping.AddMilliseconds (this.receive_timeout * 1.25),
DateTime.Now
);
if (sleepiness <= 0) {
// 10057 means "Socket is not connected"
Console.WriteLine ("SLEEP OCCURED");
throw new SocketException (10057);
}
SparkleHelpers.DebugInfo ("ListenerTcp", "Pinging " + Server);
byte [] ping_bytes = Encoding.UTF8.GetBytes ("ping\n");
byte [] pong_bytes = new byte [4096];
lock (this.socket_lock)
this.socket.Send (ping_bytes);
this.socket.ReceiveTimeout = 10 * 1000;
if (this.socket.Receive (pong_bytes) < 1)
// 10057 means "Socket is not connected"
throw new SocketException (10057);
SparkleHelpers.DebugInfo ("ListenerTcp", "Received pong from " + Server);
this.socket.ReceiveTimeout = this.receive_timeout;
last_ping = DateTime.Now;
// The ping failed: disconnect completely
} catch (SocketException) {
this.is_connected = false;
this.is_connecting = false;
this.socket.ReceiveTimeout = this.receive_timeout;
OnDisconnected ("Ping timeout");
break;
}
}
// Parse the received message
if (bytes_read > 0) {
string received = Encoding.UTF8.GetString (bytes);
string line = received.Substring (0, received.IndexOf ("\n"));
if (!line.Contains ("!"))
continue;
string folder_identifier = line.Substring (0, line.IndexOf ("!"));
string message = CleanMessage (line.Substring (line.IndexOf ("!") + 1));
if (!folder_identifier.Equals ("debug") &&
!String.IsNullOrEmpty (message)) {
// We have a message!
OnAnnouncement (new SparkleAnnouncement (folder_identifier, message));
}
}
}
})
);
@ -150,18 +197,14 @@ namespace SparkleLib {
string to_send = "subscribe " + folder_identifier + "\n";
try {
lock (this.socket_lock) {
lock (this.socket_lock)
this.socket.Send (Encoding.UTF8.GetBytes (to_send));
}
} catch (SocketException e) {
SparkleHelpers.DebugInfo ("ListenerTcp",
"Could not connect to " + Server + ": " + e.Message);
this.is_connected = false;
this.is_connecting = false;
OnDisconnected ();
OnDisconnected (e.Message);
}
}
@ -176,13 +219,10 @@ namespace SparkleLib {
this.socket.Send (Encoding.UTF8.GetBytes (to_send));
} catch (SocketException e) {
SparkleHelpers.DebugInfo ("ListenerTcp",
"Could not connect to " + Server + ": " + e.Message);
this.is_connected = false;
this.is_connecting = false;
OnDisconnected ();
OnDisconnected (e.Message);
}
}

File diff suppressed because it is too large Load diff

View file

@ -23,7 +23,6 @@ using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Timers;
using System.Xml;
namespace SparkleLib {
@ -41,21 +40,21 @@ namespace SparkleLib {
private TimeSpan long_interval = new TimeSpan (0, 0, 10, 0);
private SparkleWatcher watcher;
private SparkleListenerBase listener;
private TimeSpan poll_interval;
private System.Timers.Timer local_timer = new System.Timers.Timer () { Interval = 0.25 * 1000 };
private System.Timers.Timer remote_timer = new System.Timers.Timer () { Interval = 10 * 1000 };
private DateTime last_poll = DateTime.Now;
private List<double> sizebuffer = new List<double> ();
private bool has_changed = false;
private Object change_lock = new Object ();
private Object watch_lock = new Object ();
private double progress_percentage = 0.0;
private string progress_speed = "";
private DateTime last_poll = DateTime.Now;
private List<double> size_buffer = new List<double> ();
private bool has_changed = false;
private Object change_lock = new Object ();
private Object watch_lock = new Object ();
private double progress_percentage = 0.0;
private string progress_speed = "";
private SyncStatus status;
protected SparkleListenerBase listener;
protected SyncStatus status;
protected bool is_buffering = false;
protected bool server_online = true;
private bool is_buffering = false;
private bool server_online = true;
public readonly string LocalPath;
public readonly string Name;
@ -68,6 +67,7 @@ namespace SparkleLib {
public abstract bool SyncDown ();
public abstract double CalculateSize (DirectoryInfo parent);
public abstract bool HasUnsyncedChanges { get; set; }
public abstract bool HasRemoteChanges { get; }
public abstract List<string> ExcludePaths { get; }
public abstract double Size { get; }
@ -121,7 +121,7 @@ namespace SparkleLib {
if (time_to_poll) {
this.last_poll = DateTime.Now;
if (CheckForRemoteChanges ())
if (HasRemoteChanges)
SyncDownBase ();
}
@ -191,6 +191,7 @@ namespace SparkleLib {
public string Domain {
get {
// TODO: use Uri class
Regex regex = new Regex (@"(@|://)([a-z0-9\.-]+)(/|:)");
Match match = regex.Match (SparkleConfig.DefaultConfig.GetUrlForFolder (Name));
@ -211,12 +212,6 @@ namespace SparkleLib {
}
public virtual bool CheckForRemoteChanges () // TODO: HasRemoteChanges { get; }
{
return true;
}
public virtual List<SparkleChangeSet> GetChangeSets (int count) {
return null;
}
@ -270,7 +265,7 @@ namespace SparkleLib {
this.poll_interval = this.long_interval;
new Thread (new ThreadStart (delegate {
if (!IsSyncing && CheckForRemoteChanges ())
if (!IsSyncing && HasRemoteChanges)
SyncDownBase ();
})).Start ();
}
@ -283,7 +278,7 @@ namespace SparkleLib {
if (!IsSyncing) {
// Check for changes manually one more time
if (CheckForRemoteChanges ())
if (HasRemoteChanges)
SyncDownBase ();
// Push changes that were made since the last disconnect
@ -336,16 +331,16 @@ namespace SparkleLib {
{
lock (this.change_lock) {
if (this.has_changed) {
if (this.sizebuffer.Count >= 4)
this.sizebuffer.RemoveAt (0);
if (this.size_buffer.Count >= 4)
this.size_buffer.RemoveAt (0);
DirectoryInfo dir_info = new DirectoryInfo (LocalPath);
this.sizebuffer.Add (CalculateSize (dir_info));
this.size_buffer.Add (CalculateSize (dir_info));
if (this.sizebuffer.Count >= 4 &&
this.sizebuffer [0].Equals (this.sizebuffer [1]) &&
this.sizebuffer [1].Equals (this.sizebuffer [2]) &&
this.sizebuffer [2].Equals (this.sizebuffer [3])) {
if (this.size_buffer.Count >= 4 &&
this.size_buffer [0].Equals (this.size_buffer [1]) &&
this.size_buffer [1].Equals (this.size_buffer [2]) &&
this.size_buffer [2].Equals (this.size_buffer [3])) {
SparkleHelpers.DebugInfo ("Local", "[" + Name + "] Changes have settled.");
this.is_buffering = false;

View file

@ -54,7 +54,7 @@ namespace SparkleShare {
// Let's use the bundled git first
SparkleBackend.DefaultBackend.Path =
SparkleGit.Path =
Path.Combine (NSBundle.MainBundle.ResourcePath,
"git", "libexec", "git-core", "git");

View file

@ -33,6 +33,7 @@ namespace SparkleShare {
public SparkleStatusIconController Controller = new SparkleStatusIconController ();
// TODO: Fix case
private Timer Animation;
private int FrameNumber;
private string StateText;

View file

@ -40,9 +40,6 @@ namespace SparkleShare {
public double ProgressPercentage = 0.0;
public string ProgressSpeed = "";
public event OnQuitWhileSyncingHandler OnQuitWhileSyncing;
public delegate void OnQuitWhileSyncingHandler ();
public event FolderFetchedEventHandler FolderFetched;
public delegate void FolderFetchedEventHandler (string [] warnings);
@ -783,13 +780,6 @@ namespace SparkleShare {
}
public bool BackendIsPresent {
get {
return SparkleBackend.DefaultBackend.IsPresent;
}
}
// Looks up the user's name from the global configuration
public string UserName
{
@ -1116,9 +1106,6 @@ namespace SparkleShare {
repo.Status == SyncStatus.SyncDown ||
repo.IsBuffering) {
if (OnQuitWhileSyncing != null)
OnQuitWhileSyncing ();
return;
}
}

View file

@ -63,12 +63,9 @@ namespace SparkleShare {
Setup = new SparkleSetup ();
Setup.Controller.ShowSetupPage ();
}
Program.Controller.OnQuitWhileSyncing += delegate {
// TODO: Pop up a warning when quitting whilst syncing
};
}
// Runs the application
public void Run ()
{