Merge branch 'master' into gettext-cs
Conflicts: SparkleLib/Git/SparkleRepoGit.cs
This commit is contained in:
commit
d096c39e5d
11
NEWS
11
NEWS
|
@ -1,3 +1,14 @@
|
||||||
|
0.8.1 for Linux and Mac (Sun Jan 29):
|
||||||
|
|
||||||
|
Hylke:
|
||||||
|
- Disable the Quit menu item when a sync is going on
|
||||||
|
- Show remote url when hovering project names in the log
|
||||||
|
- Fix the event log on Linux
|
||||||
|
- Allow server ports to be specified once again
|
||||||
|
- Open Folder button after setup now takes you to SparkleShare/subfolder
|
||||||
|
- Close event log on Cmd+W on Mac
|
||||||
|
|
||||||
|
|
||||||
0.8.0 for Linux and Mac (Sun Jan 22):
|
0.8.0 for Linux and Mac (Sun Jan 22):
|
||||||
|
|
||||||
Hylke:
|
Hylke:
|
||||||
|
|
|
@ -51,7 +51,7 @@ namespace SparkleLib {
|
||||||
if (!uri.Scheme.Equals ("ssh") &&
|
if (!uri.Scheme.Equals ("ssh") &&
|
||||||
!uri.Scheme.Equals ("git")) {
|
!uri.Scheme.Equals ("git")) {
|
||||||
|
|
||||||
uri = new Uri ("ssh://" + server);
|
uri = new Uri ("ssh://" + uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,8 +72,10 @@ namespace SparkleLib {
|
||||||
uri = new Uri ("ssh://git@gnome.org/git" + uri.AbsolutePath);
|
uri = new Uri ("ssh://git@gnome.org/git" + uri.AbsolutePath);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (string.IsNullOrEmpty (uri.UserInfo))
|
if (string.IsNullOrEmpty (uri.UserInfo)) {
|
||||||
uri = new Uri (uri.Scheme + "://git@" + uri.Host + uri.AbsolutePath);
|
uri = new Uri (uri.Scheme + "://git@" + uri.Host + ":" + uri.Port + uri.AbsolutePath);
|
||||||
|
uri = new Uri (uri.ToString ().Replace (":-1", ""));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -221,75 +223,11 @@ namespace SparkleLib {
|
||||||
SparkleHelpers.CombineMore (this.target_folder, ".git", "info"));
|
SparkleHelpers.CombineMore (this.target_folder, ".git", "info"));
|
||||||
|
|
||||||
// File that lists the files we want git to ignore
|
// File that lists the files we want git to ignore
|
||||||
string exlude_rules_file_path = Path.Combine (info.FullName, "exclude");
|
string exclude_rules_file_path = Path.Combine (info.FullName, "exclude");
|
||||||
TextWriter writer = new StreamWriter (exlude_rules_file_path);
|
TextWriter writer = new StreamWriter (exclude_rules_file_path);
|
||||||
|
|
||||||
// gedit and emacs
|
foreach (string exclude_rule in ExcludeRules)
|
||||||
writer.WriteLine ("*~");
|
writer.WriteLine (exclude_rule);
|
||||||
|
|
||||||
// Firefox and Chromium temporary download files
|
|
||||||
writer.WriteLine ("*.part");
|
|
||||||
writer.WriteLine ("*.crdownload");
|
|
||||||
|
|
||||||
// vi(m)
|
|
||||||
writer.WriteLine (".*.sw[a-z]");
|
|
||||||
writer.WriteLine ("*.un~");
|
|
||||||
writer.WriteLine ("*.swp");
|
|
||||||
writer.WriteLine ("*.swo");
|
|
||||||
|
|
||||||
// KDE
|
|
||||||
writer.WriteLine (".directory");
|
|
||||||
|
|
||||||
// Mac OS X
|
|
||||||
writer.WriteLine (".DS_Store");
|
|
||||||
writer.WriteLine ("Icon?");
|
|
||||||
writer.WriteLine ("._*");
|
|
||||||
writer.WriteLine (".Spotlight-V100");
|
|
||||||
writer.WriteLine (".Trashes");
|
|
||||||
|
|
||||||
// Omnigraffle
|
|
||||||
writer.WriteLine ("*(Autosaved).graffle");
|
|
||||||
|
|
||||||
// Windows
|
|
||||||
writer.WriteLine ("Thumbs.db");
|
|
||||||
writer.WriteLine ("Desktop.ini");
|
|
||||||
|
|
||||||
// MS Office
|
|
||||||
writer.WriteLine ("~*.tmp");
|
|
||||||
writer.WriteLine ("~*.TMP");
|
|
||||||
writer.WriteLine ("*~*.tmp");
|
|
||||||
writer.WriteLine ("*~*.TMP");
|
|
||||||
writer.WriteLine ("~*.ppt");
|
|
||||||
writer.WriteLine ("~*.PPT");
|
|
||||||
writer.WriteLine ("~*.pptx");
|
|
||||||
writer.WriteLine ("~*.PPTX");
|
|
||||||
writer.WriteLine ("~*.xls");
|
|
||||||
writer.WriteLine ("~*.XLS");
|
|
||||||
writer.WriteLine ("~*.xlsx");
|
|
||||||
writer.WriteLine ("~*.XLSX");
|
|
||||||
writer.WriteLine ("~*.doc");
|
|
||||||
writer.WriteLine ("~*.DOC");
|
|
||||||
writer.WriteLine ("~*.docx");
|
|
||||||
writer.WriteLine ("~*.DOCX");
|
|
||||||
|
|
||||||
// CVS
|
|
||||||
writer.WriteLine ("*/CVS/*");
|
|
||||||
writer.WriteLine (".cvsignore");
|
|
||||||
writer.WriteLine ("*/.cvsignore");
|
|
||||||
|
|
||||||
// Subversion
|
|
||||||
writer.WriteLine ("/.svn/*");
|
|
||||||
writer.WriteLine ("*/.svn/*");
|
|
||||||
|
|
||||||
// Mercurial
|
|
||||||
writer.WriteLine ("/.hg/*");
|
|
||||||
writer.WriteLine ("*/.hg/*");
|
|
||||||
writer.WriteLine ("*/.hgignore");
|
|
||||||
|
|
||||||
// Bazaar
|
|
||||||
writer.WriteLine ("/.bzr/*");
|
|
||||||
writer.WriteLine ("*/.bzr/*");
|
|
||||||
writer.WriteLine ("*/.bzrignore");
|
|
||||||
|
|
||||||
writer.Close ();
|
writer.Close ();
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ namespace SparkleLib {
|
||||||
StartInfo.RedirectStandardOutput = true;
|
StartInfo.RedirectStandardOutput = true;
|
||||||
StartInfo.UseShellExecute = false;
|
StartInfo.UseShellExecute = false;
|
||||||
StartInfo.WorkingDirectory = path;
|
StartInfo.WorkingDirectory = path;
|
||||||
|
StartInfo.CreateNoWindow = true;
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty (ExecPath))
|
if (!string.IsNullOrEmpty (ExecPath))
|
||||||
StartInfo.Arguments = "--exec-path=\"" + ExecPath + "\" " + args;
|
StartInfo.Arguments = "--exec-path=\"" + ExecPath + "\" " + args;
|
||||||
|
|
|
@ -26,8 +26,9 @@ namespace SparkleLib {
|
||||||
|
|
||||||
public class SparkleRepoGit : SparkleRepoBase {
|
public class SparkleRepoGit : SparkleRepoBase {
|
||||||
|
|
||||||
public SparkleRepoGit (string path, SparkleBackend backend) :
|
public SparkleRepoGit (string path) : base (path)
|
||||||
base (path, backend) { }
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private string identifier = null;
|
private string identifier = null;
|
||||||
|
@ -71,7 +72,7 @@ namespace SparkleLib {
|
||||||
|
|
||||||
public override double Size {
|
public override double Size {
|
||||||
get {
|
get {
|
||||||
string file_path = SparkleHelpers.CombineMore (LocalPath, ".git", "repo_size");
|
string file_path = new string [] {LocalPath, ".git", "repo_size"}.Combine ();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return double.Parse (File.ReadAllText (file_path));
|
return double.Parse (File.ReadAllText (file_path));
|
||||||
|
@ -85,7 +86,7 @@ namespace SparkleLib {
|
||||||
|
|
||||||
public override double HistorySize {
|
public override double HistorySize {
|
||||||
get {
|
get {
|
||||||
string file_path = SparkleHelpers.CombineMore(LocalPath, ".git", "repo_history_size");
|
string file_path = new string [] {LocalPath, ".git", "repo_history_size"}.Combine ();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return double.Parse (File.ReadAllText (file_path));
|
return double.Parse (File.ReadAllText (file_path));
|
||||||
|
@ -105,8 +106,8 @@ namespace SparkleLib {
|
||||||
double history_size = CalculateSize (
|
double history_size = CalculateSize (
|
||||||
new DirectoryInfo (Path.Combine (LocalPath, ".git")));
|
new DirectoryInfo (Path.Combine (LocalPath, ".git")));
|
||||||
|
|
||||||
string size_file_path = SparkleHelpers.CombineMore(LocalPath, ".git", "repo_size");
|
string size_file_path = new string [] {LocalPath, ".git", "repo_size"}.Combine ();
|
||||||
string history_size_file_path = SparkleHelpers.CombineMore(LocalPath, ".git", "repo_history_size");
|
string history_size_file_path = new string [] {LocalPath, ".git", "repo_history_size"}.Combine ();
|
||||||
|
|
||||||
File.WriteAllText (size_file_path, size.ToString ());
|
File.WriteAllText (size_file_path, size.ToString ());
|
||||||
File.WriteAllText (history_size_file_path, history_size.ToString ());
|
File.WriteAllText (history_size_file_path, history_size.ToString ());
|
||||||
|
@ -169,7 +170,7 @@ namespace SparkleLib {
|
||||||
public override bool CheckForRemoteChanges ()
|
public override bool CheckForRemoteChanges ()
|
||||||
{
|
{
|
||||||
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");
|
SparkleGit git = new SparkleGit (LocalPath, "ls-remote " + Url + " master");
|
||||||
|
|
||||||
git.Start ();
|
git.Start ();
|
||||||
git.WaitForExit ();
|
git.WaitForExit ();
|
||||||
|
@ -201,7 +202,7 @@ namespace SparkleLib {
|
||||||
|
|
||||||
SparkleGit git = new SparkleGit (LocalPath,
|
SparkleGit git = new SparkleGit (LocalPath,
|
||||||
"push --progress " + // Redirects progress stats to standarderror
|
"push --progress " + // Redirects progress stats to standarderror
|
||||||
"origin master");
|
Url + " master");
|
||||||
|
|
||||||
git.StartInfo.RedirectStandardError = true;
|
git.StartInfo.RedirectStandardError = true;
|
||||||
git.Start ();
|
git.Start ();
|
||||||
|
@ -258,7 +259,7 @@ namespace SparkleLib {
|
||||||
|
|
||||||
public override bool SyncDown ()
|
public override bool SyncDown ()
|
||||||
{
|
{
|
||||||
SparkleGit git = new SparkleGit (LocalPath, "fetch --progress");
|
SparkleGit git = new SparkleGit (LocalPath, "fetch --progress " + Url);
|
||||||
|
|
||||||
git.StartInfo.RedirectStandardError = true;
|
git.StartInfo.RedirectStandardError = true;
|
||||||
git.Start ();
|
git.Start ();
|
||||||
|
@ -623,11 +624,12 @@ namespace SparkleLib {
|
||||||
if (match.Success) {
|
if (match.Success) {
|
||||||
SparkleChangeSet change_set = new SparkleChangeSet ();
|
SparkleChangeSet change_set = new SparkleChangeSet ();
|
||||||
|
|
||||||
change_set.Folder = Name;
|
change_set.Folder = Name;
|
||||||
change_set.Revision = match.Groups [1].Value;
|
change_set.Revision = match.Groups [1].Value;
|
||||||
change_set.User.Name = match.Groups [2].Value;
|
change_set.User.Name = match.Groups [2].Value;
|
||||||
change_set.User.Email = match.Groups [3].Value;
|
change_set.User.Email = match.Groups [3].Value;
|
||||||
change_set.IsMagical = is_merge_commit;
|
change_set.IsMagical = is_merge_commit;
|
||||||
|
change_set.Url = Url;
|
||||||
|
|
||||||
change_set.Timestamp = new DateTime (int.Parse (match.Groups [4].Value),
|
change_set.Timestamp = new DateTime (int.Parse (match.Groups [4].Value),
|
||||||
int.Parse (match.Groups [5].Value), int.Parse (match.Groups [6].Value),
|
int.Parse (match.Groups [5].Value), int.Parse (match.Groups [6].Value),
|
||||||
|
|
|
@ -9,6 +9,7 @@ SOURCES = \
|
||||||
SparkleBackend.cs \
|
SparkleBackend.cs \
|
||||||
SparkleChangeSet.cs \
|
SparkleChangeSet.cs \
|
||||||
SparkleConfig.cs \
|
SparkleConfig.cs \
|
||||||
|
SparkleExtensions.cs \
|
||||||
SparkleFetcherBase.cs \
|
SparkleFetcherBase.cs \
|
||||||
SparkleHelpers.cs \
|
SparkleHelpers.cs \
|
||||||
SparkleListenerBase.cs \
|
SparkleListenerBase.cs \
|
||||||
|
|
|
@ -30,6 +30,7 @@ namespace SparkleLib {
|
||||||
public DateTime Timestamp;
|
public DateTime Timestamp;
|
||||||
public DateTime FirstTimestamp;
|
public DateTime FirstTimestamp;
|
||||||
public bool IsMagical = false;
|
public bool IsMagical = false;
|
||||||
|
public Uri Url;
|
||||||
|
|
||||||
public List<string> Added = new List<string> ();
|
public List<string> Added = new List<string> ();
|
||||||
public List<string> Deleted = new List<string> ();
|
public List<string> Deleted = new List<string> ();
|
||||||
|
|
35
SparkleLib/SparkleExtensions.cs
Executable file
35
SparkleLib/SparkleExtensions.cs
Executable file
|
@ -0,0 +1,35 @@
|
||||||
|
// 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.IO;
|
||||||
|
|
||||||
|
namespace SparkleLib {
|
||||||
|
|
||||||
|
public static class Extensions {
|
||||||
|
|
||||||
|
public static string Combine (this String [] parts)
|
||||||
|
{
|
||||||
|
string new_path = "";
|
||||||
|
|
||||||
|
foreach (string part in parts)
|
||||||
|
new_path = Path.Combine (new_path, part);
|
||||||
|
|
||||||
|
return new_path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,8 +16,8 @@
|
||||||
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
using System.Security.AccessControl;
|
using System.Security.AccessControl;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
@ -37,6 +37,8 @@ namespace SparkleLib {
|
||||||
public event FailedEventHandler Failed;
|
public event FailedEventHandler Failed;
|
||||||
public event ProgressChangedEventHandler ProgressChanged;
|
public event ProgressChangedEventHandler ProgressChanged;
|
||||||
|
|
||||||
|
public string [] ExcludeRules;
|
||||||
|
|
||||||
protected string target_folder;
|
protected string target_folder;
|
||||||
protected string remote_url;
|
protected string remote_url;
|
||||||
|
|
||||||
|
@ -47,12 +49,82 @@ namespace SparkleLib {
|
||||||
{
|
{
|
||||||
this.target_folder = target_folder;
|
this.target_folder = target_folder;
|
||||||
this.remote_url = server + "/" + remote_folder;
|
this.remote_url = server + "/" + remote_folder;
|
||||||
|
|
||||||
|
ExcludeRules = new string [] {
|
||||||
|
// gedit and emacs
|
||||||
|
"*~",
|
||||||
|
|
||||||
|
// Firefox and Chromium temporary download files
|
||||||
|
"*.part",
|
||||||
|
"*.crdownload",
|
||||||
|
|
||||||
|
// vi(m)
|
||||||
|
".*.sw[a-z]",
|
||||||
|
"*.un~",
|
||||||
|
"*.swp",
|
||||||
|
"*.swo",
|
||||||
|
|
||||||
|
// KDE
|
||||||
|
".directory",
|
||||||
|
|
||||||
|
// Mac OS X
|
||||||
|
".DS_Store",
|
||||||
|
"Icon?",
|
||||||
|
"._*",
|
||||||
|
".Spotlight-V100",
|
||||||
|
".Trashes",
|
||||||
|
|
||||||
|
// Omnigraffle
|
||||||
|
"*(Autosaved).graffle",
|
||||||
|
|
||||||
|
// Windows
|
||||||
|
"Thumbs.db",
|
||||||
|
"Desktop.ini",
|
||||||
|
|
||||||
|
// MS Office
|
||||||
|
"~*.tmp",
|
||||||
|
"~*.TMP",
|
||||||
|
"*~*.tmp",
|
||||||
|
"*~*.TMP",
|
||||||
|
"~*.ppt",
|
||||||
|
"~*.PPT",
|
||||||
|
"~*.pptx",
|
||||||
|
"~*.PPTX",
|
||||||
|
"~*.xls",
|
||||||
|
"~*.XLS",
|
||||||
|
"~*.xlsx",
|
||||||
|
"~*.XLSX",
|
||||||
|
"~*.doc",
|
||||||
|
"~*.DOC",
|
||||||
|
"~*.docx",
|
||||||
|
"~*.DOCX",
|
||||||
|
|
||||||
|
// CVS
|
||||||
|
"*/CVS/*",
|
||||||
|
".cvsignore",
|
||||||
|
"*/.cvsignore",
|
||||||
|
|
||||||
|
// Subversion
|
||||||
|
"/.svn/*",
|
||||||
|
"*/.svn/*",
|
||||||
|
|
||||||
|
// Mercurial
|
||||||
|
"/.hg/*",
|
||||||
|
"*/.hg/*",
|
||||||
|
"*/.hgignore",
|
||||||
|
|
||||||
|
// Bazaar
|
||||||
|
"/.bzr/*",
|
||||||
|
"*/.bzr/*",
|
||||||
|
"*/.bzrignore"
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public abstract bool Fetch ();
|
public abstract bool Fetch ();
|
||||||
public abstract string [] Warnings { get; }
|
public abstract string [] Warnings { get; }
|
||||||
|
|
||||||
|
|
||||||
// Clones the remote repository
|
// Clones the remote repository
|
||||||
public void Start ()
|
public void Start ()
|
||||||
{
|
{
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
<Compile Include="SparkleBackend.cs" />
|
<Compile Include="SparkleBackend.cs" />
|
||||||
<Compile Include="SparkleConfig.cs" />
|
<Compile Include="SparkleConfig.cs" />
|
||||||
<Compile Include="SparkleWatcher.cs" />
|
<Compile Include="SparkleWatcher.cs" />
|
||||||
|
<Compile Include="SparkleExtensions.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
<ProjectExtensions>
|
<ProjectExtensions>
|
||||||
|
|
|
@ -64,7 +64,7 @@ namespace SparkleLib {
|
||||||
SparkleHelpers.DebugInfo ("ListenerFactory",
|
SparkleHelpers.DebugInfo ("ListenerFactory",
|
||||||
"Refered to existing listener for " + announce_uri);
|
"Refered to existing listener for " + announce_uri);
|
||||||
|
|
||||||
listener.AlsoListenTo (folder_identifier);
|
listener.AlsoListenToBase (folder_identifier);
|
||||||
return (SparkleListenerBase) listener;
|
return (SparkleListenerBase) listener;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,40 +90,52 @@ namespace SparkleLib {
|
||||||
// listens for change notifications
|
// listens for change notifications
|
||||||
public abstract class SparkleListenerBase {
|
public abstract class SparkleListenerBase {
|
||||||
|
|
||||||
// We've connected to the server
|
|
||||||
public event ConnectedEventHandler Connected;
|
public event ConnectedEventHandler Connected;
|
||||||
public delegate void ConnectedEventHandler ();
|
public delegate void ConnectedEventHandler ();
|
||||||
|
|
||||||
// We've disconnected from the server
|
|
||||||
public event DisconnectedEventHandler Disconnected;
|
public event DisconnectedEventHandler Disconnected;
|
||||||
public delegate void DisconnectedEventHandler ();
|
public delegate void DisconnectedEventHandler ();
|
||||||
|
|
||||||
// We've been notified about a remote
|
public event ReceivedEventHandler Received;
|
||||||
// change by the channel
|
public delegate void ReceivedEventHandler (SparkleAnnouncement announcement);
|
||||||
public event AnnouncementEventHandler Announcement;
|
|
||||||
public delegate void AnnouncementEventHandler (SparkleAnnouncement announcement);
|
public readonly Uri Server;
|
||||||
|
|
||||||
|
|
||||||
public abstract void Connect ();
|
public abstract void Connect ();
|
||||||
public abstract void Announce (SparkleAnnouncement announcent);
|
|
||||||
public abstract void AlsoListenTo (string folder_identifier);
|
|
||||||
public abstract bool IsConnected { get; }
|
public abstract bool IsConnected { get; }
|
||||||
|
public abstract bool IsConnecting { get; }
|
||||||
|
protected abstract void Announce (SparkleAnnouncement announcent);
|
||||||
|
protected abstract void AlsoListenTo (string folder_identifier);
|
||||||
|
|
||||||
|
|
||||||
protected List<string> channels = new List<string> ();
|
protected List<string> channels = new List<string> ();
|
||||||
protected Dictionary<string,List<SparkleAnnouncement>> recent_announcements = new Dictionary<string, List<SparkleAnnouncement>> ();
|
|
||||||
protected int max_recent_announcements = 10;
|
|
||||||
protected Dictionary<string, SparkleAnnouncement> queue_up = new Dictionary<string, SparkleAnnouncement> ();
|
private int max_recent_announcements = 10;
|
||||||
protected Dictionary<string,SparkleAnnouncement> queue_down = new Dictionary<string, SparkleAnnouncement> ();
|
|
||||||
protected bool is_connecting;
|
private Dictionary<string, List<SparkleAnnouncement>> recent_announcements =
|
||||||
protected Uri server;
|
new Dictionary<string, List<SparkleAnnouncement>> ();
|
||||||
protected Timer reconnect_timer = new Timer { Interval = 60 * 1000, Enabled = true };
|
|
||||||
|
private Dictionary<string, SparkleAnnouncement> queue_up =
|
||||||
|
new Dictionary<string, SparkleAnnouncement> ();
|
||||||
|
|
||||||
|
private Dictionary<string, SparkleAnnouncement> queue_down =
|
||||||
|
new Dictionary<string, SparkleAnnouncement> ();
|
||||||
|
|
||||||
|
private Timer reconnect_timer = new Timer {
|
||||||
|
Interval = 60 * 1000,
|
||||||
|
Enabled = true
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
public SparkleListenerBase (Uri server, string folder_identifier)
|
public SparkleListenerBase (Uri server, string folder_identifier)
|
||||||
{
|
{
|
||||||
this.server = server;
|
Server = server;
|
||||||
|
this.channels.Add (folder_identifier);
|
||||||
|
|
||||||
this.reconnect_timer.Elapsed += delegate {
|
this.reconnect_timer.Elapsed += delegate {
|
||||||
if (!IsConnected && !this.is_connecting)
|
if (!IsConnected && !IsConnecting)
|
||||||
Reconnect ();
|
Reconnect ();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -133,29 +145,46 @@ namespace SparkleLib {
|
||||||
|
|
||||||
public void AnnounceBase (SparkleAnnouncement announcement)
|
public void AnnounceBase (SparkleAnnouncement announcement)
|
||||||
{
|
{
|
||||||
if (!this.IsRecentAnnounement (announcement)) {
|
if (!IsRecentAnnouncement (announcement)) {
|
||||||
if (IsConnected) {
|
if (IsConnected) {
|
||||||
SparkleHelpers.DebugInfo ("Listener",
|
SparkleHelpers.DebugInfo ("Listener",
|
||||||
"Announcing message " + announcement.Message + " to " + announcement.FolderIdentifier + " on " + this.server);
|
"Announcing message " + announcement.Message + " to " +
|
||||||
|
announcement.FolderIdentifier + " on " + Server);
|
||||||
|
|
||||||
Announce (announcement);
|
Announce (announcement);
|
||||||
this.AddRecentAnnouncement (announcement);
|
AddRecentAnnouncement (announcement);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
SparkleHelpers.DebugInfo ("Listener", "Can't send message to " + this.server + ". Queuing message");
|
SparkleHelpers.DebugInfo ("Listener",
|
||||||
|
"Can't send message to " +
|
||||||
|
Server + ". Queuing message");
|
||||||
|
|
||||||
this.queue_up [announcement.FolderIdentifier] = announcement;
|
this.queue_up [announcement.FolderIdentifier] = announcement;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
SparkleHelpers.DebugInfo ("Listener",
|
SparkleHelpers.DebugInfo ("Listener",
|
||||||
"Already processed message " + announcement.Message + " to " + announcement.FolderIdentifier + " from " + this.server);
|
"Already processed message " + announcement.Message + " to " +
|
||||||
|
announcement.FolderIdentifier + " from " + Server);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void AlsoListenToBase (string channel)
|
||||||
|
{
|
||||||
|
if (!this.channels.Contains (channel) && IsConnected) {
|
||||||
|
SparkleHelpers.DebugInfo ("Listener",
|
||||||
|
"Subscribing to channel " + channel);
|
||||||
|
|
||||||
|
this.channels.Add (channel);
|
||||||
|
AlsoListenTo (channel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void Reconnect ()
|
public void Reconnect ()
|
||||||
{
|
{
|
||||||
SparkleHelpers.DebugInfo ("Listener", "Trying to reconnect to " + this.server);
|
SparkleHelpers.DebugInfo ("Listener", "Trying to reconnect to " + Server);
|
||||||
Connect ();
|
Connect ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,7 +197,8 @@ namespace SparkleLib {
|
||||||
Connected ();
|
Connected ();
|
||||||
|
|
||||||
if (this.queue_up.Count > 0) {
|
if (this.queue_up.Count > 0) {
|
||||||
SparkleHelpers.DebugInfo ("Listener", "Delivering " + this.queue_up.Count + " queued messages...");
|
SparkleHelpers.DebugInfo ("Listener",
|
||||||
|
"Delivering " + this.queue_up.Count + " queued messages...");
|
||||||
|
|
||||||
foreach (KeyValuePair<string, SparkleAnnouncement> item in this.queue_up) {
|
foreach (KeyValuePair<string, SparkleAnnouncement> item in this.queue_up) {
|
||||||
SparkleAnnouncement announcement = item.Value;
|
SparkleAnnouncement announcement = item.Value;
|
||||||
|
@ -192,34 +222,46 @@ namespace SparkleLib {
|
||||||
public void OnAnnouncement (SparkleAnnouncement announcement)
|
public void OnAnnouncement (SparkleAnnouncement announcement)
|
||||||
{
|
{
|
||||||
SparkleHelpers.DebugInfo ("Listener",
|
SparkleHelpers.DebugInfo ("Listener",
|
||||||
"Got message " + announcement.Message + " from " + announcement.FolderIdentifier + " on " + this.server);
|
"Got message " + announcement.Message + " from " +
|
||||||
|
announcement.FolderIdentifier + " on " + Server);
|
||||||
|
|
||||||
if (IsRecentAnnounement(announcement) ){
|
if (IsRecentAnnouncement (announcement)) {
|
||||||
SparkleHelpers.DebugInfo ("Listener",
|
SparkleHelpers.DebugInfo ("Listener",
|
||||||
"Ignoring previously processed message " + announcement.Message +
|
"Ignoring previously processed message " + announcement.Message +
|
||||||
" from " + announcement.FolderIdentifier + " on " + this.server);
|
" from " + announcement.FolderIdentifier + " on " + Server);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SparkleHelpers.DebugInfo ("Listener",
|
SparkleHelpers.DebugInfo ("Listener",
|
||||||
"Processing message " + announcement.Message + " from " + announcement.FolderIdentifier + " on " + this.server);
|
"Processing message " + announcement.Message + " from " +
|
||||||
|
announcement.FolderIdentifier + " on " + Server);
|
||||||
|
|
||||||
AddRecentAnnouncement (announcement);
|
AddRecentAnnouncement (announcement);
|
||||||
this.queue_down [announcement.FolderIdentifier] = announcement;
|
this.queue_down [announcement.FolderIdentifier] = announcement;
|
||||||
|
|
||||||
if (Announcement != null)
|
if (Received != null)
|
||||||
Announcement (announcement);
|
Received (announcement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private bool IsRecentAnnounement (SparkleAnnouncement announcement)
|
public virtual void Dispose ()
|
||||||
{
|
{
|
||||||
if (!HasRecentAnnouncements (announcement.FolderIdentifier)) {
|
this.reconnect_timer.Dispose ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private bool IsRecentAnnouncement (SparkleAnnouncement announcement)
|
||||||
|
{
|
||||||
|
if (!this.recent_announcements
|
||||||
|
.ContainsKey (announcement.FolderIdentifier)) {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
foreach (SparkleAnnouncement recent_announcement in GetRecentAnnouncements (announcement.FolderIdentifier)) {
|
foreach (SparkleAnnouncement recent_announcement in
|
||||||
|
GetRecentAnnouncements (announcement.FolderIdentifier)) {
|
||||||
|
|
||||||
if (recent_announcement.Message.Equals (announcement.Message))
|
if (recent_announcement.Message.Equals (announcement.Message))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -240,39 +282,15 @@ namespace SparkleLib {
|
||||||
|
|
||||||
private void AddRecentAnnouncement (SparkleAnnouncement announcement)
|
private void AddRecentAnnouncement (SparkleAnnouncement announcement)
|
||||||
{
|
{
|
||||||
List<SparkleAnnouncement> recent_announcements = this.GetRecentAnnouncements (announcement.FolderIdentifier);
|
List<SparkleAnnouncement> recent_announcements =
|
||||||
|
GetRecentAnnouncements (announcement.FolderIdentifier);
|
||||||
|
|
||||||
if (!IsRecentAnnounement (announcement))
|
if (!IsRecentAnnouncement (announcement))
|
||||||
recent_announcements.Add (announcement);
|
recent_announcements.Add (announcement);
|
||||||
|
|
||||||
if (recent_announcements.Count > this.max_recent_announcements)
|
if (recent_announcements.Count > this.max_recent_announcements)
|
||||||
recent_announcements.RemoveRange (0, (recent_announcements.Count - this.max_recent_announcements));
|
recent_announcements.RemoveRange (0,
|
||||||
}
|
(recent_announcements.Count - this.max_recent_announcements));
|
||||||
|
|
||||||
|
|
||||||
private bool HasRecentAnnouncements (string folder_identifier)
|
|
||||||
{
|
|
||||||
return this.recent_announcements.ContainsKey (folder_identifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public virtual void Dispose ()
|
|
||||||
{
|
|
||||||
this.reconnect_timer.Dispose ();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Uri Server {
|
|
||||||
get {
|
|
||||||
return this.server;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public bool IsConnecting {
|
|
||||||
get {
|
|
||||||
return this.is_connecting;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,30 +28,31 @@ namespace SparkleLib {
|
||||||
|
|
||||||
public class SparkleListenerTcp : SparkleListenerBase {
|
public class SparkleListenerTcp : SparkleListenerBase {
|
||||||
|
|
||||||
private Thread thread;
|
|
||||||
|
|
||||||
// these are shared
|
|
||||||
private readonly Object mutex = new Object();
|
|
||||||
private Socket socket;
|
private Socket socket;
|
||||||
private bool connected;
|
private Object socket_lock = new Object ();
|
||||||
|
private Thread thread;
|
||||||
|
private bool is_connected = false;
|
||||||
|
private bool is_connecting = false;
|
||||||
|
|
||||||
|
|
||||||
public SparkleListenerTcp (Uri server, string folder_identifier) :
|
public SparkleListenerTcp (Uri server, string folder_identifier) :
|
||||||
base (server, folder_identifier)
|
base (server, folder_identifier)
|
||||||
{
|
{
|
||||||
base.channels.Add (folder_identifier);
|
|
||||||
this.connected = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override bool IsConnected {
|
public override bool IsConnected {
|
||||||
get {
|
get {
|
||||||
bool result = false;
|
lock (this.socket_lock)
|
||||||
|
return this.is_connected;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lock (this.mutex) {
|
|
||||||
result = this.connected;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
public override bool IsConnecting {
|
||||||
|
get {
|
||||||
|
lock (this.socket_lock)
|
||||||
|
return this.is_connecting;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,21 +62,29 @@ namespace SparkleLib {
|
||||||
{
|
{
|
||||||
SparkleHelpers.DebugInfo ("ListenerTcp", "Connecting to " + Server.Host);
|
SparkleHelpers.DebugInfo ("ListenerTcp", "Connecting to " + Server.Host);
|
||||||
|
|
||||||
base.is_connecting = true;
|
this.is_connecting = true;
|
||||||
|
|
||||||
this.thread = new Thread (
|
this.thread = new Thread (
|
||||||
new ThreadStart (delegate {
|
new ThreadStart (delegate {
|
||||||
try {
|
try {
|
||||||
// Connect and subscribe to the channel
|
// Connect and subscribe to the channel
|
||||||
int port = Server.Port;
|
int port = Server.Port;
|
||||||
if (port < 0) port = 9999;
|
|
||||||
|
|
||||||
lock (this.mutex) {
|
if (port < 0)
|
||||||
this.socket = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
port = 9999;
|
||||||
|
|
||||||
|
|
||||||
|
lock (this.socket_lock) {
|
||||||
|
this.socket = new Socket (AddressFamily.InterNetwork,
|
||||||
|
SocketType.Stream, ProtocolType.Tcp) {
|
||||||
|
|
||||||
|
ReceiveTimeout = 30 * 1000
|
||||||
|
};
|
||||||
|
|
||||||
this.socket.Connect (Server.Host, port);
|
this.socket.Connect (Server.Host, port);
|
||||||
|
|
||||||
base.is_connecting = false;
|
this.is_connecting = false;
|
||||||
this.connected = true;
|
this.is_connected = true;
|
||||||
|
|
||||||
OnConnected ();
|
OnConnected ();
|
||||||
|
|
||||||
|
@ -85,6 +94,7 @@ namespace SparkleLib {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
byte [] bytes = new byte [4096];
|
byte [] bytes = new byte [4096];
|
||||||
|
|
||||||
// List to the channels, this blocks the thread
|
// List to the channels, this blocks the thread
|
||||||
|
@ -93,20 +103,26 @@ namespace SparkleLib {
|
||||||
|
|
||||||
if (bytes_read > 0) {
|
if (bytes_read > 0) {
|
||||||
string received = Encoding.UTF8.GetString (bytes);
|
string received = Encoding.UTF8.GetString (bytes);
|
||||||
string line = received.Substring (0, received.IndexOf ("\n"));
|
string line = received.Substring (0, received.IndexOf ("\n"));
|
||||||
|
|
||||||
if (!line.Contains ("!"))
|
if (!line.Contains ("!"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
string folder_identifier = line.Substring (0, line.IndexOf ("!"));
|
string folder_identifier = line.Substring (0, line.IndexOf ("!"));
|
||||||
string message = this.CleanMessage (line.Substring (line.IndexOf ("!") + 1));
|
string message = CleanMessage (line.Substring (line.IndexOf ("!") + 1));
|
||||||
if (!folder_identifier.Equals("debug") &&
|
|
||||||
!String.IsNullOrEmpty(message))
|
if (!folder_identifier.Equals ("debug") &&
|
||||||
|
!String.IsNullOrEmpty (message)) {
|
||||||
|
|
||||||
OnAnnouncement (new SparkleAnnouncement (folder_identifier, message));
|
OnAnnouncement (new SparkleAnnouncement (folder_identifier, message));
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
SparkleHelpers.DebugInfo ("ListenerTcp", "Error on socket");
|
SparkleHelpers.DebugInfo ("ListenerTcp", "Error on socket");
|
||||||
|
|
||||||
lock (this.mutex) {
|
lock (this.socket_lock) {
|
||||||
this.socket.Close ();
|
this.socket.Close ();
|
||||||
this.connected = false;
|
this.is_connected = false;
|
||||||
|
|
||||||
OnDisconnected ();
|
OnDisconnected ();
|
||||||
}
|
}
|
||||||
|
@ -117,6 +133,8 @@ namespace SparkleLib {
|
||||||
|
|
||||||
} catch (SocketException e) {
|
} catch (SocketException e) {
|
||||||
SparkleHelpers.DebugInfo ("ListenerTcp", "Could not connect to " + Server + ": " + e.Message);
|
SparkleHelpers.DebugInfo ("ListenerTcp", "Could not connect to " + Server + ": " + e.Message);
|
||||||
|
this.is_connected = false;
|
||||||
|
this.is_connecting = false;
|
||||||
|
|
||||||
OnDisconnected ();
|
OnDisconnected ();
|
||||||
}
|
}
|
||||||
|
@ -127,46 +145,44 @@ namespace SparkleLib {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void AlsoListenTo (string folder_identifier)
|
protected override void AlsoListenTo (string folder_identifier)
|
||||||
{
|
{
|
||||||
string channel = folder_identifier;
|
string to_send = "subscribe " + folder_identifier + "\n";
|
||||||
|
|
||||||
if (!base.channels.Contains (channel)) {
|
try {
|
||||||
base.channels.Add (channel);
|
lock (this.socket_lock) {
|
||||||
|
this.socket.Send (Encoding.UTF8.GetBytes (to_send));
|
||||||
if (IsConnected) {
|
|
||||||
SparkleHelpers.DebugInfo ("ListenerTcp", "Subscribing to channel " + channel);
|
|
||||||
|
|
||||||
string to_send = "subscribe " + folder_identifier + "\n";
|
|
||||||
|
|
||||||
try {
|
|
||||||
lock (this.mutex) {
|
|
||||||
this.socket.Send (Encoding.UTF8.GetBytes (to_send));
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (SocketException e) {
|
|
||||||
SparkleHelpers.DebugInfo ("ListenerTcp", "Could not connect to " + Server + ": " + e.Message);
|
|
||||||
OnDisconnected ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} catch (SocketException e) {
|
||||||
|
SparkleHelpers.DebugInfo ("ListenerTcp",
|
||||||
|
"Could not connect to " + Server + ": " + e.Message);
|
||||||
|
|
||||||
|
this.is_connected = false;
|
||||||
|
this.is_connecting = false;
|
||||||
|
|
||||||
|
OnDisconnected ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override void Announce (SparkleAnnouncement announcement)
|
protected override void Announce (SparkleAnnouncement announcement)
|
||||||
{
|
{
|
||||||
string to_send = "announce " + announcement.FolderIdentifier
|
string to_send = "announce " + announcement.FolderIdentifier
|
||||||
+ " " + announcement.Message + "\n";
|
+ " " + announcement.Message + "\n";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
lock (this.socket_lock)
|
||||||
lock (this.mutex) {
|
|
||||||
this.socket.Send (Encoding.UTF8.GetBytes (to_send));
|
this.socket.Send (Encoding.UTF8.GetBytes (to_send));
|
||||||
}
|
|
||||||
} catch (SocketException e) {
|
|
||||||
SparkleHelpers.DebugInfo ("ListenerTcp", "Could not connect to " + Server + ": " + e.Message);
|
|
||||||
|
|
||||||
OnDisconnected ();
|
} catch (SocketException e) {
|
||||||
|
SparkleHelpers.DebugInfo ("ListenerTcp",
|
||||||
|
"Could not connect to " + Server + ": " + e.Message);
|
||||||
|
|
||||||
|
this.is_connected = false;
|
||||||
|
this.is_connecting = false;
|
||||||
|
|
||||||
|
OnDisconnected ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,12 +191,16 @@ namespace SparkleLib {
|
||||||
{
|
{
|
||||||
this.thread.Abort ();
|
this.thread.Abort ();
|
||||||
this.thread.Join ();
|
this.thread.Join ();
|
||||||
|
|
||||||
base.Dispose ();
|
base.Dispose ();
|
||||||
}
|
}
|
||||||
|
|
||||||
private string CleanMessage(string message)
|
|
||||||
|
private string CleanMessage (string message)
|
||||||
{
|
{
|
||||||
return message.Trim ().Replace ("\n", "").Replace ("\0", "");
|
return message.Trim ()
|
||||||
|
.Replace ("\n", "")
|
||||||
|
.Replace ("\0", "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,9 +57,9 @@ namespace SparkleLib {
|
||||||
protected bool is_buffering = false;
|
protected bool is_buffering = false;
|
||||||
protected bool server_online = true;
|
protected bool server_online = true;
|
||||||
|
|
||||||
public readonly SparkleBackend Backend;
|
|
||||||
public readonly string LocalPath;
|
public readonly string LocalPath;
|
||||||
public readonly string Name;
|
public readonly string Name;
|
||||||
|
public readonly Uri Url;
|
||||||
|
|
||||||
public abstract bool AnyDifferences { get; }
|
public abstract bool AnyDifferences { get; }
|
||||||
public abstract string Identifier { get; }
|
public abstract string Identifier { get; }
|
||||||
|
@ -92,11 +92,12 @@ namespace SparkleLib {
|
||||||
public event ChangesDetectedEventHandler ChangesDetected;
|
public event ChangesDetectedEventHandler ChangesDetected;
|
||||||
|
|
||||||
|
|
||||||
public SparkleRepoBase (string path, SparkleBackend backend)
|
public SparkleRepoBase (string path)
|
||||||
{
|
{
|
||||||
LocalPath = path;
|
LocalPath = path;
|
||||||
Name = Path.GetFileName (LocalPath);
|
Name = Path.GetFileName (LocalPath);
|
||||||
Backend = backend;
|
Url = new Uri (SparkleConfig.DefaultConfig.GetUrlForFolder (Name));
|
||||||
|
|
||||||
this.poll_interval = this.short_interval;
|
this.poll_interval = this.short_interval;
|
||||||
|
|
||||||
SyncStatusChanged += delegate (SyncStatus status) {
|
SyncStatusChanged += delegate (SyncStatus status) {
|
||||||
|
@ -298,7 +299,7 @@ namespace SparkleLib {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Fetch changes when there is a message in the irc channel
|
// Fetch changes when there is a message in the irc channel
|
||||||
this.listener.Announcement += delegate (SparkleAnnouncement announcement) {
|
this.listener.Received += delegate (SparkleAnnouncement announcement) {
|
||||||
string identifier = Identifier;
|
string identifier = Identifier;
|
||||||
|
|
||||||
if (announcement.FolderIdentifier.Equals (identifier) &&
|
if (announcement.FolderIdentifier.Equals (identifier) &&
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
|
config \
|
||||||
AppDelegate.cs \
|
AppDelegate.cs \
|
||||||
Growl.framework \
|
Growl.framework \
|
||||||
Growl.plist \
|
Growl.plist \
|
||||||
|
|
|
@ -46,6 +46,8 @@ namespace SparkleShare {
|
||||||
private NSTextField size_label_value;
|
private NSTextField size_label_value;
|
||||||
private NSTextField history_label;
|
private NSTextField history_label;
|
||||||
private NSTextField history_label_value;
|
private NSTextField history_label_value;
|
||||||
|
private NSButton hidden_close_button;
|
||||||
|
|
||||||
|
|
||||||
public SparkleEventLog (IntPtr handle) : base (handle) { }
|
public SparkleEventLog (IntPtr handle) : base (handle) { }
|
||||||
|
|
||||||
|
@ -68,6 +70,19 @@ namespace SparkleShare {
|
||||||
BackingType = NSBackingStore.Buffered;
|
BackingType = NSBackingStore.Buffered;
|
||||||
|
|
||||||
|
|
||||||
|
this.hidden_close_button = new NSButton () {
|
||||||
|
Frame = new RectangleF (0, 0, 0, 0),
|
||||||
|
KeyEquivalentModifierMask = NSEventModifierMask.CommandKeyMask,
|
||||||
|
KeyEquivalent = "w"
|
||||||
|
};
|
||||||
|
|
||||||
|
this.hidden_close_button.Activated += delegate {
|
||||||
|
PerformClose (this);
|
||||||
|
};
|
||||||
|
|
||||||
|
ContentView.AddSubview (this.hidden_close_button);
|
||||||
|
|
||||||
|
|
||||||
this.size_label = new NSTextField () {
|
this.size_label = new NSTextField () {
|
||||||
Alignment = NSTextAlignment.Right,
|
Alignment = NSTextAlignment.Right,
|
||||||
BackgroundColor = NSColor.WindowBackground,
|
BackgroundColor = NSColor.WindowBackground,
|
||||||
|
|
|
@ -462,10 +462,9 @@ namespace SparkleShare {
|
||||||
|
|
||||||
case PageType.Finished: {
|
case PageType.Finished: {
|
||||||
|
|
||||||
Header = "Project succesfully added!";
|
Header = "Project ‘" + Path.GetFileName (Controller.PreviousPath) +
|
||||||
Description = "Now you can access the files from " +
|
"’ succesfully added!";
|
||||||
"‘" + Controller.SyncingFolder + "’ in " +
|
Description = "Access the files from your SparkleShare folder.";
|
||||||
"your SparkleShare folder.";
|
|
||||||
|
|
||||||
if (warnings != null) {
|
if (warnings != null) {
|
||||||
WarningImage = NSImage.ImageNamed ("NSCaution");
|
WarningImage = NSImage.ImageNamed ("NSCaution");
|
||||||
|
@ -505,7 +504,7 @@ namespace SparkleShare {
|
||||||
};
|
};
|
||||||
|
|
||||||
OpenFolderButton.Activated += delegate {
|
OpenFolderButton.Activated += delegate {
|
||||||
Program.Controller.OpenSparkleShareFolder (Controller.SyncingFolder);
|
Program.Controller.OpenSparkleShareFolder (Path.GetFileName (Controller.PreviousPath));
|
||||||
};
|
};
|
||||||
|
|
||||||
Buttons.Add (FinishButton);
|
Buttons.Add (FinishButton);
|
||||||
|
|
|
@ -87,7 +87,9 @@ namespace SparkleShare {
|
||||||
MakeKeyAndOrderFront (this);
|
MakeKeyAndOrderFront (this);
|
||||||
|
|
||||||
OrderFrontRegardless ();
|
OrderFrontRegardless ();
|
||||||
Program.UI.UpdateDockIconVisibility ();
|
|
||||||
|
if (Program.UI != null)
|
||||||
|
Program.UI.UpdateDockIconVisibility ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -146,7 +148,9 @@ namespace SparkleShare {
|
||||||
{
|
{
|
||||||
base.OrderOut (this);
|
base.OrderOut (this);
|
||||||
NSApplication.SharedApplication.RemoveWindowsItem (this);
|
NSApplication.SharedApplication.RemoveWindowsItem (this);
|
||||||
Program.UI.UpdateDockIconVisibility ();
|
|
||||||
|
if (Program.UI != null)
|
||||||
|
Program.UI.UpdateDockIconVisibility ();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<RootNamespace>SparkleShare</RootNamespace>
|
<RootNamespace>SparkleShare</RootNamespace>
|
||||||
<AssemblyName>SparkleShare</AssemblyName>
|
<AssemblyName>SparkleShare</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||||
<ReleaseVersion>0.8.0</ReleaseVersion>
|
<ReleaseVersion>0.8.1</ReleaseVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
|
|
@ -16,6 +16,6 @@ Global
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(MonoDevelopProperties) = preSolution
|
GlobalSection(MonoDevelopProperties) = preSolution
|
||||||
StartupItem = SparkleShare.csproj
|
StartupItem = SparkleShare.csproj
|
||||||
version = 0.8.0
|
version = 0.8.1
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|
|
@ -91,6 +91,15 @@ namespace SparkleShare {
|
||||||
Menu.Delegate = new SparkleStatusIconMenuDelegate ();
|
Menu.Delegate = new SparkleStatusIconMenuDelegate ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Controller.UpdateQuitItemEvent += delegate (bool quit_item_enabled) {
|
||||||
|
InvokeOnMainThread (delegate {
|
||||||
|
if (QuitMenuItem != null) {
|
||||||
|
QuitMenuItem.Enabled = quit_item_enabled;
|
||||||
|
StatusItem.Menu.Update ();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
Controller.UpdateMenuEvent += delegate (IconState state) {
|
Controller.UpdateMenuEvent += delegate (IconState state) {
|
||||||
InvokeOnMainThread (delegate {
|
InvokeOnMainThread (delegate {
|
||||||
using (var a = new NSAutoreleasePool ()) {
|
using (var a = new NSAutoreleasePool ()) {
|
||||||
|
@ -137,6 +146,8 @@ namespace SparkleShare {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StatusItem.Menu.Update ();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -310,8 +321,8 @@ namespace SparkleShare {
|
||||||
|
|
||||||
|
|
||||||
QuitMenuItem = new NSMenuItem () {
|
QuitMenuItem = new NSMenuItem () {
|
||||||
Title = "Quit",
|
Title = "Quit",
|
||||||
Enabled = true
|
Enabled = Controller.QuitItemEnabled
|
||||||
};
|
};
|
||||||
|
|
||||||
QuitMenuItem.Activated += delegate {
|
QuitMenuItem.Activated += delegate {
|
||||||
|
|
|
@ -69,6 +69,8 @@ namespace SparkleShare {
|
||||||
if (Program.Controller.FirstRun) {
|
if (Program.Controller.FirstRun) {
|
||||||
Setup = new SparkleSetup ();
|
Setup = new SparkleSetup ();
|
||||||
Setup.Controller.ShowSetupPage ();
|
Setup.Controller.ShowSetupPage ();
|
||||||
|
|
||||||
|
UpdateDockIconVisibility ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace SparkleShare {
|
||||||
public SparkleBubblesController ()
|
public SparkleBubblesController ()
|
||||||
{
|
{
|
||||||
Program.Controller.ConflictNotificationRaised += delegate {
|
Program.Controller.ConflictNotificationRaised += delegate {
|
||||||
ShowBubble ("Ouch! Mid-air collision!",
|
ShowBubble ("Conflict detected.",
|
||||||
"Don't worry, SparkleShare made a copy of each conflicting file.",
|
"Don't worry, SparkleShare made a copy of each conflicting file.",
|
||||||
null);
|
null);
|
||||||
};
|
};
|
||||||
|
|
|
@ -263,7 +263,6 @@ namespace SparkleShare {
|
||||||
public abstract string DayEntryHTML { get; }
|
public abstract string DayEntryHTML { get; }
|
||||||
public abstract string EventEntryHTML { get; }
|
public abstract string EventEntryHTML { get; }
|
||||||
|
|
||||||
|
|
||||||
public string GetHTMLLog (List<SparkleChangeSet> change_sets)
|
public string GetHTMLLog (List<SparkleChangeSet> change_sets)
|
||||||
{
|
{
|
||||||
List <ActivityDay> activity_days = new List <ActivityDay> ();
|
List <ActivityDay> activity_days = new List <ActivityDay> ();
|
||||||
|
@ -456,6 +455,7 @@ namespace SparkleShare {
|
||||||
.Replace ("<!-- $event-avatar-url -->", change_set_avatar)
|
.Replace ("<!-- $event-avatar-url -->", change_set_avatar)
|
||||||
.Replace ("<!-- $event-time -->", timestamp)
|
.Replace ("<!-- $event-time -->", timestamp)
|
||||||
.Replace ("<!-- $event-folder -->", change_set.Folder)
|
.Replace ("<!-- $event-folder -->", change_set.Folder)
|
||||||
|
.Replace ("<!-- $event-url -->", change_set.Url.ToString ())
|
||||||
.Replace ("<!-- $event-revision -->", change_set.Revision)
|
.Replace ("<!-- $event-revision -->", change_set.Revision)
|
||||||
.Replace ("<!-- $event-folder-color -->", AssignColor (change_set.Folder))
|
.Replace ("<!-- $event-folder-color -->", AssignColor (change_set.Folder))
|
||||||
.Replace ("<!-- $event-comments -->", comments);
|
.Replace ("<!-- $event-comments -->", comments);
|
||||||
|
@ -570,16 +570,23 @@ namespace SparkleShare {
|
||||||
// Adds a repository to the list of repositories
|
// Adds a repository to the list of repositories
|
||||||
private void AddRepository (string folder_path)
|
private void AddRepository (string folder_path)
|
||||||
{
|
{
|
||||||
if (folder_path.Equals (SparkleConfig.DefaultConfig.TmpPath))
|
SparkleRepoBase repo = null;
|
||||||
|
string folder_name = Path.GetFileName (folder_path);
|
||||||
|
string backend = SparkleConfig.DefaultConfig.GetBackendForFolder (folder_name);
|
||||||
|
|
||||||
|
try {
|
||||||
|
repo = (SparkleRepoBase) Activator.CreateInstance (
|
||||||
|
Type.GetType ("SparkleLib.SparkleRepo" + backend + ", SparkleLib"),
|
||||||
|
folder_path
|
||||||
|
);
|
||||||
|
|
||||||
|
} catch {
|
||||||
|
SparkleHelpers.DebugInfo ("Controller",
|
||||||
|
"Failed to load \"" + backend + "\" backend for \"" + folder_name + "\"");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
string folder_name = Path.GetFileName (folder_path);
|
|
||||||
string backend = SparkleConfig.DefaultConfig.GetBackendForFolder (folder_name);
|
|
||||||
|
|
||||||
if (backend == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
SparkleRepoBase repo = new SparkleRepoGit (folder_path, SparkleBackend.DefaultBackend);
|
|
||||||
|
|
||||||
repo.NewChangeSet += delegate (SparkleChangeSet change_set) {
|
repo.NewChangeSet += delegate (SparkleChangeSet change_set) {
|
||||||
|
|
||||||
|
@ -624,6 +631,7 @@ namespace SparkleShare {
|
||||||
UpdateState ();
|
UpdateState ();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Repositories.Add (repo);
|
Repositories.Add (repo);
|
||||||
repo.Initialize ();
|
repo.Initialize ();
|
||||||
}
|
}
|
||||||
|
@ -770,6 +778,7 @@ namespace SparkleShare {
|
||||||
process.StartInfo.UseShellExecute = false;
|
process.StartInfo.UseShellExecute = false;
|
||||||
process.StartInfo.FileName = "ssh-add";
|
process.StartInfo.FileName = "ssh-add";
|
||||||
process.StartInfo.Arguments = "\"" + key_file_path + "\"";
|
process.StartInfo.Arguments = "\"" + key_file_path + "\"";
|
||||||
|
process.StartInfo.CreateNoWindow = true;
|
||||||
|
|
||||||
process.Start ();
|
process.Start ();
|
||||||
process.WaitForExit ();
|
process.WaitForExit ();
|
||||||
|
@ -817,7 +826,7 @@ namespace SparkleShare {
|
||||||
string key_file_path = Path.Combine (keys_path, key_file_name);
|
string key_file_path = Path.Combine (keys_path, key_file_name);
|
||||||
|
|
||||||
if (File.Exists (key_file_path)) {
|
if (File.Exists (key_file_path)) {
|
||||||
SparkleHelpers.DebugInfo ("Config", "Key already exists ('" + key_file_name + "'), " +
|
SparkleHelpers.DebugInfo ("Auth", "Key already exists ('" + key_file_name + "'), " +
|
||||||
"leaving it untouched");
|
"leaving it untouched");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -830,10 +839,11 @@ namespace SparkleShare {
|
||||||
EnableRaisingEvents = true
|
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;
|
||||||
process.StartInfo.FileName = "ssh-keygen";
|
process.StartInfo.FileName = "ssh-keygen";
|
||||||
|
process.StartInfo.CreateNoWindow = true;
|
||||||
|
|
||||||
// -t is the crypto type
|
// -t is the crypto type
|
||||||
// -P is the password (none)
|
// -P is the password (none)
|
||||||
|
@ -843,8 +853,8 @@ namespace SparkleShare {
|
||||||
process.Start ();
|
process.Start ();
|
||||||
process.WaitForExit ();
|
process.WaitForExit ();
|
||||||
|
|
||||||
SparkleHelpers.DebugInfo ("Config", "Created private key '" + key_file_name + "'");
|
SparkleHelpers.DebugInfo ("Auth", "Created private key '" + key_file_name + "'");
|
||||||
SparkleHelpers.DebugInfo ("Config", "Created public key '" + key_file_name + ".pub'");
|
SparkleHelpers.DebugInfo ("Auth", "Created public key '" + key_file_name + ".pub'");
|
||||||
|
|
||||||
// Add some restrictions to what the key can
|
// Add some restrictions to what the key can
|
||||||
// do when uploaded to the server
|
// do when uploaded to the server
|
||||||
|
@ -877,7 +887,7 @@ namespace SparkleShare {
|
||||||
|
|
||||||
if (!Directory.Exists (avatar_path)) {
|
if (!Directory.Exists (avatar_path)) {
|
||||||
Directory.CreateDirectory (avatar_path);
|
Directory.CreateDirectory (avatar_path);
|
||||||
SparkleHelpers.DebugInfo ("Config", "Created '" + avatar_path + "'");
|
SparkleHelpers.DebugInfo ("Avatar", "Created '" + avatar_path + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (string raw_email in emails) {
|
foreach (string raw_email in emails) {
|
||||||
|
@ -923,11 +933,11 @@ namespace SparkleShare {
|
||||||
lock (this.avatar_lock)
|
lock (this.avatar_lock)
|
||||||
File.WriteAllBytes (avatar_file_path, buffer);
|
File.WriteAllBytes (avatar_file_path, buffer);
|
||||||
|
|
||||||
SparkleHelpers.DebugInfo ("Controller", "Fetched gravatar for " + email);
|
SparkleHelpers.DebugInfo ("Avatar", "Fetched gravatar for " + email);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (WebException e) {
|
} catch (WebException e) {
|
||||||
SparkleHelpers.DebugInfo ("Controller", "Failed fetching gravatar for " + email);
|
SparkleHelpers.DebugInfo ("Avatar", "Failed fetching gravatar for " + email);
|
||||||
|
|
||||||
// Stop downloading further avatars if we have no internet access
|
// Stop downloading further avatars if we have no internet access
|
||||||
if (e.Status == WebExceptionStatus.Timeout){
|
if (e.Status == WebExceptionStatus.Timeout){
|
||||||
|
@ -971,7 +981,7 @@ namespace SparkleShare {
|
||||||
|
|
||||||
public void FetchFolder (string server, string remote_folder)
|
public void FetchFolder (string server, string remote_folder)
|
||||||
{
|
{
|
||||||
server = server.Trim ();
|
server = server.Trim ();
|
||||||
remote_folder = remote_folder.Trim ();
|
remote_folder = remote_folder.Trim ();
|
||||||
|
|
||||||
string tmp_path = SparkleConfig.DefaultConfig.TmpPath;
|
string tmp_path = SparkleConfig.DefaultConfig.TmpPath;
|
||||||
|
@ -980,26 +990,42 @@ namespace SparkleShare {
|
||||||
File.SetAttributes (tmp_path, File.GetAttributes (tmp_path) | FileAttributes.Hidden);
|
File.SetAttributes (tmp_path, File.GetAttributes (tmp_path) | FileAttributes.Hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Strip the '.git' from the name
|
// Strip the '.git' from the name
|
||||||
string canonical_name = Path.GetFileNameWithoutExtension (remote_folder);
|
string canonical_name = Path.GetFileNameWithoutExtension (remote_folder);
|
||||||
string tmp_folder = Path.Combine (tmp_path, canonical_name);
|
string tmp_folder = Path.Combine (tmp_path, canonical_name);
|
||||||
|
string backend = Path.GetExtension (remote_folder);
|
||||||
|
|
||||||
string backend = null;
|
if (!string.IsNullOrEmpty (backend)) {
|
||||||
|
backend = backend.Substring (1);
|
||||||
|
|
||||||
/* if (remote_folder.EndsWith (".hg")) {
|
char [] letters = backend.ToCharArray ();
|
||||||
remote_folder = remote_folder.Substring (0, (remote_folder.Length - 3));
|
letters [0] = char.ToUpper (letters [0]);
|
||||||
fetcher = new SparkleFetcherHg (server, remote_folder, tmp_folder);
|
backend = new string (letters);
|
||||||
backend = "Hg";
|
|
||||||
|
|
||||||
} else if (remote_folder.EndsWith (".scp")) {
|
} else {
|
||||||
remote_folder = remote_folder.Substring (0, (remote_folder.Length - 4));
|
|
||||||
fetcher = new SparkleFetcherScp (server, remote_folder, tmp_folder);
|
|
||||||
backend = "Scp";
|
|
||||||
|
|
||||||
} else {*/
|
|
||||||
this.fetcher = new SparkleFetcherGit (server, remote_folder, tmp_folder);
|
|
||||||
backend = "Git";
|
backend = "Git";
|
||||||
//}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.fetcher = (SparkleFetcherBase) Activator.CreateInstance (
|
||||||
|
Type.GetType ("SparkleLib.SparkleFetcher" + backend + ", SparkleLib"),
|
||||||
|
server,
|
||||||
|
remote_folder,
|
||||||
|
tmp_folder
|
||||||
|
);
|
||||||
|
|
||||||
|
} catch {
|
||||||
|
SparkleHelpers.DebugInfo ("Controller",
|
||||||
|
"Failed to load \"" + backend + "\" backend for \"" + canonical_name + "\"");
|
||||||
|
|
||||||
|
if (FolderFetchError != null)
|
||||||
|
FolderFetchError (Path.Combine (server, remote_folder));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool target_folder_exists = Directory.Exists (
|
bool target_folder_exists = Directory.Exists (
|
||||||
Path.Combine (SparkleConfig.DefaultConfig.FoldersPath, canonical_name));
|
Path.Combine (SparkleConfig.DefaultConfig.FoldersPath, canonical_name));
|
||||||
|
@ -1046,7 +1072,6 @@ namespace SparkleShare {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
this.fetcher.Failed += delegate {
|
this.fetcher.Failed += delegate {
|
||||||
if (FolderFetchError != null)
|
if (FolderFetchError != null)
|
||||||
FolderFetchError (this.fetcher.RemoteUrl);
|
FolderFetchError (this.fetcher.RemoteUrl);
|
||||||
|
@ -1057,7 +1082,6 @@ namespace SparkleShare {
|
||||||
Directory.Delete (tmp_path, true);
|
Directory.Delete (tmp_path, true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
this.fetcher.ProgressChanged += delegate (double percentage) {
|
this.fetcher.ProgressChanged += delegate (double percentage) {
|
||||||
if (FolderFetching != null)
|
if (FolderFetching != null)
|
||||||
FolderFetching (percentage);
|
FolderFetching (percentage);
|
||||||
|
|
|
@ -174,8 +174,9 @@ namespace SparkleShare {
|
||||||
TreeIter iter;
|
TreeIter iter;
|
||||||
this.combo_box.GetActiveIter (out iter);
|
this.combo_box.GetActiveIter (out iter);
|
||||||
string selection = (string) this.combo_box.Model.GetValue (iter, 0);
|
string selection = (string) this.combo_box.Model.GetValue (iter, 0);
|
||||||
|
TreePath path = this.combo_box.Model.GetPath (iter);
|
||||||
|
|
||||||
if (selection.Equals (_("All Folders")))
|
if (path.Indices [0] == 0)
|
||||||
Controller.SelectedFolder = null;
|
Controller.SelectedFolder = null;
|
||||||
else
|
else
|
||||||
Controller.SelectedFolder = selection;
|
Controller.SelectedFolder = selection;
|
||||||
|
@ -224,7 +225,7 @@ namespace SparkleShare {
|
||||||
|
|
||||||
Application.Invoke (delegate {
|
Application.Invoke (delegate {
|
||||||
this.spinner.Stop ();
|
this.spinner.Stop ();
|
||||||
this.web_view.LoadString (html, null, null, "file:///");
|
this.web_view.LoadString (html, null, null, "file://");
|
||||||
this.content_wrapper.Remove (this.content_wrapper.Child);
|
this.content_wrapper.Remove (this.content_wrapper.Child);
|
||||||
this.content_wrapper.Add (this.scrolled_window);
|
this.content_wrapper.Add (this.scrolled_window);
|
||||||
this.content_wrapper.ShowAll ();
|
this.content_wrapper.ShowAll ();
|
||||||
|
|
|
@ -66,8 +66,8 @@ namespace SparkleShare {
|
||||||
|
|
||||||
// A short delay is less annoying than
|
// A short delay is less annoying than
|
||||||
// a flashing window
|
// a flashing window
|
||||||
if (watch.ElapsedMilliseconds < 500)
|
if (watch.ElapsedMilliseconds < 750)
|
||||||
Thread.Sleep (500 - (int) watch.ElapsedMilliseconds);
|
Thread.Sleep (750 - (int) watch.ElapsedMilliseconds);
|
||||||
|
|
||||||
if (UpdateContentEvent != null)
|
if (UpdateContentEvent != null)
|
||||||
UpdateContentEvent (html);
|
UpdateContentEvent (html);
|
||||||
|
|
|
@ -441,20 +441,21 @@ namespace SparkleShare {
|
||||||
UrgencyHint = true;
|
UrgencyHint = true;
|
||||||
|
|
||||||
if (!HasToplevelFocus) {
|
if (!HasToplevelFocus) {
|
||||||
string title = String.Format (_("‘{0}’ has been successfully added"), Controller.SyncingFolder);
|
string title = _("Project successfully added!");
|
||||||
string subtext = "";
|
string subtext = "";
|
||||||
|
|
||||||
SparkleUI.Bubbles.Controller.ShowBubble (title, subtext, null);
|
SparkleUI.Bubbles.Controller.ShowBubble (title, subtext, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
Header = _("Project successfully added!");
|
Header = _("Project ‘" + System.IO.Path.GetFileName (Controller.PreviousPath) +
|
||||||
|
"’ successfully added!");
|
||||||
Description = _("Access the files from your SparkleShare folder.");
|
Description = _("Access the files from your SparkleShare folder.");
|
||||||
|
|
||||||
// A button that opens the synced folder
|
// A button that opens the synced folder
|
||||||
Button open_folder_button = new Button (_("Open Folder"));
|
Button open_folder_button = new Button (_("Open Folder"));
|
||||||
|
|
||||||
open_folder_button.Clicked += delegate {
|
open_folder_button.Clicked += delegate {
|
||||||
Program.Controller.OpenSparkleShareFolder (Controller.SyncingFolder);
|
Program.Controller.OpenSparkleShareFolder (System.IO.Path.GetFileName (Controller.PreviousPath));
|
||||||
};
|
};
|
||||||
|
|
||||||
Button finish_button = new Button (_("Finish"));
|
Button finish_button = new Button (_("Finish"));
|
||||||
|
|
|
@ -33,11 +33,13 @@ namespace SparkleShare {
|
||||||
|
|
||||||
public SparkleStatusIconController Controller = new SparkleStatusIconController ();
|
public SparkleStatusIconController Controller = new SparkleStatusIconController ();
|
||||||
|
|
||||||
|
// TODO: fix case
|
||||||
private Timer Animation;
|
private Timer Animation;
|
||||||
private Gdk.Pixbuf [] AnimationFrames;
|
private Gdk.Pixbuf [] AnimationFrames;
|
||||||
private int FrameNumber;
|
private int FrameNumber;
|
||||||
private string StateText;
|
private string StateText;
|
||||||
private Menu Menu;
|
private Menu Menu;
|
||||||
|
private MenuItem quit_item;
|
||||||
|
|
||||||
#if HAVE_APP_INDICATOR
|
#if HAVE_APP_INDICATOR
|
||||||
private ApplicationIndicator indicator;
|
private ApplicationIndicator indicator;
|
||||||
|
@ -78,58 +80,70 @@ namespace SparkleShare {
|
||||||
|
|
||||||
CreateMenu ();
|
CreateMenu ();
|
||||||
|
|
||||||
|
|
||||||
|
Controller.UpdateQuitItemEvent += delegate (bool quit_item_enabled) {
|
||||||
|
Application.Invoke (delegate {
|
||||||
|
if (this.quit_item != null) {
|
||||||
|
this.quit_item.Sensitive = quit_item_enabled;
|
||||||
|
Menu.ShowAll ();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
Controller.UpdateMenuEvent += delegate (IconState state) {
|
Controller.UpdateMenuEvent += delegate (IconState state) {
|
||||||
Application.Invoke (delegate {
|
Application.Invoke (delegate {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case IconState.Idle:
|
case IconState.Idle:
|
||||||
|
|
||||||
Animation.Stop ();
|
Animation.Stop ();
|
||||||
|
|
||||||
if (Controller.Folders.Length == 0)
|
if (Controller.Folders.Length == 0)
|
||||||
StateText = _("Welcome to SparkleShare!");
|
StateText = _("Welcome to SparkleShare!");
|
||||||
else
|
else
|
||||||
StateText = _("Up to date") + Controller.FolderSize;
|
StateText = _("Up to date") + Controller.FolderSize;
|
||||||
|
|
||||||
#if HAVE_APP_INDICATOR
|
#if HAVE_APP_INDICATOR
|
||||||
this.indicator.IconName = "process-syncing-sparkleshare-i";
|
this.indicator.IconName = "process-syncing-sparkleshare-i";
|
||||||
#else
|
#else
|
||||||
this.status_icon.Pixbuf = AnimationFrames [0];
|
this.status_icon.Pixbuf = AnimationFrames [0];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
UpdateStateText ();
|
UpdateStateText ();
|
||||||
CreateMenu ();
|
CreateMenu ();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IconState.Syncing:
|
case IconState.Syncing:
|
||||||
|
|
||||||
StateText = _("Syncing… ") +
|
StateText = _("Syncing… ") +
|
||||||
Controller.ProgressPercentage + "% " +
|
Controller.ProgressPercentage + "% " +
|
||||||
Controller.ProgressSpeed;
|
Controller.ProgressSpeed;
|
||||||
|
|
||||||
UpdateStateText ();
|
UpdateStateText ();
|
||||||
|
|
||||||
if (!Animation.Enabled)
|
if (!Animation.Enabled)
|
||||||
Animation.Start ();
|
Animation.Start ();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IconState.Error:
|
case IconState.Error:
|
||||||
|
|
||||||
Animation.Stop ();
|
Animation.Stop ();
|
||||||
|
|
||||||
StateText = _("Not everything is synced");
|
StateText = _("Not everything is synced");
|
||||||
UpdateStateText ();
|
UpdateStateText ();
|
||||||
CreateMenu ();
|
CreateMenu ();
|
||||||
|
|
||||||
#if HAVE_APP_INDICATOR
|
#if HAVE_APP_INDICATOR
|
||||||
this.indicator.IconName = "sparkleshare-syncing-error";
|
this.indicator.IconName = "sparkleshare-syncing-error";
|
||||||
#else
|
#else
|
||||||
this.status_icon.Pixbuf = SparkleUIHelpers.GetIcon ("sparkleshare-syncing-error", 24);
|
this.status_icon.Pixbuf = SparkleUIHelpers.GetIcon ("sparkleshare-syncing-error", 24);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Menu.ShowAll ();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -311,13 +325,15 @@ namespace SparkleShare {
|
||||||
Menu.Add (new SeparatorMenuItem ());
|
Menu.Add (new SeparatorMenuItem ());
|
||||||
|
|
||||||
// A menu item that quits the application
|
// A menu item that quits the application
|
||||||
MenuItem quit_item = new MenuItem (_("Quit"));
|
this.quit_item = new MenuItem (_("Quit")) {
|
||||||
|
Sensitive = Controller.QuitItemEnabled
|
||||||
|
};
|
||||||
|
|
||||||
quit_item.Activated += delegate {
|
this.quit_item.Activated += delegate {
|
||||||
Program.Controller.Quit ();
|
Program.Controller.Quit ();
|
||||||
};
|
};
|
||||||
|
|
||||||
Menu.Add (quit_item);
|
Menu.Add (this.quit_item);
|
||||||
Menu.ShowAll ();
|
Menu.ShowAll ();
|
||||||
|
|
||||||
#if HAVE_APP_INDICATOR
|
#if HAVE_APP_INDICATOR
|
||||||
|
|
|
@ -38,6 +38,9 @@ namespace SparkleShare {
|
||||||
public event UpdateMenuEventHandler UpdateMenuEvent;
|
public event UpdateMenuEventHandler UpdateMenuEvent;
|
||||||
public delegate void UpdateMenuEventHandler (IconState state);
|
public delegate void UpdateMenuEventHandler (IconState state);
|
||||||
|
|
||||||
|
public event UpdateQuitItemEventHandler UpdateQuitItemEvent;
|
||||||
|
public delegate void UpdateQuitItemEventHandler (bool quit_item_enabled);
|
||||||
|
|
||||||
public IconState CurrentState = IconState.Idle;
|
public IconState CurrentState = IconState.Idle;
|
||||||
|
|
||||||
public string [] Folders {
|
public string [] Folders {
|
||||||
|
@ -76,6 +79,14 @@ namespace SparkleShare {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool QuitItemEnabled {
|
||||||
|
get {
|
||||||
|
return (CurrentState != IconState.Syncing &&
|
||||||
|
CurrentState != IconState.SyncingDown &&
|
||||||
|
CurrentState != IconState.SyncingUp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public SparkleStatusIconController ()
|
public SparkleStatusIconController ()
|
||||||
{
|
{
|
||||||
|
@ -89,6 +100,9 @@ namespace SparkleShare {
|
||||||
if (CurrentState != IconState.Error)
|
if (CurrentState != IconState.Error)
|
||||||
CurrentState = IconState.Idle;
|
CurrentState = IconState.Idle;
|
||||||
|
|
||||||
|
if (UpdateQuitItemEvent != null)
|
||||||
|
UpdateQuitItemEvent (QuitItemEnabled);
|
||||||
|
|
||||||
if (UpdateMenuEvent != null)
|
if (UpdateMenuEvent != null)
|
||||||
UpdateMenuEvent (CurrentState);
|
UpdateMenuEvent (CurrentState);
|
||||||
};
|
};
|
||||||
|
@ -97,6 +111,9 @@ namespace SparkleShare {
|
||||||
Program.Controller.OnSyncing += delegate {
|
Program.Controller.OnSyncing += delegate {
|
||||||
CurrentState = IconState.Syncing;
|
CurrentState = IconState.Syncing;
|
||||||
|
|
||||||
|
if (UpdateQuitItemEvent != null)
|
||||||
|
UpdateQuitItemEvent (QuitItemEnabled);
|
||||||
|
|
||||||
if (UpdateMenuEvent != null)
|
if (UpdateMenuEvent != null)
|
||||||
UpdateMenuEvent (IconState.Syncing);
|
UpdateMenuEvent (IconState.Syncing);
|
||||||
};
|
};
|
||||||
|
@ -105,6 +122,9 @@ namespace SparkleShare {
|
||||||
Program.Controller.OnError += delegate {
|
Program.Controller.OnError += delegate {
|
||||||
CurrentState = IconState.Error;
|
CurrentState = IconState.Error;
|
||||||
|
|
||||||
|
if (UpdateQuitItemEvent != null)
|
||||||
|
UpdateQuitItemEvent (QuitItemEnabled);
|
||||||
|
|
||||||
if (UpdateMenuEvent != null)
|
if (UpdateMenuEvent != null)
|
||||||
UpdateMenuEvent (IconState.Error);
|
UpdateMenuEvent (IconState.Error);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
if [[ $UID -eq 0 ]]; then
|
if [[ $UID -eq 0 ]]; then
|
||||||
echo "Cannot run as root. Things would go utterly wrong."
|
echo "Cannot run as root. Things would go utterly wrong."
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
dnl Process this file with autoconf to produce a configure script.
|
dnl Process this file with autoconf to produce a configure script.
|
||||||
m4_define([sparkleshare_version],
|
m4_define([sparkleshare_version],
|
||||||
[0.8.0])
|
[0.8.1])
|
||||||
|
|
||||||
m4_define([sparkleshare_asm_version],
|
m4_define([sparkleshare_asm_version],
|
||||||
[0.8.0])
|
[0.8.1])
|
||||||
|
|
||||||
AC_PREREQ([2.54])
|
AC_PREREQ([2.54])
|
||||||
AC_INIT([SparkleShare], sparkleshare_version)
|
AC_INIT([SparkleShare], sparkleshare_version)
|
||||||
AM_INIT_AUTOMAKE([1.11 dist-bzip2 dist-zip foreign tar-ustar])
|
AM_INIT_AUTOMAKE([1.11 dist-bzip2 dist-zip foreign tar-pax])
|
||||||
AM_MAINTAINER_MODE
|
AM_MAINTAINER_MODE
|
||||||
|
|
||||||
dnl Export Version Info
|
dnl Export Version Info
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div class='event-entry' style='background-image: url("<!-- $event-avatar-url -->");'>
|
<div class='event-entry' style='background-image: url("<!-- $event-avatar-url -->");'>
|
||||||
<div class='event-user-name'><!-- $event-user-name --></div>
|
<div class='event-user-name'><!-- $event-user-name --></div>
|
||||||
<div class='event-folder'><!-- $event-folder --></div>
|
<div class='event-folder'><!-- $event-folder --><span><!-- $event-url --></span></div>
|
||||||
|
|
||||||
<!-- $event-entry-content -->
|
<!-- $event-entry-content -->
|
||||||
|
|
||||||
|
|
|
@ -88,23 +88,23 @@
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
* {
|
* {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background-color: #fff;
|
background-color: #fafafa;
|
||||||
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: 18px;
|
padding: 18px;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
small {
|
small {
|
||||||
font-size: <!-- $small-font-size -->;
|
font-size: <!-- $small-font-size -->;
|
||||||
color: <!-- $secondary-font-color -->;
|
color: <!-- $secondary-font-color -->;
|
||||||
}
|
}
|
||||||
|
|
||||||
.moved-arrow {
|
.moved-arrow {
|
||||||
|
@ -152,23 +152,45 @@
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.event-folder {
|
.event-folder {
|
||||||
float: right;
|
float: right;
|
||||||
color: <!-- $secondary-font-color -->;
|
color: <!-- $secondary-font-color -->;
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.event-folder span {
|
||||||
|
display: none
|
||||||
|
}
|
||||||
|
|
||||||
|
.event-folder:hover span {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 20px;
|
||||||
|
right: 0;
|
||||||
|
background-color: rgba(20, 20, 20, 0.8);
|
||||||
|
color: #fafafa;
|
||||||
|
padding: 7px 12px;
|
||||||
|
border-radius: 5px;
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
float:right;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.event-entry {
|
.event-entry {
|
||||||
margin-bottom: 24px;
|
margin-bottom: 24px;
|
||||||
padding-bottom: 24px;
|
padding-bottom: 24px;
|
||||||
border-bottom: 1px <!-- $secondary-font-color --> solid;
|
border-bottom: 1px #ddd solid;
|
||||||
width: 95%;
|
width: 99%;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
padding-left: 72px;
|
padding-left: 72px;
|
||||||
padding-right: 12px;
|
padding-right: 12px;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: 12px top;
|
background-position: 12px top;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.action {
|
.action {
|
||||||
|
@ -209,16 +231,16 @@
|
||||||
|
|
||||||
dd {
|
dd {
|
||||||
display: none;
|
display: none;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
width: 90%;
|
width: 90%;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
padding-top: 2px;
|
padding-top: 2px;
|
||||||
padding-bottom: 2px;
|
padding-bottom: 2px;
|
||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
margin-bottom: 1px;
|
margin-bottom: 1px;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: center left;
|
background-position: center left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,17 +274,17 @@
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
float: left;
|
float: left;
|
||||||
margin-right: 12px;
|
margin-right: 12px;
|
||||||
width: 48px;
|
width: 48px;
|
||||||
background-image: url('<!-- $no-buddy-icon-background-image -->');
|
background-image: url('<!-- $no-buddy-icon-background-image -->');
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: top center;
|
background-position: top center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.buddy-icon {
|
.buddy-icon {
|
||||||
width: 48px;
|
width: 48px;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.comments {
|
.comments {
|
||||||
|
@ -295,23 +317,23 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.comment-textarea {
|
.comment-textarea {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 3em;
|
height: 3em;
|
||||||
padding-bottom: 6px;
|
padding-bottom: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.comments-section {
|
.comments-section {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.comments-wrapper {
|
.comments-wrapper {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue