[helpers] split up helpers to gui and non gui parts.

This commit is contained in:
Hylke Bons 2010-09-04 13:27:06 +01:00
parent 71cfc24642
commit 1644c5c5f2
12 changed files with 289 additions and 336 deletions

View file

@ -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!

View file

@ -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

View file

@ -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);
} }

View file

@ -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>

View file

@ -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;
}
}
} }

View file

@ -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

View file

@ -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,54 +411,56 @@ namespace SparkleShare {
} }
// The page shown when syncing has succeeded
private void ShowSuccessPage (string name) private void ShowSuccessPage (string name)
{ {
Reset (); Reset ();
VBox layout_vertical = new VBox (false, 0); VBox layout_vertical = new VBox (false, 0);
Label header = new Label ("<span size='x-large'><b>" + Label header = new Label ("<span size='x-large'><b>" +
_("Folder synced successfully!") + _("Folder synced successfully!") +
"</b></span>") { "</b></span>") {
UseMarkup = true, UseMarkup = true,
Xalign = 0 Xalign = 0
}; };
Label information = new Label (_("Now you can access the synced files from " + name + " " + Label information = new Label (_("Now you can access the synced files from " + name + " " +
"in your SparkleShare folder.")) { "in your SparkleShare folder.")) {
Xalign = 0, Xalign = 0,
Wrap = true, Wrap = true,
UseMarkup = true UseMarkup = true
}; };
Button open_folder_button = new Button (_("Open Folder")); // A button that opens the synced 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) {
string path = SparkleHelpers.CombineMore (SparklePaths.SparklePath, name); string path = SparkleHelpers.CombineMore (SparklePaths.SparklePath, name);
Process process = new Process (); Process process = new Process ();
process.StartInfo.FileName = "xdg-open"; process.StartInfo.FileName = "xdg-open";
process.StartInfo.Arguments = path.Replace (" ", "\\ "); // Escape space-characters process.StartInfo.Arguments = path.Replace (" ", "\\ "); // Escape space-characters
process.Start (); process.Start ();
if (ServerFormOnly) if (ServerFormOnly)
Destroy ();
};
Button finish_button = new Button (_("Finish"));
finish_button.Clicked += delegate (object o, EventArgs args) {
Destroy (); Destroy ();
};
AddButton (open_folder_button);
AddButton (finish_button);
layout_vertical.PackStart (header, false, false, 0); };
layout_vertical.PackStart (information, false, false, 21);
Button finish_button = new Button (_("Finish"));
finish_button.Clicked += delegate (object o, EventArgs args) {
Destroy ();
};
AddButton (open_folder_button);
AddButton (finish_button);
layout_vertical.PackStart (header, false, false, 0);
layout_vertical.PackStart (information, false, false, 21);
Add (layout_vertical); Add (layout_vertical);
@ -457,55 +469,56 @@ namespace SparkleShare {
} }
// The page shown whilst syncing
private void ShowSyncingPage (string name) private void ShowSyncingPage (string name)
{ {
Reset (); Reset ();
VBox layout_vertical = new VBox (false, 0); VBox layout_vertical = new VBox (false, 0);
Label header = new Label ("<span size='x-large'><b>" + Label header = new Label ("<span size='x-large'><b>" +
String.Format (_("Syncing folder {0}’…"), name) + String.Format (_("Syncing folder {0}’…"), name) +
"</b></span>") { "</b></span>") {
UseMarkup = true, UseMarkup = true,
Xalign = 0, Xalign = 0,
Wrap = true Wrap = true
};
Label information = new Label (_("This may take a while.\n") +
_("You sure its not coffee o-clock?")) {
UseMarkup = true,
Xalign = 0
};
Button button = new Button () {
Sensitive = false,
Label = _("Finish")
};
button.Clicked += delegate {
Destroy ();
};
AddButton (button);
SparkleSpinner spinner = new SparkleSpinner (22);
Table table = new Table (2, 2, false) {
RowSpacing = 12,
ColumnSpacing = 9
}; };
HBox box = new HBox (false, 0); Label information = new Label (_("This may take a while.\n") +
_("You sure its not coffee o-clock?")) {
UseMarkup = true,
Xalign = 0
};
table.Attach (spinner, 0, 1, 0, 1);
table.Attach (header, 1, 2, 0, 1);
table.Attach (information, 1, 2, 1, 2);
box.PackStart (table, false, false, 0); Button button = new Button () {
Sensitive = false,
Label = _("Finish")
};
button.Clicked += delegate {
Destroy ();
};
layout_vertical.PackStart (box, false, false, 0); AddButton (button);
SparkleSpinner spinner = new SparkleSpinner (22);
Table table = new Table (2, 2, false) {
RowSpacing = 12,
ColumnSpacing = 9
};
HBox box = new HBox (false, 0);
table.Attach (spinner, 0, 1, 0, 1);
table.Attach (header, 1, 2, 0, 1);
table.Attach (information, 1, 2, 1, 2);
box.PackStart (table, false, false, 0);
layout_vertical.PackStart (box, false, false, 0);
Add (layout_vertical); Add (layout_vertical);
@ -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;
}
} }
} }

View file

@ -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,10 +328,11 @@ 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);
moved_files.PackStart (new Label (""), false, false, 0);
if (change_set.MovedFrom.Count > 1)
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,16 +466,18 @@ 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
{ {
public string UserName; public string UserName;
public string UserEmail; public string UserEmail;
public string Message; public string Message;
@ -501,7 +488,7 @@ namespace SparkleShare {
public List <string> MovedTo; public List <string> MovedTo;
public DateTime DateTime; public DateTime DateTime;
public string Hash; public string Hash;
public ChangeSet (string user_name, string user_email, string message, DateTime date_time, string hash) public ChangeSet (string user_name, string user_email, string message, DateTime date_time, string hash)
{ {
@ -511,9 +498,9 @@ namespace SparkleShare {
DateTime = date_time; DateTime = date_time;
Hash = hash; Hash = hash;
Edited = new List <string> (); Edited = new List <string> ();
Added = new List <string> (); Added = new List <string> ();
Deleted = new List <string> (); Deleted = new List <string> ();
MovedFrom = new List <string> (); MovedFrom = new List <string> ();
MovedTo = new List <string> (); MovedTo = new List <string> ();

View file

@ -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;

View file

@ -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");
} }

View file

@ -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 {

View 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;
}
}
}
}
}