[helpers] split up helpers to gui and non gui parts.
This commit is contained in:
parent
71cfc24642
commit
1644c5c5f2
3
AUTHORS
3
AUTHORS
|
@ -10,7 +10,7 @@ Contributors:
|
||||||
Benjamin Podszun <benjamin.podszun@gmail.com>
|
Benjamin Podszun <benjamin.podszun@gmail.com>
|
||||||
Bertrand Lorentz <bertrand.lorentz@gmail.com>
|
Bertrand Lorentz <bertrand.lorentz@gmail.com>
|
||||||
Garrett LeSage <garrett@novell.com>
|
Garrett LeSage <garrett@novell.com>
|
||||||
Jakub Steiner <jimmac@novell.com>
|
Jakub Steiner <jimmac@redhat.com>
|
||||||
Lapo Calamandrei <calamandrei@gmail.com>
|
Lapo Calamandrei <calamandrei@gmail.com>
|
||||||
Łukasz Jernaś <deejay1@srem.org>
|
Łukasz Jernaś <deejay1@srem.org>
|
||||||
Michael Monreal <michael.monreal@gmail.com>
|
Michael Monreal <michael.monreal@gmail.com>
|
||||||
|
@ -21,5 +21,6 @@ Contributors:
|
||||||
Sandy Armstrong <sanfordarmstrong@gmail.com>
|
Sandy Armstrong <sanfordarmstrong@gmail.com>
|
||||||
Simon Pither <simon@pither.com>
|
Simon Pither <simon@pither.com>
|
||||||
Steven Harms <sharms@ubuntu.com>
|
Steven Harms <sharms@ubuntu.com>
|
||||||
|
Vincent Untz <vuntz@gnome.org>
|
||||||
|
|
||||||
Thanks very much!
|
Thanks very much!
|
||||||
|
|
|
@ -5,9 +5,10 @@ LINK = $(REF_SPARKLELIB)
|
||||||
|
|
||||||
SOURCES = \
|
SOURCES = \
|
||||||
Defines.cs \
|
Defines.cs \
|
||||||
SparkleOptions.cs \
|
SparkleEvents.cs \
|
||||||
SparkleFetcher.cs \
|
SparkleFetcher.cs \
|
||||||
SparkleHelpers.cs \
|
SparkleHelpers.cs \
|
||||||
|
SparkleOptions.cs \
|
||||||
SparklePaths.cs \
|
SparklePaths.cs \
|
||||||
SparklePlatform.cs \
|
SparklePlatform.cs \
|
||||||
SparkleRepo.cs
|
SparkleRepo.cs
|
||||||
|
|
|
@ -14,176 +14,46 @@
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
using Gtk;
|
|
||||||
using Mono.Unix;
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
|
|
||||||
namespace SparkleLib {
|
namespace SparkleLib {
|
||||||
|
|
||||||
public static class SparkleHelpers
|
public static class SparkleHelpers
|
||||||
{
|
{
|
||||||
|
|
||||||
// Gets the avatar for a specific email address and size
|
|
||||||
public static Gdk.Pixbuf GetAvatar (string Email, int Size)
|
|
||||||
{
|
|
||||||
|
|
||||||
string AvatarPath = CombineMore (SparklePaths.SparkleLocalIconPath, Size + "x" + Size, "status");
|
|
||||||
|
|
||||||
if (!Directory.Exists (AvatarPath)) {
|
|
||||||
Directory.CreateDirectory (AvatarPath);
|
|
||||||
SparkleHelpers.DebugInfo ("Config", "Created '" + AvatarPath + "'");
|
|
||||||
}
|
|
||||||
|
|
||||||
string AvatarFilePath = CombineMore (AvatarPath, "avatar-" + Email);
|
|
||||||
|
|
||||||
if (File.Exists (AvatarFilePath))
|
|
||||||
return new Gdk.Pixbuf (AvatarFilePath);
|
|
||||||
else {
|
|
||||||
|
|
||||||
// Let's try to get the person's gravatar for next time
|
|
||||||
WebClient WebClient = new WebClient ();
|
|
||||||
Uri GravatarUri = new Uri ("http://www.gravatar.com/avatar/" + GetMD5 (Email) +
|
|
||||||
".jpg?s=" + Size + "&d=404");
|
|
||||||
|
|
||||||
string TmpFile = CombineMore (SparklePaths.SparkleTmpPath, Email + Size);
|
|
||||||
|
|
||||||
if (!File.Exists (TmpFile)) {
|
|
||||||
|
|
||||||
WebClient.DownloadFileAsync (GravatarUri, TmpFile);
|
|
||||||
WebClient.DownloadFileCompleted += delegate {
|
|
||||||
File.Delete (AvatarFilePath);
|
|
||||||
FileInfo TmpFileInfo = new FileInfo (TmpFile);
|
|
||||||
if (TmpFileInfo.Length > 255)
|
|
||||||
File.Move (TmpFile, AvatarFilePath);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fall back to a generic icon if there is no gravatar
|
|
||||||
if (File.Exists (AvatarFilePath))
|
|
||||||
return new Gdk.Pixbuf (AvatarFilePath);
|
|
||||||
else
|
|
||||||
return GetIcon ("avatar-default", Size);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Creates an MD5 hash of input
|
|
||||||
public static string GetMD5 (string s)
|
|
||||||
{
|
|
||||||
MD5 md5 = new MD5CryptoServiceProvider ();
|
|
||||||
Byte[] bytes = ASCIIEncoding.Default.GetBytes (s);
|
|
||||||
Byte[] encodedBytes = md5.ComputeHash (bytes);
|
|
||||||
return BitConverter.ToString (encodedBytes).ToLower ().Replace ("-", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Makes it possible to combine more than
|
|
||||||
// two paths at once
|
|
||||||
public static string CombineMore (params string [] Parts)
|
|
||||||
{
|
|
||||||
string NewPath = " ";
|
|
||||||
foreach (string Part in Parts)
|
|
||||||
NewPath = Path.Combine (NewPath, Part);
|
|
||||||
return NewPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Looks up an icon from the system's theme
|
|
||||||
public static Gdk.Pixbuf GetIcon (string name, int size)
|
|
||||||
{
|
|
||||||
|
|
||||||
IconTheme IconTheme = new IconTheme ();
|
|
||||||
IconTheme.AppendSearchPath (SparklePaths.SparkleIconPath);
|
|
||||||
IconTheme.AppendSearchPath (SparklePaths.SparkleLocalIconPath);
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
return IconTheme.LoadIcon (name, size, IconLookupFlags.GenericFallback);
|
|
||||||
|
|
||||||
} catch {
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
return IconTheme.LoadIcon ("gtk-missing-image", size, IconLookupFlags.GenericFallback);
|
|
||||||
|
|
||||||
} catch {
|
|
||||||
|
|
||||||
return null;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static bool ShowDebugInfo = true;
|
public static bool ShowDebugInfo = true;
|
||||||
|
|
||||||
|
|
||||||
// Show debug info if needed
|
// Show debug info if needed
|
||||||
public static void DebugInfo (string Type, string Message)
|
public static void DebugInfo (string type, string message)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (ShowDebugInfo) {
|
if (ShowDebugInfo) {
|
||||||
DateTime DateTime = new DateTime ();
|
|
||||||
string TimeStamp = DateTime.Now.ToString ("HH:mm:ss");
|
string timestamp = DateTime.Now.ToString ("HH:mm:ss");
|
||||||
if (Message.StartsWith ("["))
|
|
||||||
Console.WriteLine ("[" + TimeStamp + "]" + "[" + Type + "]" + Message);
|
if (message.StartsWith ("["))
|
||||||
|
Console.WriteLine ("[" + timestamp + "]" + "[" + type + "]" + message);
|
||||||
else
|
else
|
||||||
Console.WriteLine ("[" + TimeStamp + "]" + "[" + Type + "] " + Message);
|
Console.WriteLine ("[" + timestamp + "]" + "[" + type + "] " + message);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Formats a timestamp to a relative date compared to the current time
|
// Makes it possible to combine more than
|
||||||
// Example: "about 5 hours ago"
|
// two paths at once
|
||||||
public static string ToRelativeDate (DateTime date_time)
|
public static string CombineMore (params string [] parts)
|
||||||
{
|
{
|
||||||
|
|
||||||
TimeSpan time_span = new TimeSpan (0);
|
string new_path = "";
|
||||||
time_span = DateTime.Now - date_time;
|
|
||||||
|
|
||||||
if (time_span <= TimeSpan.FromSeconds (60)) {
|
foreach (string part in parts)
|
||||||
return string.Format (Catalog.GetPluralString ("a second ago", "{0} seconds ago",
|
new_path = Path.Combine (new_path, part);
|
||||||
time_span.Seconds),
|
|
||||||
time_span.Seconds);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (time_span <= TimeSpan.FromSeconds (60)) {
|
return new_path;
|
||||||
return string.Format (Catalog.GetPluralString ("a minute ago", "about {0} minutes ago",
|
|
||||||
time_span.Minutes),
|
|
||||||
time_span.Minutes);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (time_span <= TimeSpan.FromHours (24)) {
|
|
||||||
return string.Format (Catalog.GetPluralString ("about an hour ago", "about {0} hours ago",
|
|
||||||
time_span.Hours),
|
|
||||||
time_span.Hours);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (time_span <= TimeSpan.FromDays (30)) {
|
|
||||||
return string.Format (Catalog.GetPluralString ("yesterday", "{0} days ago",
|
|
||||||
time_span.Days),
|
|
||||||
time_span.Days);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (time_span <= TimeSpan.FromDays (365)) {
|
|
||||||
return string.Format (Catalog.GetPluralString ("a month ago", "{0} months ago",
|
|
||||||
(int) time_span.Days / 30),
|
|
||||||
(int) time_span.Days / 30);
|
|
||||||
}
|
|
||||||
|
|
||||||
return string.Format (Catalog.GetPluralString ("a year ago", "{0} years ago",
|
|
||||||
(int) time_span.Days / 365),
|
|
||||||
(int) time_span.Days / 365);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,9 +30,6 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
|
|
||||||
<Package>gtk-sharp-2.0</Package>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Mono.Posix" />
|
<Reference Include="Mono.Posix" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -42,6 +39,8 @@
|
||||||
<Compile Include="SparkleHelpers.cs" />
|
<Compile Include="SparkleHelpers.cs" />
|
||||||
<Compile Include="SparklePaths.cs" />
|
<Compile Include="SparklePaths.cs" />
|
||||||
<Compile Include="SparklePlatform.cs" />
|
<Compile Include="SparklePlatform.cs" />
|
||||||
|
<Compile Include="SparkleEvents.cs" />
|
||||||
|
<Compile Include="SparkleOptions.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
<ProjectExtensions>
|
<ProjectExtensions>
|
||||||
|
|
|
@ -775,40 +775,4 @@ namespace SparkleLib {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Arguments for most events
|
|
||||||
public class SparkleEventArgs : System.EventArgs {
|
|
||||||
|
|
||||||
public string Type;
|
|
||||||
public string Message;
|
|
||||||
|
|
||||||
public SparkleEventArgs (string type)
|
|
||||||
{
|
|
||||||
|
|
||||||
Type = type;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Arguments for the NewCommit event
|
|
||||||
public class NewCommitArgs : System.EventArgs {
|
|
||||||
|
|
||||||
public string Author;
|
|
||||||
public string Email;
|
|
||||||
public string Message;
|
|
||||||
public string RepositoryName;
|
|
||||||
|
|
||||||
public NewCommitArgs (string author, string email, string message, string repository_name)
|
|
||||||
{
|
|
||||||
|
|
||||||
Author = author;
|
|
||||||
Email = email;
|
|
||||||
Message = message;
|
|
||||||
RepositoryName = repository_name;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ SOURCES = \
|
||||||
SparkleSpinner.cs \
|
SparkleSpinner.cs \
|
||||||
SparkleStatusIcon.cs \
|
SparkleStatusIcon.cs \
|
||||||
SparkleUI.cs \
|
SparkleUI.cs \
|
||||||
|
SparkleUIHelpers.cs \
|
||||||
SparkleWindow.cs
|
SparkleWindow.cs
|
||||||
|
|
||||||
include $(top_srcdir)/build/build.mk
|
include $(top_srcdir)/build/build.mk
|
||||||
|
|
|
@ -172,7 +172,7 @@ namespace SparkleShare {
|
||||||
HBox layout_server = new HBox (true, 0);
|
HBox layout_server = new HBox (true, 0);
|
||||||
|
|
||||||
ServerEntry = new SparkleEntry () {
|
ServerEntry = new SparkleEntry () {
|
||||||
ExampleText = _("ssh://address-to-my-server/")
|
ExampleText = _("address-to-server.com")
|
||||||
};
|
};
|
||||||
|
|
||||||
ServerEntry.Changed += CheckServerForm;
|
ServerEntry.Changed += CheckServerForm;
|
||||||
|
@ -295,9 +295,18 @@ namespace SparkleShare {
|
||||||
if (name.EndsWith ("/"))
|
if (name.EndsWith ("/"))
|
||||||
name = name.TrimEnd ("/".ToCharArray ());
|
name = name.TrimEnd ("/".ToCharArray ());
|
||||||
|
|
||||||
|
if (name.StartsWith ("/"))
|
||||||
|
name = name.TrimStart ("/".ToCharArray ());
|
||||||
|
|
||||||
if (radio_button.Active) {
|
if (radio_button.Active) {
|
||||||
|
|
||||||
server = SparkleToGitUrl (ServerEntry.Text);
|
// Use the default user 'git' if no username is specified
|
||||||
|
if (!server.Contains ("@"))
|
||||||
|
server = "git@" + server;
|
||||||
|
|
||||||
|
// Prepend the Secure Shell protocol when it isn't specified
|
||||||
|
if (!server.StartsWith ("ssh://"))
|
||||||
|
server = "ssh://" + server;
|
||||||
|
|
||||||
// Remove the trailing slash if there is one
|
// Remove the trailing slash if there is one
|
||||||
if (server.EndsWith ("/"))
|
if (server.EndsWith ("/"))
|
||||||
|
@ -368,6 +377,7 @@ namespace SparkleShare {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// The page shown when syncing has failed
|
||||||
private void ShowErrorPage ()
|
private void ShowErrorPage ()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -401,6 +411,7 @@ namespace SparkleShare {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// The page shown when syncing has succeeded
|
||||||
private void ShowSuccessPage (string name)
|
private void ShowSuccessPage (string name)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -422,6 +433,7 @@ namespace SparkleShare {
|
||||||
UseMarkup = true
|
UseMarkup = true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// A button that opens the synced folder
|
||||||
Button open_folder_button = new Button (_("Open Folder"));
|
Button open_folder_button = new Button (_("Open Folder"));
|
||||||
|
|
||||||
open_folder_button.Clicked += delegate (object o, EventArgs args) {
|
open_folder_button.Clicked += delegate (object o, EventArgs args) {
|
||||||
|
@ -457,6 +469,7 @@ namespace SparkleShare {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// The page shown whilst syncing
|
||||||
private void ShowSyncingPage (string name)
|
private void ShowSyncingPage (string name)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -514,6 +527,7 @@ namespace SparkleShare {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// The page shown when the setup has been completed
|
||||||
private void ShowCompletedPage ()
|
private void ShowCompletedPage ()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -572,9 +586,11 @@ namespace SparkleShare {
|
||||||
private void FetchFolder (string url, string name)
|
private void FetchFolder (string url, string name)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// Strip the '.git' from the name
|
||||||
string canonical_name = System.IO.Path.GetFileNameWithoutExtension (name);
|
string canonical_name = System.IO.Path.GetFileNameWithoutExtension (name);
|
||||||
string tmp_folder = SparkleHelpers.CombineMore (SparklePaths.SparkleTmpPath, canonical_name);
|
string tmp_folder = SparkleHelpers.CombineMore (SparklePaths.SparkleTmpPath, canonical_name);
|
||||||
|
|
||||||
|
ShowSyncingPage (canonical_name);
|
||||||
SparkleFetcher fetcher = new SparkleFetcher (url, tmp_folder);
|
SparkleFetcher fetcher = new SparkleFetcher (url, tmp_folder);
|
||||||
|
|
||||||
|
|
||||||
|
@ -643,8 +659,6 @@ namespace SparkleShare {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ShowSyncingPage (canonical_name);
|
|
||||||
|
|
||||||
fetcher.Clone ();
|
fetcher.Clone ();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -806,19 +820,6 @@ namespace SparkleShare {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Convert the more human readable sparkle:// url to something Git can use.
|
|
||||||
// Example: sparkle://gitorious.org/sparkleshare ssh://git@gitorious.org/sparkleshare
|
|
||||||
private static string SparkleToGitUrl (string url)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (url.StartsWith ("sparkle://"))
|
|
||||||
url = url.Replace ("sparkle://", "ssh://git@");
|
|
||||||
|
|
||||||
return url;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -290,10 +290,6 @@ namespace SparkleShare {
|
||||||
|
|
||||||
link.ModifyBg (StateType.Normal, background_color);
|
link.ModifyBg (StateType.Normal, background_color);
|
||||||
|
|
||||||
link.ButtonPressEvent += delegate {
|
|
||||||
Destroy ();
|
|
||||||
};
|
|
||||||
|
|
||||||
added_files.PackStart (link, false, false, 0);
|
added_files.PackStart (link, false, false, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -306,10 +302,6 @@ namespace SparkleShare {
|
||||||
|
|
||||||
link.ModifyBg (StateType.Normal, background_color);
|
link.ModifyBg (StateType.Normal, background_color);
|
||||||
|
|
||||||
link.ButtonPressEvent += delegate {
|
|
||||||
Destroy ();
|
|
||||||
};
|
|
||||||
|
|
||||||
deleted_files.PackStart (link, false, false, 0);
|
deleted_files.PackStart (link, false, false, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -321,19 +313,11 @@ namespace SparkleShare {
|
||||||
|
|
||||||
from_link.ModifyBg (StateType.Normal, background_color);
|
from_link.ModifyBg (StateType.Normal, background_color);
|
||||||
|
|
||||||
from_link.ButtonPressEvent += delegate {
|
|
||||||
Destroy ();
|
|
||||||
};
|
|
||||||
|
|
||||||
SparkleLink to_link = new SparkleLink (change_set.MovedTo [i],
|
SparkleLink to_link = new SparkleLink (change_set.MovedTo [i],
|
||||||
SparkleHelpers.CombineMore (LocalPath, change_set.MovedTo [i]));
|
SparkleHelpers.CombineMore (LocalPath, change_set.MovedTo [i]));
|
||||||
|
|
||||||
to_link.ModifyBg (StateType.Normal, background_color);
|
to_link.ModifyBg (StateType.Normal, background_color);
|
||||||
|
|
||||||
to_link.ButtonPressEvent += delegate {
|
|
||||||
Destroy ();
|
|
||||||
};
|
|
||||||
|
|
||||||
Label to_label = new Label ("<span fgcolor='" + secondary_text_color +"'>" +
|
Label to_label = new Label ("<span fgcolor='" + secondary_text_color +"'>" +
|
||||||
"<small>to</small></span> ") {
|
"<small>to</small></span> ") {
|
||||||
UseMarkup = true,
|
UseMarkup = true,
|
||||||
|
@ -344,9 +328,10 @@ namespace SparkleShare {
|
||||||
link_wrapper.PackStart (to_label, false, false, 0);
|
link_wrapper.PackStart (to_label, false, false, 0);
|
||||||
link_wrapper.PackStart (to_link, true, true, 0);
|
link_wrapper.PackStart (to_link, true, true, 0);
|
||||||
|
|
||||||
|
|
||||||
moved_files.PackStart (from_link, false, false, 0);
|
moved_files.PackStart (from_link, false, false, 0);
|
||||||
moved_files.PackStart (link_wrapper, false, false, 0);
|
moved_files.PackStart (link_wrapper, false, false, 0);
|
||||||
|
|
||||||
|
if (change_set.MovedFrom.Count > 1)
|
||||||
moved_files.PackStart (new Label (""), false, false, 0);
|
moved_files.PackStart (new Label (""), false, false, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -419,7 +404,7 @@ namespace SparkleShare {
|
||||||
|
|
||||||
HBox hbox = new HBox (false, 0);
|
HBox hbox = new HBox (false, 0);
|
||||||
|
|
||||||
Image avatar = new Image (SparkleHelpers.GetAvatar (change_set.UserEmail, 32)) {
|
Image avatar = new Image (SparkleUIHelpers.GetAvatar (change_set.UserEmail, 32)) {
|
||||||
Yalign = 0
|
Yalign = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -452,7 +437,7 @@ namespace SparkleShare {
|
||||||
|
|
||||||
|
|
||||||
// Converts a UNIX timestamp to a more usable time object
|
// Converts a UNIX timestamp to a more usable time object
|
||||||
public DateTime UnixTimestampToDateTime (int timestamp)
|
public static DateTime UnixTimestampToDateTime (int timestamp)
|
||||||
{
|
{
|
||||||
DateTime unix_epoch = new DateTime (1970, 1, 1, 0, 0, 0, 0);
|
DateTime unix_epoch = new DateTime (1970, 1, 1, 0, 0, 0, 0);
|
||||||
return unix_epoch.AddSeconds (timestamp);
|
return unix_epoch.AddSeconds (timestamp);
|
||||||
|
@ -461,7 +446,7 @@ namespace SparkleShare {
|
||||||
|
|
||||||
// Converts a Gdk RGB color to a hex value.
|
// Converts a Gdk RGB color to a hex value.
|
||||||
// Example: from "rgb:0,0,0" to "#000000"
|
// Example: from "rgb:0,0,0" to "#000000"
|
||||||
public string GdkColorToHex (Gdk.Color color)
|
public static string GdkColorToHex (Gdk.Color color)
|
||||||
{
|
{
|
||||||
|
|
||||||
return String.Format ("#{0:X2}{1:X2}{2:X2}",
|
return String.Format ("#{0:X2}{1:X2}{2:X2}",
|
||||||
|
@ -481,13 +466,15 @@ namespace SparkleShare {
|
||||||
|
|
||||||
public ActivityDay (DateTime date_time)
|
public ActivityDay (DateTime date_time)
|
||||||
{
|
{
|
||||||
|
|
||||||
DateTime = date_time;
|
DateTime = date_time;
|
||||||
DateTime = new DateTime (DateTime.Year, DateTime.Month, DateTime.Day);
|
DateTime = new DateTime (DateTime.Year, DateTime.Month, DateTime.Day);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Move this to the repo
|
||||||
public class ChangeSet
|
public class ChangeSet
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace SparkleShare {
|
||||||
CycleDuration = 600;
|
CycleDuration = 600;
|
||||||
CurrentStep = 0;
|
CurrentStep = 0;
|
||||||
|
|
||||||
Gdk.Pixbuf spinner_gallery = SparkleHelpers.GetIcon ("process-working", Size);
|
Gdk.Pixbuf spinner_gallery = SparkleUIHelpers.GetIcon ("process-working", Size);
|
||||||
|
|
||||||
int frames_in_width = spinner_gallery.Width / Size;
|
int frames_in_width = spinner_gallery.Width / Size;
|
||||||
int frames_in_height = spinner_gallery.Height / Size;
|
int frames_in_height = spinner_gallery.Height / Size;
|
||||||
|
|
|
@ -37,7 +37,6 @@ namespace SparkleShare {
|
||||||
private Gdk.Pixbuf [] AnimationFrames;
|
private Gdk.Pixbuf [] AnimationFrames;
|
||||||
private int FrameNumber;
|
private int FrameNumber;
|
||||||
|
|
||||||
private Gtk.Action FolderAction;
|
|
||||||
private double FolderSize;
|
private double FolderSize;
|
||||||
|
|
||||||
|
|
||||||
|
@ -79,7 +78,7 @@ namespace SparkleShare {
|
||||||
{
|
{
|
||||||
|
|
||||||
Gdk.Pixbuf [] animation_frames = new Gdk.Pixbuf [5];
|
Gdk.Pixbuf [] animation_frames = new Gdk.Pixbuf [5];
|
||||||
Gdk.Pixbuf frames_pixbuf = SparkleHelpers.GetIcon ("process-syncing-sparkleshare", 24);
|
Gdk.Pixbuf frames_pixbuf = SparkleUIHelpers.GetIcon ("process-syncing-sparkleshare", 24);
|
||||||
|
|
||||||
for (int i = 0; i < animation_frames.Length; i++)
|
for (int i = 0; i < animation_frames.Length; i++)
|
||||||
animation_frames [i] = new Gdk.Pixbuf (frames_pixbuf, (i * 24), 0, 24, 24);
|
animation_frames [i] = new Gdk.Pixbuf (frames_pixbuf, (i * 24), 0, 24, 24);
|
||||||
|
@ -133,7 +132,7 @@ namespace SparkleShare {
|
||||||
|
|
||||||
double size = 0;
|
double size = 0;
|
||||||
|
|
||||||
// Ignore the temporary rebase-apply directory.
|
// Ignore the temporary 'rebase-apply' directory
|
||||||
// This prevents potential crashes when files are being
|
// This prevents potential crashes when files are being
|
||||||
// queried whilst the files have already been deleted.
|
// queried whilst the files have already been deleted.
|
||||||
if (parent.Name.Equals ("rebase-apply"))
|
if (parent.Name.Equals ("rebase-apply"))
|
||||||
|
@ -164,25 +163,30 @@ namespace SparkleShare {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Format a file size nicely.
|
// Format a file size nicely with small caps.
|
||||||
// Example: 1048576 becomes "1 ᴍʙ"
|
// Example: 1048576 becomes "1 ᴍʙ"
|
||||||
private string FormatFileSize (double byte_count)
|
private string FormatFileSize (double byte_count)
|
||||||
{
|
{
|
||||||
|
|
||||||
string size = "";
|
|
||||||
|
|
||||||
if (byte_count >= 1099511627776)
|
if (byte_count >= 1099511627776)
|
||||||
size = String.Format (_("{0:##.##} ᴛʙ"), Math.Round (byte_count / 1099511627776, 1));
|
|
||||||
else if (byte_count >= 1073741824)
|
|
||||||
size = String.Format (_("{0:##.##} ɢʙ"), Math.Round (byte_count / 1073741824, 1));
|
|
||||||
else if (byte_count >= 1048576)
|
|
||||||
size = String.Format (_("{0:##.##} ᴍʙ"), Math.Round (byte_count / 1048576, 1));
|
|
||||||
else if (byte_count >= 1024)
|
|
||||||
size = String.Format (_("{0:##.##} ᴋʙ"), Math.Round (byte_count / 1024, 1));
|
|
||||||
else
|
|
||||||
size = byte_count.ToString () + " bytes";
|
|
||||||
|
|
||||||
return size;
|
return String.Format ("{0:##.##} ᴛʙ", Math.Round (byte_count / 1099511627776, 1));
|
||||||
|
|
||||||
|
else if (byte_count >= 1073741824)
|
||||||
|
|
||||||
|
return String.Format ("{0:##.##} ɢʙ", Math.Round (byte_count / 1073741824, 1));
|
||||||
|
|
||||||
|
else if (byte_count >= 1048576)
|
||||||
|
|
||||||
|
return String.Format ("{0:##.##} ᴍʙ", Math.Round (byte_count / 1048576, 1));
|
||||||
|
|
||||||
|
else if (byte_count >= 1024)
|
||||||
|
|
||||||
|
return String.Format ("{0:##.##} ᴋʙ", Math.Round (byte_count / 1024, 1));
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
return byte_count.ToString () + " bytes";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,20 +198,21 @@ namespace SparkleShare {
|
||||||
|
|
||||||
Menu = new Menu ();
|
Menu = new Menu ();
|
||||||
|
|
||||||
|
// The menu item showing the status and size of the SparkleShare folder
|
||||||
StatusMenuItem = new MenuItem (StateText) {
|
StatusMenuItem = new MenuItem (StateText) {
|
||||||
Sensitive = false
|
Sensitive = false
|
||||||
};
|
};
|
||||||
|
|
||||||
Menu.Add (StatusMenuItem);
|
Menu.Add (StatusMenuItem);
|
||||||
|
|
||||||
Menu.Add (new SeparatorMenuItem ());
|
Menu.Add (new SeparatorMenuItem ());
|
||||||
|
|
||||||
FolderAction = new Gtk.Action ("", "SparkleShare") {
|
// A menu item that provides a link to the SparkleShare folder
|
||||||
|
Gtk.Action folder_action = new Gtk.Action ("", "SparkleShare") {
|
||||||
IconName = "folder-sparkleshare",
|
IconName = "folder-sparkleshare",
|
||||||
IsImportant = true
|
IsImportant = true
|
||||||
};
|
};
|
||||||
|
|
||||||
FolderAction.Activated += delegate {
|
folder_action.Activated += delegate {
|
||||||
|
|
||||||
Process process = new Process ();
|
Process process = new Process ();
|
||||||
process.StartInfo.FileName = "xdg-open";
|
process.StartInfo.FileName = "xdg-open";
|
||||||
|
@ -216,20 +221,22 @@ namespace SparkleShare {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Menu.Add (FolderAction.CreateMenuItem ());
|
Menu.Add (folder_action.CreateMenuItem ());
|
||||||
|
|
||||||
|
|
||||||
if (SparkleUI.Repositories.Count > 0) {
|
if (SparkleUI.Repositories.Count > 0) {
|
||||||
|
|
||||||
|
// Creates a menu item for each repository with a link to them
|
||||||
foreach (SparkleRepo repo in SparkleUI.Repositories) {
|
foreach (SparkleRepo repo in SparkleUI.Repositories) {
|
||||||
|
|
||||||
FolderAction = new Gtk.Action ("", repo.Name) {
|
folder_action = new Gtk.Action ("", repo.Name) {
|
||||||
IconName = "folder",
|
IconName = "folder",
|
||||||
IsImportant = true
|
IsImportant = true
|
||||||
};
|
};
|
||||||
|
|
||||||
FolderAction.Activated += CreateWindowDelegate (repo.LocalPath);
|
folder_action.Activated += CreateWindowDelegate (repo.LocalPath);
|
||||||
|
|
||||||
MenuItem menu_item = (MenuItem) FolderAction.CreateMenuItem ();
|
MenuItem menu_item = (MenuItem) folder_action.CreateMenuItem ();
|
||||||
|
|
||||||
if (repo.Description != null)
|
if (repo.Description != null)
|
||||||
menu_item.TooltipText = repo.Description;
|
menu_item.TooltipText = repo.Description;
|
||||||
|
@ -258,7 +265,6 @@ namespace SparkleShare {
|
||||||
};
|
};
|
||||||
|
|
||||||
Menu.Add (add_item);
|
Menu.Add (add_item);
|
||||||
|
|
||||||
Menu.Add (new SeparatorMenuItem ());
|
Menu.Add (new SeparatorMenuItem ());
|
||||||
|
|
||||||
CheckMenuItem notify_item = new CheckMenuItem (_("Show Notifications"));
|
CheckMenuItem notify_item = new CheckMenuItem (_("Show Notifications"));
|
||||||
|
@ -296,11 +302,9 @@ namespace SparkleShare {
|
||||||
};
|
};
|
||||||
|
|
||||||
Menu.Add (about_item);
|
Menu.Add (about_item);
|
||||||
|
|
||||||
Menu.Add (new SeparatorMenuItem ());
|
Menu.Add (new SeparatorMenuItem ());
|
||||||
|
|
||||||
MenuItem quit_item = new MenuItem (_("Quit"));
|
MenuItem quit_item = new MenuItem (_("Quit"));
|
||||||
|
|
||||||
quit_item.Activated += Quit;
|
quit_item.Activated += Quit;
|
||||||
|
|
||||||
Menu.Add (quit_item);
|
Menu.Add (quit_item);
|
||||||
|
@ -320,9 +324,7 @@ namespace SparkleShare {
|
||||||
private void UpdateStatusMenuItem ()
|
private void UpdateStatusMenuItem ()
|
||||||
{
|
{
|
||||||
|
|
||||||
Label label = (Label) StatusMenuItem.Children [0];
|
(StatusMenuItem.Children [0] as Label).Text = StateText;
|
||||||
label.Text = StateText;
|
|
||||||
|
|
||||||
Menu.ShowAll ();
|
Menu.ShowAll ();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -336,6 +338,7 @@ namespace SparkleShare {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Shows the state and keeps the number of syncing repositories in mind
|
||||||
public void ShowState (bool error)
|
public void ShowState (bool error)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -394,7 +397,7 @@ namespace SparkleShare {
|
||||||
{
|
{
|
||||||
|
|
||||||
Timer.Stop ();
|
Timer.Stop ();
|
||||||
Application.Invoke (delegate { Pixbuf = SparkleHelpers.GetIcon ("sparkleshare-syncing-error", 24); });
|
Application.Invoke (delegate { Pixbuf = SparkleUIHelpers.GetIcon ("sparkleshare-syncing-error", 24); });
|
||||||
StateText = _("Failed to sync changes");
|
StateText = _("Failed to sync changes");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -311,7 +311,7 @@ namespace SparkleShare {
|
||||||
if (File.Exists (notify_settings_file)) {
|
if (File.Exists (notify_settings_file)) {
|
||||||
|
|
||||||
SparkleBubble bubble = new SparkleBubble (author, message) {
|
SparkleBubble bubble = new SparkleBubble (author, message) {
|
||||||
Icon = SparkleHelpers.GetAvatar (email, 32)
|
Icon = SparkleUIHelpers.GetAvatar (email, 32)
|
||||||
};
|
};
|
||||||
|
|
||||||
bubble.AddAction ("", "Show Events", delegate {
|
bubble.AddAction ("", "Show Events", delegate {
|
||||||
|
|
126
SparkleShare/SparkleUIHelpers.cs
Normal file
126
SparkleShare/SparkleUIHelpers.cs
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
// SparkleShare, an instant update workflow to Git.
|
||||||
|
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
using Gtk;
|
||||||
|
using SparkleLib;
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace SparkleShare {
|
||||||
|
|
||||||
|
public static class SparkleUIHelpers
|
||||||
|
{
|
||||||
|
|
||||||
|
// Creates an MD5 hash of input
|
||||||
|
public static string GetMD5 (string s)
|
||||||
|
{
|
||||||
|
MD5 md5 = new MD5CryptoServiceProvider ();
|
||||||
|
Byte[] bytes = ASCIIEncoding.Default.GetBytes (s);
|
||||||
|
Byte[] encodedBytes = md5.ComputeHash (bytes);
|
||||||
|
return BitConverter.ToString (encodedBytes).ToLower ().Replace ("-", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Gets the avatar for a specific email address and size
|
||||||
|
public static Gdk.Pixbuf GetAvatar (string email, int size)
|
||||||
|
{
|
||||||
|
|
||||||
|
string avatar_path = SparkleHelpers.CombineMore (SparklePaths.SparkleLocalIconPath,
|
||||||
|
size + "x" + size, "status");
|
||||||
|
|
||||||
|
if (!Directory.Exists (avatar_path)) {
|
||||||
|
|
||||||
|
Directory.CreateDirectory (avatar_path);
|
||||||
|
SparkleHelpers.DebugInfo ("Config", "Created '" + avatar_path + "'");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
string avatar_file_path = SparkleHelpers.CombineMore (avatar_path, "avatar-" + email);
|
||||||
|
|
||||||
|
if (File.Exists (avatar_file_path)) {
|
||||||
|
|
||||||
|
return new Gdk.Pixbuf (avatar_file_path);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Let's try to get the person's gravatar for next time
|
||||||
|
WebClient WebClient = new WebClient ();
|
||||||
|
Uri uri = new Uri ("http://www.gravatar.com/avatar/" + GetMD5 (email) +
|
||||||
|
".jpg?s=" + size + "&d=404");
|
||||||
|
|
||||||
|
string tmp_file_path = SparkleHelpers.CombineMore (SparklePaths.SparkleTmpPath, email + size);
|
||||||
|
|
||||||
|
if (!File.Exists (tmp_file_path)) {
|
||||||
|
|
||||||
|
WebClient.DownloadFileAsync (uri, tmp_file_path);
|
||||||
|
|
||||||
|
WebClient.DownloadFileCompleted += delegate {
|
||||||
|
|
||||||
|
File.Delete (avatar_file_path);
|
||||||
|
FileInfo tmp_file_info = new FileInfo (tmp_file_path);
|
||||||
|
|
||||||
|
if (tmp_file_info.Length > 255)
|
||||||
|
File.Move (tmp_file_path, avatar_file_path);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fall back to a generic icon if there is no gravatar
|
||||||
|
if (File.Exists (avatar_file_path))
|
||||||
|
return new Gdk.Pixbuf (avatar_file_path);
|
||||||
|
else
|
||||||
|
return GetIcon ("avatar-default", size);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Looks up an icon from the system's theme
|
||||||
|
public static Gdk.Pixbuf GetIcon (string name, int size)
|
||||||
|
{
|
||||||
|
|
||||||
|
IconTheme icon_theme = new IconTheme ();
|
||||||
|
icon_theme.AppendSearchPath (SparklePaths.SparkleIconPath);
|
||||||
|
icon_theme.AppendSearchPath (SparklePaths.SparkleLocalIconPath);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
return icon_theme.LoadIcon (name, size, IconLookupFlags.GenericFallback);
|
||||||
|
|
||||||
|
} catch {
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
return icon_theme.LoadIcon ("gtk-missing-image", size, IconLookupFlags.GenericFallback);
|
||||||
|
|
||||||
|
} catch {
|
||||||
|
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue