2010-07-22 21:10:38 +00:00
|
|
|
// 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 Mono.Unix;
|
2010-08-02 15:42:42 +00:00
|
|
|
using SparkleLib;
|
2010-07-22 21:10:38 +00:00
|
|
|
using System;
|
|
|
|
using System.Diagnostics;
|
|
|
|
using System.IO;
|
|
|
|
using System.Timers;
|
|
|
|
|
|
|
|
namespace SparkleShare {
|
|
|
|
|
|
|
|
public class SparkleStatusIcon : StatusIcon
|
|
|
|
{
|
|
|
|
|
|
|
|
public int SyncingReposCount;
|
|
|
|
|
2010-07-22 23:01:57 +00:00
|
|
|
private Menu Menu;
|
|
|
|
private MenuItem StatusMenuItem;
|
|
|
|
private string StateText;
|
2010-08-09 09:51:00 +00:00
|
|
|
|
|
|
|
private Timer Timer;
|
2010-07-24 21:31:24 +00:00
|
|
|
private Gdk.Pixbuf [] AnimationFrames;
|
|
|
|
private int FrameNumber;
|
2010-08-09 09:51:00 +00:00
|
|
|
|
2010-08-05 21:46:48 +00:00
|
|
|
private Gtk.Action FolderAction;
|
|
|
|
private double FolderSize;
|
2010-07-24 21:31:24 +00:00
|
|
|
|
2010-07-22 23:01:57 +00:00
|
|
|
|
2010-07-22 21:10:38 +00:00
|
|
|
// Short alias for the translations
|
|
|
|
public static string _ (string s) {
|
|
|
|
return Catalog.GetString (s);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public SparkleStatusIcon () : base ()
|
|
|
|
{
|
|
|
|
|
2010-08-05 21:46:48 +00:00
|
|
|
FolderSize = GetFolderSize (new DirectoryInfo (SparklePaths.SparklePath));
|
|
|
|
|
2010-07-24 21:31:24 +00:00
|
|
|
CreateAnimationFrames ();
|
|
|
|
CreateTimer ();
|
2010-07-22 21:10:38 +00:00
|
|
|
|
|
|
|
SyncingReposCount = 0;
|
|
|
|
|
2010-07-24 21:31:24 +00:00
|
|
|
StateText = "";
|
|
|
|
StatusMenuItem = new MenuItem ();
|
|
|
|
|
2010-07-22 23:01:57 +00:00
|
|
|
CreateMenu ();
|
|
|
|
Activate += ShowMenu;
|
2010-08-10 15:19:48 +00:00
|
|
|
PopupMenu += ShowMenu;
|
2010-07-22 21:10:38 +00:00
|
|
|
|
|
|
|
SetIdleState ();
|
2010-07-22 23:01:57 +00:00
|
|
|
ShowState ();
|
2010-07-22 21:10:38 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-07-22 23:01:57 +00:00
|
|
|
|
2010-07-24 21:31:24 +00:00
|
|
|
private void CreateAnimationFrames ()
|
|
|
|
{
|
|
|
|
|
|
|
|
FrameNumber = 0;
|
|
|
|
|
|
|
|
AnimationFrames = new Gdk.Pixbuf [5];
|
|
|
|
Gdk.Pixbuf frames_pixbuf = SparkleHelpers.GetIcon ("process-syncing-sparkleshare", 24);
|
|
|
|
|
|
|
|
for (int i = 0; i < AnimationFrames.Length; i++)
|
|
|
|
AnimationFrames [i] = new Gdk.Pixbuf (frames_pixbuf, (i * 24), 0, 24, 24);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Creates the timer that handles the syncing animation
|
|
|
|
private void CreateTimer ()
|
|
|
|
{
|
|
|
|
|
|
|
|
Timer = new Timer () {
|
|
|
|
Interval = 35
|
|
|
|
};
|
|
|
|
|
|
|
|
Timer.Elapsed += delegate {
|
|
|
|
|
|
|
|
if (FrameNumber < AnimationFrames.Length - 1)
|
|
|
|
FrameNumber++;
|
|
|
|
else
|
|
|
|
FrameNumber = 0;
|
|
|
|
|
|
|
|
Application.Invoke (delegate { SetPixbuf (AnimationFrames [FrameNumber]); });
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private EventHandler CreateWindowDelegate (SparkleRepo repo)
|
2010-07-22 21:10:38 +00:00
|
|
|
{
|
2010-07-24 21:31:24 +00:00
|
|
|
|
2010-07-22 23:01:57 +00:00
|
|
|
return delegate {
|
2010-07-24 21:31:24 +00:00
|
|
|
|
|
|
|
SparkleWindow SparkleWindow = new SparkleWindow (repo);
|
2010-07-22 23:01:57 +00:00
|
|
|
SparkleWindow.ShowAll ();
|
2010-07-24 21:31:24 +00:00
|
|
|
|
2010-07-22 23:01:57 +00:00
|
|
|
};
|
2010-07-24 21:31:24 +00:00
|
|
|
|
2010-07-22 23:01:57 +00:00
|
|
|
}
|
2010-07-22 21:10:38 +00:00
|
|
|
|
|
|
|
|
2010-08-05 21:46:48 +00:00
|
|
|
private double GetFolderSize (DirectoryInfo parent)
|
|
|
|
{
|
|
|
|
|
|
|
|
double size = 0;
|
|
|
|
|
|
|
|
FileInfo [] files = parent.GetFiles();
|
|
|
|
|
2010-08-10 09:34:47 +00:00
|
|
|
foreach (FileInfo file in files) {
|
|
|
|
|
|
|
|
if (!file.Exists)
|
|
|
|
return 0;
|
|
|
|
|
2010-08-05 21:46:48 +00:00
|
|
|
size += file.Length;
|
|
|
|
|
2010-08-10 09:34:47 +00:00
|
|
|
}
|
|
|
|
|
2010-08-05 21:46:48 +00:00
|
|
|
foreach (DirectoryInfo directory in parent.GetDirectories())
|
|
|
|
size += GetFolderSize (directory);
|
|
|
|
|
|
|
|
return size;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-08-09 09:51:00 +00:00
|
|
|
private void UpdateFolderSize ()
|
|
|
|
{
|
|
|
|
|
|
|
|
FolderSize = GetFolderSize (new DirectoryInfo (SparklePaths.SparklePath));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-08-10 09:43:17 +00:00
|
|
|
// Format a file size nicely.
|
|
|
|
// Example: 1048576 becomes "1 ᴍʙ"
|
2010-08-09 09:51:00 +00:00
|
|
|
private string FormatFileSize (double byte_count)
|
2010-08-05 21:46:48 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
string size = "";
|
|
|
|
|
|
|
|
if (byte_count >= 1099511627776)
|
2010-08-10 09:43:17 +00:00
|
|
|
size = String.Format (_("{0:##.##} ᴛʙ"), Math.Round (byte_count / 1099511627776, 1));
|
2010-08-05 21:46:48 +00:00
|
|
|
else if (byte_count >= 1073741824)
|
2010-08-10 09:43:17 +00:00
|
|
|
size = String.Format (_("{0:##.##} ɢʙ"), Math.Round (byte_count / 1073741824, 1));
|
2010-08-05 21:46:48 +00:00
|
|
|
else if (byte_count >= 1048576)
|
2010-08-10 09:43:17 +00:00
|
|
|
size = String.Format (_("{0:##.##} ᴍʙ"), Math.Round (byte_count / 1048576, 1));
|
2010-08-05 21:46:48 +00:00
|
|
|
else if (byte_count >= 1024)
|
2010-08-10 09:43:17 +00:00
|
|
|
size = String.Format (_("{0:##.##} ᴋʙ"), Math.Round (byte_count / 1024, 1));
|
2010-08-05 21:46:48 +00:00
|
|
|
else
|
|
|
|
size = byte_count.ToString () + " bytes";
|
|
|
|
|
|
|
|
return size;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-07-24 21:31:24 +00:00
|
|
|
// Creates the menu that is popped up when the
|
|
|
|
// user clicks the statusicon
|
2010-08-05 21:46:48 +00:00
|
|
|
public void CreateMenu ()
|
2010-07-22 23:01:57 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
Menu = new Menu ();
|
|
|
|
|
2010-07-24 21:31:24 +00:00
|
|
|
StatusMenuItem = new MenuItem (StateText) {
|
|
|
|
Sensitive = false
|
|
|
|
};
|
2010-07-22 21:10:38 +00:00
|
|
|
|
|
|
|
Menu.Add (StatusMenuItem);
|
2010-07-24 21:31:24 +00:00
|
|
|
|
2010-07-22 21:10:38 +00:00
|
|
|
Menu.Add (new SeparatorMenuItem ());
|
|
|
|
|
2010-08-07 21:41:26 +00:00
|
|
|
FolderAction = new Gtk.Action ("", "SparkleShare") {
|
2010-07-24 21:31:24 +00:00
|
|
|
IconName = "folder-sparkleshare",
|
|
|
|
IsImportant = true
|
|
|
|
};
|
|
|
|
|
2010-08-05 21:46:48 +00:00
|
|
|
FolderAction.Activated += delegate {
|
2010-07-24 21:31:24 +00:00
|
|
|
|
|
|
|
Process process = new Process ();
|
|
|
|
process.StartInfo.FileName = "xdg-open";
|
|
|
|
process.StartInfo.Arguments = SparklePaths.SparklePath;
|
|
|
|
process.Start ();
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2010-08-05 21:46:48 +00:00
|
|
|
Menu.Add (FolderAction.CreateMenuItem ());
|
2010-07-24 21:31:24 +00:00
|
|
|
|
|
|
|
if (SparkleUI.Repositories.Count > 0) {
|
|
|
|
|
|
|
|
foreach (SparkleRepo SparkleRepo in SparkleUI.Repositories) {
|
|
|
|
|
2010-08-05 21:46:48 +00:00
|
|
|
FolderAction = new Gtk.Action ("", SparkleRepo.Name) {
|
2010-07-24 21:31:24 +00:00
|
|
|
IconName = "folder",
|
|
|
|
IsImportant = true
|
|
|
|
};
|
|
|
|
|
2010-08-05 21:46:48 +00:00
|
|
|
FolderAction.Activated += CreateWindowDelegate (SparkleRepo);
|
2010-07-24 21:31:24 +00:00
|
|
|
|
2010-08-05 21:46:48 +00:00
|
|
|
Menu.Add (FolderAction.CreateMenuItem ());
|
2010-07-24 21:31:24 +00:00
|
|
|
|
2010-07-22 21:10:38 +00:00
|
|
|
}
|
|
|
|
|
2010-07-24 21:31:24 +00:00
|
|
|
} else {
|
|
|
|
|
|
|
|
MenuItem no_folders_item = new MenuItem (_("No Shared Folders Yet")) {
|
|
|
|
Sensitive = false
|
|
|
|
};
|
|
|
|
|
|
|
|
Menu.Add (no_folders_item);
|
|
|
|
|
2010-07-22 21:10:38 +00:00
|
|
|
}
|
|
|
|
|
2010-08-07 22:13:11 +00:00
|
|
|
MenuItem add_item = new MenuItem (_("Sync Remote Folder…"));
|
2010-07-24 21:31:24 +00:00
|
|
|
|
|
|
|
add_item.Activated += delegate {
|
|
|
|
|
2010-07-27 09:56:20 +00:00
|
|
|
SparkleIntro intro = new SparkleIntro ();
|
2010-07-27 14:46:17 +00:00
|
|
|
intro.ShowStepTwo (true);
|
2010-07-27 09:56:20 +00:00
|
|
|
intro.ShowAll ();
|
2010-07-24 21:31:24 +00:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
Menu.Add (add_item);
|
|
|
|
|
2010-07-22 21:10:38 +00:00
|
|
|
Menu.Add (new SeparatorMenuItem ());
|
|
|
|
|
2010-07-24 21:31:24 +00:00
|
|
|
CheckMenuItem notify_item = new CheckMenuItem (_("Show Notifications"));
|
|
|
|
|
|
|
|
string notify_setting = SparkleHelpers.CombineMore (SparklePaths.SparkleConfigPath,
|
|
|
|
"sparkleshare.notify");
|
|
|
|
|
|
|
|
if (File.Exists (notify_setting))
|
|
|
|
notify_item.Active = true;
|
2010-07-22 21:10:38 +00:00
|
|
|
|
2010-07-24 21:31:24 +00:00
|
|
|
notify_item.Toggled += delegate {
|
|
|
|
|
|
|
|
if (File.Exists (notify_setting))
|
|
|
|
File.Delete (notify_setting);
|
|
|
|
else
|
|
|
|
File.Create (notify_setting);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
Menu.Add (notify_item);
|
2010-07-22 21:10:38 +00:00
|
|
|
|
|
|
|
Menu.Add (new SeparatorMenuItem ());
|
2010-07-24 21:31:24 +00:00
|
|
|
|
2010-08-09 22:54:43 +00:00
|
|
|
MenuItem about_item = new MenuItem (_("Visit Website"));
|
2010-07-24 21:31:24 +00:00
|
|
|
|
|
|
|
about_item.Activated += delegate {
|
|
|
|
|
|
|
|
Process process = new Process ();
|
|
|
|
|
|
|
|
process.StartInfo.FileName = "xdg-open";
|
|
|
|
process.StartInfo.Arguments = "http://www.sparkleshare.org/";
|
|
|
|
|
|
|
|
process.Start ();
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
Menu.Add (about_item);
|
|
|
|
|
|
|
|
Menu.Add (new SeparatorMenuItem ());
|
|
|
|
|
|
|
|
MenuItem quit_item = new MenuItem (_("Quit"));
|
|
|
|
|
|
|
|
quit_item.Activated += Quit;
|
|
|
|
|
|
|
|
Menu.Add (quit_item);
|
2010-07-22 23:01:57 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void ShowMenu (object o, EventArgs args)
|
|
|
|
{
|
|
|
|
|
|
|
|
Menu.ShowAll ();
|
|
|
|
Menu.Popup (null, null, SetPosition, 0, Global.CurrentEventTime);
|
|
|
|
|
2010-07-22 21:10:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-07-22 23:01:57 +00:00
|
|
|
private void UpdateStatusMenuItem ()
|
|
|
|
{
|
|
|
|
|
|
|
|
Label label = (Label) StatusMenuItem.Children [0];
|
2010-07-24 21:31:24 +00:00
|
|
|
label.Text = StateText;
|
2010-07-22 23:01:57 +00:00
|
|
|
|
|
|
|
Menu.ShowAll ();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-07-24 21:31:24 +00:00
|
|
|
|
2010-07-22 23:01:57 +00:00
|
|
|
public void ShowState ()
|
2010-07-22 21:10:38 +00:00
|
|
|
{
|
|
|
|
|
2010-08-09 09:51:00 +00:00
|
|
|
UpdateFolderSize ();
|
|
|
|
|
2010-08-08 19:16:48 +00:00
|
|
|
if (SyncingReposCount < 0)
|
|
|
|
SyncingReposCount = 0;
|
|
|
|
|
2010-08-09 08:53:38 +00:00
|
|
|
if (SyncingReposCount > SparkleUI.Repositories.Count)
|
|
|
|
SyncingReposCount = SparkleUI.Repositories.Count;
|
|
|
|
|
2010-07-22 21:10:38 +00:00
|
|
|
if (SyncingReposCount > 0)
|
|
|
|
SetSyncingState ();
|
|
|
|
else
|
|
|
|
SetIdleState ();
|
|
|
|
|
2010-07-22 23:01:57 +00:00
|
|
|
UpdateStatusMenuItem ();
|
2010-08-05 21:46:48 +00:00
|
|
|
|
2010-08-09 09:51:00 +00:00
|
|
|
SparkleHelpers.DebugInfo ("Status", "Number of repos syncing: " + SyncingReposCount);
|
2010-07-22 23:01:57 +00:00
|
|
|
|
2010-07-22 21:10:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-07-24 21:31:24 +00:00
|
|
|
// Changes the state to idle for when there's no syncing going on
|
|
|
|
private void SetIdleState ()
|
2010-07-22 21:10:38 +00:00
|
|
|
{
|
2010-07-22 23:01:57 +00:00
|
|
|
|
2010-07-24 21:31:24 +00:00
|
|
|
Timer.Stop ();
|
|
|
|
|
2010-08-10 15:05:47 +00:00
|
|
|
Application.Invoke (delegate { SetPixbuf (AnimationFrames [0]); });
|
2010-08-09 09:51:00 +00:00
|
|
|
StateText = _("Up to date") + " (" + FormatFileSize (FolderSize) + ")";
|
2010-07-22 23:01:57 +00:00
|
|
|
|
2010-07-22 21:10:38 +00:00
|
|
|
}
|
|
|
|
|
2010-07-24 21:31:24 +00:00
|
|
|
|
2010-07-22 21:10:38 +00:00
|
|
|
// Changes the status icon to the syncing animation
|
2010-07-24 21:31:24 +00:00
|
|
|
private void SetSyncingState ()
|
2010-07-22 21:10:38 +00:00
|
|
|
{
|
|
|
|
|
2010-07-22 23:01:57 +00:00
|
|
|
StateText = _("Syncing…");
|
2010-07-24 21:31:24 +00:00
|
|
|
Timer.Start ();
|
2010-07-22 21:10:38 +00:00
|
|
|
|
2010-07-24 21:31:24 +00:00
|
|
|
}
|
2010-07-22 21:10:38 +00:00
|
|
|
|
|
|
|
|
2010-07-24 21:31:24 +00:00
|
|
|
// Updates the icon used for the statusicon
|
|
|
|
private void SetPixbuf (Gdk.Pixbuf pixbuf)
|
|
|
|
{
|
2010-07-22 21:10:38 +00:00
|
|
|
|
2010-07-24 21:31:24 +00:00
|
|
|
Pixbuf = pixbuf;
|
|
|
|
|
2010-07-22 21:10:38 +00:00
|
|
|
}
|
|
|
|
|
2010-07-24 21:31:24 +00:00
|
|
|
|
|
|
|
// Makes sure the menu pops up in the right position
|
|
|
|
private void SetPosition (Menu menu, out int x, out int y, out bool push_in)
|
2010-07-22 21:10:38 +00:00
|
|
|
{
|
2010-07-22 23:01:57 +00:00
|
|
|
|
2010-07-24 21:31:24 +00:00
|
|
|
PositionMenu (menu, out x, out y, out push_in, Handle);
|
2010-07-22 23:01:57 +00:00
|
|
|
|
2010-07-22 21:10:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Quits the program
|
2010-07-24 21:31:24 +00:00
|
|
|
private void Quit (object o, EventArgs args)
|
2010-07-22 21:10:38 +00:00
|
|
|
{
|
2010-07-24 21:31:24 +00:00
|
|
|
|
|
|
|
File.Delete (SparkleHelpers.CombineMore (SparklePaths.SparkleTmpPath, "sparkleshare.pid"));
|
2010-07-22 21:10:38 +00:00
|
|
|
Application.Quit ();
|
2010-07-24 21:31:24 +00:00
|
|
|
|
2010-07-22 21:10:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|