diff options
Diffstat (limited to 'SparkleShare/Windows/UserInterface/StatusIcon.cs')
-rw-r--r-- | SparkleShare/Windows/UserInterface/StatusIcon.cs | 339 |
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); + } + } +} |