summaryrefslogtreecommitdiff
path: root/SparkleShare/Windows/UserInterface/StatusIcon.cs
diff options
context:
space:
mode:
Diffstat (limited to 'SparkleShare/Windows/UserInterface/StatusIcon.cs')
-rw-r--r--SparkleShare/Windows/UserInterface/StatusIcon.cs339
1 files changed, 339 insertions, 0 deletions
diff --git a/SparkleShare/Windows/UserInterface/StatusIcon.cs b/SparkleShare/Windows/UserInterface/StatusIcon.cs
new file mode 100644
index 0000000..fb02f59
--- /dev/null
+++ b/SparkleShare/Windows/UserInterface/StatusIcon.cs
@@ -0,0 +1,339 @@
+// SparkleShare, a collaboration and sharing tool.
+// Copyright (C) 2010 Hylke Bons <hi@planetpeanut.uk>
+//
+// 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.Windows;
+using System.Windows.Interop;
+using System.Windows.Media.Imaging;
+using System.Windows.Controls;
+
+using Drawing = System.Drawing;
+
+namespace SparkleShare {
+
+ public class StatusIcon : Control {
+
+ public StatusIconController Controller = new StatusIconController();
+
+ private readonly Drawing.Bitmap syncing_idle_image = UserInterfaceHelpers.GetBitmap("process-syncing-idle");
+ private readonly Drawing.Bitmap syncing_up_image = UserInterfaceHelpers.GetBitmap("process-syncing-up");
+ private readonly Drawing.Bitmap syncing_down_image = UserInterfaceHelpers.GetBitmap("process-syncing-down");
+ private readonly Drawing.Bitmap syncing_image = UserInterfaceHelpers.GetBitmap("process-syncing");
+ private readonly Drawing.Bitmap syncing_error_image = UserInterfaceHelpers.GetBitmap("process-syncing-error");
+
+ private ContextMenu context_menu;
+
+ private SparkleMenuItem log_item;
+ private SparkleMenuItem state_item;
+ private SparkleMenuItem exit_item;
+ private SparkleMenuItem[] state_menu_items;
+
+ private readonly NotifyIcon notify_icon = new NotifyIcon();
+
+
+ public StatusIcon() {
+ this.notify_icon.HeaderText = "SparkleShare";
+ this.notify_icon.Icon = this.syncing_idle_image;
+
+ CreateMenu();
+
+ Controller.UpdateIconEvent += delegate(IconState state) {
+ Dispatcher.BeginInvoke(
+ (Action) delegate {
+ switch(state) {
+ case IconState.Idle: {
+ this.notify_icon.Icon = this.syncing_idle_image;
+ break;
+ }
+ case IconState.SyncingUp: {
+ this.notify_icon.Icon = this.syncing_up_image;
+ break;
+ }
+ case IconState.SyncingDown: {
+ this.notify_icon.Icon = this.syncing_down_image;
+ break;
+ }
+ case IconState.Syncing: {
+ this.notify_icon.Icon = this.syncing_image;
+ break;
+ }
+ case IconState.Error: {
+ this.notify_icon.Icon = this.syncing_error_image;
+ break;
+ }
+ }
+ });
+ };
+
+ Controller.UpdateStatusItemEvent += delegate(string state_text) {
+ Dispatcher.BeginInvoke(
+ (Action) delegate {
+ this.state_item.Header = state_text;
+ this.state_item.UpdateLayout();
+
+ if(Controller.Projects.Length == state_menu_items.Length) {
+ for(int i = 0; i < Controller.Projects.Length; i++)
+ state_menu_items[i].Header = Controller.Projects[i].StatusMessage;
+ }
+
+ this.notify_icon.HeaderText = "SparkleShare\n" + state_text;
+ });
+ };
+
+ Controller.UpdateMenuEvent += delegate {
+ Dispatcher.BeginInvoke((Action) CreateMenu);
+ };
+
+ Controller.UpdateQuitItemEvent += delegate(bool item_enabled) {
+ Dispatcher.BeginInvoke((Action) delegate {
+ this.exit_item.IsEnabled = item_enabled;
+ this.exit_item.UpdateLayout();
+ });
+ };
+ }
+
+
+ public void CreateMenu() {
+ this.context_menu = new ContextMenu();
+
+ this.state_item = new SparkleMenuItem {
+ Header = Controller.StateText,
+ IsEnabled = false
+ };
+
+ Image folder_image = new Image {
+ Source = UserInterfaceHelpers.GetImageSource("sparkleshare-folder"),
+ Width = 16,
+ Height = 16
+ };
+
+ SparkleMenuItem folder_item = new SparkleMenuItem {
+ Header = "SparkleShare",
+ Icon = folder_image
+ };
+
+ SparkleMenuItem add_item = new SparkleMenuItem {
+ Header = "Add hosted project…"
+ };
+
+ this.log_item = new SparkleMenuItem {
+ Header = "Recent changes…",
+ IsEnabled = Controller.RecentEventsItemEnabled
+ };
+
+ SparkleMenuItem link_code_item = new SparkleMenuItem {
+ Header = "Client ID"
+ };
+
+ if(Controller.LinkCodeItemEnabled) {
+ SparkleMenuItem code_item = new SparkleMenuItem {
+ Header = SparkleShare.Controller.UserAuthenticationInfo.PublicKey.Substring(0, 20) + "..."
+ };
+
+ SparkleMenuItem copy_item = new SparkleMenuItem {
+ Header = "Copy to Clipboard"
+ };
+ copy_item.Click += delegate {
+ Controller.CopyToClipboardClicked();
+ };
+
+ link_code_item.Items.Add(code_item);
+ link_code_item.Items.Add(new Separator());
+ link_code_item.Items.Add(copy_item);
+ }
+
+ CheckBox notify_check_box = new CheckBox {
+ Margin = new Thickness(6, 0, 0, 0),
+ IsChecked = SparkleShare.Controller.NotificationsEnabled
+ };
+
+ SparkleMenuItem notify_item = new SparkleMenuItem {
+ Header = "Notifications",
+ Icon = notify_check_box
+ };
+
+ SparkleMenuItem about_item = new SparkleMenuItem {
+ Header = "About SparkleShare"
+ };
+ this.exit_item = new SparkleMenuItem {
+ Header = "Exit"
+ };
+
+
+ add_item.Click += delegate {
+ Controller.AddHostedProjectClicked();
+ };
+ this.log_item.Click += delegate {
+ Controller.RecentEventsClicked();
+ };
+ about_item.Click += delegate {
+ Controller.AboutClicked();
+ };
+
+ notify_check_box.Click += delegate {
+ this.context_menu.IsOpen = false;
+ SparkleShare.Controller.ToggleNotifications();
+ notify_check_box.IsChecked = SparkleShare.Controller.NotificationsEnabled;
+ };
+
+ notify_item.Click += delegate {
+ SparkleShare.Controller.ToggleNotifications();
+ notify_check_box.IsChecked = SparkleShare.Controller.NotificationsEnabled;
+ };
+
+ this.exit_item.Click += delegate {
+ this.notify_icon.Dispose();
+ Controller.QuitClicked();
+ };
+
+
+ this.context_menu.Items.Add(this.state_item);
+ this.context_menu.Items.Add(new Separator());
+ this.context_menu.Items.Add(folder_item);
+
+ state_menu_items = new SparkleMenuItem[Controller.Projects.Length];
+
+ if(Controller.Projects.Length > 0) {
+ int i = 0;
+ foreach(ProjectInfo project in Controller.Projects) {
+
+ SparkleMenuItem subfolder_item = new SparkleMenuItem {
+ Header = project.Name.Replace("_", "__"),
+ Icon = new Image {
+ Source = UserInterfaceHelpers.GetImageSource("folder"),
+ Width = 16,
+ Height = 16
+ }
+ };
+
+ state_menu_items[i] = new SparkleMenuItem {
+ Header = project.StatusMessage,
+ IsEnabled = false
+ };
+
+ subfolder_item.Items.Add(state_menu_items[i]);
+ subfolder_item.Items.Add(new Separator());
+
+ SparkleMenuItem open_item = new SparkleMenuItem {
+ Header = "Open folder",
+ Icon = new Image
+ {
+ Source = UserInterfaceHelpers.GetImageSource("folder"),
+ Width = 16,
+ Height = 16
+ }
+ };
+
+ open_item.Click += new RoutedEventHandler(Controller.OpenFolderDelegate(project.Name));
+ subfolder_item.Items.Add(open_item);
+ subfolder_item.Items.Add(new Separator());
+
+ if(project.IsPaused) {
+ SparkleMenuItem resume_item;
+
+ if(project.UnsyncedChangesInfo.Count > 0) {
+ foreach(KeyValuePair<string, string> pair in project.UnsyncedChangesInfo)
+ subfolder_item.Items.Add(new SparkleMenuItem {
+ Header = pair.Key,
+ // TODO image
+ IsEnabled = false
+ });
+
+ if(!string.IsNullOrEmpty(project.MoreUnsyncedChanges)) {
+ subfolder_item.Items.Add(new SparkleMenuItem {
+ Header = project.MoreUnsyncedChanges,
+ IsEnabled = false
+ });
+ }
+
+ subfolder_item.Items.Add(new Separator());
+ resume_item = new SparkleMenuItem {
+ Header = "Sync and Resume…"
+ };
+
+ } else {
+ resume_item = new SparkleMenuItem {
+ Header = "Resume"
+ };
+ }
+
+ resume_item.Click += (sender, e) => Controller.ResumeDelegate(project.Name)(sender, e);
+ subfolder_item.Items.Add(resume_item);
+
+ } else {
+ if(Controller.Projects[i].HasError) {
+ subfolder_item.Icon = new Image {
+ Source = Imaging.CreateBitmapSourceFromHIcon(
+ Drawing.SystemIcons.Exclamation.Handle, Int32Rect.Empty,
+ BitmapSizeOptions.FromWidthAndHeight(16, 16))
+ };
+
+ SparkleMenuItem try_again_item = new SparkleMenuItem {
+ Header = "Retry Sync"
+ };
+ try_again_item.Click += (sender, e) => Controller.TryAgainDelegate(project.Name)(sender, e);
+ subfolder_item.Items.Add(try_again_item);
+
+ } else {
+ SparkleMenuItem pause_item = new SparkleMenuItem {
+ Header = "Pause"
+ };
+ pause_item.Click +=
+ (sender, e) => Controller.PauseDelegate(project.Name)(sender, e);
+ subfolder_item.Items.Add(pause_item);
+ }
+ }
+
+ this.context_menu.Items.Add(subfolder_item);
+ i++;
+ };
+ }
+
+ folder_item.Items.Add(this.log_item);
+ folder_item.Items.Add(add_item);
+ folder_item.Items.Add(new Separator());
+ folder_item.Items.Add(notify_item);
+ folder_item.Items.Add(new Separator());
+ folder_item.Items.Add(link_code_item);
+ folder_item.Items.Add(new Separator());
+ folder_item.Items.Add(about_item);
+
+ this.context_menu.Items.Add(new Separator());
+ this.context_menu.Items.Add(this.exit_item);
+
+ this.notify_icon.ContextMenu = this.context_menu;
+ }
+
+
+ public void ShowBalloon(string title, string subtext, string image_path) {
+ this.notify_icon.ShowBalloonTip(title, subtext, image_path);
+ }
+
+
+ public void Dispose() {
+ this.notify_icon.Dispose();
+ }
+ }
+
+ public class SparkleMenuItem : MenuItem {
+
+ public SparkleMenuItem() {
+ Padding = new Thickness(6, 3, 4, 0);
+ }
+ }
+}