SparkleShare/SparkleShare/SparkleStatusIcon.cs

388 lines
8.2 KiB
C#
Raw Normal View History

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
2010-07-22 21:10:38 +00:00
// 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;
using System;
2010-11-20 13:21:17 +00:00
using System.IO;
2010-07-22 21:10:38 +00:00
using System.Timers;
namespace SparkleShare {
// The statusicon that stays in the
// user's notification area
2010-10-16 22:48:50 +00:00
public class SparkleStatusIcon : StatusIcon {
2010-09-04 21:40:35 +00:00
private Timer Animation;
2010-07-24 21:31:24 +00:00
private Gdk.Pixbuf [] AnimationFrames;
private int FrameNumber;
2010-10-16 22:48:50 +00:00
private string StateText;
private Menu Menu;
2010-07-22 21:10:38 +00:00
// Short alias for the translations
2010-10-16 22:48:50 +00:00
public static string _ (string s)
{
2010-07-22 21:10:38 +00:00
return Catalog.GetString (s);
}
public SparkleStatusIcon () : base ()
{
2010-08-10 21:22:51 +00:00
AnimationFrames = CreateAnimationFrames ();
2010-09-04 21:40:35 +00:00
Animation = CreateAnimation ();
2010-07-22 21:10:38 +00:00
2010-10-16 22:48:50 +00:00
Activate += ShowMenu; // Primary mouse button click
PopupMenu += ShowMenu; // Secondary mouse button click
2010-07-24 21:31:24 +00:00
2010-10-16 22:48:50 +00:00
SetNormalState ();
CreateMenu ();
2010-08-10 21:22:51 +00:00
2010-10-16 22:48:50 +00:00
SparkleShare.Controller.FolderSizeChanged += delegate {
Application.Invoke (delegate {
if (!Animation.Enabled)
SetNormalState ();
2010-10-16 22:48:50 +00:00
UpdateMenu ();
2010-10-16 22:48:50 +00:00
});
};
2010-11-20 13:21:17 +00:00
SparkleShare.Controller.FolderListChanged += delegate {
2010-10-16 22:48:50 +00:00
Application.Invoke (delegate {
SetNormalState ();
CreateMenu ();
2010-10-16 22:48:50 +00:00
});
};
SparkleShare.Controller.OnIdle += delegate {
Application.Invoke (delegate {
SetNormalState ();
UpdateMenu ();
});
};
SparkleShare.Controller.OnSyncing += delegate {
Application.Invoke (delegate {
SetAnimationState ();
UpdateMenu ();
});
};
2010-07-22 21:10:38 +00:00
2010-10-16 22:48:50 +00:00
SparkleShare.Controller.OnError += delegate {
Application.Invoke (delegate {
SetNormalState (true);
UpdateMenu ();
});
};
2010-07-22 21:10:38 +00:00
}
2010-09-04 21:40:35 +00:00
// Slices up the graphic that contains the
// animation frames.
2010-08-10 21:22:51 +00:00
private Gdk.Pixbuf [] CreateAnimationFrames ()
2010-07-24 21:31:24 +00:00
{
2010-08-10 21:22:51 +00:00
Gdk.Pixbuf [] animation_frames = new Gdk.Pixbuf [5];
Gdk.Pixbuf frames_pixbuf = SparkleUIHelpers.GetIcon ("process-syncing-sparkleshare", 24);
2010-07-24 21:31:24 +00:00
2010-08-10 21:22:51 +00:00
for (int i = 0; i < animation_frames.Length; i++)
animation_frames [i] = new Gdk.Pixbuf (frames_pixbuf, (i * 24), 0, 24, 24);
return animation_frames;
2010-07-24 21:31:24 +00:00
}
2010-10-16 22:48:50 +00:00
// Creates the Animation that handles the syncing animation
2010-09-04 21:40:35 +00:00
private Timer CreateAnimation ()
2010-07-24 21:31:24 +00:00
{
2010-11-20 13:21:17 +00:00
FrameNumber = 0;
2010-09-04 21:40:35 +00:00
Timer Animation = new Timer () {
2010-07-24 21:31:24 +00:00
Interval = 35
};
2010-09-04 21:40:35 +00:00
Animation.Elapsed += delegate {
2010-07-24 21:31:24 +00:00
if (FrameNumber < AnimationFrames.Length - 1)
FrameNumber++;
else
FrameNumber = 0;
2010-09-05 14:56:06 +00:00
Application.Invoke (delegate {
2010-10-16 22:48:50 +00:00
Pixbuf = AnimationFrames [FrameNumber];
2010-09-05 14:56:06 +00:00
});
2010-07-24 21:31:24 +00:00
};
2010-09-04 21:40:35 +00:00
return Animation;
2010-08-10 21:22:51 +00:00
2010-07-24 21:31:24 +00:00
}
// Creates the menu that is popped up when the
2010-10-16 22:48:50 +00:00
// user clicks the status icon
public void CreateMenu ()
{
2010-10-16 22:48:50 +00:00
Menu = new Menu ();
2010-10-16 22:48:50 +00:00
// The menu item showing the status and size of the SparkleShare folder
MenuItem status_menu_item = new MenuItem (StateText) {
Sensitive = false
};
2010-07-24 21:31:24 +00:00
2011-03-15 17:16:23 +00:00
Menu.Add (status_menu_item);
Menu.Add (new SeparatorMenuItem ());
ImageMenuItem folder_item = new SparkleMenuItem ("SparkleShare"){
Image = new Image (SparkleUIHelpers.GetIcon ("folder-sparkleshare", 16))
2010-10-16 22:48:50 +00:00
};
2010-07-24 21:31:24 +00:00
2011-03-15 17:16:23 +00:00
folder_item.Activated += delegate {
2010-10-16 22:48:50 +00:00
SparkleShare.Controller.OpenSparkleShareFolder ();
};
2011-03-15 17:16:23 +00:00
Menu.Add (folder_item);
2010-07-24 21:31:24 +00:00
if (SparkleShare.Controller.Folders.Count > 0) {
2010-09-04 21:40:35 +00:00
// Creates a menu item for each repository with a link to their logs
foreach (string path in SparkleShare.Controller.Folders) {
2010-07-24 21:31:24 +00:00
2011-03-15 17:16:23 +00:00
Gdk.Pixbuf folder_icon = IconTheme.Default.LoadIcon ("folder", 16,
IconLookupFlags.GenericFallback);
ImageMenuItem subfolder_item = new SparkleMenuItem (Path.GetFileName (path)) {
Image = new Image (folder_icon)
2010-07-24 21:31:24 +00:00
};
// if (repo.HasUnsyncedChanges)
// folder_action.IconName = "dialog-error";
2011-03-07 02:29:03 +00:00
2011-03-15 17:16:23 +00:00
subfolder_item.Activated += OpenEventLogDelegate (path);
2011-03-14 02:07:14 +00:00
2011-03-15 17:16:23 +00:00
Menu.Add (subfolder_item);
2010-07-22 21:10:38 +00:00
}
2010-07-24 21:31:24 +00:00
} else {
MenuItem no_folders_item = new MenuItem (_("No Remote Folders Yet")) {
2010-07-24 21:31:24 +00:00
Sensitive = false
};
Menu.Add (no_folders_item);
2010-07-22 21:10:38 +00:00
}
2010-09-04 21:40:35 +00:00
// Opens the wizard to add a new remote folder
MenuItem sync_item = new MenuItem (_("Add Remote Folder…"));
if (SparkleShare.Controller.FirstRun)
sync_item.Sensitive = false;
2010-07-24 21:31:24 +00:00
2010-10-16 22:48:50 +00:00
sync_item.Activated += delegate {
Application.Invoke (delegate {
2010-07-24 21:31:24 +00:00
2011-03-16 00:01:20 +00:00
if (SparkleUI.Intro == null) {
SparkleUI.Intro = new SparkleIntro ();
SparkleUI.Intro.ShowServerForm (true);
}
if (!SparkleUI.Intro.Visible)
SparkleUI.Intro.ShowServerForm (true);
SparkleUI.Intro.ShowAll ();
SparkleUI.Intro.Present ();
2010-09-04 21:40:35 +00:00
2010-10-16 22:48:50 +00:00
});
};
2010-07-24 21:31:24 +00:00
2010-10-16 22:48:50 +00:00
Menu.Add (sync_item);
Menu.Add (new SeparatorMenuItem ());
2010-07-22 21:10:38 +00:00
MenuItem notify_item;
2010-10-16 22:48:50 +00:00
if (SparkleShare.Controller.NotificationsEnabled)
notify_item = new MenuItem (_("Turn Notifications Off"));
else
notify_item = new MenuItem (_("Turn Notifications On"));
2010-07-24 21:31:24 +00:00
notify_item.Activated += delegate {
2010-10-16 22:48:50 +00:00
SparkleShare.Controller.ToggleNotifications ();
CreateMenu ();
2010-10-16 22:48:50 +00:00
};
2010-07-24 21:31:24 +00:00
2010-10-16 22:48:50 +00:00
Menu.Add (notify_item);
Menu.Add (new SeparatorMenuItem ());
2010-07-24 21:31:24 +00:00
2010-10-16 22:48:50 +00:00
// A menu item that takes the user to http://www.sparkleshare.org/
2011-03-04 01:29:34 +00:00
MenuItem about_item = new MenuItem (_("About SparkleShare"));
2010-07-24 21:31:24 +00:00
2010-10-16 22:48:50 +00:00
about_item.Activated += delegate {
2010-07-24 21:31:24 +00:00
2011-03-23 10:59:42 +00:00
SparkleAbout about = new SparkleAbout ();
about.ShowAll ();
2010-07-24 21:31:24 +00:00
2010-10-16 22:48:50 +00:00
};
2010-07-24 21:31:24 +00:00
2010-10-16 22:48:50 +00:00
Menu.Add (about_item);
Menu.Add (new SeparatorMenuItem ());
2010-07-24 21:31:24 +00:00
2010-10-16 22:48:50 +00:00
// A menu item that quits the application
MenuItem quit_item = new MenuItem (_("Quit"));
2010-07-24 21:31:24 +00:00
2010-10-16 22:48:50 +00:00
quit_item.Activated += delegate {
SparkleShare.Controller.Quit ();
};
2010-07-24 21:31:24 +00:00
2010-10-16 22:48:50 +00:00
Menu.Add (quit_item);
2010-07-24 21:31:24 +00:00
2010-11-20 13:21:17 +00:00
Menu.ShowAll ();
}
2010-10-16 22:48:50 +00:00
// A method reference that makes sure that opening the
// event log for each repository works correctly
private EventHandler OpenEventLogDelegate (string path)
{
2010-10-16 22:48:50 +00:00
return delegate {
2010-07-22 21:10:38 +00:00
SparkleShare.UI.AddEventLog (path);
2010-10-16 22:48:50 +00:00
};
2010-09-04 21:40:35 +00:00
2010-07-22 21:10:38 +00:00
}
2010-10-16 22:48:50 +00:00
public void UpdateMenu ()
{
Menu.Remove (Menu.Children [0]);
MenuItem status_menu_item = new MenuItem (StateText) {
Sensitive = false
};
Menu.Add (status_menu_item);
Menu.ReorderChild (status_menu_item, 0);
Menu.ShowAll ();
}
2010-10-22 08:44:16 +00:00
2010-10-16 22:48:50 +00:00
// Makes the menu visible
private void ShowMenu (object o, EventArgs args)
2010-07-22 21:10:38 +00:00
{
2010-10-16 22:48:50 +00:00
Menu.Popup (null, null, SetPosition, 0, Global.CurrentEventTime);
2010-07-24 21:31:24 +00:00
2010-10-16 22:48:50 +00:00
}
2010-10-16 22:48:50 +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-10-16 22:48:50 +00:00
PositionMenu (menu, out x, out y, out push_in, Handle);
2010-07-24 21:31:24 +00:00
2010-10-16 22:48:50 +00:00
}
2010-07-22 21:10:38 +00:00
2010-10-16 22:48:50 +00:00
// The state when there's nothing going on
private void SetNormalState ()
{
2010-10-16 22:48:50 +00:00
SetNormalState (false);
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-10-16 22:48:50 +00:00
// The state when there's nothing going on
private void SetNormalState (bool error)
{
2010-10-16 22:48:50 +00:00
Animation.Stop ();
if (SparkleShare.Controller.Folders.Count == 0) {
2010-11-20 13:21:17 +00:00
StateText = _("Welcome to SparkleShare!");
2010-10-22 08:44:16 +00:00
Application.Invoke (delegate {
Pixbuf = AnimationFrames [0];
});
2010-10-16 22:48:50 +00:00
} else {
if (error) {
2010-10-16 22:48:50 +00:00
StateText = _("Not everything is synced");
2010-10-22 08:44:16 +00:00
Application.Invoke (delegate {
Pixbuf = SparkleUIHelpers.GetIcon ("sparkleshare-syncing-error", 24);
});
2010-07-22 21:10:38 +00:00
2010-10-16 22:48:50 +00:00
} else {
2010-07-22 21:10:38 +00:00
2010-10-16 22:48:50 +00:00
StateText = _("Up to date") + " (" + SparkleShare.Controller.FolderSize + ")";
2010-10-22 08:44:16 +00:00
Application.Invoke (delegate {
Pixbuf = AnimationFrames [0];
});
2010-07-24 21:31:24 +00:00
2010-10-16 22:48:50 +00:00
}
2010-10-16 22:48:50 +00:00
}
2010-07-22 21:10:38 +00:00
}
2010-10-16 22:48:50 +00:00
// The state when animating
private void SetAnimationState ()
2010-07-22 21:10:38 +00:00
{
2010-07-24 21:31:24 +00:00
2010-10-16 22:48:50 +00:00
StateText = _("Syncing…");
2010-09-12 17:46:00 +00:00
2010-10-16 22:48:50 +00:00
if (!Animation.Enabled)
Animation.Start ();
2010-07-24 21:31:24 +00:00
2010-07-22 21:10:38 +00:00
}
}
public class SparkleMenuItem : ImageMenuItem {
2011-03-15 17:16:23 +00:00
public SparkleMenuItem (string text) : base (text)
{
SetProperty ("always-show-image", new GLib.Value (true));
}
}
2010-07-22 21:10:38 +00:00
}