Merge with upstream (11a932b73e
)
This commit is contained in:
parent
d66656da08
commit
636efe9011
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -47,3 +47,4 @@ SparkleShare/Nautilus/sparkleshare-nautilus-extension.py
|
|||
gnome-doc-utils.make
|
||||
/sparkleshare-*
|
||||
desktop.ini
|
||||
_ReSharper.*
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml;
|
||||
|
||||
namespace SparkleLib {
|
||||
|
@ -25,6 +26,9 @@ namespace SparkleLib {
|
|||
// Sets up a fetcher that can get remote folders
|
||||
public class SparkleFetcherGit : SparkleFetcherBase {
|
||||
|
||||
private SparkleGit git;
|
||||
|
||||
|
||||
public SparkleFetcherGit (string server, string remote_folder, string target_folder) :
|
||||
base (server, remote_folder, target_folder)
|
||||
{
|
||||
|
@ -57,13 +61,20 @@ namespace SparkleLib {
|
|||
} else {
|
||||
server = server.TrimEnd ("/".ToCharArray ());
|
||||
|
||||
string protocol = "ssh://";
|
||||
|
||||
if (server.StartsWith ("ssh://"))
|
||||
server = server.Substring (6);
|
||||
|
||||
if (server.StartsWith ("git://")) {
|
||||
server = server.Substring (6);
|
||||
protocol = "git://";
|
||||
}
|
||||
|
||||
if (!server.Contains ("@"))
|
||||
server = "git@" + server;
|
||||
|
||||
server = "ssh://" + server;
|
||||
server = protocol + server;
|
||||
}
|
||||
|
||||
base.target_folder = target_folder;
|
||||
|
@ -73,15 +84,51 @@ namespace SparkleLib {
|
|||
|
||||
public override bool Fetch ()
|
||||
{
|
||||
SparkleGit git = new SparkleGit (SparklePaths.SparkleTmpPath,
|
||||
"clone \"" + base.remote_url + "\" " + "\"" + base.target_folder + "\"");
|
||||
this.git = new SparkleGit (SparkleConfig.DefaultConfig.TmpPath,
|
||||
"clone " +
|
||||
"--progress " + // Redirects progress stats to standarderror
|
||||
"\"" + base.remote_url + "\" " + "\"" + base.target_folder + "\"");
|
||||
|
||||
git.Start ();
|
||||
git.WaitForExit ();
|
||||
this.git.StartInfo.RedirectStandardError = true;
|
||||
this.git.Start ();
|
||||
|
||||
SparkleHelpers.DebugInfo ("Git", "Exit code " + git.ExitCode.ToString ());
|
||||
double percentage = 1.0;
|
||||
Regex progress_regex = new Regex (@"([0-9]+)%", RegexOptions.Compiled);
|
||||
|
||||
if (git.ExitCode != 0) {
|
||||
while (!this.git.StandardError.EndOfStream) {
|
||||
string line = this.git.StandardError.ReadLine ();
|
||||
Match match = progress_regex.Match (line);
|
||||
|
||||
double number = 0.0;
|
||||
if (match.Success) {
|
||||
number = double.Parse (match.Groups [1].Value);
|
||||
|
||||
// The cloning progress consists of two stages: the "Compressing
|
||||
// objects" stage which we count as 20% of the total progress, and
|
||||
// the "Receiving objects" stage which we count as the last 80%
|
||||
if (line.Contains ("|"))
|
||||
// "Receiving objects" stage
|
||||
number = (number / 100 * 75 + 20);
|
||||
else
|
||||
// "Compressing objects" stage
|
||||
number = (number / 100 * 20);
|
||||
}
|
||||
|
||||
if (number >= percentage) {
|
||||
percentage = number;
|
||||
|
||||
// FIXME: for some reason it doesn't go above 95%
|
||||
base.OnProgressChanged (percentage);
|
||||
}
|
||||
|
||||
System.Threading.Thread.Sleep (100);
|
||||
}
|
||||
|
||||
this.git.WaitForExit ();
|
||||
|
||||
SparkleHelpers.DebugInfo ("Git", "Exit code " + this.git.ExitCode.ToString ());
|
||||
|
||||
if (this.git.ExitCode != 0) {
|
||||
return false;
|
||||
} else {
|
||||
InstallConfiguration ();
|
||||
|
@ -91,11 +138,22 @@ namespace SparkleLib {
|
|||
}
|
||||
|
||||
|
||||
public override void Stop ()
|
||||
{
|
||||
if (this.git != null) {
|
||||
this.git.Kill ();
|
||||
this.git.Dispose ();
|
||||
}
|
||||
|
||||
base.Stop ();
|
||||
}
|
||||
|
||||
|
||||
// Install the user's name and email and some config into
|
||||
// the newly cloned repository
|
||||
private void InstallConfiguration ()
|
||||
{
|
||||
string global_config_file_path = Path.Combine (SparklePaths.SparkleConfigPath, "config.xml");
|
||||
string global_config_file_path = Path.Combine (SparkleConfig.DefaultConfig.TmpPath, "config.xml");
|
||||
|
||||
if (!File.Exists (global_config_file_path))
|
||||
return;
|
||||
|
@ -103,17 +161,20 @@ namespace SparkleLib {
|
|||
string repo_config_file_path = SparkleHelpers.CombineMore (base.target_folder, ".git", "config");
|
||||
string config = String.Join (Environment.NewLine, File.ReadAllLines (repo_config_file_path));
|
||||
|
||||
string n = Environment.NewLine;
|
||||
|
||||
// Show special characters in the logs
|
||||
config = config.Replace ("[core]" + n,
|
||||
"[core]" + n + "quotepath = false" + n);
|
||||
|
||||
// Be case sensitive explicitly to work on Mac
|
||||
config = config.Replace ("ignorecase = true", "ignorecase = false");
|
||||
|
||||
// Ignore permission changes
|
||||
config = config.Replace ("filemode = true", "filemode = false");
|
||||
config = config.Replace ("fetch = +refs/heads/*:refs/remotes/origin/*",
|
||||
"fetch = +refs/heads/*:refs/remotes/origin/*" + Environment.NewLine +
|
||||
"\tfetch = +refs/notes/*:refs/notes/*");
|
||||
|
||||
|
||||
// Add user info
|
||||
string n = Environment.NewLine;
|
||||
XmlDocument xml = new XmlDocument();
|
||||
xml.Load (global_config_file_path);
|
||||
|
||||
|
@ -146,6 +207,10 @@ namespace SparkleLib {
|
|||
// gedit and emacs
|
||||
writer.WriteLine ("*~");
|
||||
|
||||
// Firefox and Chromium temporary download files
|
||||
writer.WriteLine ("*.part");
|
||||
writer.WriteLine ("*.crdownload");
|
||||
|
||||
// vi(m)
|
||||
writer.WriteLine (".*.sw[a-z]");
|
||||
writer.WriteLine ("*.un~");
|
||||
|
@ -168,7 +233,6 @@ namespace SparkleLib {
|
|||
// Windows
|
||||
writer.WriteLine ("Thumbs.db");
|
||||
writer.WriteLine ("Desktop.ini");
|
||||
writer.WriteLine ("~*");
|
||||
|
||||
// CVS
|
||||
writer.WriteLine ("*/CVS/*");
|
||||
|
|
|
@ -131,7 +131,9 @@ namespace SparkleLib {
|
|||
public override bool SyncUp ()
|
||||
{
|
||||
Add ();
|
||||
Commit ("Changes made by SparkleShare");
|
||||
|
||||
string message = FormatCommitMessage ();
|
||||
Commit (message);
|
||||
|
||||
SparkleGit git = new SparkleGit (LocalPath, "push origin master");
|
||||
git.Start ();
|
||||
|
@ -163,6 +165,8 @@ namespace SparkleLib {
|
|||
|
||||
public override bool AnyDifferences {
|
||||
get {
|
||||
FillEmptyDirectories (LocalPath);
|
||||
|
||||
SparkleGit git = new SparkleGit (LocalPath, "status --porcelain");
|
||||
git.Start ();
|
||||
|
||||
|
@ -197,7 +201,7 @@ namespace SparkleLib {
|
|||
|
||||
if (value) {
|
||||
if (!File.Exists (unsynced_file_path))
|
||||
File.Create (unsynced_file_path);
|
||||
File.Create (unsynced_file_path).Close ();
|
||||
} else {
|
||||
File.Delete (unsynced_file_path);
|
||||
}
|
||||
|
@ -330,7 +334,7 @@ namespace SparkleLib {
|
|||
// Windows doesn't allow colons in the file name, so
|
||||
// we use "h" between the hours and minutes instead.
|
||||
string timestamp = DateTime.Now.ToString ("HH\\hmm MMM d");
|
||||
string their_path = conflicting_path + " (" + SparkleConfig.DefaultConfig.UserName + ", " + timestamp + ")";
|
||||
string their_path = conflicting_path + " (" + SparkleConfig.DefaultConfig.User.Name + ", " + timestamp + ")";
|
||||
string abs_conflicting_path = Path.Combine (LocalPath, conflicting_path);
|
||||
string abs_their_path = Path.Combine (LocalPath, their_path);
|
||||
|
||||
|
@ -452,9 +456,9 @@ namespace SparkleLib {
|
|||
|
||||
change_set.Folder = Name;
|
||||
change_set.Revision = match.Groups [1].Value;
|
||||
change_set.UserName = match.Groups [2].Value;
|
||||
change_set.UserEmail = match.Groups [3].Value;
|
||||
change_set.IsMerge = is_merge_commit;
|
||||
change_set.User.Name = match.Groups [2].Value;
|
||||
change_set.User.Email = match.Groups [3].Value;
|
||||
change_set.IsMagical = is_merge_commit;
|
||||
|
||||
change_set.Timestamp = new DateTime (int.Parse (match.Groups [4].Value),
|
||||
int.Parse (match.Groups [5].Value), int.Parse (match.Groups [6].Value),
|
||||
|
@ -477,6 +481,9 @@ namespace SparkleLib {
|
|||
string file_path = entry_line.Substring (39);
|
||||
string to_file_path;
|
||||
|
||||
if (file_path.EndsWith (".empty"))
|
||||
file_path = file_path.Substring (0, file_path.Length - ".empty".Length);
|
||||
|
||||
if (change_type.Equals ("A") && !file_path.Contains (".notes")) {
|
||||
change_set.Added.Add (file_path);
|
||||
|
||||
|
@ -512,6 +519,22 @@ namespace SparkleLib {
|
|||
}
|
||||
|
||||
|
||||
// Git doesn't track empty directories, so this method
|
||||
// fills them all with a hidden empty file
|
||||
private void FillEmptyDirectories (string path)
|
||||
{
|
||||
foreach (string child_path in Directory.GetDirectories (path)) {
|
||||
if (child_path.EndsWith (".git") || child_path.EndsWith (".notes"))
|
||||
continue;
|
||||
|
||||
FillEmptyDirectories (child_path);
|
||||
}
|
||||
|
||||
if (Directory.GetFiles (path).Length == 0)
|
||||
File.Create (Path.Combine (path, ".empty")).Close ();
|
||||
}
|
||||
|
||||
|
||||
// Creates a pretty commit message based on what has changed
|
||||
private string FormatCommitMessage ()
|
||||
{
|
||||
|
|
|
@ -130,7 +130,7 @@ namespace SparkleLib {
|
|||
|
||||
if (value) {
|
||||
if (!File.Exists (unsynced_file_path))
|
||||
File.Create (unsynced_file_path);
|
||||
File.Create (unsynced_file_path).Close ();
|
||||
} else {
|
||||
File.Delete (unsynced_file_path);
|
||||
}
|
||||
|
@ -234,11 +234,13 @@ namespace SparkleLib {
|
|||
|
||||
SparkleChangeSet change_set = new SparkleChangeSet () {
|
||||
Revision = match.Groups [9].Value,
|
||||
UserName = match.Groups [7].Value.Trim (),
|
||||
UserEmail = match.Groups [8].Value,
|
||||
IsMerge = is_merge_commit
|
||||
IsMagical = is_merge_commit
|
||||
};
|
||||
|
||||
change_set.User.Name = match.Groups [7].Value.Trim ();
|
||||
change_set.User.Email = match.Groups [8].Value;
|
||||
|
||||
|
||||
change_set.Timestamp = new DateTime (int.Parse (match.Groups [1].Value),
|
||||
int.Parse (match.Groups [2].Value), int.Parse (match.Groups [3].Value),
|
||||
int.Parse (match.Groups [4].Value), int.Parse (match.Groups [5].Value), 0);
|
||||
|
|
|
@ -11,10 +11,6 @@ SOURCES = \
|
|||
Defines.cs \
|
||||
Git/SparkleFetcherGit.cs \
|
||||
Git/SparkleRepoGit.cs \
|
||||
Hg/SparkleFetcherHg.cs \
|
||||
Hg/SparkleRepoHg.cs \
|
||||
Scp/SparkleFetcherScp.cs \
|
||||
Scp/SparkleRepoScp.cs \
|
||||
SparkleBackend.cs \
|
||||
SparkleChangeSet.cs \
|
||||
SparkleConfig.cs \
|
||||
|
@ -24,7 +20,6 @@ SOURCES = \
|
|||
SparkleListenerIrc.cs \
|
||||
SparkleListenerTcp.cs \
|
||||
SparkleOptions.cs \
|
||||
SparklePaths.cs \
|
||||
SparkleRepoBase.cs \
|
||||
SparkleWatcher.cs
|
||||
|
||||
|
|
|
@ -1,139 +0,0 @@
|
|||
// 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;
|
||||
using System.Diagnostics;
|
||||
using System.Xml;
|
||||
|
||||
namespace SparkleLib {
|
||||
|
||||
// Sets up a fetcher that can get remote folders
|
||||
public class SparkleFetcherScp : SparkleFetcherBase {
|
||||
|
||||
public SparkleFetcherScp (string server, string remote_folder, string target_folder) :
|
||||
base (server, remote_folder, target_folder) { }
|
||||
|
||||
|
||||
public override bool Fetch ()
|
||||
{
|
||||
SparkleScp scp = new SparkleScp (SparklePaths.SparkleTmpPath,
|
||||
"-r \"" + base.remote_url + "\" " + "\"" + base.target_folder + "\"");
|
||||
|
||||
scp.Start ();
|
||||
scp.WaitForExit ();
|
||||
|
||||
SparkleHelpers.DebugInfo ("Scp", "Exit code " + scp.ExitCode.ToString ());
|
||||
|
||||
if (scp.ExitCode != 0) {
|
||||
return false;
|
||||
} else {
|
||||
InstallConfiguration ();
|
||||
InstallExcludeRules ();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Install the user's name and email and some config into
|
||||
// the newly cloned repository
|
||||
private void InstallConfiguration ()
|
||||
{
|
||||
string log_file_path = SparkleHelpers.CombineMore (base.target_folder, ".sparkleshare", "log");
|
||||
File.Create (log_file_path);
|
||||
|
||||
string config_file_path = SparkleHelpers.CombineMore (base.target_folder, ".sparkleshare", "config");
|
||||
File.Create (config_file_path);
|
||||
|
||||
string config = "";
|
||||
|
||||
// Write the config to the file
|
||||
TextWriter writer = new StreamWriter (config_file_path);
|
||||
writer.WriteLine (config);
|
||||
writer.Close ();
|
||||
|
||||
SparkleHelpers.DebugInfo ("Config", "Added configuration to '" + config_file_path + "'");
|
||||
}
|
||||
|
||||
|
||||
// Add a .gitignore file to the repo
|
||||
private void InstallExcludeRules ()
|
||||
{
|
||||
string exlude_rules_file_path = SparkleHelpers.CombineMore (base.target_folder, ".sparkleshare", "exclude");
|
||||
File.Create (exlude_rules_file_path);
|
||||
|
||||
TextWriter writer = new StreamWriter (exlude_rules_file_path);
|
||||
|
||||
// gedit and emacs
|
||||
writer.WriteLine ("*~");
|
||||
|
||||
// vi(m)
|
||||
writer.WriteLine (".*.sw[a-z]");
|
||||
writer.WriteLine ("*.un~");
|
||||
writer.WriteLine ("*.swp");
|
||||
writer.WriteLine ("*.swo");
|
||||
|
||||
// KDE
|
||||
writer.WriteLine (".directory");
|
||||
|
||||
// Mac OSX
|
||||
writer.WriteLine (".DS_Store");
|
||||
writer.WriteLine ("Icon?");
|
||||
writer.WriteLine ("._*");
|
||||
writer.WriteLine (".Spotlight-V100");
|
||||
writer.WriteLine (".Trashes");
|
||||
|
||||
// Mac OSX
|
||||
writer.WriteLine ("*(Autosaved).graffle");
|
||||
|
||||
// Windows
|
||||
writer.WriteLine ("Thumbs.db");
|
||||
writer.WriteLine ("Desktop.ini");
|
||||
|
||||
// CVS
|
||||
writer.WriteLine ("*/CVS/*");
|
||||
writer.WriteLine (".cvsignore");
|
||||
writer.WriteLine ("*/.cvsignore");
|
||||
|
||||
// Subversion
|
||||
writer.WriteLine ("/.svn/*");
|
||||
writer.WriteLine ("*/.svn/*");
|
||||
|
||||
writer.Close ();
|
||||
}
|
||||
}
|
||||
|
||||
public class SparkleScp : Process {
|
||||
|
||||
public SparkleScp (string path, string args) : base ()
|
||||
{
|
||||
EnableRaisingEvents = true;
|
||||
StartInfo.FileName = SparkleBackend.DefaultBackend.Path;
|
||||
StartInfo.Arguments = args;
|
||||
StartInfo.RedirectStandardOutput = true;
|
||||
StartInfo.UseShellExecute = false;
|
||||
StartInfo.WorkingDirectory = path;
|
||||
}
|
||||
|
||||
|
||||
new public void Start ()
|
||||
{
|
||||
SparkleHelpers.DebugInfo ("Cmd", StartInfo.FileName + " " + StartInfo.Arguments);
|
||||
base.Start ();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
// 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;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace SparkleLib {
|
||||
|
||||
public class SparkleRepoScp : SparkleRepoBase {
|
||||
|
||||
public SparkleRepoScp (string path, SparkleBackend backend) :
|
||||
base (path, backend) { }
|
||||
|
||||
|
||||
public override string Identifier {
|
||||
get {
|
||||
return "sparkles";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override string CurrentRevision {
|
||||
get {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override bool CheckForRemoteChanges ()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public override bool SyncUp ()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public override bool SyncDown ()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public override bool AnyDifferences {
|
||||
get {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override bool HasUnsyncedChanges {
|
||||
get {
|
||||
string unsynced_file_path = SparkleHelpers.CombineMore (LocalPath,
|
||||
".sparkleshare", "has_unsynced_changes");
|
||||
|
||||
return File.Exists (unsynced_file_path);
|
||||
}
|
||||
|
||||
set {
|
||||
string unsynced_file_path = SparkleHelpers.CombineMore (LocalPath,
|
||||
".sparkleshare", "has_unsynced_changes");
|
||||
|
||||
if (value) {
|
||||
if (!File.Exists (unsynced_file_path))
|
||||
File.Create (unsynced_file_path);
|
||||
} else {
|
||||
File.Delete (unsynced_file_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override List <SparkleChangeSet> GetChangeSets (int count)
|
||||
{
|
||||
var l = new List<SparkleChangeSet> ();
|
||||
l.Add (new SparkleChangeSet () { UserName = "test", UserEmail = "test", Revision = "test", Timestamp = DateTime.Now });
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
public override void CreateInitialChangeSet ()
|
||||
{
|
||||
base.CreateInitialChangeSet ();
|
||||
}
|
||||
|
||||
|
||||
public override bool UsesNotificationCenter
|
||||
{
|
||||
get {
|
||||
string file_path = SparkleHelpers.CombineMore (LocalPath, ".sparkleshare", "disable_notification_center");
|
||||
return !File.Exists (file_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -32,7 +32,7 @@ namespace SparkleLib {
|
|||
public SparkleBackend (string name, string [] paths)
|
||||
{
|
||||
Name = name;
|
||||
Path = "git"; // default
|
||||
Path = "git";
|
||||
|
||||
foreach (string path in paths) {
|
||||
if (File.Exists (path)) {
|
||||
|
|
|
@ -16,20 +16,20 @@
|
|||
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SparkleLib {
|
||||
|
||||
public class SparkleChangeSet {
|
||||
|
||||
public string UserName;
|
||||
public string UserEmail;
|
||||
public SparkleUser User = new SparkleUser ("Unknown", "Unknown");
|
||||
|
||||
public string Folder;
|
||||
public string Revision;
|
||||
public DateTime Timestamp;
|
||||
public DateTime FirstTimestamp;
|
||||
public bool IsMerge = false;
|
||||
public bool IsMagical = false;
|
||||
|
||||
public List<string> Added = new List<string> ();
|
||||
public List<string> Deleted = new List<string> ();
|
||||
|
@ -76,10 +76,44 @@ namespace SparkleLib {
|
|||
|
||||
public class SparkleNote {
|
||||
|
||||
public string UserName;
|
||||
public string UserEmail;
|
||||
public SparkleUser User;
|
||||
|
||||
public DateTime Timestamp;
|
||||
public string Body;
|
||||
}
|
||||
|
||||
|
||||
public class SparkleUser {
|
||||
|
||||
public string Name;
|
||||
public string Email;
|
||||
|
||||
public string PublicKey;
|
||||
|
||||
|
||||
public SparkleUser (string name, string email)
|
||||
{
|
||||
Name = name;
|
||||
Email = email;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class SparkleFolder {
|
||||
|
||||
public string Name;
|
||||
// TODO: Uri
|
||||
|
||||
public string FullPath {
|
||||
get {
|
||||
return Path.Combine (SparkleConfig.DefaultConfig.FoldersPath, Name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public SparkleFolder (string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,19 +23,37 @@ using System.Xml;
|
|||
#if __MonoCS__
|
||||
using Mono.Unix;
|
||||
#endif
|
||||
|
||||
namespace SparkleLib {
|
||||
|
||||
public class SparkleConfig : XmlDocument {
|
||||
|
||||
public static SparkleConfig DefaultConfig = new SparkleConfig (
|
||||
SparklePaths.SparkleConfigPath, "config.xml");
|
||||
public static string ConfigPath = Path.Combine (
|
||||
Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData),
|
||||
"sparkleshare");
|
||||
|
||||
public string Path;
|
||||
public static SparkleConfig DefaultConfig = new SparkleConfig (ConfigPath, "config.xml");
|
||||
|
||||
|
||||
public string FullPath;
|
||||
|
||||
public string HomePath = Environment.GetFolderPath (Environment.SpecialFolder.Personal);
|
||||
public string TmpPath;
|
||||
|
||||
public string FoldersPath {
|
||||
get {
|
||||
if (GetConfigOption ("folders_path") != null)
|
||||
return GetConfigOption ("folders_path");
|
||||
else
|
||||
return Path.Combine (HomePath, "SparkleShare");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public SparkleConfig (string config_path, string config_file_name)
|
||||
{
|
||||
Path = System.IO.Path.Combine (config_path, config_file_name);
|
||||
FullPath = System.IO.Path.Combine (config_path, config_file_name);
|
||||
TmpPath = Path.Combine (FoldersPath, ".tmp");
|
||||
|
||||
if (!Directory.Exists (config_path)) {
|
||||
Directory.CreateDirectory (config_path);
|
||||
|
@ -48,10 +66,30 @@ namespace SparkleLib {
|
|||
SparkleHelpers.DebugInfo ("Config", "Created \"" + icons_path + "\"");
|
||||
}
|
||||
|
||||
if (!File.Exists (Path))
|
||||
try {
|
||||
Load (FullPath);
|
||||
|
||||
} catch (TypeInitializationException) {
|
||||
CreateInitialConfig ();
|
||||
|
||||
Load (Path);
|
||||
} catch (IOException) {
|
||||
CreateInitialConfig ();
|
||||
|
||||
} catch (XmlException) {
|
||||
|
||||
FileInfo file = new FileInfo (FullPath);
|
||||
|
||||
if (file.Length == 0) {
|
||||
File.Delete (FullPath);
|
||||
CreateInitialConfig ();
|
||||
|
||||
} else {
|
||||
throw new XmlException (FullPath + " does not contain a valid config XML structure.");
|
||||
}
|
||||
|
||||
} finally {
|
||||
Load (FullPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -59,20 +97,23 @@ namespace SparkleLib {
|
|||
{
|
||||
string user_name = "Unknown";
|
||||
|
||||
if (SparkleBackend.Platform == PlatformID.Unix ||
|
||||
SparkleBackend.Platform == PlatformID.MacOSX) {
|
||||
#if __MonoCS__
|
||||
user_name = new UnixUserInfo (UnixEnvironment.UserName).RealName;
|
||||
if (string.IsNullOrEmpty (user_name))
|
||||
user_name = UnixEnvironment.UserName;
|
||||
else
|
||||
user_name = user_name.TrimEnd (",".ToCharArray());
|
||||
#else
|
||||
user_name = Environment.UserName;
|
||||
#endif
|
||||
} else {
|
||||
user_name = Environment.UserName;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty (user_name))
|
||||
user_name = "Unknown";
|
||||
|
||||
TextWriter writer = new StreamWriter (Path);
|
||||
TextWriter writer = new StreamWriter (FullPath);
|
||||
string n = Environment.NewLine;
|
||||
|
||||
writer.Write ("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" + n +
|
||||
|
@ -84,36 +125,31 @@ namespace SparkleLib {
|
|||
"</sparkleshare>");
|
||||
writer.Close ();
|
||||
|
||||
SparkleHelpers.DebugInfo ("Config", "Created \"" + Path + "\"");
|
||||
SparkleHelpers.DebugInfo ("Config", "Created \"" + FullPath + "\"");
|
||||
}
|
||||
|
||||
|
||||
public string UserName {
|
||||
public SparkleUser User {
|
||||
get {
|
||||
XmlNode node = SelectSingleNode ("/sparkleshare/user/name/text()");
|
||||
return node.Value;
|
||||
XmlNode name_node = SelectSingleNode ("/sparkleshare/user/name/text()");
|
||||
string name = name_node.Value;
|
||||
|
||||
XmlNode email_node = SelectSingleNode ("/sparkleshare/user/email/text()");
|
||||
string email = email_node.Value;
|
||||
|
||||
return new SparkleUser (name, email);
|
||||
}
|
||||
|
||||
set {
|
||||
XmlNode node = SelectSingleNode ("/sparkleshare/user/name/text()");
|
||||
node.InnerText = value;
|
||||
SparkleUser user = (SparkleUser) value;
|
||||
|
||||
Save ();
|
||||
}
|
||||
}
|
||||
XmlNode name_node = SelectSingleNode ("/sparkleshare/user/name/text()");
|
||||
name_node.InnerText = user.Name;
|
||||
|
||||
XmlNode email_node = SelectSingleNode ("/sparkleshare/user/email/text()");
|
||||
email_node.InnerText = user.Email;
|
||||
|
||||
public string UserEmail {
|
||||
get {
|
||||
XmlNode node = SelectSingleNode ("/sparkleshare/user/email/text()");
|
||||
return node.Value;
|
||||
}
|
||||
|
||||
set {
|
||||
XmlNode node = SelectSingleNode ("/sparkleshare/user/email/text()");
|
||||
node.InnerText = value;
|
||||
|
||||
Save ();
|
||||
this.Save ();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -149,22 +185,7 @@ namespace SparkleLib {
|
|||
XmlNode node_root = SelectSingleNode ("/sparkleshare");
|
||||
node_root.AppendChild (node_folder);
|
||||
|
||||
Save ();
|
||||
}
|
||||
|
||||
public bool SetFolderOptionalAttribute (string name, string key, string value)
|
||||
{
|
||||
XmlNode folder = this.GetFolder(name);
|
||||
if (folder == null) return false;
|
||||
|
||||
if (folder[key] != null) {
|
||||
folder[key].InnerText = value;
|
||||
} else {
|
||||
XmlNode new_node = CreateElement(key);
|
||||
new_node.InnerText = value;
|
||||
folder.AppendChild(new_node);
|
||||
}
|
||||
return true;
|
||||
this.Save ();
|
||||
}
|
||||
|
||||
|
||||
|
@ -175,14 +196,14 @@ namespace SparkleLib {
|
|||
SelectSingleNode ("/sparkleshare").RemoveChild (node_folder);
|
||||
}
|
||||
|
||||
Save ();
|
||||
this.Save ();
|
||||
}
|
||||
|
||||
|
||||
public bool FolderExists (string name)
|
||||
{
|
||||
XmlNode folder = this.GetFolder (name);
|
||||
return folder != null;
|
||||
return (folder != null);
|
||||
}
|
||||
|
||||
|
||||
|
@ -198,12 +219,49 @@ namespace SparkleLib {
|
|||
}
|
||||
|
||||
|
||||
public bool SetFolderOptionalAttribute (string folder_name, string key, string value)
|
||||
{
|
||||
XmlNode folder = this.GetFolder (folder_name);
|
||||
|
||||
if (folder == null)
|
||||
return false;
|
||||
|
||||
if (folder [key] != null) {
|
||||
folder [key].InnerText = value;
|
||||
|
||||
} else {
|
||||
XmlNode new_node = CreateElement (key);
|
||||
new_node.InnerText = value;
|
||||
folder.AppendChild (new_node);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public string GetFolderOptionalAttribute (string folder_name, string key)
|
||||
{
|
||||
XmlNode folder = this.GetFolder (folder_name);
|
||||
|
||||
if (folder != null) {
|
||||
if (folder [key] != null)
|
||||
return folder [key].InnerText;
|
||||
else
|
||||
return null;
|
||||
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<string> Hosts {
|
||||
get {
|
||||
List<string> hosts = new List<string> ();
|
||||
|
||||
foreach (XmlNode node_folder in SelectNodes ("/sparkleshare/folder")) {
|
||||
Uri uri = new Uri (node_folder ["url"].InnerText);
|
||||
|
||||
if (!hosts.Contains (uri.Host))
|
||||
hosts.Add (uri.Host);
|
||||
}
|
||||
|
@ -213,21 +271,40 @@ namespace SparkleLib {
|
|||
}
|
||||
|
||||
|
||||
public string GetAnnouncementsForFolder (string name)
|
||||
{
|
||||
return this.GetFolderValue(name, "announcements");
|
||||
public List<string> HostsWithUsername {
|
||||
get {
|
||||
List<string> hosts = new List<string> ();
|
||||
|
||||
foreach (XmlNode node_folder in SelectNodes ("/sparkleshare/folder")) {
|
||||
Uri uri = new Uri (node_folder ["url"].InnerText);
|
||||
|
||||
if ("git" != uri.UserInfo && !hosts.Contains (uri.UserInfo + "@" + uri.Host))
|
||||
hosts.Add (uri.UserInfo + "@" + uri.Host);
|
||||
}
|
||||
|
||||
return hosts;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public string GetAnnouncementUrlForFolder (string name)
|
||||
private XmlNode GetFolder (string name)
|
||||
{
|
||||
// examples?
|
||||
// tcp://localhost:9999/
|
||||
// xmpp:someuser@somexmppserver?canhavefunnybits
|
||||
// irc://hbons/#somechatroom
|
||||
return this.GetFolderValue(name, "announcements_url");
|
||||
return SelectSingleNode (String.Format("/sparkleshare/folder[name='{0}']", name));
|
||||
}
|
||||
|
||||
|
||||
private string GetFolderValue (string name, string key)
|
||||
{
|
||||
XmlNode folder = this.GetFolder(name);
|
||||
|
||||
if ((folder != null) && (folder [key] != null)) {
|
||||
return folder [key].InnerText;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public string GetConfigOption (string name)
|
||||
{
|
||||
XmlNode node = SelectSingleNode ("/sparkleshare/" + name);
|
||||
|
@ -255,34 +332,17 @@ namespace SparkleLib {
|
|||
}
|
||||
|
||||
SparkleHelpers.DebugInfo ("Config", "Updated " + name + ":" + content);
|
||||
Save ();
|
||||
this.Save ();
|
||||
}
|
||||
|
||||
|
||||
public void Save ()
|
||||
private void Save ()
|
||||
{
|
||||
if (!File.Exists (Path))
|
||||
throw new ConfigFileNotFoundException (Path + " does not exist");
|
||||
if (!File.Exists (FullPath))
|
||||
throw new ConfigFileNotFoundException (FullPath + " does not exist");
|
||||
|
||||
Save (Path);
|
||||
SparkleHelpers.DebugInfo ("Config", "Updated \"" + Path + "\"");
|
||||
}
|
||||
|
||||
|
||||
private XmlNode GetFolder (string name)
|
||||
{
|
||||
return SelectSingleNode(String.Format("/sparkleshare/folder[name='{0}']", name));
|
||||
}
|
||||
|
||||
|
||||
private string GetFolderValue (string name, string key)
|
||||
{
|
||||
XmlNode folder = this.GetFolder(name);
|
||||
|
||||
if ((folder != null) && (folder[key] != null)) {
|
||||
return folder[key].InnerText;
|
||||
}
|
||||
return null;
|
||||
this.Save (FullPath);
|
||||
SparkleHelpers.DebugInfo ("Config", "Updated \"" + FullPath + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -293,3 +353,4 @@ namespace SparkleLib {
|
|||
base (message) { }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,16 +33,17 @@ namespace SparkleLib {
|
|||
public delegate void StartedEventHandler ();
|
||||
public delegate void FinishedEventHandler ();
|
||||
public delegate void FailedEventHandler ();
|
||||
public delegate void ProgressChangedEventHandler (double percentage);
|
||||
|
||||
public event StartedEventHandler Started;
|
||||
public event FinishedEventHandler Finished;
|
||||
public event FailedEventHandler Failed;
|
||||
public event ProgressChangedEventHandler ProgressChanged;
|
||||
|
||||
protected string target_folder;
|
||||
protected string remote_url;
|
||||
private Thread thread;
|
||||
|
||||
public abstract bool Fetch ();
|
||||
private Thread thread;
|
||||
|
||||
|
||||
public SparkleFetcherBase (string server, string remote_folder, string target_folder)
|
||||
|
@ -52,6 +53,9 @@ namespace SparkleLib {
|
|||
}
|
||||
|
||||
|
||||
public abstract bool Fetch ();
|
||||
|
||||
|
||||
// Clones the remote repository
|
||||
public void Start ()
|
||||
{
|
||||
|
@ -97,6 +101,13 @@ namespace SparkleLib {
|
|||
}
|
||||
|
||||
|
||||
public virtual void Stop ()
|
||||
{
|
||||
this.thread.Abort ();
|
||||
this.thread.Join ();
|
||||
}
|
||||
|
||||
|
||||
public string RemoteUrl {
|
||||
get {
|
||||
return this.remote_url;
|
||||
|
@ -113,9 +124,15 @@ namespace SparkleLib {
|
|||
}
|
||||
|
||||
|
||||
protected void OnProgressChanged (double percentage) {
|
||||
if (ProgressChanged != null)
|
||||
ProgressChanged (percentage);
|
||||
}
|
||||
|
||||
|
||||
private void DisableHostKeyCheckingForHost (string host)
|
||||
{
|
||||
string path = SparklePaths.HomePath;
|
||||
string path = SparkleConfig.DefaultConfig.HomePath;
|
||||
|
||||
if (!(SparkleBackend.Platform == PlatformID.Unix ||
|
||||
SparkleBackend.Platform == PlatformID.MacOSX)) {
|
||||
|
@ -154,7 +171,7 @@ namespace SparkleLib {
|
|||
|
||||
private void EnableHostKeyCheckingForHost (string host)
|
||||
{
|
||||
string path = SparklePaths.HomePath;
|
||||
string path = SparkleConfig.DefaultConfig.HomePath;
|
||||
|
||||
if (!(SparkleBackend.Platform == PlatformID.Unix ||
|
||||
SparkleBackend.Platform == PlatformID.MacOSX)) {
|
||||
|
|
|
@ -41,34 +41,43 @@ namespace SparkleLib {
|
|||
|
||||
public static SparkleListenerBase CreateListener (string folder_name, string folder_identifier)
|
||||
{
|
||||
string announce_uri = SparkleConfig.DefaultConfig.GetAnnouncementUrlForFolder (folder_name);
|
||||
string uri = SparkleConfig.DefaultConfig.GetFolderOptionalAttribute (
|
||||
folder_name, "announcements_url");
|
||||
|
||||
if (announce_uri == null) {
|
||||
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
|
||||
|
||||
announce_uri = "irc://204.62.14.135/";
|
||||
uri = "tcp://204.62.14.135:1986"; // TODO: announcements.sparkleshare.org
|
||||
}
|
||||
|
||||
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);
|
||||
SparkleHelpers.DebugInfo ("ListenerFactory",
|
||||
"Refered to existing listener for " + announce_uri);
|
||||
|
||||
listener.AlsoListenTo (folder_identifier);
|
||||
return (SparkleListenerBase) listener;
|
||||
}
|
||||
}
|
||||
|
||||
Uri listen_on = new Uri (announce_uri);
|
||||
|
||||
switch (listen_on.Scheme) {
|
||||
// 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 (listen_on, folder_identifier));
|
||||
listeners.Add (new SparkleListenerTcp (announce_uri, folder_identifier));
|
||||
break;
|
||||
case "irc":
|
||||
listeners.Add (new SparkleListenerIrc (announce_uri, folder_identifier));
|
||||
break;
|
||||
default:
|
||||
listeners.Add (new SparkleListenerIrc (listen_on, folder_identifier));
|
||||
listeners.Add (new SparkleListenerTcp (announce_uri, folder_identifier));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -109,20 +118,25 @@ namespace SparkleLib {
|
|||
protected Uri server;
|
||||
protected 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;
|
||||
|
||||
this.reconnect_timer.Elapsed += delegate {
|
||||
if (!IsConnected && !this.is_connecting)
|
||||
Reconnect ();
|
||||
};
|
||||
|
||||
this.server = server;
|
||||
this.reconnect_timer.Start ();
|
||||
}
|
||||
|
||||
|
||||
public void AnnounceBase (SparkleAnnouncement announcement) {
|
||||
public void AnnounceBase (SparkleAnnouncement announcement)
|
||||
{
|
||||
if (IsConnected) {
|
||||
SparkleHelpers.DebugInfo ("Listener", "Announcing to " + announcement.FolderIdentifier + " on " + this.server);
|
||||
SparkleHelpers.DebugInfo ("Listener",
|
||||
"Announcing to " + announcement.FolderIdentifier + " on " + this.server);
|
||||
|
||||
Announce (announcement);
|
||||
|
||||
} else {
|
||||
|
@ -161,6 +175,7 @@ namespace SparkleLib {
|
|||
|
||||
if (this.queue_up.Count > 0) {
|
||||
SparkleHelpers.DebugInfo ("Listener", "Delivering queued messages...");
|
||||
|
||||
foreach (SparkleAnnouncement announcement in this.queue_up) {
|
||||
AnnounceBase (announcement);
|
||||
this.queue_up.Remove (announcement);
|
||||
|
@ -171,7 +186,7 @@ namespace SparkleLib {
|
|||
|
||||
public void OnDisconnected ()
|
||||
{
|
||||
SparkleHelpers.DebugInfo ("Listener", "Disonnected");
|
||||
SparkleHelpers.DebugInfo ("Listener", "Disonnected from " + Server);
|
||||
|
||||
if (Disconnected != null)
|
||||
Disconnected ();
|
||||
|
|
|
@ -48,6 +48,20 @@ namespace SparkleLib {
|
|||
PingInterval = 60
|
||||
};
|
||||
|
||||
string proxy = Environment.GetEnvironmentVariable ("http_proxy");
|
||||
Uri proxy_uri = null;
|
||||
if (!String.IsNullOrEmpty (proxy) &&
|
||||
Uri.TryCreate (proxy, UriKind.Absolute, out proxy_uri)) {
|
||||
|
||||
#if __MonoCS__
|
||||
if (proxy_uri.Scheme == "http") {
|
||||
this.client.ProxyType = ProxyType.Http;
|
||||
this.client.ProxyHost = proxy_uri.Host;
|
||||
this.client.ProxyPort = proxy_uri.Port;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
this.client.OnConnected += delegate {
|
||||
base.is_connecting = false;
|
||||
OnConnected ();
|
||||
|
@ -92,11 +106,12 @@ namespace SparkleLib {
|
|||
int port = base.server.Port;
|
||||
if (port < 0) port = 6667;
|
||||
this.client.Connect (base.server.Host, port);
|
||||
this.client.Login (this.nick, this.nick);
|
||||
this.client.Login (this.nick, this.nick, 8, this.nick);
|
||||
|
||||
foreach (string channel in base.channels) {
|
||||
SparkleHelpers.DebugInfo ("ListenerIrc", "Joining channel " + channel);
|
||||
this.client.RfcJoin (channel);
|
||||
this.client.RfcMode (channel, "+s");
|
||||
}
|
||||
|
||||
// List to the channel, this blocks the thread
|
||||
|
@ -124,6 +139,7 @@ namespace SparkleLib {
|
|||
if (IsConnected) {
|
||||
SparkleHelpers.DebugInfo ("ListenerIrc", "Joining channel " + channel);
|
||||
this.client.RfcJoin (channel);
|
||||
this.client.RfcMode (channel, "+s");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,11 +46,12 @@ namespace SparkleLib {
|
|||
|
||||
public override bool IsConnected {
|
||||
get {
|
||||
//return this.client.IsConnected;
|
||||
bool result = false;
|
||||
|
||||
lock (this.mutex) {
|
||||
result = this.connected;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -70,40 +71,46 @@ namespace SparkleLib {
|
|||
int port = Server.Port;
|
||||
if (port < 0) port = 9999;
|
||||
this.socket.Connect (Server.Host, port);
|
||||
|
||||
lock (this.mutex) {
|
||||
base.is_connecting = false;
|
||||
this.connected = true;
|
||||
|
||||
OnConnected ();
|
||||
|
||||
foreach (string channel in base.channels) {
|
||||
SparkleHelpers.DebugInfo ("ListenerTcp", "Subscribing to channel " + channel);
|
||||
this.socket.Send (Encoding.UTF8.GetBytes ("subscribe " + channel + "\n"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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 folder_identifier = received.Substring (0, received.IndexOf ("!"));
|
||||
string message = received.Substring (received.IndexOf ("!") + 1);
|
||||
|
||||
OnAnnouncement (new SparkleAnnouncement (folder_identifier, message));
|
||||
|
||||
} else {
|
||||
SparkleHelpers.DebugInfo ("ListenerTcp", "Error on socket");
|
||||
|
||||
lock (this.mutex) {
|
||||
this.socket.Close ();
|
||||
this.connected = false;
|
||||
|
||||
OnDisconnected ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SparkleHelpers.DebugInfo ("ListenerTcp", "Disconnected from " + Server.Host);
|
||||
|
||||
// TODO: attempt to reconnect..?
|
||||
} catch (SocketException e) {
|
||||
SparkleHelpers.DebugInfo ("ListenerTcp", "Could not connect to " + Server + ": " + e.Message);
|
||||
}
|
||||
|
|
|
@ -67,9 +67,12 @@ namespace SparkleLib {
|
|||
public delegate void SyncStatusChangedEventHandler (SyncStatus new_status);
|
||||
public event SyncStatusChangedEventHandler SyncStatusChanged;
|
||||
|
||||
public delegate void NewChangeSetEventHandler (SparkleChangeSet change_set, string source_path);
|
||||
public delegate void NewChangeSetEventHandler (SparkleChangeSet change_set);
|
||||
public event NewChangeSetEventHandler NewChangeSet;
|
||||
|
||||
public delegate void NewNoteEventHandler (string user_name, string user_email);
|
||||
public event NewNoteEventHandler NewNote;
|
||||
|
||||
public delegate void ConflictResolvedEventHandler ();
|
||||
public event ConflictResolvedEventHandler ConflictResolved;
|
||||
|
||||
|
@ -253,6 +256,8 @@ namespace SparkleLib {
|
|||
this.listener.Announcement += delegate (SparkleAnnouncement announcement) {
|
||||
string identifier = Identifier;
|
||||
|
||||
Console.WriteLine (announcement.Message + " ! " + CurrentRevision);
|
||||
|
||||
if (announcement.FolderIdentifier == identifier &&
|
||||
!announcement.Message.Equals (CurrentRevision)) {
|
||||
if ((Status != SyncStatus.SyncUp) &&
|
||||
|
@ -276,7 +281,6 @@ namespace SparkleLib {
|
|||
{
|
||||
lock (this.change_lock) {
|
||||
if (this.has_changed) {
|
||||
Console.WriteLine ("checking...");
|
||||
if (this.sizebuffer.Count >= 4)
|
||||
this.sizebuffer.RemoveAt (0);
|
||||
|
||||
|
@ -363,8 +367,8 @@ namespace SparkleLib {
|
|||
|
||||
if (match_notes.Success) {
|
||||
SparkleNote note = new SparkleNote () {
|
||||
UserName = match_notes.Groups [1].Value,
|
||||
UserEmail = match_notes.Groups [2].Value,
|
||||
User = new SparkleUser (match_notes.Groups [1].Value,
|
||||
match_notes.Groups [2].Value),
|
||||
Timestamp = new DateTime (1970, 1, 1).AddSeconds (int.Parse (match_notes.Groups [3].Value)),
|
||||
Body = match_notes.Groups [4].Value
|
||||
};
|
||||
|
@ -446,13 +450,26 @@ namespace SparkleLib {
|
|||
if (change_sets != null && change_sets.Count > 0) {
|
||||
SparkleChangeSet change_set = change_sets [0];
|
||||
|
||||
if (NewChangeSet != null)
|
||||
NewChangeSet (change_set, LocalPath);
|
||||
bool note_added = false;
|
||||
foreach (string added in change_set.Added) {
|
||||
if (added.Contains (".notes")) {
|
||||
if (NewNote != null)
|
||||
NewNote (change_set.User.Name, change_set.User.Email);
|
||||
|
||||
note_added = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// There could be changes from a
|
||||
// resolved conflict. Tries only once,
|
||||
//then let the timer try again periodicallly
|
||||
if (!note_added) {
|
||||
if (NewChangeSet != null)
|
||||
NewChangeSet (change_set);
|
||||
}
|
||||
}
|
||||
|
||||
// There could be changes from a resolved
|
||||
// conflict. Tries only once, then lets
|
||||
// the timer try again periodically
|
||||
if (HasUnsyncedChanges)
|
||||
SyncUp ();
|
||||
|
||||
|
@ -510,8 +527,8 @@ namespace SparkleLib {
|
|||
string n = Environment.NewLine;
|
||||
note = "<note>" + n +
|
||||
" <user>" + n +
|
||||
" <name>" + SparkleConfig.DefaultConfig.UserName + "</name>" + n +
|
||||
" <email>" + SparkleConfig.DefaultConfig.UserEmail + "</email>" + n +
|
||||
" <name>" + SparkleConfig.DefaultConfig.User.Name + "</name>" + n +
|
||||
" <email>" + SparkleConfig.DefaultConfig.User.Email + "</email>" + n +
|
||||
" </user>" + n +
|
||||
" <timestamp>" + timestamp + "</timestamp>" + n +
|
||||
" <body>" + note + "</body>" + n +
|
||||
|
|
|
@ -79,16 +79,12 @@
|
|||
<Compile Include="..\Hg\SparkleRepoHg.cs">
|
||||
<Link>SparkleRepoHg.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Scp\SparkleFetcherScp.cs">
|
||||
<Link>SparkleFetcherScp.cs</Link>
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="..\Scp\SparkleRepoScp.cs">
|
||||
<Link>SparkleRepoScp.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\SparkleConfig.cs">
|
||||
<Link>SparkleConfig.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\SparklePaths.cs">
|
||||
<Link>SparklePaths.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\SparkleRepoBase.cs">
|
||||
<Link>SparkleRepoBase.cs</Link>
|
||||
</Compile>
|
||||
|
@ -105,7 +101,6 @@
|
|||
</Compile>
|
||||
<Compile Include="..\SparkleFetcherBase.cs" />
|
||||
<Compile Include="..\SparkleHelpers.cs" />
|
||||
<Compile Include="..\SparklePaths.cs" />
|
||||
<Compile Include="..\SparkleOptions.cs" />
|
||||
<Compile Include="..\SparkleChangeSet.cs" />
|
||||
<Compile Include="..\SparkleListenerBase.cs" />
|
||||
|
|
|
@ -12,19 +12,20 @@ BUILD_DEFINES="-define:HAVE_APP_INDICATOR"
|
|||
endif
|
||||
|
||||
SOURCES = \
|
||||
Program.cs \
|
||||
SparkleAbout.cs \
|
||||
SparkleAboutController.cs \
|
||||
SparkleBubbles.cs \
|
||||
SparkleBubblesController.cs \
|
||||
SparkleController.cs \
|
||||
SparkleControllerBase.cs \
|
||||
SparkleEntry.cs \
|
||||
SparkleEventLog.cs \
|
||||
SparkleEventLogController.cs \
|
||||
SparkleLinController.cs \
|
||||
SparkleExtensions.cs \
|
||||
SparkleSetup.cs \
|
||||
SparkleSetupController.cs \
|
||||
SparkleSetupWindow.cs \
|
||||
SparkleShare.cs \
|
||||
SparkleSpinner.cs \
|
||||
SparkleStatusIcon.cs \
|
||||
SparkleStatusIconController.cs \
|
||||
|
@ -40,7 +41,7 @@ SOURCES = \
|
|||
SparkleSetup.cs \
|
||||
SparkleSetupController.cs \
|
||||
SparkleSetupWindow.cs \
|
||||
SparkleShare.cs \
|
||||
Program.cs \
|
||||
SparkleSpinner.cs \
|
||||
SparkleStatusIcon.cs \
|
||||
SparkleStatusIconController.cs \
|
||||
|
|
131
SparkleShare/Program.cs
Normal file
131
SparkleShare/Program.cs
Normal file
|
@ -0,0 +1,131 @@
|
|||
// 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;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
using Mono.Unix;
|
||||
//using Mono.Unix.Native;
|
||||
using SparkleLib;
|
||||
using SparkleLib.Options;
|
||||
|
||||
namespace SparkleShare {
|
||||
|
||||
// This is SparkleShare!
|
||||
public class Program {
|
||||
|
||||
public static SparkleController Controller;
|
||||
public static SparkleUI UI;
|
||||
|
||||
|
||||
// Short alias for the translations
|
||||
public static string _ (string s)
|
||||
{
|
||||
return Catalog.GetString (s);
|
||||
}
|
||||
|
||||
|
||||
public static void Main (string [] args)
|
||||
{
|
||||
// Parse the command line options
|
||||
bool show_help = false;
|
||||
OptionSet option_set = new OptionSet () {
|
||||
{ "v|version", _("Print version information"), v => { PrintVersion (); } },
|
||||
{ "h|help", _("Show this help text"), v => show_help = v != null }
|
||||
};
|
||||
|
||||
try {
|
||||
option_set.Parse (args);
|
||||
|
||||
} catch (OptionException e) {
|
||||
Console.Write ("SparkleShare: ");
|
||||
Console.WriteLine (e.Message);
|
||||
Console.WriteLine ("Try `sparkleshare --help' for more information.");
|
||||
}
|
||||
|
||||
if (show_help)
|
||||
ShowHelp (option_set);
|
||||
|
||||
|
||||
// Initialize the controller this way so that
|
||||
// there aren't any exceptions in the OS specific UI's
|
||||
Controller = new SparkleController ();
|
||||
Controller.Initialize ();
|
||||
|
||||
if (Controller != null) {
|
||||
UI = new SparkleUI ();
|
||||
UI.Run ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Prints the help output
|
||||
public static void ShowHelp (OptionSet option_set)
|
||||
{
|
||||
Console.WriteLine (" ");
|
||||
Console.WriteLine (_("SparkleShare, a collaboration and sharing tool."));
|
||||
Console.WriteLine (_("Copyright (C) 2010 Hylke Bons"));
|
||||
Console.WriteLine (" ");
|
||||
Console.WriteLine (_("This program comes with ABSOLUTELY NO WARRANTY."));
|
||||
Console.WriteLine (" ");
|
||||
Console.WriteLine (_("This is free software, and you are welcome to redistribute it "));
|
||||
Console.WriteLine (_("under certain conditions. Please read the GNU GPLv3 for details."));
|
||||
Console.WriteLine (" ");
|
||||
Console.WriteLine (_("SparkleShare automatically syncs Git repositories in "));
|
||||
Console.WriteLine (_("the ~/SparkleShare folder with their remote origins."));
|
||||
Console.WriteLine (" ");
|
||||
Console.WriteLine (_("Usage: sparkleshare [start|stop|restart] [OPTION]..."));
|
||||
Console.WriteLine (_("Sync SparkleShare folder with remote repositories."));
|
||||
Console.WriteLine (" ");
|
||||
Console.WriteLine (_("Arguments:"));
|
||||
|
||||
option_set.WriteOptionDescriptions (Console.Out);
|
||||
Environment.Exit (0);
|
||||
}
|
||||
|
||||
|
||||
// Prints the version information
|
||||
public static void PrintVersion ()
|
||||
{
|
||||
Console.WriteLine (_("SparkleShare " + Defines.VERSION));
|
||||
Environment.Exit (0);
|
||||
}
|
||||
|
||||
|
||||
// Strange magic needed by SetProcessName ()
|
||||
[DllImport ("libc")]
|
||||
private static extern int prctl (int option, byte [] arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5);
|
||||
|
||||
|
||||
// Sets the Unix process name to 'sparkleshare' instead of 'mono'
|
||||
private static void SetProcessName (string name)
|
||||
{
|
||||
try {
|
||||
if (prctl (15, Encoding.ASCII.GetBytes (name + "\0"), IntPtr.Zero, IntPtr.Zero, IntPtr.Zero) != 0)
|
||||
throw new ApplicationException ("Error setting process name: " +
|
||||
Mono.Unix.Native.Stdlib.GetLastError ());
|
||||
|
||||
} catch (EntryPointNotFoundException) {
|
||||
Console.WriteLine ("SetProcessName: Entry point not found");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,20 +21,20 @@ using System.IO;
|
|||
using System.Net;
|
||||
|
||||
using Gtk;
|
||||
using Mono.Unix;
|
||||
|
||||
namespace SparkleShare {
|
||||
|
||||
public class SparkleAbout : Window {
|
||||
|
||||
public SparkleAboutController Controller = new SparkleAboutController ();
|
||||
|
||||
public SparkleAboutController Controller;
|
||||
private Label updates;
|
||||
|
||||
|
||||
// Short alias for the translations
|
||||
public static string _(string s)
|
||||
{
|
||||
return s;
|
||||
return Catalog.GetString (s);
|
||||
}
|
||||
|
||||
|
||||
|
@ -53,21 +53,22 @@ namespace SparkleShare {
|
|||
Title = _("About SparkleShare");
|
||||
AppPaintable = true;
|
||||
|
||||
MemoryStream MemStream = new MemoryStream();
|
||||
Icons.about.Save(MemStream, System.Drawing.Imaging.ImageFormat.Png);
|
||||
MemStream.Seek(0, SeekOrigin.Begin);
|
||||
string image_path = new string [] {SparkleUI.AssetsPath,
|
||||
"pixmaps", "about.png"}.Combine ();
|
||||
|
||||
Realize ();
|
||||
Gdk.Pixbuf buf = new Gdk.Pixbuf(MemStream);
|
||||
Gdk.Pixbuf buf = new Gdk.Pixbuf (image_path);
|
||||
Gdk.Pixmap map, map2;
|
||||
buf.RenderPixmapAndMask (out map, out map2, 255);
|
||||
GdkWindow.SetBackPixmap (map, false);
|
||||
|
||||
CreateAbout ();
|
||||
Controller = new SparkleAboutController ();
|
||||
|
||||
Controller.NewVersionEvent += delegate (string new_version) {
|
||||
Application.Invoke (delegate {
|
||||
this.updates.Markup = String.Format ("<span font_size='small' fgcolor='#f57900'>{0}</span>",
|
||||
String.Format (_("A newer version ({0}) is available!"), new_version));
|
||||
|
||||
this.updates.ShowAll ();
|
||||
});
|
||||
};
|
||||
|
@ -76,6 +77,7 @@ namespace SparkleShare {
|
|||
Application.Invoke (delegate {
|
||||
this.updates.Markup = String.Format ("<span font_size='small' fgcolor='#4e9a06'>{0}</span>",
|
||||
_("You are running the latest version."));
|
||||
|
||||
this.updates.ShowAll ();
|
||||
});
|
||||
};
|
||||
|
@ -84,9 +86,12 @@ namespace SparkleShare {
|
|||
Application.Invoke (delegate {
|
||||
this.updates.Markup = String.Format ("<span font_size='small' fgcolor='#4e9a06'>{0}</span>",
|
||||
_("Checking for updates..."));
|
||||
|
||||
this.updates.ShowAll ();
|
||||
});
|
||||
};
|
||||
|
||||
this.CreateAbout ();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -68,9 +68,9 @@ namespace SparkleShare {
|
|||
Uri uri = new Uri ("http://www.sparkleshare.org/version");
|
||||
|
||||
web_client.DownloadStringCompleted += delegate (object o, DownloadStringCompletedEventArgs args) {
|
||||
if (args.Error != null) {
|
||||
Console.WriteLine ("Error during version check: {0}", args.Error.Message);
|
||||
} else {
|
||||
if (args.Error != null)
|
||||
return;
|
||||
|
||||
string new_version = args.Result.Trim ();
|
||||
|
||||
// Add a little delay, making it seems we're
|
||||
|
@ -85,7 +85,7 @@ namespace SparkleShare {
|
|||
if (NewVersionEvent != null)
|
||||
NewVersionEvent (new_version);
|
||||
}
|
||||
}
|
||||
|
||||
this.version_checker.Start ();
|
||||
};
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace SparkleShare {
|
|||
public SparkleBubbles ()
|
||||
{
|
||||
Controller.ShowBubbleEvent += delegate (string title, string subtext, string image_path) {
|
||||
try {
|
||||
Notification notification = new Notification () {
|
||||
Timeout = 5 * 1000,
|
||||
Urgency = Urgency.Low
|
||||
|
@ -41,16 +42,12 @@ namespace SparkleShare {
|
|||
notification.IconName = "folder-sparkleshare";
|
||||
|
||||
notification.Show ();
|
||||
|
||||
} catch (Exception) {
|
||||
// Ignore exceptions thrown by libnotify,
|
||||
// they're not important enough to crash
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// Checks whether the system allows adding buttons to a notification,
|
||||
// prevents error messages in Ubuntu.
|
||||
// new public void AddAction (string action, string label, ActionHandler handler)
|
||||
// {
|
||||
// if (Array.IndexOf (Notifications.Global.Capabilities, "actions") > -1)
|
||||
// base.AddAction (action, label, handler);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,19 +27,24 @@ namespace SparkleShare {
|
|||
|
||||
public SparkleBubblesController ()
|
||||
{
|
||||
SparkleShare.Controller.ConflictNotificationRaised += delegate {
|
||||
if (ShowBubbleEvent != null && SparkleShare.Controller.NotificationsEnabled)
|
||||
ShowBubbleEvent ("Ouch! Mid-air collision!",
|
||||
"Don't worry, SparkleShare made a copy of each conflicting file.", null);
|
||||
Program.Controller.ConflictNotificationRaised += delegate {
|
||||
ShowBubble ("Ouch! Mid-air collision!",
|
||||
"Don't worry, SparkleShare made a copy of each conflicting file.",
|
||||
null);
|
||||
};
|
||||
|
||||
SparkleShare.Controller.NotificationRaised += delegate (string user_name, string user_email,
|
||||
Program.Controller.NotificationRaised += delegate (string user_name, string user_email,
|
||||
string message, string folder_path) {
|
||||
|
||||
if (ShowBubbleEvent != null && SparkleShare.Controller.NotificationsEnabled)
|
||||
ShowBubbleEvent (user_name, message,
|
||||
SparkleShare.Controller.GetAvatar (user_email, 36));
|
||||
ShowBubble (user_name, message,
|
||||
Program.Controller.GetAvatar (user_email, 36));
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public void ShowBubble (string title, string subtext, string image_path)
|
||||
{
|
||||
if (ShowBubbleEvent != null && Program.Controller.NotificationsEnabled)
|
||||
ShowBubbleEvent (title, subtext, image_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
1183
SparkleShare/SparkleControllerBase.cs
Normal file
1183
SparkleShare/SparkleControllerBase.cs
Normal file
File diff suppressed because it is too large
Load diff
|
@ -23,24 +23,21 @@ using System.Threading;
|
|||
|
||||
using Gtk;
|
||||
using Mono.Unix;
|
||||
using SparkleLib;
|
||||
using WebKit;
|
||||
|
||||
namespace SparkleShare {
|
||||
|
||||
public class SparkleEventLog : Window {
|
||||
|
||||
private ScrolledWindow ScrolledWindow;
|
||||
private MenuBar MenuBar;
|
||||
private WebView WebView;
|
||||
private string LinkStatus;
|
||||
private SparkleSpinner Spinner;
|
||||
private string HTML;
|
||||
private EventBox LogContent;
|
||||
private List<SparkleChangeSet> change_sets;
|
||||
private string selected_log = null;
|
||||
private ComboBox combo_box;
|
||||
public SparkleEventLogController Controller = new SparkleEventLogController ();
|
||||
|
||||
private HBox layout_horizontal;
|
||||
private ComboBox combo_box;
|
||||
private EventBox content_wrapper;
|
||||
private ScrolledWindow scrolled_window;
|
||||
private WebView web_view;
|
||||
private SparkleSpinner spinner;
|
||||
private string link_status;
|
||||
|
||||
|
||||
// Short alias for the translations
|
||||
|
@ -63,45 +60,39 @@ namespace SparkleShare {
|
|||
|
||||
DeleteEvent += Close;
|
||||
|
||||
CreateEvents ();
|
||||
UpdateEvents (false);
|
||||
UpdateChooser ();
|
||||
}
|
||||
|
||||
|
||||
private void CreateEvents ()
|
||||
{
|
||||
VBox layout_vertical = new VBox (false, 0);
|
||||
LogContent = new EventBox ();
|
||||
this.spinner = new SparkleSpinner (22);
|
||||
this.content_wrapper = new EventBox ();
|
||||
this.scrolled_window = new ScrolledWindow ();
|
||||
|
||||
ScrolledWindow = new ScrolledWindow ();
|
||||
|
||||
WebView = new WebView () {
|
||||
this.web_view = new WebView () {
|
||||
Editable = false
|
||||
};
|
||||
|
||||
WebView.HoveringOverLink += delegate (object o, WebKit.HoveringOverLinkArgs args) {
|
||||
LinkStatus = args.Link;
|
||||
this.web_view.HoveringOverLink += delegate (object o, WebKit.HoveringOverLinkArgs args) {
|
||||
this.link_status = args.Link;
|
||||
};
|
||||
|
||||
WebView.NavigationRequested += delegate (object o, WebKit.NavigationRequestedArgs args) {
|
||||
if (args.Request.Uri == LinkStatus) {
|
||||
this.web_view.NavigationRequested += delegate (object o, WebKit.NavigationRequestedArgs args) {
|
||||
if (args.Request.Uri == this.link_status) {
|
||||
// TODO: controller
|
||||
Process process = new Process ();
|
||||
process.StartInfo.FileName = "xdg-open";
|
||||
process.StartInfo.Arguments = args.Request.Uri.Replace (" ", "\\ "); // Escape space-characters
|
||||
process.Start ();
|
||||
|
||||
} else {
|
||||
//TODO: controller
|
||||
Regex regex = new Regex (@"(.+)~(.+)~(.+)");
|
||||
Match match = regex.Match (args.Request.Uri);
|
||||
|
||||
if (match.Success) {
|
||||
string folder_name = match.Groups [1].Value;
|
||||
string revision = match.Groups [2].Value;
|
||||
string note = match.Groups [3].Value.Replace ("%20", " ");
|
||||
string note = match.Groups [3].Value;
|
||||
|
||||
Thread thread = new Thread (new ThreadStart (delegate {
|
||||
SparkleShare.Controller.AddNoteToFolder (folder_name, revision, note);
|
||||
Program.Controller.AddNoteToFolder (folder_name, revision, note);
|
||||
}));
|
||||
|
||||
thread.Start ();
|
||||
|
@ -113,44 +104,75 @@ namespace SparkleShare {
|
|||
args.RetVal = 1;
|
||||
};
|
||||
|
||||
ScrolledWindow.Add (WebView);
|
||||
LogContent.Add (ScrolledWindow);
|
||||
this.scrolled_window.Add (this.web_view);
|
||||
this.content_wrapper.Add (this.spinner);
|
||||
|
||||
this.spinner.Start ();
|
||||
|
||||
this.layout_horizontal = new HBox (true, 0);
|
||||
this.layout_horizontal.PackStart (new Label (""), true, true, 0);
|
||||
this.layout_horizontal.PackStart (new Label (""), true, true, 0);
|
||||
|
||||
layout_vertical.PackStart (layout_horizontal, false, false, 0);
|
||||
layout_vertical.PackStart (LogContent, true, true, 0);
|
||||
|
||||
// We have to hide the menubar somewhere...
|
||||
layout_vertical.PackStart (this.layout_horizontal, false, false, 0);
|
||||
layout_vertical.PackStart (CreateShortcutsBar (), false, false, 0);
|
||||
layout_vertical.PackStart (this.content_wrapper, true, true, 0);
|
||||
|
||||
Add (layout_vertical);
|
||||
ShowAll ();
|
||||
|
||||
UpdateChooser (null);
|
||||
UpdateContent (null);
|
||||
|
||||
|
||||
// Hook up the controller events
|
||||
Controller.UpdateChooserEvent += delegate (string [] folders) {
|
||||
Application.Invoke (delegate {
|
||||
UpdateChooser (folders);
|
||||
});
|
||||
};
|
||||
|
||||
Controller.UpdateContentEvent += delegate (string html) {
|
||||
Application.Invoke (delegate {
|
||||
UpdateContent (html);
|
||||
});
|
||||
};
|
||||
|
||||
Controller.ContentLoadingEvent += delegate {
|
||||
Application.Invoke (delegate {
|
||||
if (this.content_wrapper.Child != null)
|
||||
this.content_wrapper.Remove (this.content_wrapper.Child);
|
||||
|
||||
this.content_wrapper.Add (this.spinner);
|
||||
this.spinner.Start ();
|
||||
this.content_wrapper.ShowAll ();
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public void UpdateChooser ()
|
||||
public void UpdateChooser (string [] folders)
|
||||
{
|
||||
if (folders == null)
|
||||
folders = Controller.Folders;
|
||||
|
||||
if (this.combo_box != null && this.combo_box.Parent != null)
|
||||
this.layout_horizontal.Remove (this.combo_box);
|
||||
|
||||
this.combo_box = new ComboBox ();
|
||||
this.layout_horizontal.BorderWidth = 9;
|
||||
|
||||
CellRendererText cell = new CellRendererText();
|
||||
this.combo_box.PackStart (cell, false);
|
||||
this.combo_box.AddAttribute (cell, "text", 0);
|
||||
|
||||
ListStore store = new ListStore (typeof (string));
|
||||
this.combo_box.Model = store;
|
||||
|
||||
store.AppendValues (_("All Folders"));
|
||||
store.AppendValues ("---");
|
||||
|
||||
foreach (string folder_name in SparkleShare.Controller.Folders)
|
||||
store.AppendValues (folder_name);
|
||||
foreach (string folder in folders)
|
||||
store.AppendValues (folder);
|
||||
|
||||
this.combo_box.Model = store;
|
||||
this.combo_box.Active = 0;
|
||||
|
||||
this.combo_box.RowSeparatorFunc = delegate (TreeModel model, TreeIter iter) {
|
||||
|
@ -158,116 +180,75 @@ namespace SparkleShare {
|
|||
return (item == "---");
|
||||
};
|
||||
|
||||
if (this.selected_log != null &&
|
||||
!SparkleShare.Controller.Folders.Contains (this.selected_log)) {
|
||||
|
||||
this.selected_log = null;
|
||||
}
|
||||
|
||||
this.combo_box.Changed += delegate {
|
||||
TreeIter iter;
|
||||
this.combo_box.GetActiveIter (out iter);
|
||||
|
||||
string selection = (string) this.combo_box.Model.GetValue (iter, 0);
|
||||
|
||||
if (selection.Equals (_("All Folders")))
|
||||
this.selected_log = null;
|
||||
Controller.SelectedFolder = null;
|
||||
else
|
||||
this.selected_log = selection;
|
||||
|
||||
UpdateEvents (false);
|
||||
Controller.SelectedFolder = selection;
|
||||
};
|
||||
|
||||
this.layout_horizontal.BorderWidth = 9;
|
||||
this.layout_horizontal.PackStart (this.combo_box, true, true, 0);
|
||||
this.layout_horizontal.ShowAll ();
|
||||
}
|
||||
|
||||
|
||||
public void UpdateEvents ()
|
||||
public void UpdateContent (string html)
|
||||
{
|
||||
UpdateEvents (true);
|
||||
}
|
||||
|
||||
|
||||
public void UpdateEvents (bool silent)
|
||||
{
|
||||
if (!silent) {
|
||||
LogContent.Remove (LogContent.Child);
|
||||
Spinner = new SparkleSpinner (22);
|
||||
LogContent.Add (Spinner);
|
||||
LogContent.ShowAll ();
|
||||
}
|
||||
|
||||
Thread thread = new Thread (new ThreadStart (delegate {
|
||||
Stopwatch watch = new Stopwatch ();
|
||||
watch.Start ();
|
||||
this.change_sets = SparkleShare.Controller.GetLog (this.selected_log);
|
||||
GenerateHTML ();
|
||||
watch.Stop ();
|
||||
if (html == null)
|
||||
html = Controller.HTML;
|
||||
|
||||
// A short delay is less annoying than
|
||||
// a flashing window
|
||||
if (watch.ElapsedMilliseconds < 500 && !silent)
|
||||
Thread.Sleep (500 - (int) watch.ElapsedMilliseconds);
|
||||
if (html == null)
|
||||
return;
|
||||
|
||||
AddHTML ();
|
||||
html = html.Replace ("<!-- $body-font-size -->", (double) (Style.FontDescription.Size / 1024 + 3) + "px");
|
||||
html = html.Replace ("<!-- $day-entry-header-font-size -->", (Style.FontDescription.Size / 1024 + 3) + "px");
|
||||
html = html.Replace ("<!-- $a-color -->", "#0085cf");
|
||||
html = html.Replace ("<!-- $a-hover-color -->", "#009ff8");
|
||||
html = html.Replace ("<!-- $body-font-family -->", "\"" + Style.FontDescription.Family + "\"");
|
||||
html = html.Replace ("<!-- $body-color -->", SparkleUIHelpers.GdkColorToHex (Style.Foreground (StateType.Normal)));
|
||||
html = html.Replace ("<!-- $body-background-color -->", SparkleUIHelpers.GdkColorToHex (new TreeView ().Style.Base (StateType.Normal)));
|
||||
html = html.Replace ("<!-- $day-entry-header-background-color -->", SparkleUIHelpers.GdkColorToHex (Style.Background (StateType.Normal)));
|
||||
html = html.Replace ("<!-- $secondary-font-color -->", SparkleUIHelpers.GdkColorToHex (Style.Foreground (StateType.Insensitive)));
|
||||
html = html.Replace ("<!-- $small-color -->", SparkleUIHelpers.GdkColorToHex (Style.Foreground (StateType.Insensitive)));
|
||||
html = html.Replace ("<!-- $no-buddy-icon-background-image -->", "file://" +
|
||||
new string [] {SparkleUI.AssetsPath, "icons",
|
||||
"hicolor", "32x32", "status", "avatar-default.png"}.Combine ());
|
||||
html = html.Replace ("<!-- $document-added-background-image -->", "file://" +
|
||||
new string [] {SparkleUI.AssetsPath, "icons",
|
||||
"hicolor", "12x12", "status", "document-added.png"}.Combine ());
|
||||
html = html.Replace ("<!-- $document-edited-background-image -->", "file://" +
|
||||
new string [] {SparkleUI.AssetsPath, "icons",
|
||||
"hicolor", "12x12", "status", "document-edited.png"}.Combine ());
|
||||
html = html.Replace ("<!-- $document-deleted-background-image -->", "file://" +
|
||||
new string [] {SparkleUI.AssetsPath, "icons",
|
||||
"hicolor", "12x12", "status", "document-deleted.png"}.Combine ());
|
||||
html = html.Replace ("<!-- $document-moved-background-image -->", "file://" +
|
||||
new string [] {SparkleUI.AssetsPath, "icons",
|
||||
"hicolor", "12x12", "status", "document-moved.png"}.Combine ());
|
||||
|
||||
Application.Invoke (delegate {
|
||||
this.spinner.Stop ();
|
||||
this.web_view.LoadString (html, null, null, "file://");
|
||||
this.content_wrapper.Remove (this.content_wrapper.Child);
|
||||
this.content_wrapper.Add (this.scrolled_window);
|
||||
this.content_wrapper.ShowAll ();
|
||||
});
|
||||
}));
|
||||
|
||||
thread.Start ();
|
||||
}
|
||||
|
||||
|
||||
private void GenerateHTML ()
|
||||
{
|
||||
HTML = SparkleShare.Controller.GetHTMLLog (this.change_sets);
|
||||
|
||||
HTML = HTML.Replace ("<!-- $body-font-size -->", (double) (Style.FontDescription.Size / 1024 + 3) + "px");
|
||||
HTML = HTML.Replace ("<!-- $day-entry-header-font-size -->", (Style.FontDescription.Size / 1024 + 3) + "px");
|
||||
HTML = HTML.Replace ("<!-- $a-color -->", "#0085cf");
|
||||
HTML = HTML.Replace ("<!-- $a-hover-color -->", "#009ff8");
|
||||
HTML = HTML.Replace ("<!-- $body-font-family -->", "\"" + Style.FontDescription.Family + "\"");
|
||||
HTML = HTML.Replace ("<!-- $body-color -->", SparkleUIHelpers.GdkColorToHex (Style.Foreground (StateType.Normal)));
|
||||
HTML = HTML.Replace ("<!-- $body-background-color -->", SparkleUIHelpers.GdkColorToHex (new TreeView ().Style.Base (StateType.Normal)));
|
||||
HTML = HTML.Replace ("<!-- $day-entry-header-background-color -->", SparkleUIHelpers.GdkColorToHex (Style.Background (StateType.Normal)));
|
||||
HTML = HTML.Replace ("<!-- $secondary-font-color -->", SparkleUIHelpers.GdkColorToHex (Style.Foreground (StateType.Insensitive)));
|
||||
HTML = HTML.Replace ("<!-- $small-color -->", SparkleUIHelpers.GdkColorToHex (Style.Foreground (StateType.Insensitive)));
|
||||
HTML = HTML.Replace ("<!-- $no-buddy-icon-background-image -->", "file://" +
|
||||
SparkleHelpers.CombineMore (Defines.PREFIX, "share", "sparkleshare", "icons",
|
||||
"hicolor", "32x32", "status", "avatar-default.png"));
|
||||
HTML = HTML.Replace ("<!-- $document-added-background-image -->", "file://" +
|
||||
SparkleHelpers.CombineMore (Defines.PREFIX, "share", "sparkleshare", "icons",
|
||||
"hicolor", "12x12", "status", "document-added.png"));
|
||||
HTML = HTML.Replace ("<!-- $document-edited-background-image -->", "file://" +
|
||||
SparkleHelpers.CombineMore (Defines.PREFIX, "share", "sparkleshare", "icons",
|
||||
"hicolor", "12x12", "status", "document-edited.png"));
|
||||
HTML = HTML.Replace ("<!-- $document-deleted-background-image -->", "file://" +
|
||||
SparkleHelpers.CombineMore (Defines.PREFIX, "share", "sparkleshare", "icons",
|
||||
"hicolor", "12x12", "status", "document-deleted.png"));
|
||||
HTML = HTML.Replace ("<!-- $document-moved-background-image -->", "file://" +
|
||||
SparkleHelpers.CombineMore (Defines.PREFIX, "share", "sparkleshare", "icons",
|
||||
"hicolor", "12x12", "status", "document-moved.png"));
|
||||
}
|
||||
|
||||
|
||||
private void AddHTML ()
|
||||
{
|
||||
Application.Invoke (delegate {
|
||||
Spinner.Stop ();
|
||||
LogContent.Remove (LogContent.Child);
|
||||
|
||||
WebView.LoadString (HTML, null, null, "file://");
|
||||
|
||||
LogContent.Add (ScrolledWindow);
|
||||
LogContent.ShowAll ();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void Close (object o, DeleteEventArgs args)
|
||||
{
|
||||
HideAll ();
|
||||
args.RetVal = true;
|
||||
// TODO: window positions aren't saved
|
||||
}
|
||||
|
||||
|
||||
|
@ -275,7 +256,7 @@ namespace SparkleShare {
|
|||
{
|
||||
// Adds a hidden menubar that contains to enable keyboard
|
||||
// shortcuts to close the log
|
||||
MenuBar = new MenuBar ();
|
||||
MenuBar menu_bar = new MenuBar ();
|
||||
|
||||
MenuItem file_item = new MenuItem ("File");
|
||||
|
||||
|
@ -304,15 +285,14 @@ namespace SparkleShare {
|
|||
|
||||
file_item.Submenu = file_menu;
|
||||
|
||||
MenuBar.Append (file_item);
|
||||
menu_bar.Append (file_item);
|
||||
|
||||
// Hacky way to hide the menubar, but the accellerators
|
||||
// will simply be disabled when using Hide ()
|
||||
MenuBar.HeightRequest = 1;
|
||||
MenuBar.ModifyBg (StateType.Normal, Style.Background (StateType.Normal));
|
||||
menu_bar.HeightRequest = 1;
|
||||
menu_bar.ModifyBg (StateType.Normal, Style.Background (StateType.Normal));
|
||||
|
||||
return MenuBar;
|
||||
return menu_bar;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -69,14 +69,14 @@ namespace SparkleShare {
|
|||
|
||||
public string HTML {
|
||||
get {
|
||||
List<SparkleChangeSet> change_sets = SparkleShare.Controller.GetLog (this.selected_folder);
|
||||
return SparkleShare.Controller.GetHTMLLog (change_sets);
|
||||
List<SparkleChangeSet> change_sets = Program.Controller.GetLog (this.selected_folder);
|
||||
return Program.Controller.GetHTMLLog (change_sets);
|
||||
}
|
||||
}
|
||||
|
||||
public string [] Folders {
|
||||
get {
|
||||
return SparkleShare.Controller.Folders.ToArray ();
|
||||
return Program.Controller.Folders.ToArray ();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,19 +86,19 @@ namespace SparkleShare {
|
|||
|
||||
public SparkleEventLogController ()
|
||||
{
|
||||
SparkleShare.Controller.AvatarFetched += delegate {
|
||||
Program.Controller.AvatarFetched += delegate {
|
||||
if (UpdateContentEvent != null)
|
||||
UpdateContentEvent (HTML);
|
||||
};
|
||||
|
||||
SparkleShare.Controller.OnIdle += delegate {
|
||||
Program.Controller.OnIdle += delegate {
|
||||
if (UpdateContentEvent != null)
|
||||
UpdateContentEvent (HTML);
|
||||
};
|
||||
|
||||
SparkleShare.Controller.FolderListChanged += delegate {
|
||||
Program.Controller.FolderListChanged += delegate {
|
||||
if (this.selected_folder != null &&
|
||||
!SparkleShare.Controller.Folders.Contains (this.selected_folder)) {
|
||||
!Program.Controller.Folders.Contains (this.selected_folder)) {
|
||||
|
||||
this.selected_folder = null;
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ namespace SparkleShare {
|
|||
UpdateContentEvent (HTML);
|
||||
};
|
||||
|
||||
SparkleShare.Controller.NotificationRaised += delegate {
|
||||
Program.Controller.NotificationRaised += delegate {
|
||||
if (UpdateContentEvent != null)
|
||||
UpdateContentEvent (HTML);
|
||||
};
|
||||
|
|
35
SparkleShare/SparkleExtensions.cs
Normal file
35
SparkleShare/SparkleExtensions.cs
Normal 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 SparkleShare {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -73,8 +73,11 @@ namespace SparkleShare {
|
|||
// from the Internet category if needed
|
||||
public override void InstallLauncher ()
|
||||
{
|
||||
string apps_path = SparkleHelpers.CombineMore (SparklePaths.HomePath, ".local", "share", "applications");
|
||||
string desktopfile_path = SparkleHelpers.CombineMore (apps_path, "sparkleshare.desktop");
|
||||
string apps_path =
|
||||
new string [] {SparkleConfig.DefaultConfig.HomePath,
|
||||
".local", "share", "applications"}.Combine ();
|
||||
|
||||
string desktopfile_path = Path.Combine (apps_path, "sparkleshare.desktop");
|
||||
|
||||
if (!File.Exists (desktopfile_path)) {
|
||||
if (!Directory.Exists (apps_path))
|
||||
|
@ -104,8 +107,8 @@ namespace SparkleShare {
|
|||
// list of bookmarked places
|
||||
public override void AddToBookmarks ()
|
||||
{
|
||||
string bookmarks_file_path = Path.Combine (SparklePaths.HomePath, ".gtk-bookmarks");
|
||||
string sparkleshare_bookmark = "file://" + SparklePaths.SparklePath + " SparkleShare";
|
||||
string bookmarks_file_path = Path.Combine (SparkleConfig.DefaultConfig.HomePath, ".gtk-bookmarks");
|
||||
string sparkleshare_bookmark = "file://" + SparkleConfig.DefaultConfig.FoldersPath + " SparkleShare";
|
||||
|
||||
if (File.Exists (bookmarks_file_path)) {
|
||||
StreamReader reader = new StreamReader (bookmarks_file_path);
|
||||
|
@ -114,12 +117,12 @@ namespace SparkleShare {
|
|||
|
||||
if (!bookmarks.Contains (sparkleshare_bookmark)) {
|
||||
TextWriter writer = File.AppendText (bookmarks_file_path);
|
||||
writer.WriteLine ("file://" + SparklePaths.SparklePath + " SparkleShare");
|
||||
writer.WriteLine ("file://" + SparkleConfig.DefaultConfig.FoldersPath + " SparkleShare");
|
||||
writer.Close ();
|
||||
}
|
||||
} else {
|
||||
StreamWriter writer = new StreamWriter (bookmarks_file_path);
|
||||
writer.WriteLine ("file://" + SparklePaths.SparklePath + " SparkleShare");
|
||||
writer.WriteLine ("file://" + SparkleConfig.DefaultConfig.FoldersPath + " SparkleShare");
|
||||
writer.Close ();
|
||||
}
|
||||
}
|
||||
|
@ -128,13 +131,14 @@ namespace SparkleShare {
|
|||
// Creates the SparkleShare folder in the user's home folder
|
||||
public override bool CreateSparkleShareFolder ()
|
||||
{
|
||||
if (!Directory.Exists (SparklePaths.SparklePath)) {
|
||||
if (!Directory.Exists (SparkleConfig.DefaultConfig.FoldersPath)) {
|
||||
|
||||
Directory.CreateDirectory (SparklePaths.SparklePath);
|
||||
SparkleHelpers.DebugInfo ("Controller", "Created '" + SparklePaths.SparklePath + "'");
|
||||
Directory.CreateDirectory (SparkleConfig.DefaultConfig.FoldersPath);
|
||||
SparkleHelpers.DebugInfo ("Controller", "Created '" + SparkleConfig.DefaultConfig.FoldersPath + "'");
|
||||
|
||||
string gvfs_command_path = SparkleHelpers.CombineMore (Path.VolumeSeparatorChar.ToString (),
|
||||
"usr", "bin", "gvfs-set-attribute");
|
||||
string gvfs_command_path =
|
||||
new string [] {Path.VolumeSeparatorChar.ToString (),
|
||||
"usr", "bin", "gvfs-set-attribute"}.Combine ();
|
||||
|
||||
// Add a special icon to the SparkleShare folder
|
||||
if (File.Exists (gvfs_command_path)) {
|
||||
|
@ -145,12 +149,12 @@ namespace SparkleShare {
|
|||
process.StartInfo.FileName = "gvfs-set-attribute";
|
||||
|
||||
// Clear the custom (legacy) icon path
|
||||
process.StartInfo.Arguments = "-t unset " + SparklePaths.SparklePath + " metadata::custom-icon";
|
||||
process.StartInfo.Arguments = "-t unset " + SparkleConfig.DefaultConfig.FoldersPath + " metadata::custom-icon";
|
||||
process.Start ();
|
||||
process.WaitForExit ();
|
||||
|
||||
// Give the SparkleShare folder an icon name, so that it scales
|
||||
process.StartInfo.Arguments = SparklePaths.SparklePath + " metadata::custom-icon-name 'folder-sparkleshare'";
|
||||
process.StartInfo.Arguments = SparkleConfig.DefaultConfig.FoldersPath + " metadata::custom-icon-name 'folder-sparkleshare'";
|
||||
process.Start ();
|
||||
process.WaitForExit ();
|
||||
}
|
||||
|
@ -164,13 +168,13 @@ namespace SparkleShare {
|
|||
|
||||
public override string EventLogHTML {
|
||||
get {
|
||||
string path = SparkleHelpers.CombineMore (Defines.PREFIX,
|
||||
"share", "sparkleshare", "html", "event-log.html");
|
||||
string path = new string [] {Defines.PREFIX,
|
||||
"share", "sparkleshare", "html", "event-log.html"}.Combine ();
|
||||
|
||||
string html = String.Join (Environment.NewLine, File.ReadAllLines (path));
|
||||
|
||||
html = html.Replace ("<!-- $jquery-url -->", "file://" +
|
||||
SparkleHelpers.CombineMore (Defines.PREFIX, "share", "sparkleshare", "html", "jquery.js"));
|
||||
new string [] {Defines.PREFIX, "share", "sparkleshare", "html", "jquery.js"}.Combine ());
|
||||
|
||||
return html;
|
||||
}
|
||||
|
@ -179,8 +183,8 @@ namespace SparkleShare {
|
|||
|
||||
public override string DayEntryHTML {
|
||||
get {
|
||||
string path = SparkleHelpers.CombineMore (Defines.PREFIX,
|
||||
"share", "sparkleshare", "html", "day-entry.html");
|
||||
string path = new string [] {Defines.PREFIX,
|
||||
"share", "sparkleshare", "html", "day-entry.html"}.Combine ();
|
||||
|
||||
return String.Join (Environment.NewLine, File.ReadAllLines (path));
|
||||
}
|
||||
|
@ -189,8 +193,8 @@ namespace SparkleShare {
|
|||
|
||||
public override string EventEntryHTML {
|
||||
get {
|
||||
string path = SparkleHelpers.CombineMore (Defines.PREFIX,
|
||||
"share", "sparkleshare", "html", "event-entry.html");
|
||||
string path = new string [] {Defines.PREFIX,
|
||||
"share", "sparkleshare", "html", "event-entry.html"}.Combine ();
|
||||
|
||||
return String.Join (Environment.NewLine, File.ReadAllLines (path));
|
||||
}
|
||||
|
@ -199,7 +203,7 @@ namespace SparkleShare {
|
|||
|
||||
public override void OpenSparkleShareFolder (string subfolder)
|
||||
{
|
||||
string folder = Path.Combine (SparklePaths.SparklePath, subfolder);
|
||||
string folder = Path.Combine (SparkleConfig.DefaultConfig.FoldersPath, subfolder);
|
||||
|
||||
Process process = new Process ();
|
||||
process.StartInfo.FileName = "xdg-open";
|
||||
|
|
|
@ -43,9 +43,7 @@ namespace SparkleShare {
|
|||
private Button SyncButton;
|
||||
|
||||
private Table Table;
|
||||
|
||||
private ProgressBar progress_bar = new ProgressBar () { PulseStep = 0.01 };
|
||||
private Timer progress_bar_pulse_timer = new Timer () { Interval = 25, Enabled = true };
|
||||
private ProgressBar progress_bar = new ProgressBar ();
|
||||
|
||||
|
||||
// Short alias for the translations
|
||||
|
@ -64,7 +62,7 @@ namespace SparkleShare {
|
|||
Reset ();
|
||||
|
||||
switch (type) {
|
||||
case PageType.Setup:
|
||||
case PageType.Setup: {
|
||||
|
||||
Header = _("Welcome to SparkleShare!");
|
||||
Description = _("Before we can create a SparkleShare folder on this " +
|
||||
|
@ -79,12 +77,12 @@ namespace SparkleShare {
|
|||
Xalign = 0
|
||||
};
|
||||
|
||||
NameEntry = new Entry (SparkleShare.Controller.UserName);
|
||||
NameEntry = new Entry (Controller.GuessedUserName);
|
||||
NameEntry.Changed += delegate {
|
||||
CheckSetupPage ();
|
||||
};
|
||||
|
||||
EmailEntry = new Entry ();
|
||||
EmailEntry = new Entry (Controller.GuessedUserEmail);
|
||||
EmailEntry.Changed += delegate {
|
||||
CheckSetupPage ();
|
||||
};
|
||||
|
@ -116,13 +114,14 @@ namespace SparkleShare {
|
|||
CheckSetupPage ();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PageType.Add:
|
||||
case PageType.Add: {
|
||||
|
||||
Header = _("Where is your remote folder?");
|
||||
Header = _("Where is your project?");
|
||||
|
||||
Table = new Table (6, 2, false) {
|
||||
RowSpacing = 12
|
||||
RowSpacing = 0
|
||||
};
|
||||
|
||||
HBox layout_server = new HBox (true, 0);
|
||||
|
@ -150,8 +149,8 @@ namespace SparkleShare {
|
|||
|
||||
ListStore server_store = new ListStore (typeof (string));
|
||||
|
||||
//TODO foreach (string host in SparkleShare.Controller.PreviousHosts)
|
||||
// server_store.AppendValues (host);
|
||||
foreach (string host in Program.Controller.PreviousHosts)
|
||||
server_store.AppendValues (host);
|
||||
|
||||
ServerEntry.Completion.Model = server_store;
|
||||
ServerEntry.Completion.TextColumn = 0;
|
||||
|
@ -173,11 +172,7 @@ namespace SparkleShare {
|
|||
Table.Attach (layout_server, 0, 2, 1, 2);
|
||||
|
||||
// Github radiobutton
|
||||
string github_text = "<b>" + "Github" + "</b>\n" +
|
||||
"<span fgcolor='" + SecondaryTextColor + "' size='small'>" +
|
||||
_("Free hosting for Free and Open Source Software projects.") + "\n" +
|
||||
_("Also has paid accounts for extra private space and bandwidth.") +
|
||||
"</span>";
|
||||
string github_text = "<b>" + "Github" + "</b>";
|
||||
|
||||
RadioButton radio_button_github = new RadioButton (radio_button, github_text);
|
||||
(radio_button_github.Child as Label).UseMarkup = true;
|
||||
|
@ -190,11 +185,7 @@ namespace SparkleShare {
|
|||
|
||||
|
||||
// Gitorious radiobutton
|
||||
string gitorious_text = "<b>" + _("Gitorious") + "</b>\n" +
|
||||
"<span fgcolor='" + SecondaryTextColor + "' size='small'>" +
|
||||
_("Completely Free as in Freedom infrastructure.") + "\n" +
|
||||
_("Free accounts for Free and Open Source projects.") +
|
||||
"</span>";
|
||||
string gitorious_text = "<b>" + _("Gitorious") + "</b>";
|
||||
|
||||
RadioButton radio_button_gitorious = new RadioButton (radio_button, gitorious_text);
|
||||
(radio_button_gitorious.Child as Label).UseMarkup = true;
|
||||
|
@ -207,11 +198,7 @@ namespace SparkleShare {
|
|||
|
||||
|
||||
// GNOME radiobutton
|
||||
string gnome_text = "<b>" + _("The GNOME Project") + "</b>\n"+
|
||||
"<span fgcolor='" + SecondaryTextColor + "' size='small'>" +
|
||||
_("GNOME is an easy to understand interface to your computer.") + "\n" +
|
||||
_("Select this option if you’re a developer or designer working on GNOME.") +
|
||||
"</span>";
|
||||
string gnome_text = "<b>" + _("The GNOME Project") + "</b>";
|
||||
|
||||
RadioButton radio_button_gnome = new RadioButton (radio_button, gnome_text);
|
||||
(radio_button_gnome.Child as Label).UseMarkup = true;
|
||||
|
@ -236,6 +223,15 @@ namespace SparkleShare {
|
|||
|
||||
FolderEntry = new SparkleEntry ();
|
||||
FolderEntry.ExampleText = _("Folder");
|
||||
FolderEntry.Completion = new EntryCompletion();
|
||||
|
||||
ListStore folder_store = new ListStore (typeof (string));
|
||||
|
||||
//foreach (string host in Program.Controller.FolderPaths)
|
||||
// folder_store.AppendValues (host);
|
||||
|
||||
FolderEntry.Completion.Model = folder_store;
|
||||
FolderEntry.Completion.TextColumn = 0;
|
||||
|
||||
FolderEntry.Changed += delegate {
|
||||
CheckAddPage ();
|
||||
|
@ -245,7 +241,10 @@ namespace SparkleShare {
|
|||
layout_folder.PackStart (FolderEntry, true, true, 0);
|
||||
|
||||
Table.Attach (layout_folder, 0, 2, 5, 6);
|
||||
Add (Table);
|
||||
|
||||
VBox box = new VBox (false, 0);
|
||||
box.PackStart (Table, false, false, 0);
|
||||
Add (box);
|
||||
|
||||
// Cancel button
|
||||
Button cancel_button = new Button (_("Cancel"));
|
||||
|
@ -256,7 +255,7 @@ namespace SparkleShare {
|
|||
|
||||
|
||||
// Sync button
|
||||
SyncButton = new Button (_("Sync"));
|
||||
SyncButton = new Button (_("Add"));
|
||||
|
||||
SyncButton.Clicked += delegate {
|
||||
string server = ServerEntry.Text;
|
||||
|
@ -280,27 +279,33 @@ namespace SparkleShare {
|
|||
CheckAddPage ();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PageType.Syncing:
|
||||
case PageType.Syncing: {
|
||||
|
||||
Header = String.Format (_("Syncing folder ‘{0}’…"), Controller.SyncingFolder);
|
||||
Header = String.Format (_("Adding project ‘{0}’…"), Controller.SyncingFolder);
|
||||
Description = _("This may take a while." + Environment.NewLine) +
|
||||
_("Are you sure it’s not coffee o'clock?");
|
||||
|
||||
Button button = new Button () {
|
||||
Button finish_button = new Button () {
|
||||
Sensitive = false,
|
||||
Label = _("Finish")
|
||||
};
|
||||
|
||||
button.Clicked += delegate {
|
||||
Close ();
|
||||
Button cancel_button = new Button () {
|
||||
Label = _("Cancel")
|
||||
};
|
||||
|
||||
AddButton (button);
|
||||
cancel_button.Clicked += delegate {
|
||||
Controller.SyncingCancelled ();
|
||||
};
|
||||
|
||||
this.progress_bar_pulse_timer.Elapsed += delegate {
|
||||
AddButton (cancel_button);
|
||||
AddButton (finish_button);
|
||||
|
||||
Controller.UpdateProgressBarEvent += delegate (double percentage) {
|
||||
Application.Invoke (delegate {
|
||||
progress_bar.Pulse ();
|
||||
this.progress_bar.Fraction = percentage / 100;
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -313,32 +318,59 @@ namespace SparkleShare {
|
|||
Add (bar_wrapper);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PageType.Error:
|
||||
|
||||
string n = Environment.NewLine;
|
||||
case PageType.Error: {
|
||||
|
||||
Header = _("Something went wrong") + "…";
|
||||
Description = "We don't know exactly what the problem is, " +
|
||||
"but we can try to help you pinpoint it.";
|
||||
|
||||
VBox points = new VBox (false, 0);
|
||||
Image list_point_one = new Image (SparkleUIHelpers.GetIcon ("list-point", 16)) { };
|
||||
Image list_point_two = new Image (SparkleUIHelpers.GetIcon ("list-point", 16)) { };
|
||||
Image list_point_three = new Image (SparkleUIHelpers.GetIcon ("list-point", 16)) { };
|
||||
|
||||
Label label_one = new Label () {
|
||||
Text = "First, have you tried turning it off and on again?",
|
||||
Wrap = true,
|
||||
Xalign = 0
|
||||
};
|
||||
|
||||
Label label_two = new Label () {
|
||||
Markup = "<b>" + Controller.PreviousUrl + "</b> is the address we've compiled. " +
|
||||
"Does this look alright?",
|
||||
Wrap = true,
|
||||
Xalign = 0
|
||||
};
|
||||
|
||||
Label label_three = new Label () {
|
||||
Text = "The host needs to know who you are. Did you upload the key that's in " +
|
||||
"your SparkleShare folder?",
|
||||
Wrap = true,
|
||||
Xalign = 0
|
||||
};
|
||||
|
||||
|
||||
Label l = new Label (
|
||||
"First, have you tried turning it off and on again?" + n +
|
||||
n +
|
||||
Controller.SyncingFolder +" is the address we've compiled from the information " +
|
||||
"you entered. Does this look correct?" + n +
|
||||
n +
|
||||
"The host needs to know who you are. Have you uploaded the key that sits in your SparkleShare folder?");
|
||||
points.PackStart (new Label ("Please check the following:") { Xalign = 0 }, false, false, 6);
|
||||
|
||||
HBox point_one = new HBox (false, 0);
|
||||
point_one.PackStart (list_point_one, false, false, 0);
|
||||
point_one.PackStart (label_one, true, true, 12);
|
||||
points.PackStart (point_one, false, false, 12);
|
||||
|
||||
HBox point_two = new HBox (false, 0);
|
||||
point_two.PackStart (list_point_two, false, false, 0);
|
||||
point_two.PackStart (label_two, true, true, 12);
|
||||
points.PackStart (point_two, false, false, 12);
|
||||
|
||||
HBox point_three = new HBox (false, 0);
|
||||
point_three.PackStart (list_point_three, false, false, 0);
|
||||
point_three.PackStart (label_three, true, true, 12);
|
||||
points.PackStart (point_three, false, false, 12);
|
||||
|
||||
points.PackStart (new Label (""), true, true, 0);
|
||||
|
||||
|
||||
|
||||
l.Xpad = 12;
|
||||
l.Wrap = true;
|
||||
|
||||
|
||||
|
||||
Button try_again_button = new Button (_("Try Again")) {
|
||||
Button try_again_button = new Button (_("Try Again…")) {
|
||||
Sensitive = true
|
||||
};
|
||||
|
||||
|
@ -347,34 +379,36 @@ namespace SparkleShare {
|
|||
};
|
||||
|
||||
AddButton (try_again_button);
|
||||
Add (l);
|
||||
Add (points);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PageType.Finished:
|
||||
case PageType.Finished: {
|
||||
|
||||
UrgencyHint = true;
|
||||
|
||||
if (!HasToplevelFocus) {
|
||||
string title = String.Format (_("‘{0}’ has been successfully added"), Controller.SyncingFolder);
|
||||
string subtext = _("");
|
||||
string subtext = "";
|
||||
|
||||
//TODO new SparkleBubble (title, subtext).Show ();
|
||||
SparkleUI.Bubbles.Controller.ShowBubble (title, subtext, null);
|
||||
}
|
||||
|
||||
Header = _("Folder synced successfully!");
|
||||
Description = _("Access the synced files from your SparkleShare folder.");
|
||||
Header = _("Project successfully added!");
|
||||
Description = _("Access the files from your SparkleShare folder.");
|
||||
|
||||
// A button that opens the synced folder
|
||||
Button open_folder_button = new Button (_("Open Folder"));
|
||||
|
||||
open_folder_button.Clicked += delegate {
|
||||
SparkleShare.Controller.OpenSparkleShareFolder (Controller.SyncingFolder);
|
||||
Program.Controller.OpenSparkleShareFolder (Controller.SyncingFolder);
|
||||
};
|
||||
|
||||
Button finish_button = new Button (_("Finish"));
|
||||
|
||||
finish_button.Clicked += delegate {
|
||||
Controller.FinishedPageCompleted ();
|
||||
Close ();
|
||||
};
|
||||
|
||||
|
@ -386,10 +420,116 @@ namespace SparkleShare {
|
|||
break;
|
||||
}
|
||||
|
||||
|
||||
case PageType.Tutorial: {
|
||||
|
||||
switch (Controller.TutorialPageNumber) {
|
||||
case 1: {
|
||||
Header = _("What's happening next?");
|
||||
Description = _("SparkleShare creates a special folder in your personal folder " +
|
||||
"that will keep track of your projects.");
|
||||
|
||||
Button skip_tutorial_button = new Button (_("Skip Tutorial"));
|
||||
skip_tutorial_button.Clicked += delegate {
|
||||
Controller.TutorialSkipped ();
|
||||
};
|
||||
|
||||
Button continue_button = new Button (_("Continue"));
|
||||
continue_button.Clicked += delegate {
|
||||
Controller.TutorialPageCompleted ();
|
||||
};
|
||||
|
||||
Image slide = SparkleUIHelpers.GetImage ("tutorial-slide-1.png");
|
||||
|
||||
Add (slide);
|
||||
|
||||
AddButton (skip_tutorial_button);
|
||||
AddButton (continue_button);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: {
|
||||
Header = _("Sharing files with others");
|
||||
Description = _("All files added to your project folders are synced with the host " +
|
||||
"automatically, as well as with your collaborators.");
|
||||
|
||||
Button continue_button = new Button (_("Continue"));
|
||||
continue_button.Clicked += delegate {
|
||||
Controller.TutorialPageCompleted ();
|
||||
};
|
||||
|
||||
Image slide = SparkleUIHelpers.GetImage ("tutorial-slide-2.png");
|
||||
|
||||
Add (slide);
|
||||
AddButton (continue_button);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 3: {
|
||||
Header = _("The status icon is here to help");
|
||||
Description = _("It shows the syncing process status, " +
|
||||
"and contains links to your projects and the event log.");
|
||||
|
||||
Button continue_button = new Button (_("Continue"));
|
||||
continue_button.Clicked += delegate {
|
||||
Controller.TutorialPageCompleted ();
|
||||
};
|
||||
|
||||
Image slide = SparkleUIHelpers.GetImage ("tutorial-slide-3.png");
|
||||
|
||||
Add (slide);
|
||||
AddButton (continue_button);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 4: {
|
||||
Header = _("Adding projects to SparkleShare");
|
||||
Description = _("Just click this button when you see it on the web, and " +
|
||||
"the project will be automatically added:");
|
||||
|
||||
Label label = new Label (_("…or select <b>‘Add Project…’</b> from the status icon menu " +
|
||||
"to add one by hand.")) {
|
||||
Wrap = true,
|
||||
Xalign = 0,
|
||||
UseMarkup = true
|
||||
};
|
||||
|
||||
Image slide = SparkleUIHelpers.GetImage ("tutorial-slide-4.png");
|
||||
|
||||
Button add_project_button = new Button (_("Add Project…"));
|
||||
add_project_button.Clicked += delegate {
|
||||
Controller.TutorialPageCompleted ();
|
||||
};
|
||||
|
||||
Button finish_button = new Button (_("Finish"));
|
||||
finish_button.Clicked += delegate {
|
||||
Close ();
|
||||
};
|
||||
|
||||
|
||||
VBox box = new VBox (false, 0);
|
||||
box.Add (slide);
|
||||
box.Add (label);
|
||||
|
||||
Add (box);
|
||||
|
||||
AddButton (add_project_button);
|
||||
AddButton (finish_button);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ShowAll ();
|
||||
});
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -398,7 +538,7 @@ namespace SparkleShare {
|
|||
private void CheckSetupPage ()
|
||||
{
|
||||
if (NameEntry.Text.Length > 0 &&
|
||||
SparkleShare.Controller.IsValidEmail (EmailEntry.Text)) {
|
||||
Program.Controller.IsValidEmail (EmailEntry.Text)) {
|
||||
|
||||
NextButton.Sensitive = true;
|
||||
} else {
|
||||
|
|
|
@ -25,7 +25,8 @@ namespace SparkleShare {
|
|||
Add,
|
||||
Syncing,
|
||||
Error,
|
||||
Finished
|
||||
Finished,
|
||||
Tutorial
|
||||
}
|
||||
|
||||
|
||||
|
@ -34,6 +35,22 @@ namespace SparkleShare {
|
|||
public event ChangePageEventHandler ChangePageEvent;
|
||||
public delegate void ChangePageEventHandler (PageType page);
|
||||
|
||||
public event UpdateProgressBarEventHandler UpdateProgressBarEvent;
|
||||
public delegate void UpdateProgressBarEventHandler (double percentage);
|
||||
|
||||
|
||||
public int TutorialPageNumber {
|
||||
get {
|
||||
return this.tutorial_page_number;
|
||||
}
|
||||
}
|
||||
|
||||
public string PreviousUrl {
|
||||
get {
|
||||
return this.previous_url;
|
||||
}
|
||||
}
|
||||
|
||||
public string PreviousServer {
|
||||
get {
|
||||
return this.previous_server;
|
||||
|
@ -58,11 +75,30 @@ namespace SparkleShare {
|
|||
}
|
||||
}
|
||||
|
||||
public string GuessedUserName {
|
||||
get {
|
||||
return Program.Controller.UserName;
|
||||
}
|
||||
}
|
||||
|
||||
public string GuessedUserEmail {
|
||||
get {
|
||||
if (Program.Controller.UserEmail.Equals ("Unknown"))
|
||||
return "";
|
||||
else
|
||||
return Program.Controller.UserEmail;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private string previous_server = "";
|
||||
private string previous_folder = "";
|
||||
private string previous_url = "";
|
||||
private string syncing_folder = "";
|
||||
private int tutorial_page_number = 1;
|
||||
private PageType previous_page;
|
||||
|
||||
|
||||
public SparkleSetupController ()
|
||||
{
|
||||
ChangePageEvent += delegate (PageType page) {
|
||||
|
@ -94,34 +130,59 @@ namespace SparkleShare {
|
|||
Program.Controller.UpdateState ();
|
||||
|
||||
if (ChangePageEvent != null)
|
||||
ChangePageEvent (PageType.Add);
|
||||
ChangePageEvent (PageType.Tutorial);
|
||||
}
|
||||
|
||||
|
||||
public void TutorialPageCompleted ()
|
||||
{
|
||||
this.tutorial_page_number++;
|
||||
|
||||
if (ChangePageEvent != null)
|
||||
ChangePageEvent (PageType.Tutorial);
|
||||
}
|
||||
|
||||
|
||||
public void TutorialSkipped ()
|
||||
{
|
||||
this.tutorial_page_number = 4;
|
||||
|
||||
if (ChangePageEvent != null)
|
||||
ChangePageEvent (PageType.Tutorial);
|
||||
}
|
||||
|
||||
|
||||
public void AddPageCompleted (string server, string folder_name)
|
||||
{
|
||||
this.syncing_folder = folder_name;
|
||||
this.syncing_folder = Path.GetFileNameWithoutExtension (folder_name);
|
||||
this.previous_server = server;
|
||||
this.previous_folder = folder_name;
|
||||
|
||||
if (ChangePageEvent != null)
|
||||
ChangePageEvent (PageType.Syncing);
|
||||
|
||||
Program.Controller.FolderFetched += (target_folder_name) => {
|
||||
this.syncing_folder = target_folder_name;
|
||||
|
||||
Program.Controller.FolderFetched += delegate {
|
||||
if (ChangePageEvent != null)
|
||||
ChangePageEvent (PageType.Finished);
|
||||
|
||||
this.syncing_folder = "";
|
||||
};
|
||||
|
||||
Program.Controller.FolderFetchError += delegate {
|
||||
Program.Controller.FolderFetchError += delegate (string remote_url) {
|
||||
this.previous_url = remote_url;
|
||||
|
||||
if (ChangePageEvent != null)
|
||||
ChangePageEvent (PageType.Error);
|
||||
|
||||
this.syncing_folder = "";
|
||||
};
|
||||
|
||||
Program.Controller.FetchFolder (server, this.syncing_folder);
|
||||
Program.Controller.FolderFetching += delegate (double percentage) {
|
||||
if (UpdateProgressBarEvent != null)
|
||||
UpdateProgressBarEvent (percentage);
|
||||
};
|
||||
|
||||
Program.Controller.FetchFolder (server, folder_name);
|
||||
}
|
||||
|
||||
|
||||
|
@ -132,6 +193,15 @@ namespace SparkleShare {
|
|||
}
|
||||
|
||||
|
||||
public void SyncingCancelled ()
|
||||
{
|
||||
Program.Controller.StopFetcher ();
|
||||
|
||||
if (ChangePageEvent != null)
|
||||
ChangePageEvent (PageType.Add);
|
||||
}
|
||||
|
||||
|
||||
public void FinishedPageCompleted ()
|
||||
{
|
||||
this.previous_server = "";
|
||||
|
|
|
@ -23,6 +23,7 @@ using System.Text.RegularExpressions;
|
|||
using System.Timers;
|
||||
|
||||
using Gtk;
|
||||
using Mono.Unix;
|
||||
using SparkleLib;
|
||||
|
||||
namespace SparkleShare {
|
||||
|
@ -41,7 +42,7 @@ namespace SparkleShare {
|
|||
|
||||
public SparkleSetupWindow () : base ("")
|
||||
{
|
||||
Title = "SparkleShare Setup";
|
||||
Title = Catalog.GetString ("SparkleShare Setup");
|
||||
BorderWidth = 0;
|
||||
IconName = "folder-sparkleshare";
|
||||
Resizable = false;
|
||||
|
@ -70,15 +71,11 @@ namespace SparkleShare {
|
|||
|
||||
EventBox box = new EventBox ();
|
||||
Gdk.Color bg_color = new Gdk.Color ();
|
||||
Gdk.Color.Parse ("#2e3336", ref bg_color);
|
||||
Gdk.Color.Parse ("#000", ref bg_color);
|
||||
box.ModifyBg (StateType.Normal, bg_color);
|
||||
|
||||
string image_path = SparkleHelpers.CombineMore (Defines.DATAROOTDIR, "sparkleshare",
|
||||
"pixmaps", "side-splash.png");
|
||||
|
||||
Image side_splash = new Image (image_path) {
|
||||
Yalign = 1
|
||||
};
|
||||
Image side_splash = SparkleUIHelpers.GetImage ("side-splash.png");
|
||||
side_splash.Yalign = 1;
|
||||
|
||||
box.Add (side_splash);
|
||||
|
||||
|
@ -125,7 +122,7 @@ namespace SparkleShare {
|
|||
layout_vertical.PackStart (description, false, false, 21);
|
||||
|
||||
if (widget != null)
|
||||
layout_vertical.PackStart (widget, true, true, 21);
|
||||
layout_vertical.PackStart (widget, true, true, 0);
|
||||
|
||||
Wrapper.PackStart (layout_vertical, true, true, 0);
|
||||
ShowAll ();
|
||||
|
@ -148,9 +145,7 @@ namespace SparkleShare {
|
|||
|
||||
new public void ShowAll ()
|
||||
{
|
||||
|
||||
Present ();
|
||||
|
||||
base.ShowAll ();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
|
@ -9,6 +9,7 @@
|
|||
<AssemblyName>SparkleShare</AssemblyName>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<RootNamespace>SparkleShare</RootNamespace>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
|
@ -37,15 +38,9 @@
|
|||
<Reference Include="System" />
|
||||
<Reference Include="Mono.Posix" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SparkleLib\SparkleLib.csproj">
|
||||
<Project>{2C914413-B31C-4362-93C7-1AE34F09112A}</Project>
|
||||
<Name>SparkleLib</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ProjectExtensions>
|
||||
<MonoDevelop>
|
||||
<Properties InternalTargetFrameworkVersion="3.5">
|
||||
<Properties>
|
||||
<MonoDevelop.Autotools.MakefileInfo IntegrationEnabled="true" RelativeMakefileName="Makefile.am">
|
||||
<BuildFilesVar Sync="true" Name="SOURCES" />
|
||||
<DeployFilesVar />
|
||||
|
@ -63,11 +58,10 @@
|
|||
<Compile Include="SparkleBubblesController.cs" />
|
||||
<Compile Include="SparkleController.cs" />
|
||||
<Compile Include="SparkleEntry.cs" />
|
||||
<Compile Include="SparkleLinController.cs" />
|
||||
<Compile Include="SparkleSetup.cs" />
|
||||
<Compile Include="SparkleSetupController.cs" />
|
||||
<Compile Include="SparkleSetupWindow.cs" />
|
||||
<Compile Include="SparkleShare.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="SparkleSpinner.cs" />
|
||||
<Compile Include="SparkleStatusIcon.cs" />
|
||||
<Compile Include="SparkleStatusIconController.cs" />
|
||||
|
@ -77,5 +71,7 @@
|
|||
<Compile Include="SparkleEventLog.cs" />
|
||||
<Compile Include="SparkleAboutController.cs" />
|
||||
<Compile Include="SparkleAbout.cs" />
|
||||
<Compile Include="SparkleExtensions.cs" />
|
||||
<Compile Include="SparkleControllerBase.cs" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
@ -1,20 +1,14 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||
# Visual Studio 2005
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual Studio 2008
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SparkleShare", "SparkleShare.csproj", "{728483AA-E34B-4441-BF2C-C8BC2901E4E0}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SparkleLib", "..\SparkleLib\SparkleLib.csproj", "{2C914413-B31C-4362-93C7-1AE34F09112A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{2C914413-B31C-4362-93C7-1AE34F09112A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2C914413-B31C-4362-93C7-1AE34F09112A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2C914413-B31C-4362-93C7-1AE34F09112A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2C914413-B31C-4362-93C7-1AE34F09112A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{728483AA-E34B-4441-BF2C-C8BC2901E4E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{728483AA-E34B-4441-BF2C-C8BC2901E4E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{728483AA-E34B-4441-BF2C-C8BC2901E4E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
@ -22,7 +16,5 @@ Global
|
|||
EndGlobalSection
|
||||
GlobalSection(MonoDevelopProperties) = preSolution
|
||||
StartupItem = SparkleShare.csproj
|
||||
outputpath = ..\bin
|
||||
name = SparkleShare
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
@ -23,7 +23,7 @@ using System.Timers;
|
|||
using AppIndicator;
|
||||
#endif
|
||||
using Gtk;
|
||||
using SparkleLib;
|
||||
using Mono.Unix;
|
||||
|
||||
namespace SparkleShare {
|
||||
|
||||
|
@ -31,6 +31,8 @@ namespace SparkleShare {
|
|||
// user's notification area
|
||||
public class SparkleStatusIcon {
|
||||
|
||||
public SparkleStatusIconController Controller = new SparkleStatusIconController ();
|
||||
|
||||
private Timer Animation;
|
||||
private Gdk.Pixbuf [] AnimationFrames;
|
||||
private int FrameNumber;
|
||||
|
@ -46,7 +48,7 @@ namespace SparkleShare {
|
|||
// Short alias for the translations
|
||||
public static string _ (string s)
|
||||
{
|
||||
return s;
|
||||
return Catalog.GetString (s);
|
||||
}
|
||||
|
||||
|
||||
|
@ -66,45 +68,63 @@ namespace SparkleShare {
|
|||
|
||||
this.status_icon.Activate += ShowMenu; // Primary mouse button click
|
||||
this.status_icon.PopupMenu += ShowMenu; // Secondary mouse button click
|
||||
this.status_icon.Pixbuf = AnimationFrames [0];
|
||||
#endif
|
||||
|
||||
SetNormalState ();
|
||||
if (Controller.Folders.Length == 0)
|
||||
StateText = _("Welcome to SparkleShare!");
|
||||
else
|
||||
StateText = _("Up to date") + " — " + Controller.FolderSize;
|
||||
|
||||
CreateMenu ();
|
||||
|
||||
SparkleShare.Controller.FolderSizeChanged += delegate {
|
||||
Controller.UpdateMenuEvent += delegate (IconState state) {
|
||||
Application.Invoke (delegate {
|
||||
switch (state) {
|
||||
case IconState.Idle:
|
||||
|
||||
Animation.Stop ();
|
||||
|
||||
if (Controller.Folders.Length == 0)
|
||||
StateText = _("Welcome to SparkleShare!");
|
||||
else
|
||||
StateText = _("Up to date") + " — " + Controller.FolderSize;
|
||||
|
||||
#if HAVE_APP_INDICATOR
|
||||
this.indicator.IconName = "process-syncing-sparkleshare-i";
|
||||
#else
|
||||
this.status_icon.Pixbuf = AnimationFrames [0];
|
||||
#endif
|
||||
|
||||
UpdateStateText ();
|
||||
CreateMenu ();
|
||||
|
||||
break;
|
||||
|
||||
case IconState.Syncing:
|
||||
|
||||
StateText = _("Syncing…");
|
||||
UpdateStateText (); // TODO
|
||||
|
||||
if (!Animation.Enabled)
|
||||
SetNormalState ();
|
||||
Animation.Start ();
|
||||
|
||||
UpdateMenu ();
|
||||
});
|
||||
};
|
||||
break;
|
||||
|
||||
SparkleShare.Controller.FolderListChanged += delegate {
|
||||
Application.Invoke (delegate {
|
||||
SetNormalState ();
|
||||
case IconState.Error:
|
||||
|
||||
StateText = _("Not everything is synced");
|
||||
UpdateStateText ();
|
||||
CreateMenu ();
|
||||
});
|
||||
};
|
||||
|
||||
SparkleShare.Controller.OnIdle += delegate {
|
||||
Application.Invoke (delegate {
|
||||
SetNormalState ();
|
||||
UpdateMenu ();
|
||||
});
|
||||
};
|
||||
#if HAVE_APP_INDICATOR
|
||||
this.indicator.IconName = "sparkleshare-syncing-error";
|
||||
#else
|
||||
this.status_icon.Pixbuf = SparkleUIHelpers.GetIcon ("sparkleshare-syncing-error", 24);
|
||||
#endif
|
||||
|
||||
SparkleShare.Controller.OnSyncing += delegate {
|
||||
Application.Invoke (delegate {
|
||||
SetAnimationState ();
|
||||
UpdateMenu ();
|
||||
});
|
||||
};
|
||||
|
||||
SparkleShare.Controller.OnError += delegate {
|
||||
Application.Invoke (delegate {
|
||||
SetNormalState (true);
|
||||
UpdateMenu ();
|
||||
break;
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
@ -176,18 +196,18 @@ namespace SparkleShare {
|
|||
};
|
||||
|
||||
folder_item.Activated += delegate {
|
||||
SparkleShare.Controller.OpenSparkleShareFolder ();
|
||||
Program.Controller.OpenSparkleShareFolder ();
|
||||
};
|
||||
|
||||
Menu.Add (folder_item);
|
||||
|
||||
if (SparkleShare.Controller.Folders.Count > 0) {
|
||||
if (Program.Controller.Folders.Count > 0) {
|
||||
|
||||
// Creates a menu item for each repository with a link to their logs
|
||||
foreach (string folder_name in SparkleShare.Controller.Folders) {
|
||||
foreach (string folder_name in Program.Controller.Folders) {
|
||||
Gdk.Pixbuf folder_icon;
|
||||
|
||||
if (SparkleShare.Controller.UnsyncedFolders.Contains (folder_name)) {
|
||||
if (Program.Controller.UnsyncedFolders.Contains (folder_name)) {
|
||||
folder_icon = IconTheme.Default.LoadIcon ("dialog-error", 16,
|
||||
IconLookupFlags.GenericFallback);
|
||||
|
||||
|
@ -205,7 +225,7 @@ namespace SparkleShare {
|
|||
}
|
||||
|
||||
} else {
|
||||
MenuItem no_folders_item = new MenuItem (_("No Remote Folders Yet")) {
|
||||
MenuItem no_folders_item = new MenuItem (_("No projects yet")) {
|
||||
Sensitive = false
|
||||
};
|
||||
|
||||
|
@ -215,9 +235,9 @@ namespace SparkleShare {
|
|||
Menu.Add (new SeparatorMenuItem ());
|
||||
|
||||
// Opens the wizard to add a new remote folder
|
||||
MenuItem sync_item = new MenuItem (_("Add Remote Folder…"));
|
||||
MenuItem sync_item = new MenuItem (_("Add Project…"));
|
||||
|
||||
if (SparkleShare.Controller.FirstRun)
|
||||
if (Program.Controller.FirstRun)
|
||||
sync_item.Sensitive = false;
|
||||
|
||||
sync_item.Activated += delegate {
|
||||
|
@ -241,7 +261,7 @@ namespace SparkleShare {
|
|||
|
||||
MenuItem recent_events_item = new MenuItem (_("Show Recent Events"));
|
||||
|
||||
if (SparkleShare.Controller.Folders.Count < 1)
|
||||
if (Program.Controller.Folders.Count < 1)
|
||||
recent_events_item.Sensitive = false;
|
||||
|
||||
recent_events_item.Activated += delegate {
|
||||
|
@ -258,13 +278,13 @@ namespace SparkleShare {
|
|||
|
||||
MenuItem notify_item;
|
||||
|
||||
if (SparkleShare.Controller.NotificationsEnabled)
|
||||
if (Program.Controller.NotificationsEnabled)
|
||||
notify_item = new MenuItem (_("Turn Notifications Off"));
|
||||
else
|
||||
notify_item = new MenuItem (_("Turn Notifications On"));
|
||||
|
||||
notify_item.Activated += delegate {
|
||||
SparkleShare.Controller.ToggleNotifications ();
|
||||
Program.Controller.ToggleNotifications ();
|
||||
CreateMenu ();
|
||||
};
|
||||
|
||||
|
@ -291,7 +311,7 @@ namespace SparkleShare {
|
|||
MenuItem quit_item = new MenuItem (_("Quit"));
|
||||
|
||||
quit_item.Activated += delegate {
|
||||
SparkleShare.Controller.Quit ();
|
||||
Program.Controller.Quit ();
|
||||
};
|
||||
|
||||
Menu.Add (quit_item);
|
||||
|
@ -308,12 +328,12 @@ namespace SparkleShare {
|
|||
private EventHandler OpenFolderDelegate (string name)
|
||||
{
|
||||
return delegate {
|
||||
SparkleShare.Controller.OpenSparkleShareFolder (name);
|
||||
Program.Controller.OpenSparkleShareFolder (name);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public void UpdateMenu ()
|
||||
public void UpdateStateText ()
|
||||
{
|
||||
((Menu.Children [0] as MenuItem).Child as Label).Text = StateText;
|
||||
Menu.ShowAll ();
|
||||
|
@ -323,11 +343,7 @@ namespace SparkleShare {
|
|||
// Makes the menu visible
|
||||
private void ShowMenu (object o, EventArgs args)
|
||||
{
|
||||
if ((SparkleBackend.Platform == PlatformID.Unix ||
|
||||
SparkleBackend.Platform == PlatformID.MacOSX))
|
||||
Menu.Popup (null, null, SetPosition, 0, Global.CurrentEventTime);
|
||||
else
|
||||
Menu.Popup (null, null, null, 0, Global.CurrentEventTime);
|
||||
}
|
||||
|
||||
|
||||
|
@ -337,63 +353,6 @@ namespace SparkleShare {
|
|||
StatusIcon.PositionMenu (menu, out x, out y, out push_in, this.status_icon.Handle);
|
||||
}
|
||||
#endif
|
||||
|
||||
// The state when there's nothing going on
|
||||
private void SetNormalState ()
|
||||
{
|
||||
SetNormalState (false);
|
||||
}
|
||||
|
||||
|
||||
// The state when there's nothing going on
|
||||
private void SetNormalState (bool error)
|
||||
{
|
||||
Animation.Stop ();
|
||||
|
||||
if (SparkleShare.Controller.Folders.Count == 0) {
|
||||
StateText = _("Welcome to SparkleShare!");
|
||||
|
||||
Application.Invoke (delegate {
|
||||
#if HAVE_APP_INDICATOR
|
||||
this.indicator.IconName = "process-syncing-sparkleshare-i";
|
||||
#else
|
||||
this.status_icon.Pixbuf = AnimationFrames [0];
|
||||
#endif
|
||||
});
|
||||
|
||||
} else {
|
||||
if (error) {
|
||||
StateText = _("Not everything is synced");
|
||||
|
||||
Application.Invoke (delegate {
|
||||
#if HAVE_APP_INDICATOR
|
||||
this.indicator.IconName = "sparkleshare-syncing-error";
|
||||
#else
|
||||
this.status_icon.Pixbuf = SparkleUIHelpers.GetIcon ("sparkleshare-syncing-error", 24);
|
||||
#endif
|
||||
});
|
||||
} else {
|
||||
StateText = _("Up to date") + " (" + SparkleShare.Controller.FolderSize + ")";
|
||||
Application.Invoke (delegate {
|
||||
#if HAVE_APP_INDICATOR
|
||||
this.indicator.IconName = "process-syncing-sparkleshare-i";
|
||||
#else
|
||||
this.status_icon.Pixbuf = AnimationFrames [0];
|
||||
#endif
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// The state when animating
|
||||
private void SetAnimationState ()
|
||||
{
|
||||
StateText = _("Syncing…");
|
||||
|
||||
if (!Animation.Enabled)
|
||||
Animation.Start ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -38,29 +38,29 @@ namespace SparkleShare {
|
|||
|
||||
public string [] Folders {
|
||||
get {
|
||||
return SparkleShare.Controller.Folders.ToArray ();
|
||||
return Program.Controller.Folders.ToArray ();
|
||||
}
|
||||
}
|
||||
|
||||
public string FolderSize {
|
||||
get {
|
||||
return SparkleShare.Controller.FolderSize;
|
||||
return Program.Controller.FolderSize;
|
||||
}
|
||||
}
|
||||
|
||||
public SparkleStatusIconController ()
|
||||
{
|
||||
SparkleShare.Controller.FolderSizeChanged += delegate {
|
||||
Program.Controller.FolderSizeChanged += delegate {
|
||||
if (UpdateMenuEvent != null)
|
||||
UpdateMenuEvent (CurrentState);
|
||||
};
|
||||
|
||||
SparkleShare.Controller.FolderListChanged += delegate {
|
||||
Program.Controller.FolderListChanged += delegate {
|
||||
if (UpdateMenuEvent != null)
|
||||
UpdateMenuEvent (CurrentState);
|
||||
};
|
||||
|
||||
SparkleShare.Controller.OnIdle += delegate {
|
||||
Program.Controller.OnIdle += delegate {
|
||||
if (CurrentState != IconState.Error)
|
||||
CurrentState = IconState.Idle;
|
||||
|
||||
|
@ -68,14 +68,16 @@ namespace SparkleShare {
|
|||
UpdateMenuEvent (CurrentState);
|
||||
};
|
||||
|
||||
SparkleShare.Controller.OnSyncing += delegate {
|
||||
Program.Controller.OnSyncing += delegate {
|
||||
CurrentState = IconState.Syncing;
|
||||
|
||||
// TODO up down both
|
||||
|
||||
if (UpdateMenuEvent != null)
|
||||
UpdateMenuEvent (IconState.Syncing);
|
||||
};
|
||||
|
||||
SparkleShare.Controller.OnError += delegate {
|
||||
Program.Controller.OnError += delegate {
|
||||
CurrentState = IconState.Error;
|
||||
|
||||
if (UpdateMenuEvent != null)
|
||||
|
|
|
@ -40,14 +40,20 @@ namespace SparkleShare {
|
|||
public static Gdk.Pixbuf GetIcon (string name, int size)
|
||||
{
|
||||
IconTheme icon_theme = new IconTheme ();
|
||||
icon_theme.AppendSearchPath (SparklePaths.SparkleIconPath);
|
||||
icon_theme.AppendSearchPath (SparklePaths.SparkleLocalIconPath);
|
||||
|
||||
icon_theme.AppendSearchPath (
|
||||
Path.Combine (SparkleUI.AssetsPath, "icons"));
|
||||
|
||||
icon_theme.AppendSearchPath (
|
||||
Path.Combine (SparkleConfig.ConfigPath, "icons"));
|
||||
|
||||
try {
|
||||
return icon_theme.LoadIcon (name, size, IconLookupFlags.GenericFallback);
|
||||
|
||||
} catch {
|
||||
try {
|
||||
return icon_theme.LoadIcon ("gtk-missing-image", size, IconLookupFlags.GenericFallback);
|
||||
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
|
@ -55,6 +61,15 @@ namespace SparkleShare {
|
|||
}
|
||||
|
||||
|
||||
public static Image GetImage (string name)
|
||||
{
|
||||
string image_path = SparkleHelpers.CombineMore (Defines.DATAROOTDIR, "sparkleshare",
|
||||
"pixmaps", name);
|
||||
|
||||
return new Image (image_path);
|
||||
}
|
||||
|
||||
|
||||
// Converts a Gdk RGB color to a hex value.
|
||||
// Example: from "rgb:0,0,0" to "#000000"
|
||||
public static string GdkColorToHex (Gdk.Color color)
|
||||
|
|
|
@ -22,13 +22,16 @@ using System.IO;
|
|||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
#if __MonoCS__
|
||||
using Mono.Unix;
|
||||
//using Mono.Unix.Native;
|
||||
#endif
|
||||
using SparkleLib;
|
||||
using SparkleLib.Options;
|
||||
|
||||
namespace SparkleShare {
|
||||
|
||||
// This is SparkleShare!
|
||||
// http://blogs.msdn.com/b/ericlippert/archive/2010/03/09/do-not-name-a-class-the-same-as-its-namespace-part-one.aspx
|
||||
public class Program {
|
||||
|
||||
public static SparkleController Controller;
|
||||
|
@ -38,22 +41,18 @@ namespace SparkleShare {
|
|||
// Short alias for the translations
|
||||
public static string _ (string s)
|
||||
{
|
||||
#if __MonoCS__
|
||||
return Catalog.GetString (s);
|
||||
#else
|
||||
return s;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !__MonoCS__
|
||||
[STAThread]
|
||||
#endif
|
||||
public static void Main (string [] args)
|
||||
{
|
||||
// Don't allow running as root on Linux or Mac
|
||||
#if __MonoCS__
|
||||
if (new Mono.Unix.UnixUserInfo (Mono.Unix.UnixEnvironment.UserName).UserId == 0) {
|
||||
|
||||
Console.WriteLine (_("Sorry, you can't run SparkleShare with these permissions."));
|
||||
Console.WriteLine (_("Things would go utterly wrong."));
|
||||
Environment.Exit (-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Parse the command line options
|
||||
bool show_help = false;
|
||||
OptionSet option_set = new OptionSet () {
|
||||
|
@ -73,25 +72,10 @@ namespace SparkleShare {
|
|||
if (show_help)
|
||||
ShowHelp (option_set);
|
||||
|
||||
// Load the right controller for the OS
|
||||
string controller_name = "Lin";
|
||||
switch (SparkleBackend.Platform) {
|
||||
case PlatformID.Unix:
|
||||
SetProcessName ("sparkleshare");
|
||||
break;
|
||||
case PlatformID.MacOSX:
|
||||
controller_name = "Mac";
|
||||
break;
|
||||
case PlatformID.Win32NT:
|
||||
controller_name = "Win";
|
||||
break;
|
||||
}
|
||||
|
||||
// Initialize the controller this way so that
|
||||
// there aren't any exceptions in the OS specific UI's
|
||||
Controller = (SparkleController) Activator.CreateInstance (
|
||||
Type.GetType ("SparkleShare.Sparkle" + controller_name + "Controller"));
|
||||
|
||||
Controller = new SparkleController ();
|
||||
Controller.Initialize ();
|
||||
|
||||
if (Controller != null) {
|
||||
|
|
|
@ -28,9 +28,9 @@ using CefSharp;
|
|||
|
||||
namespace SparkleShare {
|
||||
|
||||
public class SparkleWinController : SparkleController {
|
||||
public class SparkleController : SparkleControllerBase {
|
||||
|
||||
public SparkleWinController () : base ()
|
||||
public SparkleController () : base ()
|
||||
{
|
||||
}
|
||||
|
|
@ -71,6 +71,12 @@
|
|||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>GlobalAssemblyInfo.tt</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="..\SparkleControllerBase.cs">
|
||||
<Link>SparkleControllerBase.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\SparkleExtensions.cs">
|
||||
<Link>SparkleExtensions.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="ApplicationSchemeHandler.cs" />
|
||||
<Compile Include="AssemblyInfo.cs" />
|
||||
<Compile Include="controls\ExampleTextBox.cs">
|
||||
|
@ -104,8 +110,8 @@
|
|||
</Compile>
|
||||
<Compile Include="..\SparkleSetupController.cs" />
|
||||
<Compile Include="..\SparkleUI.cs" />
|
||||
<Compile Include="..\SparkleController.cs" />
|
||||
<Compile Include="..\SparkleAboutController.cs" />
|
||||
<Compile Include="SparkleController.cs" />
|
||||
<Compile Include="SparkleEventLog.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
@ -121,7 +127,6 @@
|
|||
<Compile Include="Program.cs" />
|
||||
<Compile Include="SparkleStatusIcon.cs" />
|
||||
<Compile Include="SparkleUIHelpers.cs" />
|
||||
<Compile Include="SparkleWinController.cs" />
|
||||
<Compile Include="controls\TablessControl.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [[ $UID -eq 0 ]]; then
|
||||
echo "Cannot run as root. Things would go utterly wrong."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$XDG_RUNTIME_DIR" ]; then
|
||||
pidfile=${XDG_RUNTIME_DIR}/sparkleshare.pid
|
||||
else
|
||||
|
|
Loading…
Reference in a new issue