diff --git a/AUTHORS b/AUTHORS index 2c5591cf..f2aa8b0a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -24,6 +24,7 @@ Contributors: Jakub Steiner Kristi Tsukida Lapo Calamandrei + Lars Falk-Petersen Luis Cordova Łukasz Jernaś Michael Monreal diff --git a/SparkleLib/Makefile.am b/SparkleLib/Makefile.am index 0c928dc4..e5fdcd51 100644 --- a/SparkleLib/Makefile.am +++ b/SparkleLib/Makefile.am @@ -22,7 +22,7 @@ SOURCES = \ SparkleHelpers.cs \ SparkleListenerBase.cs \ SparkleListenerIrc.cs \ - SparkleListenerTcp.cs \ + SparkleListenerTcp.cs \ SparkleOptions.cs \ SparklePaths.cs \ SparkleRepoBase.cs \ diff --git a/SparkleShare/Mac/Growl.plist b/SparkleShare/Mac/Growl.plist index cb8e7130..af7016e0 100644 --- a/SparkleShare/Mac/Growl.plist +++ b/SparkleShare/Mac/Growl.plist @@ -2,19 +2,15 @@ - TicketVersion - 1 - AllNotifications - - Start - Stop - Info - - DefaultNotifications - - Start - Stop - Info - + TicketVersion + 1 + AllNotifications + + Event + + DefaultNotifications + + Event + diff --git a/SparkleShare/Mac/SparkleAbout.cs b/SparkleShare/Mac/SparkleAbout.cs index 8177789e..e145b120 100644 --- a/SparkleShare/Mac/SparkleAbout.cs +++ b/SparkleShare/Mac/SparkleAbout.cs @@ -24,14 +24,15 @@ using MonoMac.AppKit; using MonoMac.ObjCRuntime; using MonoMac.WebKit; + namespace SparkleShare { public class SparkleAbout : NSWindow { - private NSButton WebsiteButton; - private NSButton CreditsButton; - private NSBox Box; - private NSTextField HeaderTextField; + public SparkleAboutController Controller = new SparkleAboutController (); + + private NSImage AboutImage; + private NSImageView AboutImageView; private NSTextField VersionTextField; private NSTextField UpdatesTextField; private NSTextField CreditsTextField; @@ -41,21 +42,22 @@ namespace SparkleShare { public SparkleAbout () : base () { - SetFrame (new RectangleF (0, 0, 360, 288), true); + SetFrame (new RectangleF (0, 0, 640, 281), true); Center (); Delegate = new SparkleAboutDelegate (); StyleMask = (NSWindowStyle.Closable | NSWindowStyle.Titled); Title = "About SparkleShare"; - MaxSize = new SizeF (360, 288); - MinSize = new SizeF (360, 288); + MaxSize = new SizeF (640, 281); + MinSize = new SizeF (640, 281); HasShadow = true; BackingType = NSBackingStore.Buffered; CreateAbout (); + OrderFrontRegardless (); MakeKeyAndOrderFront (this); - SparkleShare.Controller.NewVersionAvailable += delegate (string new_version) { + Controller.NewVersionEvent += delegate (string new_version) { InvokeOnMainThread (delegate { UpdatesTextField.StringValue = "A newer version (" + new_version + ") is available!"; UpdatesTextField.TextColor = @@ -63,7 +65,7 @@ namespace SparkleShare { }); }; - SparkleShare.Controller.VersionUpToDate += delegate { + Controller.VersionUpToDateEvent += delegate { InvokeOnMainThread (delegate { UpdatesTextField.StringValue = "You are running the latest version."; UpdatesTextField.TextColor = @@ -71,103 +73,83 @@ namespace SparkleShare { }); }; - CheckForNewVersion (); - } - - - public void CheckForNewVersion () - { - SparkleShare.Controller.CheckForNewVersion (); + Controller.CheckingForNewVersionEvent += delegate { + InvokeOnMainThread (delegate { + UpdatesTextField.StringValue = "Checking for updates..."; + UpdatesTextField.TextColor = NSColor.DisabledControlText; + }); + }; } private void CreateAbout () { - Box = new NSBox () { - FillColor = NSColor.White, - Frame = new RectangleF (-1, Frame.Height - 105, Frame.Width + 2, 105), - BoxType = NSBoxType.NSBoxCustom + string about_image_path = Path.Combine (NSBundle.MainBundle.ResourcePath, + "Pixmaps", "about.png"); + + AboutImage = new NSImage (about_image_path) { + Size = new SizeF (640, 260) }; - HeaderTextField = new NSTextField () { - StringValue = "SparkleShare", - Frame = new RectangleF (22, Frame.Height - 89, 318, 48), - BackgroundColor = NSColor.White, - Bordered = false, - Editable = false, - Font = NSFontManager.SharedFontManager.FontWithFamily - ("Lucida Grande", NSFontTraitMask.Condensed, 0, 24) + AboutImageView = new NSImageView () { + Image = AboutImage, + Frame = new RectangleF (0, 0, 640, 260) }; + VersionTextField = new NSTextField () { - StringValue = SparkleShare.Controller.Version, - Frame = new RectangleF (22, Frame.Height - 94, 318, 22), + StringValue = "version " + Controller.RunningVersion, + Frame = new RectangleF (295, 140, 318, 22), BackgroundColor = NSColor.White, Bordered = false, Editable = false, + DrawsBackground = false, + TextColor = NSColor.White, Font = NSFontManager.SharedFontManager.FontWithFamily - ("Lucida Grande", NSFontTraitMask.Unbold, 0, 11), - TextColor = NSColor.DisabledControlText + ("Lucida Grande", NSFontTraitMask.Unbold, 0, 11) }; UpdatesTextField = new NSTextField () { StringValue = "Checking for updates...", - Frame = new RectangleF (22, Frame.Height - 222, 318, 98), - BackgroundColor = NSColor.WindowBackground, + Frame = new RectangleF (295, Frame.Height - 232, 318, 98), Bordered = false, Editable = false, + DrawsBackground = false, Font = NSFontManager.SharedFontManager.FontWithFamily ("Lucida Grande", NSFontTraitMask.Unbold, 0, 11), TextColor = NSColor.DisabledControlText }; CreditsTextField = new NSTextField () { - StringValue = @"Copyright © 2010–" + DateTime.Now.Year + " Hylke Bons and others" + + StringValue = @"Copyright © 2010–" + DateTime.Now.Year + " Hylke Bons and others." + "\n" + "\n" + "SparkleShare is Free and Open Source Software. You are free to use, modify, and redistribute it " + "under the GNU General Public License version 3 or later.", - Frame = new RectangleF (22, Frame.Height - 250, 318, 98), - BackgroundColor = NSColor.WindowBackground, + Frame = new RectangleF (295, Frame.Height - 260, 318, 98), + TextColor = NSColor.White, + DrawsBackground = false, Bordered = false, Editable = false, Font = NSFontManager.SharedFontManager.FontWithFamily ("Lucida Grande", NSFontTraitMask.Unbold, 0, 11), }; - WebsiteButton = new NSButton () { - Frame = new RectangleF (12, 12, 120, 32), - Title = "Visit Website", - BezelStyle = NSBezelStyle.Rounded, - Font = SparkleUI.Font - }; +// WebsiteButton.Activated += delegate { +// NSUrl url = new NSUrl ("http://www.sparkleshare.org/"); +// NSWorkspace.SharedWorkspace.OpenUrl (url); +// }; - WebsiteButton.Activated += delegate { - NSUrl url = new NSUrl ("http://www.sparkleshare.org/"); - NSWorkspace.SharedWorkspace.OpenUrl (url); - }; +// CreditsButton.Activated += delegate { +// NSUrl url = new NSUrl ("http://www.sparkleshare.org/credits/"); +// NSWorkspace.SharedWorkspace.OpenUrl (url); +// }; - CreditsButton = new NSButton () { - Frame = new RectangleF (Frame.Width - 12 - 120, 12, 120, 32), - Title = "Show Credits", - BezelStyle = NSBezelStyle.Rounded, - Font = SparkleUI.Font - }; + ContentView.AddSubview (AboutImageView); - CreditsButton.Activated += delegate { - - NSUrl url = new NSUrl ("http://www.sparkleshare.org/credits/"); - NSWorkspace.SharedWorkspace.OpenUrl (url); - - }; - - ContentView.AddSubview (Box); - ContentView.AddSubview (HeaderTextField); ContentView.AddSubview (VersionTextField); ContentView.AddSubview (UpdatesTextField); ContentView.AddSubview (CreditsTextField); - ContentView.AddSubview (CreditsButton); - ContentView.AddSubview (WebsiteButton); } } diff --git a/SparkleShare/Mac/SparkleBubble.cs b/SparkleShare/Mac/SparkleBubble.cs deleted file mode 100644 index 05523f1f..00000000 --- a/SparkleShare/Mac/SparkleBubble.cs +++ /dev/null @@ -1,58 +0,0 @@ -// SparkleShare, a collaboration and sharing tool. -// Copyright (C) 2010 Hylke Bons -// -// 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 . - - -using System; -using System.IO; - -using MonoMac.AppKit; -using MonoMac.Foundation; -using MonoMac.Growl; - -namespace SparkleShare { - - public class SparkleBubble : NSObject { - - public string ImagePath; - - private string title; - private string subtext; - - - public SparkleBubble (string title, string subtext) - { - this.title = title; - this.subtext = subtext; - } - - - public void Show () - { - InvokeOnMainThread (delegate { - if (ImagePath != null && File.Exists (ImagePath)) { - NSData image_data = NSData.FromFile (ImagePath); - - GrowlApplicationBridge.Notify (this.title, this.subtext, - "Start", image_data, 0, false, null); - - } else { - GrowlApplicationBridge.Notify (this.title, this.subtext, - "Start", null, 0, false, null); - } - }); - } - } -} diff --git a/SparkleShare/Mac/SparkleBubbles.cs b/SparkleShare/Mac/SparkleBubbles.cs new file mode 100644 index 00000000..95487186 --- /dev/null +++ b/SparkleShare/Mac/SparkleBubbles.cs @@ -0,0 +1,64 @@ +// SparkleShare, a collaboration and sharing tool. +// Copyright (C) 2010 Hylke Bons +// +// 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 . + + +using System; +using System.IO; + +using MonoMac.AppKit; +using MonoMac.Foundation; +using MonoMac.Growl; + +namespace SparkleShare { + + public class SparkleBubbles : NSObject { + + private SparkleBubblesController controller = new SparkleBubblesController (); + + + public SparkleBubbles () + { + this.controller.ShowBubbleEvent += delegate (string title, string subtext, string image_path) { + InvokeOnMainThread (delegate { + if (!GrowlApplicationBridge.IsGrowlRunning ()) { + NSApplication.SharedApplication.RequestUserAttention ( + NSRequestUserAttentionType.InformationalRequest); + + return; + } + + if (NSApplication.SharedApplication.DockTile.BadgeLabel == null) { + NSApplication.SharedApplication.DockTile.BadgeLabel = "1"; + + } else { + int events = int.Parse (NSApplication.SharedApplication.DockTile.BadgeLabel); + NSApplication.SharedApplication.DockTile.BadgeLabel = (events + 1).ToString (); + } + + if (image_path != null && File.Exists (image_path)) { + NSData image_data = NSData.FromFile (image_path); + GrowlApplicationBridge.Notify (title, subtext, + "Event", image_data, 0, false, null); + + } else { + GrowlApplicationBridge.Notify (title, subtext, + "Event", null, 0, false, null); + } + }); + }; + } + } +} diff --git a/SparkleShare/Mac/SparkleEventLog.cs b/SparkleShare/Mac/SparkleEventLog.cs index 9c8bd92a..88df1f37 100644 --- a/SparkleShare/Mac/SparkleEventLog.cs +++ b/SparkleShare/Mac/SparkleEventLog.cs @@ -16,8 +16,6 @@ using System; -using System.Collections.Generic; -using System.Diagnostics; using System.Drawing; using System.IO; using System.Text.RegularExpressions; @@ -27,23 +25,29 @@ using MonoMac.Foundation; using MonoMac.AppKit; using MonoMac.ObjCRuntime; using MonoMac.WebKit; -using SparkleLib; // Only used for SparkleChangeSet namespace SparkleShare { public class SparkleEventLog : NSWindow { - private WebView WebView; - private NSBox Separator; - private string HTML; + private SparkleEventLogController controller = new SparkleEventLogController (); + + private WebView web_view = new WebView (new RectangleF (0, 0, 480, 579), "", "") { + PolicyDelegate = new SparkleWebPolicyDelegate () + }; + + private NSBox Separator = new NSBox (new RectangleF (0, 579, 480, 1)) { + BorderColor = NSColor.LightGray, + BoxType = NSBoxType.NSBoxCustom + }; + private NSPopUpButton popup_button; - private NSProgressIndicator ProgressIndicator; - private List change_sets; - private string selected_log = null; + private NSProgressIndicator progress_indicator; public SparkleEventLog (IntPtr handle) : base (handle) { } + // TODO: Window needs to be made resizable public SparkleEventLog () : base () { Title = "Recent Events"; @@ -61,39 +65,52 @@ namespace SparkleShare { HasShadow = true; BackingType = NSBackingStore.Buffered; - CreateEvents (); - UpdateEvents (false); - UpdateChooser (); - - OrderFrontRegardless (); - } - - - private void CreateEvents () - { - Separator = new NSBox (new RectangleF (0, 579, 480, 1)) { - BorderColor = NSColor.LightGray, - BoxType = NSBoxType.NSBoxCustom - }; - ContentView.AddSubview (Separator); - WebView = new WebView (new RectangleF (0, 0, 480, 579), "", "") { - PolicyDelegate = new SparkleWebPolicyDelegate () - }; - ProgressIndicator = new NSProgressIndicator () { + this.progress_indicator = new NSProgressIndicator () { Style = NSProgressIndicatorStyle.Spinning, - Frame = new RectangleF (WebView.Frame.Width / 2 - 10, WebView.Frame.Height / 2 + 10, 20, 20) + Frame = new RectangleF (this.web_view.Frame.Width / 2 - 10, this.web_view.Frame.Height / 2 + 10, 20, 20) }; - ProgressIndicator.StartAnimation (this); - Update (); + this.progress_indicator.StartAnimation (this); + ContentView.AddSubview (this.progress_indicator); + + + UpdateContent (null); + UpdateChooser (null); + OrderFrontRegardless (); + + + // Hook up the controller events + this.controller.UpdateChooserEvent += delegate (string [] folders) { + InvokeOnMainThread (delegate { + UpdateChooser (folders); + }); + }; + + this.controller.UpdateContentEvent += delegate (string html) { + InvokeOnMainThread (delegate { + UpdateContent (html); + }); + }; + + this.controller.ContentLoadingEvent += delegate { + InvokeOnMainThread (delegate { + if (this.web_view.Superview == ContentView) + this.web_view.RemoveFromSuperview (); + + ContentView.AddSubview (this.progress_indicator); + }); + }; } - public void UpdateChooser () + public void UpdateChooser (string [] folders) { + if (folders == null) + folders = this.controller.Folders; + if (this.popup_button != null) this.popup_button.RemoveFromSuperview (); @@ -104,104 +121,61 @@ namespace SparkleShare { this.popup_button.Cell.ControlSize = NSControlSize.Small; this.popup_button.Font = NSFontManager.SharedFontManager.FontWithFamily - ("Lucida Grande", NSFontTraitMask.Condensed, 0, NSFont.SmallSystemFontSize); + ("Lucida Grande", NSFontTraitMask.Condensed, 0, NSFont.SmallSystemFontSize); this.popup_button.AddItem ("All Folders"); this.popup_button.Menu.AddItem (NSMenuItem.SeparatorItem); - this.popup_button.AddItems (SparkleShare.Controller.Folders.ToArray ()); - - if (this.selected_log != null && - !SparkleShare.Controller.Folders.Contains (this.selected_log)) { - - this.selected_log = null; - } + this.popup_button.AddItems (folders); this.popup_button.Activated += delegate { if (this.popup_button.IndexOfSelectedItem == 0) - this.selected_log = null; + this.controller.SelectedFolder = null; else - this.selected_log = this.popup_button.SelectedItem.Title; - - UpdateEvents (false); + this.controller.SelectedFolder = this.popup_button.SelectedItem.Title; }; ContentView.AddSubview (this.popup_button); } - public void UpdateEvents () + public void UpdateContent (string html) { - UpdateEvents (true); - } - - - public void UpdateEvents (bool silent) - { - if (!silent) { - InvokeOnMainThread (delegate { - if (WebView.Superview == ContentView) - WebView.RemoveFromSuperview (); + using (NSAutoreleasePool pool = new NSAutoreleasePool ()) { + Thread thread = new Thread (new ThreadStart (delegate { + if (html == null) + html = this.controller.HTML; - ContentView.AddSubview (ProgressIndicator); - }); + html = html.Replace ("", "Lucida Grande"); + html = html.Replace ("", "13.6px"); + html = html.Replace ("", "13.4px"); + html = html.Replace ("", "#bbb"); + html = html.Replace ("", "#ddd"); + html = html.Replace ("", "#f5f5f5"); + html = html.Replace ("", "#0085cf"); + html = html.Replace ("", "#009ff8"); + html = html.Replace ("", + "file://" + Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "avatar-default.png")); + html = html.Replace ("", + "file://" + Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "document-added-12.png")); + html = html.Replace ("", + "file://" + Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "document-deleted-12.png")); + html = html.Replace ("", + "file://" + Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "document-edited-12.png")); + html = html.Replace ("", + "file://" + Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "document-moved-12.png")); + + InvokeOnMainThread (delegate { + if (this.progress_indicator.Superview == ContentView) + this.progress_indicator.RemoveFromSuperview (); + + // TODO: still causes some flashes + this.web_view.MainFrame.LoadHtmlString (html, new NSUrl ("")); + ContentView.AddSubview (this.web_view); + }); + })); + + thread.Start (); } - - Thread thread = new Thread (new ThreadStart (delegate { - using (NSAutoreleasePool pool = new NSAutoreleasePool ()) { - Stopwatch watch = new Stopwatch (); - watch.Start (); - this.change_sets = SparkleShare.Controller.GetLog (this.selected_log); - GenerateHTML (); - watch.Stop (); - - // A short delay is less annoying than - // a flashing window - if (watch.ElapsedMilliseconds < 500 && !silent) - Thread.Sleep (500 - (int) watch.ElapsedMilliseconds); - - AddHTML (); - } - })); - - thread.Start (); - } - - - private void GenerateHTML () - { - HTML = SparkleShare.Controller.GetHTMLLog (this.change_sets); - - HTML = HTML.Replace ("", "Lucida Grande"); - HTML = HTML.Replace ("", "13.6px"); - HTML = HTML.Replace ("", "13.4px"); - HTML = HTML.Replace ("", "#bbb"); - HTML = HTML.Replace ("", "#ddd"); - HTML = HTML.Replace ("", "#f5f5f5"); - HTML = HTML.Replace ("", "#0085cf"); - HTML = HTML.Replace ("", "#009ff8"); - HTML = HTML.Replace ("", - "file://" + Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "avatar-default.png")); - HTML = HTML.Replace ("", - "file://" + Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "document-added-12.png")); - HTML = HTML.Replace ("", - "file://" + Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "document-deleted-12.png")); - HTML = HTML.Replace ("", - "file://" + Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "document-edited-12.png")); - HTML = HTML.Replace ("", - "file://" + Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "document-moved-12.png")); - } - - - private void AddHTML () - { - InvokeOnMainThread (delegate { - if (ProgressIndicator.Superview == ContentView) - ProgressIndicator.RemoveFromSuperview (); - - WebView.MainFrame.LoadHtmlString (HTML, new NSUrl ("")); - ContentView.AddSubview (WebView); - Update (); - }); } } diff --git a/SparkleShare/Mac/SparkleIntro.cs b/SparkleShare/Mac/SparkleIntro.cs deleted file mode 100644 index 37d25c93..00000000 --- a/SparkleShare/Mac/SparkleIntro.cs +++ /dev/null @@ -1,445 +0,0 @@ -// SparkleShare, a collaboration and sharing tool. -// Copyright (C) 2010 Hylke Bons -// -// 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 . - - -using System; -using System.Drawing; -using System.IO; -using System.Timers; - -using Mono.Unix; -using MonoMac.Foundation; -using MonoMac.AppKit; -using MonoMac.ObjCRuntime; -using MonoMac.WebKit; - -namespace SparkleShare { - - public class SparkleIntro : SparkleWindow { - - private NSButton ContinueButton; - private NSButton SyncButton; - private NSButton TryAgainButton; - private NSButton CancelButton; - private NSButton SkipButton; - private NSButton OpenFolderButton; - private NSButton FinishButton; - private NSForm UserInfoForm; - private NSProgressIndicator ProgressIndicator; - private NSTextField AddressTextField; - private NSTextField FolderNameTextField; - private NSTextField ServerTypeLabel; - private NSTextField AddressLabel; - private NSTextField FolderNameLabel; - private NSTextField FolderNameHelpLabel; - private NSButtonCell ButtonCellProto; - private NSMatrix Matrix; - private int ServerType; - private bool ServerFormOnly; - - - public SparkleIntro () : base () - { - ServerFormOnly = false; - } - - - public void ShowAccountForm () - { - Reset (); - - Header = "Welcome to SparkleShare!"; - Description = "Before we can create a SparkleShare folder on this " + - "computer, we need some information from you."; - - UserInfoForm = new NSForm (new RectangleF (250, 115, 350, 64)); - UserInfoForm.AddEntry ("Full Name:"); - UserInfoForm.AddEntry ("Email Address:"); - UserInfoForm.CellSize = new SizeF (280, 22); - UserInfoForm.IntercellSpacing = new SizeF (4, 4); - UserInfoForm.Cells [0].LineBreakMode = NSLineBreakMode.TruncatingTail; - UserInfoForm.Cells [1].LineBreakMode = NSLineBreakMode.TruncatingTail; - - UserInfoForm.Cells [0].StringValue = SparkleShare.Controller.UserName; - UserInfoForm.Cells [1].StringValue = SparkleShare.Controller.UserEmail; - - ContinueButton = new NSButton () { - Title = "Continue", - Enabled = false - }; - - ContinueButton.Activated += delegate { - SparkleShare.Controller.UserName = UserInfoForm.Cells [0].StringValue.Trim (); - SparkleShare.Controller.UserEmail = UserInfoForm.Cells [1].StringValue.Trim (); - SparkleShare.Controller.GenerateKeyPair (); - SparkleUI.StatusIcon.CreateMenu (); - - InvokeOnMainThread (delegate { - ShowServerForm (); - }); - }; - - // TODO: Ugly hack, do properly with events - Timer timer = new Timer () { - Interval = 50 - }; - - timer.Elapsed += delegate { - InvokeOnMainThread (delegate { - bool name_is_correct = - !UserInfoForm.Cells [0].StringValue.Trim ().Equals (""); - - bool email_is_correct = SparkleShare.Controller.IsValidEmail ( - UserInfoForm.Cells [1].StringValue.Trim ()); - - ContinueButton.Enabled = (name_is_correct && email_is_correct); - }); - }; - - timer.Start (); - - ContentView.AddSubview (UserInfoForm); - Buttons.Add (ContinueButton); - - ShowAll (); - } - - - public void ShowServerForm (bool server_form_only) - { - ServerFormOnly = server_form_only; - ShowServerForm (); - } - - - public void ShowServerForm () - { - Reset (); - - Header = "Where is your remote folder?"; - Description = ""; - - ServerTypeLabel = new NSTextField () { - Alignment = NSTextAlignment.Right, - BackgroundColor = NSColor.WindowBackground, - Bordered = false, - Editable = false, - Frame = new RectangleF (150, Frame.Height - 139 , 160, 17), - StringValue = "Server Type:", - Font = SparkleUI.Font - }; - - AddressLabel = new NSTextField () { - Alignment = NSTextAlignment.Right, - BackgroundColor = NSColor.WindowBackground, - Bordered = false, - Editable = false, - Frame = new RectangleF (150, Frame.Height - 237 , 160, 17), - StringValue = "Address:", - Font = SparkleUI.Font - }; - - FolderNameLabel = new NSTextField () { - Alignment = NSTextAlignment.Right, - BackgroundColor = NSColor.WindowBackground, - Bordered = false, - Editable = false, - Frame = new RectangleF (150, Frame.Height - 264 , 160, 17), - StringValue = "Folder Name:", - Font = SparkleUI.Font - }; - - - AddressTextField = new NSTextField () { - Frame = new RectangleF (320, Frame.Height - 240 , 256, 22), - Font = SparkleUI.Font - }; - - AddressTextField.Cell.LineBreakMode = NSLineBreakMode.TruncatingTail; - - FolderNameTextField = new NSTextField () { - Frame = new RectangleF (320, Frame.Height - (240 + 22 + 4) , 256, 22), - StringValue = "" - }; - - FolderNameTextField.Cell.LineBreakMode = NSLineBreakMode.TruncatingTail; - - FolderNameHelpLabel = new NSTextField () { - BackgroundColor = NSColor.WindowBackground, - Bordered = false, - TextColor = NSColor.DisabledControlText, - Editable = false, - Frame = new RectangleF (320, Frame.Height - 285 , 200, 17), - StringValue = "e.g. ‘rupert/website-design’" - }; - - - ServerType = 0; - - ButtonCellProto = new NSButtonCell (); - ButtonCellProto.SetButtonType (NSButtonType.Radio) ; - - Matrix = new NSMatrix (new RectangleF (315, 180, 256, 78), - NSMatrixMode.Radio, ButtonCellProto, 4, 1); - - Matrix.CellSize = new SizeF (256, 18); - - Matrix.Cells [0].Title = "My own server"; - Matrix.Cells [1].Title = "Github"; - Matrix.Cells [2].Title = "Gitorious"; - Matrix.Cells [3].Title = "The GNOME Project"; - - foreach (NSCell cell in Matrix.Cells) - cell.Font = SparkleUI.Font; - - // TODO: Ugly hack, do properly with events - Timer timer = new Timer () { - Interval = 50 - }; - - timer.Elapsed += delegate { - - InvokeOnMainThread (delegate { - - if (Matrix.SelectedRow != ServerType) { - ServerType = Matrix.SelectedRow; - - AddressTextField.Enabled = (ServerType == 0); - - switch (ServerType) { - case 0: - AddressTextField.StringValue = ""; - FolderNameHelpLabel.StringValue = "e.g. ‘rupert/website-design’"; - break; - case 1: - AddressTextField.StringValue = "ssh://git@github.com/"; - FolderNameHelpLabel.StringValue = "e.g. ‘rupert/website-design’"; - break; - case 2: - AddressTextField.StringValue = "ssh://git@gitorious.org/"; - FolderNameHelpLabel.StringValue = "e.g. ‘project/website-design’"; - break; - case 3: - AddressTextField.StringValue = "ssh://git@gnome.org/git/"; - FolderNameHelpLabel.StringValue = "e.g. ‘gnome-icon-theme’"; - break; - } - } - - - if (ServerType == 0 && !AddressTextField.StringValue.Trim ().Equals ("") - && !FolderNameTextField.StringValue.Trim ().Equals ("")) { - - SyncButton.Enabled = true; - - } else if (ServerType != 0 && - !FolderNameTextField.StringValue.Trim ().Equals ("")) { - - SyncButton.Enabled = true; - - } else { - SyncButton.Enabled = false; - } - }); - - }; - - timer.Start (); - - ContentView.AddSubview (ServerTypeLabel); - ContentView.AddSubview (Matrix); - - ContentView.AddSubview (AddressLabel); - ContentView.AddSubview (AddressTextField); - - ContentView.AddSubview (FolderNameLabel); - ContentView.AddSubview (FolderNameTextField); - ContentView.AddSubview (FolderNameHelpLabel); - - SyncButton = new NSButton () { - Title = "Sync", - Enabled = false - }; - - SyncButton.Activated += delegate { - string folder_name = FolderNameTextField.StringValue; - string server = AddressTextField.StringValue; - string canonical_name = Path.GetFileNameWithoutExtension (folder_name); - - ShowSyncingPage (canonical_name); - - SparkleShare.Controller.FolderFetched += delegate { - InvokeOnMainThread (delegate { - ShowSuccessPage (canonical_name); - }); - }; - - SparkleShare.Controller.FolderFetchError += delegate { - InvokeOnMainThread (delegate { - ShowErrorPage (); - }); - }; - - SparkleShare.Controller.FetchFolder (server, folder_name); - }; - - Buttons.Add (SyncButton); - - if (ServerFormOnly) { - CancelButton = new NSButton () { - Title = "Cancel" - }; - - CancelButton.Activated += delegate { - InvokeOnMainThread (delegate { - PerformClose (this); - }); - }; - - Buttons.Add (CancelButton); - } else { - SkipButton = new NSButton () { - Title = "Skip" - }; - - SkipButton.Activated += delegate { - InvokeOnMainThread (delegate { - ShowCompletedPage (); - }); - }; - - Buttons.Add (SkipButton); - } - - ShowAll (); - } - - - public void ShowErrorPage () - { - Reset (); - - Header = "Something went wrong…"; - Description = ""; - - TryAgainButton = new NSButton () { - Title = "Try again…" - }; - - TryAgainButton.Activated += delegate { - InvokeOnMainThread (delegate { - ShowServerForm (); - }); - }; - - Buttons.Add (TryAgainButton); - - ShowAll (); - } - - - private void ShowSyncingPage (string name) - { - Reset (); - - Header = "Syncing folder ‘" + name + "’…"; - Description = "This may take a while.\n" + - "Are you sure it’s not coffee o'clock?"; - - ProgressIndicator = new NSProgressIndicator () { - Frame = new RectangleF (190, Frame.Height - 200, 640 - 150 - 80, 20), - Style = NSProgressIndicatorStyle.Bar - }; - - ProgressIndicator.StartAnimation (this); - - ContentView.AddSubview (ProgressIndicator); - - FinishButton = new NSButton () { - Title = "Finish", - Enabled = false - }; - - Buttons.Add (FinishButton); - - ShowAll (); - } - - - public void ShowSuccessPage (string folder_name) - { - Reset (); - - Header = "Folder synced succesfully!"; - Description = "Now you can access the synced files from ‘" + folder_name + "’ in " + - "your SparkleShare folder."; - - FinishButton = new NSButton () { - Title = "Finish" - }; - - FinishButton.Activated += delegate { - InvokeOnMainThread (delegate { - SparkleUI.StatusIcon.CreateMenu (); - PerformClose (this); - }); - }; - - OpenFolderButton = new NSButton () { - Title = "Open Folder" - }; - - OpenFolderButton.Activated += delegate { - SparkleShare.Controller.OpenSparkleShareFolder (folder_name); - }; - - Buttons.Add (FinishButton); - Buttons.Add (OpenFolderButton); - - ShowAll (); - - NSApplication.SharedApplication.RequestUserAttention - (NSRequestUserAttentionType.CriticalRequest); - } - - - private void ShowCompletedPage () - { - Reset (); - - Header = "SparkleShare is ready to go!"; - Description = "Now you can start accepting invitations from others. " + - "Just click on invitations you get by email and " + - "we will take care of the rest."; - - FinishButton = new NSButton () { - Title = "Finish" - }; - - FinishButton.Activated += delegate { - InvokeOnMainThread (delegate { - SparkleUI.StatusIcon.CreateMenu (); - PerformClose (this); - }); - - }; - - Buttons.Add (FinishButton); - - ShowAll (); - } - } -} diff --git a/SparkleShare/Mac/SparkleSetup.cs b/SparkleShare/Mac/SparkleSetup.cs new file mode 100644 index 00000000..126ce302 --- /dev/null +++ b/SparkleShare/Mac/SparkleSetup.cs @@ -0,0 +1,368 @@ +// SparkleShare, a collaboration and sharing tool. +// Copyright (C) 2010 Hylke Bons +// +// 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 . + + +using System; +using System.Drawing; +using System.IO; +using System.Timers; + +using Mono.Unix; +using MonoMac.Foundation; +using MonoMac.AppKit; +using MonoMac.ObjCRuntime; +using MonoMac.WebKit; + +namespace SparkleShare { + + public class SparkleSetup : SparkleSetupWindow { + + public SparkleSetupController Controller = new SparkleSetupController (); + + private NSButton ContinueButton; + private NSButton SyncButton; + private NSButton TryAgainButton; + private NSButton CancelButton; + private NSButton OpenFolderButton; + private NSButton FinishButton; + private NSForm UserInfoForm; + private NSProgressIndicator ProgressIndicator; + private NSTextField AddressTextField; + private NSTextField FolderNameTextField; + private NSTextField ServerTypeLabel; + private NSTextField AddressLabel; + private NSTextField FolderNameLabel; + private NSTextField FolderNameHelpLabel; + private NSButtonCell ButtonCellProto; + private NSMatrix Matrix; + private int ServerType; + private Timer timer; + + + public SparkleSetup () : base () + { + Controller.ChangePageEvent += delegate (PageType type) { + InvokeOnMainThread (delegate { + Reset (); + + switch (type) { + case PageType.Setup: + + Header = "Welcome to SparkleShare!"; + Description = "Before we can create a SparkleShare folder on this " + + "computer, we need some information from you."; + + UserInfoForm = new NSForm (new RectangleF (250, 115, 350, 64)); + + UserInfoForm.AddEntry ("Full Name:"); + UserInfoForm.AddEntry ("Email Address:"); + + UserInfoForm.CellSize = new SizeF (280, 22); + UserInfoForm.IntercellSpacing = new SizeF (4, 4); + UserInfoForm.Cells [0].LineBreakMode = NSLineBreakMode.TruncatingTail; + UserInfoForm.Cells [1].LineBreakMode = NSLineBreakMode.TruncatingTail; + + UserInfoForm.Cells [0].StringValue = SparkleShare.Controller.UserName; + UserInfoForm.Cells [1].StringValue = SparkleShare.Controller.UserEmail; + + // TODO: Ugly hack, do properly with events + timer = new Timer () { + Interval = 50 + }; + + ContinueButton = new NSButton () { + Title = "Continue", + Enabled = false + }; + + ContinueButton.Activated += delegate { + timer.Stop (); + timer = null; + + string full_name = UserInfoForm.Cells [0].StringValue.Trim (); + string email = UserInfoForm.Cells [1].StringValue.Trim (); + + Controller.SetupPageCompleted (full_name, email); + }; + + timer.Elapsed += delegate { + InvokeOnMainThread (delegate { + bool name_is_valid = !UserInfoForm.Cells [0].StringValue.Trim ().Equals (""); + + bool email_is_valid = SparkleShare.Controller.IsValidEmail ( + UserInfoForm.Cells [1].StringValue.Trim ()); + + ContinueButton.Enabled = (name_is_valid && email_is_valid); + }); + }; + + timer.Start (); + + ContentView.AddSubview (UserInfoForm); + Buttons.Add (ContinueButton); + + break; + + case PageType.Add: + + Header = "Where is your remote folder?"; + Description = ""; + + ServerTypeLabel = new NSTextField () { + Alignment = NSTextAlignment.Right, + BackgroundColor = NSColor.WindowBackground, + Bordered = false, + Editable = false, + Frame = new RectangleF (150, Frame.Height - 139 , 160, 17), + StringValue = "Server Type:", + Font = SparkleUI.Font + }; + + AddressLabel = new NSTextField () { + Alignment = NSTextAlignment.Right, + BackgroundColor = NSColor.WindowBackground, + Bordered = false, + Editable = false, + Frame = new RectangleF (150, Frame.Height - 237 , 160, 17), + StringValue = "Address:", + Font = SparkleUI.Font + }; + + FolderNameLabel = new NSTextField () { + Alignment = NSTextAlignment.Right, + BackgroundColor = NSColor.WindowBackground, + Bordered = false, + Editable = false, + Frame = new RectangleF (150, Frame.Height - 264 , 160, 17), + StringValue = "Folder Name:", + Font = SparkleUI.Font + }; + + + AddressTextField = new NSTextField () { + Frame = new RectangleF (320, Frame.Height - 240 , 256, 22), + Font = SparkleUI.Font, + StringValue = Controller.PreviousServer + }; + + AddressTextField.Cell.LineBreakMode = NSLineBreakMode.TruncatingTail; + + FolderNameTextField = new NSTextField () { + Frame = new RectangleF (320, Frame.Height - (240 + 22 + 4) , 256, 22), + StringValue = Controller.PreviousFolder + }; + + FolderNameTextField.Cell.LineBreakMode = NSLineBreakMode.TruncatingTail; + + FolderNameHelpLabel = new NSTextField () { + BackgroundColor = NSColor.WindowBackground, + Bordered = false, + TextColor = NSColor.DisabledControlText, + Editable = false, + Frame = new RectangleF (320, Frame.Height - 285 , 200, 17), + StringValue = "e.g. ‘rupert/website-design’" + }; + + ServerType = 0; + + ButtonCellProto = new NSButtonCell (); + ButtonCellProto.SetButtonType (NSButtonType.Radio) ; + + Matrix = new NSMatrix (new RectangleF (315, 180, 256, 78), + NSMatrixMode.Radio, ButtonCellProto, 4, 1); + + Matrix.CellSize = new SizeF (256, 18); + + Matrix.Cells [0].Title = "My own server"; + Matrix.Cells [1].Title = "Github"; + Matrix.Cells [2].Title = "Gitorious"; + Matrix.Cells [3].Title = "The GNOME Project"; + + foreach (NSCell cell in Matrix.Cells) + cell.Font = SparkleUI.Font; + + // TODO: Ugly hack, do properly with events + timer = new Timer () { + Interval = 50 + }; + + timer.Elapsed += delegate { + InvokeOnMainThread (delegate { + if (Matrix.SelectedRow != ServerType) { + ServerType = Matrix.SelectedRow; + + AddressTextField.Enabled = (ServerType == 0); + + switch (ServerType) { + case 0: + AddressTextField.StringValue = ""; + FolderNameHelpLabel.StringValue = "e.g. ‘rupert/website-design’"; + break; + case 1: + AddressTextField.StringValue = "ssh://git@github.com/"; + FolderNameHelpLabel.StringValue = "e.g. ‘rupert/website-design’"; + break; + case 2: + AddressTextField.StringValue = "ssh://git@gitorious.org/"; + FolderNameHelpLabel.StringValue = "e.g. ‘project/website-design’"; + break; + case 3: + AddressTextField.StringValue = "ssh://git@gnome.org/git/"; + FolderNameHelpLabel.StringValue = "e.g. ‘gnome-icon-theme’"; + break; + } + } + + + if (ServerType == 0 && !AddressTextField.StringValue.Trim ().Equals ("") + && !FolderNameTextField.StringValue.Trim ().Equals ("")) { + + SyncButton.Enabled = true; + + } else if (ServerType != 0 && + !FolderNameTextField.StringValue.Trim ().Equals ("")) { + + SyncButton.Enabled = true; + + } else { + SyncButton.Enabled = false; + } + }); + + }; + + timer.Start (); + + ContentView.AddSubview (ServerTypeLabel); + ContentView.AddSubview (Matrix); + + ContentView.AddSubview (AddressLabel); + ContentView.AddSubview (AddressTextField); + + ContentView.AddSubview (FolderNameLabel); + ContentView.AddSubview (FolderNameTextField); + ContentView.AddSubview (FolderNameHelpLabel); + + SyncButton = new NSButton () { + Title = "Sync", + Enabled = false + }; + + SyncButton.Activated += delegate { + timer.Stop (); + timer = null; + + string folder_name = FolderNameTextField.StringValue; + string server = AddressTextField.StringValue; + Controller.AddPageCompleted (server, folder_name); + }; + + Buttons.Add (SyncButton); + + CancelButton = new NSButton () { + Title = "Cancel" + }; + + CancelButton.Activated += delegate { + InvokeOnMainThread (delegate { + PerformClose (this); + }); + }; + + Buttons.Add (CancelButton); + + break; + + case PageType.Syncing: + + Header = "Syncing folder ‘" + Controller.SyncingFolder + "’…"; + Description = "This may take a while.\n" + + "Are you sure it’s not coffee o'clock?"; + + ProgressIndicator = new NSProgressIndicator () { + Frame = new RectangleF (190, Frame.Height - 200, 640 - 150 - 80, 20), + Style = NSProgressIndicatorStyle.Bar + }; + + ProgressIndicator.StartAnimation (this); + ContentView.AddSubview (ProgressIndicator); + + FinishButton = new NSButton () { + Title = "Finish", + Enabled = false + }; + + Buttons.Add (FinishButton); + + break; + + case PageType.Error: + + Header = "Something went wrong…"; + Description = ""; + + TryAgainButton = new NSButton () { + Title = "Try again…" + }; + + TryAgainButton.Activated += delegate { + Controller.ErrorPageCompleted (); + }; + + Buttons.Add (TryAgainButton); + + break; + + case PageType.Finished: + + Header = "Folder synced succesfully!"; + Description = "Now you can access the synced files from " + + "‘" + Controller.SyncingFolder + "’ in " + + "your SparkleShare folder."; + + FinishButton = new NSButton () { + Title = "Finish" + }; + + FinishButton.Activated += delegate { + InvokeOnMainThread (delegate { + PerformClose (this); + }); + }; + + OpenFolderButton = new NSButton () { + Title = "Open Folder" + }; + + OpenFolderButton.Activated += delegate { + SparkleShare.Controller.OpenSparkleShareFolder (Controller.SyncingFolder); + }; + + Buttons.Add (FinishButton); + Buttons.Add (OpenFolderButton); + + NSApplication.SharedApplication.RequestUserAttention + (NSRequestUserAttentionType.CriticalRequest); + + break; + } + + ShowAll (); + }); + }; + } + } +} diff --git a/SparkleShare/Mac/SparkleWindow.cs b/SparkleShare/Mac/SparkleSetupWindow.cs similarity index 98% rename from SparkleShare/Mac/SparkleWindow.cs rename to SparkleShare/Mac/SparkleSetupWindow.cs index 868203ff..08ef66ef 100644 --- a/SparkleShare/Mac/SparkleWindow.cs +++ b/SparkleShare/Mac/SparkleSetupWindow.cs @@ -28,7 +28,7 @@ using Mono.Unix; namespace SparkleShare { - public class SparkleWindow : NSWindow { + public class SparkleSetupWindow : NSWindow { public List Buttons; public string Header; @@ -40,7 +40,7 @@ namespace SparkleShare { private NSTextField DescriptionTextField; - public SparkleWindow () : base () + public SparkleSetupWindow () : base () { SetFrame (new RectangleF (0, 0, 640, 380), true); diff --git a/SparkleShare/Mac/SparkleShare.csproj b/SparkleShare/Mac/SparkleShare.csproj index d5fc5b16..c8354a64 100644 --- a/SparkleShare/Mac/SparkleShare.csproj +++ b/SparkleShare/Mac/SparkleShare.csproj @@ -62,7 +62,7 @@ False ..\..\bin\Meebey.SmartIrc4net.dll - + False ..\..\bin\SparkleLib.dll @@ -77,8 +77,6 @@ SparkleController.cs - - @@ -87,10 +85,25 @@ - + + + + + SparkleBubblesController.cs + + + SparkleEventLogController.cs + + + SparkleSetupController.cs + + + SparkleStatusIconController.cs + + @@ -246,6 +259,9 @@ Translations\zh_TW.po + + Pixmaps\about.png + diff --git a/SparkleShare/Mac/SparkleStatusIcon.cs b/SparkleShare/Mac/SparkleStatusIcon.cs index 4d4b7265..e68c9de9 100644 --- a/SparkleShare/Mac/SparkleStatusIcon.cs +++ b/SparkleShare/Mac/SparkleStatusIcon.cs @@ -31,6 +31,8 @@ namespace SparkleShare { // user's notification area public class SparkleStatusIcon : NSObject { + public SparkleStatusIconController Controller = new SparkleStatusIconController (); + private Timer Animation; private int FrameNumber; private string StateText; @@ -58,51 +60,232 @@ namespace SparkleShare { public SparkleStatusIcon () : base () { - Animation = CreateAnimation (); + using (var a = new NSAutoreleasePool ()) { + Animation = CreateAnimation (); - StatusItem = NSStatusBar.SystemStatusBar.CreateStatusItem (28); - StatusItem.HighlightMode = true; - - SetNormalState (); - CreateMenu (); - - Menu.Delegate = new SparkleStatusIconMenuDelegate (); + StatusItem = NSStatusBar.SystemStatusBar.CreateStatusItem (28); + StatusItem.HighlightMode = true; + + StateText = _("Up to date") + " (" + Controller.FolderSize + ")"; + CreateMenu (); + + Menu.Delegate = new SparkleStatusIconMenuDelegate (); + } - SparkleShare.Controller.FolderSizeChanged += delegate { + Controller.UpdateMenuEvent += delegate (IconState state) { InvokeOnMainThread (delegate { - if (!Animation.Enabled) - SetNormalState (); - - UpdateMenu (); - }); - }; - - SparkleShare.Controller.FolderListChanged += delegate { - InvokeOnMainThread (delegate { - SetNormalState (); - CreateMenu (); + using (var a = new NSAutoreleasePool ()) { + switch (state) { + case IconState.Idle: + + Animation.Stop (); + + if (Controller.Folders.Length == 0) + StateText = _("Welcome to SparkleShare!"); + else + StateText = _("Up to date") + " (" + Controller.FolderSize + ")"; + + StateMenuItem.Title = StateText; + CreateMenu (); + + break; + + case IconState.Syncing: + + StateText = _("Syncing…"); + StateMenuItem.Title = StateText; + + if (!Animation.Enabled) + Animation.Start (); + + break; + + case IconState.Error: + + StateText = _("Not everything is synced"); + StateMenuItem.Title = StateText; + CreateMenu (); + + InvokeOnMainThread (delegate { + StatusItem.Image = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/error.png"); + StatusItem.AlternateImage = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/error-active.png"); + StatusItem.Image.Size = new SizeF (16, 16); + StatusItem.AlternateImage.Size = new SizeF (16, 16); + }); + break; + } + } }); }; - SparkleShare.Controller.OnIdle += delegate { - InvokeOnMainThread (delegate { - SetNormalState (); - CreateMenu (); - }); - }; - SparkleShare.Controller.OnSyncing += delegate { - InvokeOnMainThread (delegate { - SetAnimationState (); - UpdateMenu (); - }); - }; - SparkleShare.Controller.OnError += delegate { - InvokeOnMainThread (delegate { - SetNormalState (true); - CreateMenu (); - }); + } + + + public void CreateMenu () + { + using (NSAutoreleasePool a = new NSAutoreleasePool ()) { + StatusItem.Image = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/idle0.png"); + StatusItem.AlternateImage = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/idle0-active.png"); + StatusItem.Image.Size = new SizeF (16, 16); + StatusItem.AlternateImage.Size = new SizeF (16, 16); + + Menu = new NSMenu (); + + StateMenuItem = new NSMenuItem () { + Title = StateText + }; + + Menu.AddItem (StateMenuItem); + Menu.AddItem (NSMenuItem.SeparatorItem); + + FolderMenuItem = new NSMenuItem () { + Title = "SparkleShare" + }; + + FolderMenuItem.Activated += delegate { + SparkleShare.Controller.OpenSparkleShareFolder (); + }; + + FolderMenuItem.Image = NSImage.ImageNamed ("sparkleshare-mac"); + FolderMenuItem.Image.Size = new SizeF (16, 16); + + Menu.AddItem (FolderMenuItem); + + FolderMenuItems = new NSMenuItem [SparkleShare.Controller.Folders.Count]; + + if (Controller.Folders.Length > 0) { + Tasks = new EventHandler [SparkleShare.Controller.Folders.Count]; + + int i = 0; + foreach (string folder_name in SparkleShare.Controller.Folders) { + NSMenuItem item = new NSMenuItem (); + + item.Title = folder_name; + + if (SparkleShare.Controller.UnsyncedFolders.Contains (folder_name)) + item.Image = NSImage.ImageNamed ("NSCaution"); + else + item.Image = NSImage.ImageNamed ("NSFolder"); + + item.Image.Size = new SizeF (16, 16); + Tasks [i] = OpenFolderDelegate (folder_name); + + FolderMenuItems [i] = item; + FolderMenuItems [i].Activated += Tasks [i]; + + i++; + }; + + } else { + FolderMenuItems = new NSMenuItem [1]; + + FolderMenuItems [0] = new NSMenuItem () { + Title = "No Remote Folders Yet" + }; + } + + foreach (NSMenuItem item in FolderMenuItems) + Menu.AddItem (item); + + Menu.AddItem (NSMenuItem.SeparatorItem); + + SyncMenuItem = new NSMenuItem () { + Title = "Add Remote Folder…" + }; + + if (!SparkleShare.Controller.FirstRun) { + SyncMenuItem.Activated += delegate { + InvokeOnMainThread (delegate { + NSApplication.SharedApplication.ActivateIgnoringOtherApps (true); + + if (SparkleUI.Setup == null) { + SparkleUI.Setup = new SparkleSetup (); + SparkleUI.Setup.Controller.ShowAddPage (); + } + + if (!SparkleUI.Setup.IsVisible) + SparkleUI.Setup.Controller.ShowAddPage (); + + SparkleUI.Setup.OrderFrontRegardless (); + SparkleUI.Setup.MakeKeyAndOrderFront (this); + }); + }; + } + + Menu.AddItem (SyncMenuItem); + Menu.AddItem (NSMenuItem.SeparatorItem); + + RecentEventsMenuItem = new NSMenuItem () { + Title = "Show Recent Events" + }; + + if (Controller.Folders.Length > 0) { + RecentEventsMenuItem.Activated += delegate { + InvokeOnMainThread (delegate { + NSApplication.SharedApplication.ActivateIgnoringOtherApps (true); + + if (SparkleUI.EventLog == null) + SparkleUI.EventLog = new SparkleEventLog (); + + SparkleUI.EventLog.OrderFrontRegardless (); + SparkleUI.EventLog.MakeKeyAndOrderFront (this); + }); + }; + } + + Menu.AddItem (RecentEventsMenuItem); + + NotificationsMenuItem = new NSMenuItem (); + + if (SparkleShare.Controller.NotificationsEnabled) + NotificationsMenuItem.Title = "Turn Notifications Off"; + else + NotificationsMenuItem.Title = "Turn Notifications On"; + + NotificationsMenuItem.Activated += delegate { + SparkleShare.Controller.ToggleNotifications (); + + InvokeOnMainThread (delegate { + if (SparkleShare.Controller.NotificationsEnabled) + NotificationsMenuItem.Title = "Turn Notifications Off"; + else + NotificationsMenuItem.Title = "Turn Notifications On"; + }); + }; + + Menu.AddItem (NotificationsMenuItem); + Menu.AddItem (NSMenuItem.SeparatorItem); + + AboutMenuItem = new NSMenuItem () { + Title = "About SparkleShare" + }; + + AboutMenuItem.Activated += delegate { + InvokeOnMainThread (delegate { + NSApplication.SharedApplication.ActivateIgnoringOtherApps (true); + + if (SparkleUI.About == null) + SparkleUI.About = new SparkleAbout (); + }); + }; + + + Menu.AddItem (AboutMenuItem); + + StatusItem.Menu = Menu; + StatusItem.Menu.Update (); + } + } + + + // A method reference that makes sure that opening the + // event log for each repository works correctly + private EventHandler OpenFolderDelegate (string name) + { + return delegate { + SparkleShare.Controller.OpenSparkleShareFolder (name); }; } @@ -125,7 +308,7 @@ namespace SparkleShare { InvokeOnMainThread (delegate { string image_path = Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "idle" + FrameNumber + ".png"); - + string alternate_image_path = Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "idle" + FrameNumber + "-active.png"); @@ -139,243 +322,6 @@ namespace SparkleShare { return Animation; } - - // Creates the menu that is popped up when the - // user clicks the status icon - public void CreateMenu () - { - Menu = new NSMenu (); - - StateMenuItem = new NSMenuItem () { - Title = StateText - }; - - Menu.AddItem (StateMenuItem); - Menu.AddItem (NSMenuItem.SeparatorItem); - - FolderMenuItem = new NSMenuItem () { - Title = "SparkleShare" - }; - - FolderMenuItem.Activated += delegate { - SparkleShare.Controller.OpenSparkleShareFolder (); - }; - - string folder_icon_path = Path.Combine (NSBundle.MainBundle.ResourcePath, - "sparkleshare-mac.icns"); - - FolderMenuItem.Image = new NSImage (folder_icon_path); - FolderMenuItem.Image.Size = new SizeF (16, 16); - - Menu.AddItem (FolderMenuItem); - - if (SparkleShare.Controller.Folders.Count > 0) { - FolderMenuItems = new NSMenuItem [SparkleShare.Controller.Folders.Count]; - Tasks = new EventHandler [SparkleShare.Controller.Folders.Count]; - - int i = 0; - foreach (string folder_name in SparkleShare.Controller.Folders) { - NSMenuItem item = new NSMenuItem (); - - item.Title = folder_name; - - if (SparkleShare.Controller.UnsyncedFolders.Contains (folder_name)) - item.Image = NSImage.ImageNamed ("NSCaution"); - else - item.Image = NSImage.ImageNamed ("NSFolder"); - - item.Image.Size = new SizeF (16, 16); - Tasks [i] = OpenFolderDelegate (folder_name); - - FolderMenuItems [i] = item; - FolderMenuItems [i].Activated += Tasks [i]; - Menu.AddItem (FolderMenuItems [i]); - - i++; - }; - - - - } else { - FolderMenuItems = new NSMenuItem [1]; - - FolderMenuItems [0] = new NSMenuItem () { - Title = "No Remote Folders Yet" - }; - - Menu.AddItem (FolderMenuItems [0]); - } - - Menu.AddItem (NSMenuItem.SeparatorItem); - - SyncMenuItem = new NSMenuItem () { - Title = "Add Remote Folder…" - }; - - if (!SparkleShare.Controller.FirstRun) { - SyncMenuItem.Activated += delegate { - InvokeOnMainThread (delegate { - NSApplication.SharedApplication.ActivateIgnoringOtherApps (true); - - if (SparkleUI.Intro == null) { - SparkleUI.Intro = new SparkleIntro (); - SparkleUI.Intro.ShowServerForm (true); - } - - if (!SparkleUI.Intro.IsVisible) - SparkleUI.Intro.ShowServerForm (true); - - SparkleUI.Intro.OrderFrontRegardless (); - SparkleUI.Intro.MakeKeyAndOrderFront (this); - }); - }; - } - - Menu.AddItem (SyncMenuItem); - Menu.AddItem (NSMenuItem.SeparatorItem); - - RecentEventsMenuItem = new NSMenuItem () { - Title = "Show Recent Events" - }; - - if (SparkleShare.Controller.Folders.Count > 0) { - RecentEventsMenuItem.Activated += delegate { - InvokeOnMainThread (delegate { - NSApplication.SharedApplication.ActivateIgnoringOtherApps (true); - - if (SparkleUI.EventLog == null) - SparkleUI.EventLog = new SparkleEventLog (); - - SparkleUI.EventLog.OrderFrontRegardless (); - SparkleUI.EventLog.MakeKeyAndOrderFront (this); - }); - }; - } - - Menu.AddItem (RecentEventsMenuItem); - - NotificationsMenuItem = new NSMenuItem (); - - if (SparkleShare.Controller.NotificationsEnabled) - NotificationsMenuItem.Title = "Turn Notifications Off"; - else - NotificationsMenuItem.Title = "Turn Notifications On"; - - NotificationsMenuItem.Activated += delegate { - SparkleShare.Controller.ToggleNotifications (); - - InvokeOnMainThread (delegate { - if (SparkleShare.Controller.NotificationsEnabled) - NotificationsMenuItem.Title = "Turn Notifications Off"; - else - NotificationsMenuItem.Title = "Turn Notifications On"; - }); - }; - - Menu.AddItem (NotificationsMenuItem); - Menu.AddItem (NSMenuItem.SeparatorItem); - - AboutMenuItem = new NSMenuItem () { - Title = "About SparkleShare" - }; - - AboutMenuItem.Activated += delegate { - InvokeOnMainThread (delegate { - NSApplication.SharedApplication.ActivateIgnoringOtherApps (true); - - if (SparkleUI.About == null) - SparkleUI.About = new SparkleAbout (); - - SparkleUI.About.OrderFrontRegardless (); - SparkleUI.About.MakeKeyAndOrderFront (this); - SparkleUI.About.CheckForNewVersion (); - }); - }; - - - Menu.AddItem (AboutMenuItem); - - - - StatusItem.Menu = Menu; - StatusItem.Menu.Update (); - } - - - // A method reference that makes sure that opening the - // event log for each repository works correctly - private EventHandler OpenFolderDelegate (string name) - { - return delegate { - SparkleShare.Controller.OpenSparkleShareFolder (name); - }; - } - - - public void UpdateMenu () - { - StateMenuItem.Title = StateText; - } - - - // The state when there's nothing going on - private void SetNormalState () - { - if (SparkleShare.Controller.UnsyncedFolders.Count > 0) - SetNormalState (true); - else - SetNormalState (false); - } - - - // The state when there's nothing going on - private void SetNormalState (bool error) - { - Animation.Stop (); - - if (SparkleShare.Controller.Folders.Count == 0) { - StateText = _("Welcome to SparkleShare!"); - - InvokeOnMainThread (delegate { - StatusItem.Image = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/idle0.png"); - StatusItem.AlternateImage = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/idle0-active.png"); - StatusItem.Image.Size = new SizeF (16, 16); - StatusItem.AlternateImage.Size = new SizeF (16, 16); - }); - - } else { - if (error) { - StateText = _("Not everything is synced"); - - InvokeOnMainThread (delegate { - StatusItem.Image = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/error.png"); - StatusItem.AlternateImage = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/error-active.png"); - StatusItem.Image.Size = new SizeF (16, 16); - StatusItem.AlternateImage.Size = new SizeF (16, 16); - }); - - } else { - StateText = _("Up to date") + " (" + SparkleShare.Controller.FolderSize + ")"; - - InvokeOnMainThread (delegate { - StatusItem.Image = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/idle0.png"); - StatusItem.AlternateImage = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/idle0-active.png"); - StatusItem.Image.Size = new SizeF (16, 16); - StatusItem.AlternateImage.Size = new SizeF (16, 16); - }); - } - } - } - - - // The state when animating - private void SetAnimationState () - { - StateText = _("Syncing…"); - - if (!Animation.Enabled) - Animation.Start (); - } } diff --git a/SparkleShare/Mac/SparkleUI.cs b/SparkleShare/Mac/SparkleUI.cs index d4e24aeb..eb3721aa 100644 --- a/SparkleShare/Mac/SparkleUI.cs +++ b/SparkleShare/Mac/SparkleUI.cs @@ -29,25 +29,12 @@ using MonoMac.Growl; namespace SparkleShare { - public partial class AppDelegate : NSApplicationDelegate { - - public override void WillBecomeActive (NSNotification notification) - { - NSApplication.SharedApplication.DockTile.BadgeLabel = null; - } - - public override void WillTerminate (NSNotification notification) - { - SparkleShare.Controller.Quit (); - } - } - - public class SparkleUI : AppDelegate { public static SparkleStatusIcon StatusIcon; public static SparkleEventLog EventLog; - public static SparkleIntro Intro; + public static SparkleSetup Setup; + public static SparkleBubbles Bubbles; public static SparkleAbout About; public static NSFont Font; @@ -69,7 +56,6 @@ namespace SparkleShare { // Use translations Catalog.Init ("sparkleshare", Path.Combine (NSBundle.MainBundle.ResourcePath, "Translations")); - using (NSAutoreleasePool pool = new NSAutoreleasePool ()) { @@ -79,86 +65,24 @@ namespace SparkleShare { NSApplication.SharedApplication.ApplicationIconImage = NSImage.ImageNamed ("sparkleshare.icns"); - SetFolderIcon (); - if (!SparkleShare.Controller.BackendIsPresent) { this.alert = new SparkleAlert (); this.alert.RunModal (); return; } + + SetFolderIcon (); Font = NSFontManager.SharedFontManager.FontWithFamily ("Lucida Grande", NSFontTraitMask.Condensed, 0, 13); StatusIcon = new SparkleStatusIcon (); - } + Bubbles = new SparkleBubbles (); - SparkleShare.Controller.NotificationRaised += delegate (string user_name, string user_email, - string message, string repository_path) { - InvokeOnMainThread (delegate { - if (EventLog != null) - EventLog.UpdateEvents (); - - if (SparkleShare.Controller.NotificationsEnabled) { - if (NSApplication.SharedApplication.DockTile.BadgeLabel == null) - NSApplication.SharedApplication.DockTile.BadgeLabel = "1"; - else - NSApplication.SharedApplication.DockTile.BadgeLabel = - (int.Parse (NSApplication.SharedApplication.DockTile.BadgeLabel) + 1).ToString (); - - if (GrowlApplicationBridge.IsGrowlRunning ()) { - SparkleBubble bubble = new SparkleBubble (user_name, message) { - ImagePath = SparkleShare.Controller.GetAvatar (user_email, 36) - }; - - bubble.Show (); - - } else { - NSApplication.SharedApplication.RequestUserAttention ( - NSRequestUserAttentionType.InformationalRequest); - } - } - }); - }; - - - SparkleShare.Controller.ConflictNotificationRaised += delegate { - string title = "Ouch! Mid-air collision!"; - string subtext = "Don't worry, SparkleShare made a copy of each conflicting file."; - - new SparkleBubble (title, subtext).Show (); - }; - - - SparkleShare.Controller.AvatarFetched += delegate { - InvokeOnMainThread (delegate { - if (EventLog != null) - EventLog.UpdateEvents (); - }); - }; - - - SparkleShare.Controller.OnIdle += delegate { - InvokeOnMainThread (delegate { - if (EventLog != null) - EventLog.UpdateEvents (); - }); - }; - - - SparkleShare.Controller.FolderListChanged += delegate { - InvokeOnMainThread (delegate { - if (EventLog != null) { - EventLog.UpdateChooser (); - EventLog.UpdateEvents (); - } - }); - }; - - - if (SparkleShare.Controller.FirstRun) { - Intro = new SparkleIntro (); - Intro.ShowAccountForm (); + if (SparkleShare.Controller.FirstRun) { + Setup = new SparkleSetup (); + Setup.Controller.ShowSetupPage (); + } } } @@ -188,4 +112,18 @@ namespace SparkleShare { return NSDictionary.FromFile (path); } } + + + public partial class AppDelegate : NSApplicationDelegate { + + public override void WillBecomeActive (NSNotification notification) + { + NSApplication.SharedApplication.DockTile.BadgeLabel = null; + } + + public override void WillTerminate (NSNotification notification) + { + SparkleShare.Controller.Quit (); + } + } } diff --git a/SparkleShare/Makefile.am b/SparkleShare/Makefile.am index c757da22..15dee260 100644 --- a/SparkleShare/Makefile.am +++ b/SparkleShare/Makefile.am @@ -13,19 +13,39 @@ endif SOURCES = \ SparkleAbout.cs \ - SparkleBubble.cs \ + SparkleAboutController.cs \ + SparkleBubbles.cs \ + SparkleBubblesController.cs \ SparkleController.cs \ SparkleEntry.cs \ - SparkleInfobar.cs \ - SparkleIntro.cs \ - SparkleLinController.cs \ SparkleEventLog.cs \ + SparkleEventLogController.cs \ + SparkleLinController.cs \ + SparkleSetup.cs \ + SparkleSetupController.cs \ + SparkleSetupWindow.cs \ SparkleShare.cs \ SparkleSpinner.cs \ SparkleStatusIcon.cs \ + SparkleStatusIconController.cs \ SparkleUI.cs \ - SparkleUIHelpers.cs \ - SparkleWindow.cs + SparkleUIHelpers.cs + SparkleBubbles.cs \ + SparkleBubblesController.cs \ + SparkleController.cs \ + SparkleEntry.cs \ + SparkleEventLog.cs \ + SparkleEventLogController.cs \ + SparkleLinController.cs \ + SparkleSetup.cs \ + SparkleSetupController.cs \ + SparkleSetupWindow.cs \ + SparkleShare.cs \ + SparkleSpinner.cs \ + SparkleStatusIcon.cs \ + SparkleStatusIconController.cs \ + SparkleUI.cs \ + SparkleUIHelpers.cs include $(top_srcdir)/build/build.mk diff --git a/SparkleShare/SparkleAbout.cs b/SparkleShare/SparkleAbout.cs index 5e738371..3d2e401b 100644 --- a/SparkleShare/SparkleAbout.cs +++ b/SparkleShare/SparkleAbout.cs @@ -27,7 +27,9 @@ namespace SparkleShare { public class SparkleAbout : Window { - private Label version; + public SparkleAboutController Controller = new SparkleAboutController (); + + private Label updates; // Short alias for the translations @@ -39,30 +41,54 @@ namespace SparkleShare { public SparkleAbout () : base ("") { - DefaultSize = new Gdk.Size (360, 260); + DeleteEvent += delegate (object o, DeleteEventArgs args) { + HideAll (); + args.RetVal = true; + }; + + DefaultSize = new Gdk.Size (600, 260); + Resizable = false; BorderWidth = 0; IconName = "folder-sparkleshare"; WindowPosition = WindowPosition.Center; Title = _("About SparkleShare"); - Resizable = false; + AppPaintable = true; + + // TODO: Should be able to do without referencing SparkleLib... + string image_path = SparkleLib.SparkleHelpers.CombineMore (SparkleLib.Defines.DATAROOTDIR, + "sparkleshare", "pixmaps", "about.png"); + + Realize (); + Gdk.Pixbuf buf = new Gdk.Pixbuf (image_path); + Gdk.Pixmap map, map2; + buf.RenderPixmapAndMask (out map, out map2, 255); + GdkWindow.SetBackPixmap (map, false); CreateAbout (); - SparkleShare.Controller.NewVersionAvailable += delegate (string new_version) { + Controller.NewVersionEvent += delegate (string new_version) { Application.Invoke (delegate { - this.version.Markup = String.Format ("{0}: {1}", _("A newer version is available"), new_version); - this.version.ShowAll (); + this.updates.Markup = String.Format ("{0}", + String.Format (_("A newer version ({0}) is available!"), new_version)); + this.updates.ShowAll (); }); }; - SparkleShare.Controller.VersionUpToDate += delegate { + Controller.VersionUpToDateEvent += delegate { Application.Invoke (delegate { - this.version.Markup = String.Format ("{0}", _("You are running the latest version.")); - this.version.ShowAll (); + this.updates.Markup = String.Format ("{0}", + _("You are running the latest version.")); + this.updates.ShowAll (); }); }; - SparkleShare.Controller.CheckForNewVersion (); + Controller.CheckingForNewVersionEvent += delegate { + Application.Invoke (delegate { + this.updates.Markup = String.Format ("{0}", + _("Checking for updates...")); + this.updates.ShowAll (); + }); + }; } @@ -71,84 +97,58 @@ namespace SparkleShare { Gdk.Color color = Style.Foreground (StateType.Insensitive); string secondary_text_color = SparkleUIHelpers.GdkColorToHex (color); - EventBox box = new EventBox (); - box.ModifyBg (StateType.Normal, new TreeView ().Style.Base (StateType.Normal)); - - Label header = new Label () { - Markup = "SparkleShare\n" + SparkleShare.Controller.Version + "", - Xalign = 0, - Xpad = 18, - Ypad = 18 - }; - - box.Add (header); - - this.version = new Label () { - Markup = String.Format ("{0}", _("Checking for updates...")), + Label version = new Label () { + Markup = "" + + "version " + Controller.RunningVersion + + "", Xalign = 0, - Xpad = 18, - Ypad = 22, + Xpad = 300 + }; + + this.updates = new Label () { + Markup = "" + + _("Checking for updates...") + + "", + Xalign = 0, + Xpad = 300 + }; + + Label copyright = new Label () { + Markup = "" + + "Copyright © 2010–" + DateTime.Now.Year + " " + + "Hylke Bons and others." + + "", + Xalign = 0, + Xpad = 300 }; Label license = new Label () { - Xalign = 0, - Xpad = 18, - Ypad = 0, LineWrap = true, - Wrap = true, LineWrapMode = Pango.WrapMode.Word, - - Markup = "Copyright © 2010–" + DateTime.Now.Year + " Hylke Bons and others\n" + - "\n" + - "SparkleShare is Free and Open Source Software. " + - "You are free to use, modify, and redistribute it " + - "under the terms of the GNU General Public License version 3 or later." + Markup = "" + + "SparkleShare is Free and Open Source Software. You are free to use, modify, " + + "and redistribute it under the GNU General Public License version 3 or later." + + "", + WidthRequest = 330, + Wrap = true, + Xalign = 0, + Xpad = 300, }; - VBox vbox = new VBox (false, 0) { - BorderWidth = 0 + VBox layout_horizontal = new VBox (false, 0) { + BorderWidth = 0, + HeightRequest = 260, + WidthRequest = 640 }; - HButtonBox button_bar = new HButtonBox () { - BorderWidth = 12 - }; + layout_horizontal.PackStart (new Label (""), false, false, 42); + layout_horizontal.PackStart (version, false, false, 0); + layout_horizontal.PackStart (this.updates, false, false, 0); + layout_horizontal.PackStart (copyright, false, false, 9); + layout_horizontal.PackStart (license, false, false, 0); + layout_horizontal.PackStart (new Label (""), false, false, 0); - Button credits_button = new Button (_("_Show Credits")) { - UseUnderline = true - }; - - credits_button.Clicked += delegate { - - Process process = new Process (); - process.StartInfo.FileName = "xdg-open"; - process.StartInfo.Arguments = "http://www.sparkleshare.org/credits"; - process.Start (); - - }; - - Button website_button = new Button (_("_Visit Website")) { - UseUnderline = true - }; - - website_button.Clicked += delegate { - - Process process = new Process (); - process.StartInfo.FileName = "xdg-open"; - process.StartInfo.Arguments = "http://www.sparkleshare.org/"; - process.Start (); - - }; - - button_bar.Add (website_button); - button_bar.Add (credits_button); - - vbox.PackStart (box, true, true, 0); - vbox.PackStart (this.version, false, false, 0); - vbox.PackStart (license, true, true, 0); - vbox.PackStart (new Label (""), true, true, 0); - vbox.PackStart (button_bar, false, false, 0); - - Add (vbox); + Add (layout_horizontal); } } } diff --git a/SparkleShare/SparkleAboutController.cs b/SparkleShare/SparkleAboutController.cs new file mode 100644 index 00000000..5495dfc9 --- /dev/null +++ b/SparkleShare/SparkleAboutController.cs @@ -0,0 +1,95 @@ +// SparkleShare, a collaboration and sharing tool. +// Copyright (C) 2010 Hylke Bons +// +// 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 . + + +using System; +using System.Net; +using System.Threading; +using System.Timers; + +using SparkleLib; + +namespace SparkleShare { + + public class SparkleAboutController { + + public event NewVersionEventHandler NewVersionEvent; + public delegate void NewVersionEventHandler (string new_version); + + public event VersionUpToDateEventHandler VersionUpToDateEvent; + public delegate void VersionUpToDateEventHandler (); + + public event CheckingForNewVersionEventHandler CheckingForNewVersionEvent; + public delegate void CheckingForNewVersionEventHandler (); + + public string RunningVersion { + get { + return SparkleBackend.Version; + } + } + + // Check for a new version once a day + private System.Timers.Timer version_checker = new System.Timers.Timer () { + Enabled = true, + Interval = 24 * 60 * 60 * 1000 + }; + + + public SparkleAboutController () + { + CheckForNewVersion (); + + this.version_checker.Elapsed += delegate { + CheckForNewVersion (); + }; + } + + + public void CheckForNewVersion () + { + this.version_checker.Stop (); + if (CheckingForNewVersionEvent != null) + CheckingForNewVersionEvent (); + + WebClient web_client = new WebClient (); + Uri uri = new Uri ("http://www.sparkleshare.org/version"); + + web_client.DownloadStringCompleted += delegate (object o, DownloadStringCompletedEventArgs args) { + if (args.Error != null) + return; + + string new_version = args.Result.Trim (); + + // Add a little delay, making it seems we're + // actually doing hard work + Thread.Sleep (2 * 1000); + + if (RunningVersion.Equals (new_version)) { + if (VersionUpToDateEvent != null) + VersionUpToDateEvent (); + + } else { + if (NewVersionEvent != null) + NewVersionEvent (new_version); + } + + this.version_checker.Start (); + }; + + web_client.DownloadStringAsync (uri); + } + } +} diff --git a/SparkleShare/SparkleBubble.cs b/SparkleShare/SparkleBubbles.cs similarity index 51% rename from SparkleShare/SparkleBubble.cs rename to SparkleShare/SparkleBubbles.cs index 61275449..7f0f2cf3 100644 --- a/SparkleShare/SparkleBubble.cs +++ b/SparkleShare/SparkleBubbles.cs @@ -16,26 +16,41 @@ using System; + +using Gtk; using Notifications; namespace SparkleShare { - public class SparkleBubble : Notification { + public class SparkleBubbles { - public SparkleBubble (string title, string subtext) : base (title, subtext) + public SparkleBubblesController Controller = new SparkleBubblesController (); + + + public SparkleBubbles () { - IconName = "folder-sparkleshare"; - Timeout = 4500; - Urgency = Urgency.Low; + Controller.ShowBubbleEvent += delegate (string title, string subtext, string image_path) { + Notification notification = new Notification () { + Timeout = 5 * 1000, + Urgency = Urgency.Low + }; + + if (image_path != null) + notification.Icon = new Gdk.Pixbuf (image_path); + else + notification.IconName = "folder-sparkleshare"; + + notification.Show (); + }; } // Checks whether the system allows adding buttons to a notification, // prevents error messages in Ubuntu. - new public void AddAction (string action, string label, ActionHandler handler) - { - if (Array.IndexOf (Notifications.Global.Capabilities, "actions") > -1) - base.AddAction (action, label, handler); - } +// new public void AddAction (string action, string label, ActionHandler handler) +// { +// if (Array.IndexOf (Notifications.Global.Capabilities, "actions") > -1) +// base.AddAction (action, label, handler); +// } } } diff --git a/SparkleShare/SparkleBubblesController.cs b/SparkleShare/SparkleBubblesController.cs new file mode 100644 index 00000000..56ffd3a9 --- /dev/null +++ b/SparkleShare/SparkleBubblesController.cs @@ -0,0 +1,45 @@ +// SparkleShare, a collaboration and sharing tool. +// Copyright (C) 2010 Hylke Bons +// +// 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 . + + +using System; + +namespace SparkleShare { + + public class SparkleBubblesController { + + public event ShowBubbleEventHandler ShowBubbleEvent; + public delegate void ShowBubbleEventHandler (string title, string subtext, string image_path); + + + public SparkleBubblesController () + { + SparkleShare.Controller.ConflictNotificationRaised += delegate { + if (ShowBubbleEvent != null && SparkleShare.Controller.NotificationsEnabled) + ShowBubbleEvent ("Ouch! Mid-air collision!", + "Don't worry, SparkleShare made a copy of each conflicting file.", null); + }; + + SparkleShare.Controller.NotificationRaised += delegate (string user_name, string user_email, + string message, string folder_path) { + + if (ShowBubbleEvent != null && SparkleShare.Controller.NotificationsEnabled) + ShowBubbleEvent (user_name, message, + SparkleShare.Controller.GetAvatar (user_email, 36)); + }; + } + } +} diff --git a/SparkleShare/SparkleController.cs b/SparkleShare/SparkleController.cs index 1ed7642e..1088b3d5 100644 --- a/SparkleShare/SparkleController.cs +++ b/SparkleShare/SparkleController.cs @@ -75,12 +75,6 @@ namespace SparkleShare { public delegate void NotificationRaisedEventHandler (string user_name, string user_email, string message, string repository_path); - public event NewVersionAvailableEventHandler NewVersionAvailable; - public delegate void NewVersionAvailableEventHandler (string new_version); - - public event VersionUpToDateEventHandler VersionUpToDate; - public delegate void VersionUpToDateEventHandler (); - // Short alias for the translations public static string _ (string s) @@ -230,15 +224,6 @@ namespace SparkleShare { } - public List PreviousHosts { - get { - List hosts = SparkleConfig.DefaultConfig.Hosts; - hosts.Sort (); - return hosts; - } - } - - public List UnsyncedFolders { get { List unsynced_folders = new List (); @@ -498,7 +483,7 @@ namespace SparkleShare { // Fires events for the current syncing state - private void UpdateState () + public void UpdateState () { foreach (SparkleRepoBase repo in Repositories) { if (repo.Status == SyncStatus.SyncDown || @@ -1006,7 +991,6 @@ namespace SparkleShare { fetcher.Failed += delegate { - if (FolderFetchError != null) FolderFetchError (); @@ -1068,11 +1052,6 @@ namespace SparkleShare { } - public string Version { - get { - return SparkleBackend.Version; - } - } public void AddNoteToFolder (string folder_name, string revision, string note) @@ -1084,29 +1063,6 @@ namespace SparkleShare { } - public void CheckForNewVersion () - { - WebClient web_client = new WebClient (); - Uri uri = new Uri ("http://www.sparkleshare.org/version"); - - web_client.DownloadStringCompleted += delegate (object o, DownloadStringCompletedEventArgs args) { - if (args.Error != null) - return; - - string new_version = args.Result.Trim (); - - if (Version.Equals (new_version)) { - if (VersionUpToDate != null) - VersionUpToDate (); - - } else { - if (NewVersionAvailable != null) - NewVersionAvailable (new_version); - } - }; - - web_client.DownloadStringAsync (uri); - } private string [] tango_palette = new string [] {"#eaab00", "#e37222", diff --git a/SparkleShare/SparkleEntry.cs b/SparkleShare/SparkleEntry.cs index 96ac5bef..3d0f846c 100644 --- a/SparkleShare/SparkleEntry.cs +++ b/SparkleShare/SparkleEntry.cs @@ -17,6 +17,7 @@ using Gtk; +// TODO: Remove with Gtk3 namespace SparkleShare { public class SparkleEntry : Entry { @@ -33,7 +34,6 @@ namespace SparkleShare { ClipboardPasted += delegate { OnEntered (); }; FocusOutEvent += delegate { - if (Text.Equals ("") || Text == null) ExampleTextActive = true; diff --git a/SparkleShare/SparkleEventLogController.cs b/SparkleShare/SparkleEventLogController.cs new file mode 100644 index 00000000..fdc99f3d --- /dev/null +++ b/SparkleShare/SparkleEventLogController.cs @@ -0,0 +1,119 @@ +// SparkleShare, a collaboration and sharing tool. +// Copyright (C) 2010 Hylke Bons +// +// 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 . + + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading; + +using SparkleLib; + +namespace SparkleShare { + + public class SparkleEventLogController { + + public event UpdateContentEventEventHandler UpdateContentEvent; + public delegate void UpdateContentEventEventHandler (string html); + + public event UpdateChooserEventHandler UpdateChooserEvent; + public delegate void UpdateChooserEventHandler (string [] folders); + + public event ContentLoadingEventHandler ContentLoadingEvent; + public delegate void ContentLoadingEventHandler (); + + + public string SelectedFolder { + get { + return this.selected_folder; + } + + set { + this.selected_folder = value; + + if (ContentLoadingEvent != null) + ContentLoadingEvent (); + + Stopwatch watch = new Stopwatch (); + watch.Start (); + + Thread thread = new Thread (new ThreadStart (delegate { + string html = HTML; + watch.Stop (); + + // A short delay is less annoying than + // a flashing window + if (watch.ElapsedMilliseconds < 500) + Thread.Sleep (500 - (int) watch.ElapsedMilliseconds); + + if (UpdateContentEvent != null) + UpdateContentEvent (html); + })); + + thread.Start (); + } + } + + public string HTML { + get { + List change_sets = SparkleShare.Controller.GetLog (this.selected_folder); + return SparkleShare.Controller.GetHTMLLog (change_sets); + } + } + + public string [] Folders { + get { + return SparkleShare.Controller.Folders.ToArray (); + } + } + + + private string selected_folder; + + + public SparkleEventLogController () + { + SparkleShare.Controller.AvatarFetched += delegate { + if (UpdateContentEvent != null) + UpdateContentEvent (HTML); + }; + + SparkleShare.Controller.OnIdle += delegate { + if (UpdateContentEvent != null) + UpdateContentEvent (HTML); + }; + + SparkleShare.Controller.FolderListChanged += delegate { + if (this.selected_folder != null && + !SparkleShare.Controller.Folders.Contains (this.selected_folder)) { + + this.selected_folder = null; + } + + if (UpdateChooserEvent != null) + UpdateChooserEvent (Folders); + + if (UpdateContentEvent != null) + UpdateContentEvent (HTML); + }; + + SparkleShare.Controller.NotificationRaised += delegate { + if (UpdateContentEvent != null) + UpdateContentEvent (HTML); + }; + } + } +} diff --git a/SparkleShare/SparkleInfobar.cs b/SparkleShare/SparkleInfobar.cs deleted file mode 100644 index b211771f..00000000 --- a/SparkleShare/SparkleInfobar.cs +++ /dev/null @@ -1,50 +0,0 @@ -// SparkleShare, a collaboration and sharing tool. -// Copyright (C) 2010 Hylke Bons -// -// 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 . - - -using Gtk; - -namespace SparkleShare { - - // An infobar - public class SparkleInfobar : EventBox { - - public SparkleInfobar (string icon_name, string title, string text) - { - Window window = new Window (WindowType.Popup) { - Name = "gtk-tooltip" - }; - - window.EnsureStyle (); - Style = window.Style; - - Label label = new Label () { - Markup = "" + title + "\n" + text - }; - - HBox hbox = new HBox (false, 12) { - BorderWidth = 12 - }; - - hbox.PackStart (new Image (SparkleUIHelpers.GetIcon (icon_name, 24)), - false, false, 0); - - hbox.PackStart (label, false, false, 0); - - Add (hbox); - } - } -} diff --git a/SparkleShare/SparkleIntro.cs b/SparkleShare/SparkleIntro.cs deleted file mode 100644 index d34d7b90..00000000 --- a/SparkleShare/SparkleIntro.cs +++ /dev/null @@ -1,721 +0,0 @@ -// SparkleShare, a collaboration and sharing tool. -// Copyright (C) 2010 Hylke Bons -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General private 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 private License for more details. -// -// You should have received a copy of the GNU General private License -// along with this program. If not, see . - - -using System; -using System.Diagnostics; -using System.IO; -using System.Text.RegularExpressions; -using System.Timers; -using System.Collections.Generic; - -using Gtk; -using Mono.Unix; -using Notifications; - -namespace SparkleShare { - - public class SparkleIntro : SparkleWindow { - - private Entry NameEntry; - private Entry EmailEntry; - private SparkleEntry ServerEntry; - private SparkleEntry FolderEntry; - private string PreviousServer; - private string PreviousFolder; - private Button NextButton; - private Button SyncButton; - private bool ServerFormOnly; - private string SecondaryTextColor; - private ProgressBar progress_bar = new ProgressBar () { PulseStep = 0.01 }; - private Timer progress_bar_pulse_timer = new Timer () { Interval = 25, Enabled = true }; - - - // Short alias for the translations - public static string _ (string s) - { - return Catalog.GetString (s); - } - - - public SparkleIntro () : base () - { - ServerFormOnly = false; - SecondaryTextColor = SparkleUIHelpers.GdkColorToHex (Style.Foreground (StateType.Insensitive)); - } - - - public void ShowAccountForm () - { - Reset (); - - VBox layout_vertical = new VBox (false, 0); - - Deletable = false; - - Label header = new Label ("" + - _("Welcome to SparkleShare!") + - "") { - UseMarkup = true, - Xalign = 0 - }; - - Label information = new Label (_("Before we can create a SparkleShare folder on this " + - "computer, we need a few bits of information from you.")) { - Xalign = 0, - Wrap = true - }; - - Table table = new Table (4, 2, true) { - RowSpacing = 6 - }; - - Label name_label = new Label ("" + _("Full Name:") + "") { - UseMarkup = true, - Xalign = 0 - }; - - NameEntry = new Entry (SparkleShare.Controller.UserName); - NameEntry.Changed += delegate { - CheckAccountForm (); - }; - - EmailEntry = new Entry (); - EmailEntry.Changed += delegate { - CheckAccountForm (); - }; - - Label email_label = new Label ("" + _("Email:") + "") { - UseMarkup = true, - Xalign = 0 - }; - - - table.Attach (name_label, 0, 1, 0, 1); - table.Attach (NameEntry, 1, 2, 0, 1); - table.Attach (email_label, 0, 1, 1, 2); - table.Attach (EmailEntry, 1, 2, 1, 2); - - NextButton = new Button (_("Next")) { - Sensitive = false - }; - - NextButton.Clicked += delegate (object o, EventArgs args) { - NextButton.Remove (NextButton.Child); - NextButton.Add (new Label (_("Configuring…"))); - - NextButton.Sensitive = false; - table.Sensitive = false; - - NextButton.ShowAll (); - - SparkleShare.Controller.UserName = NameEntry.Text; - SparkleShare.Controller.UserEmail = EmailEntry.Text; - - SparkleShare.Controller.GenerateKeyPair (); - SparkleShare.Controller.AddKey (); - - SparkleUI.StatusIcon.CreateMenu (); - - Deletable = true; - ShowServerForm (); - }; - - AddButton (NextButton); - - layout_vertical.PackStart (header, false, false, 0); - layout_vertical.PackStart (information, false, false, 21); - layout_vertical.PackStart (new Label (""), false, false, 0); - layout_vertical.PackStart (table, false, false, 0); - - Add (layout_vertical); - CheckAccountForm (); - ShowAll (); - } - - - public void ShowServerForm (bool server_form_only) - { - ServerFormOnly = server_form_only; - ShowServerForm (); - } - - - public void ShowServerForm () - { - Reset (); - - VBox layout_vertical = new VBox (false, 0); - - Label header = new Label ("" + - _("Where is your remote folder?") + - "") { - UseMarkup = true, - Xalign = 0 - }; - - Table table = new Table (7, 2, false) { - RowSpacing = 12 - }; - - HBox layout_server = new HBox (true, 0); - - ServerEntry = new SparkleEntry () { }; - ServerEntry.Completion = new EntryCompletion(); - ServerEntry.Completion.Model = ServerEntryCompletion(); - ServerEntry.Completion.TextColumn = 0; - - if (PreviousServer != null) { - ServerEntry.Text = PreviousServer; - ServerEntry.ExampleTextActive = false; - } else - ServerEntry.ExampleText = _("address-to-server.com"); - - ServerEntry.Changed += CheckServerForm; - - RadioButton radio_button = new RadioButton ("" + _("On my own server:") + ""); - - layout_server.Add (radio_button); - layout_server.Add (ServerEntry); - - string github_text = "" + "Github" + "\n" + - "" + - _("Free hosting for Free and Open Source Software projects.") + "\n" + - _("Also has paid accounts for extra private space and bandwidth.") + - ""; - - RadioButton radio_button_github = new RadioButton (radio_button, github_text); - - (radio_button_github.Child as Label).UseMarkup = true; - (radio_button_github.Child as Label).Wrap = true; - - string gnome_text = "" + _("The GNOME Project") + "\n" + - "" + - _("GNOME is an easy to understand interface to your computer.") + "\n" + - _("Select this option if you’re a developer or designer working on GNOME.") + - ""; - - RadioButton radio_button_gnome = new RadioButton (radio_button, gnome_text); - - (radio_button_gnome.Child as Label).UseMarkup = true; - (radio_button_gnome.Child as Label).Wrap = true; - - string gitorious_text = "" + _("Gitorious") + "\n" + - "" + - _("Completely Free as in Freedom infrastructure.") + "\n" + - _("Free accounts for Free and Open Source projects.") + - ""; - RadioButton radio_button_gitorious = new RadioButton (radio_button, gitorious_text) { - Xalign = 0 - }; - - (radio_button_gitorious.Child as Label).UseMarkup = true; - (radio_button_gitorious.Child as Label).Wrap = true; - - radio_button_github.Toggled += delegate { - if (radio_button_github.Active) - FolderEntry.ExampleText = _("Username/Folder"); - }; - - radio_button_gitorious.Toggled += delegate { - if (radio_button_gitorious.Active) - FolderEntry.ExampleText = _("Project/Folder"); - }; - - radio_button_gnome.Toggled += delegate { - if (radio_button_gnome.Active) - FolderEntry.ExampleText = _("Project"); - }; - - radio_button.Toggled += delegate { - if (radio_button.Active) { - FolderEntry.ExampleText = _("Folder"); - ServerEntry.Sensitive = true; - CheckServerForm (); - } else { - ServerEntry.Sensitive = false; - CheckServerForm (); - } - - ShowAll (); - }; - - table.Attach (layout_server, 0, 2, 1, 2); - table.Attach (radio_button_github, 0, 2, 2, 3); - table.Attach (radio_button_gitorious, 0, 2, 3, 4); - table.Attach (radio_button_gnome, 0, 2, 4, 5); - - HBox layout_folder = new HBox (true, 0); - - FolderEntry = new SparkleEntry () { }; - FolderEntry.Completion = new EntryCompletion(); - FolderEntry.Completion.Model = FolderEntryCompletion(); - FolderEntry.Completion.TextColumn = 0; - - if (PreviousFolder != null) { - FolderEntry.Text = PreviousFolder; - FolderEntry.ExampleTextActive = false; - } else - FolderEntry.ExampleText = _("Folder"); - - FolderEntry.Changed += CheckServerForm; - - Label folder_label = new Label (_("Folder Name:")) { - UseMarkup = true, - Xalign = 1 - }; - - (radio_button.Child as Label).UseMarkup = true; - - layout_folder.PackStart (folder_label, true, true, 12); - layout_folder.PackStart (FolderEntry, true, true, 0); - - SyncButton = new Button (_("Sync")); - - SyncButton.Clicked += delegate { - string folder_name = FolderEntry.Text; - string server = ServerEntry.Text; - string canonical_name = System.IO.Path.GetFileNameWithoutExtension (folder_name); - - PreviousServer = ServerEntry.Text; - PreviousFolder = FolderEntry.Text; - - if (radio_button_gitorious.Active) - server = "gitorious.org"; - - if (radio_button_github.Active) - server = "github.com"; - - if (radio_button_gnome.Active) - server = "gnome.org"; - - Application.Invoke (delegate { - Deletable = false; - ShowSyncingPage (canonical_name); - }); - - SparkleShare.Controller.FolderFetched += delegate { - Application.Invoke (delegate { - this.progress_bar_pulse_timer.Stop (); - Deletable = true; - UrgencyHint = true; - ShowSuccessPage (canonical_name); - }); - }; - - SparkleShare.Controller.FolderFetchError += delegate { - Application.Invoke (delegate { - this.progress_bar_pulse_timer.Stop (); - Deletable = true; - ShowErrorPage (); - }); - }; - - SparkleShare.Controller.FetchFolder (server, folder_name); - }; - - - if (ServerFormOnly) { - Button cancel_button = new Button (_("Cancel")); - - cancel_button.Clicked += delegate { - Close (); - }; - - AddButton (cancel_button); - } else { - Button skip_button = new Button (_("Skip")); - - skip_button.Clicked += delegate { - ShowCompletedPage (); - }; - - AddButton (skip_button); - } - - AddButton (SyncButton); - - layout_vertical.PackStart (header, false, false, 0); - layout_vertical.PackStart (new Label (""), false, false, 3); - layout_vertical.PackStart (table, false, false, 0); - layout_vertical.PackStart (layout_folder, false, false, 6); - - Add (layout_vertical); - CheckServerForm (); - ShowAll (); - } - - - public void ShowInvitationPage (string server, string folder, string token) - { - VBox layout_vertical = new VBox (false, 0); - - Label header = new Label ("" + - _("Invitation received!") + - "") { - UseMarkup = true, - Xalign = 0 - }; - - Label information = new Label (_("You've received an invitation to join a shared folder.\n" + - "We're ready to hook you up immediately if you wish.")) { - Xalign = 0, - Wrap = true - }; - - Label question = new Label (_("Do you accept this invitation?")) { - Xalign = 0, - Wrap = true - }; - - Table table = new Table (2, 2, false) { - RowSpacing = 6 - }; - - Label server_label = new Label (_("Server Address:")) { - Xalign = 0 - }; - - Label server_text = new Label ("" + server + "") { - UseMarkup = true, - Xalign = 0 - }; - - Label folder_label = new Label (_("Folder Name:")) { - Xalign = 0 - }; - - Label folder_text = new Label ("" + folder + "") { - UseMarkup = true, - Xalign = 0 - }; - - table.Attach (folder_label, 0, 1, 0, 1); - table.Attach (folder_text, 1, 2, 0, 1); - table.Attach (server_label, 0, 1, 1, 2); - table.Attach (server_text, 1, 2, 1, 2); - - Button reject_button = new Button (_("Reject")); - Button accept_button = new Button (_("Accept and Sync")); - - reject_button.Clicked += delegate { - Close (); - }; - - accept_button.Clicked += delegate { - string url = "ssh://git@" + server + "/" + folder; - if (server.StartsWith("http")) { - url = server; - } - - SparkleShare.Controller.FolderFetched += delegate { - Application.Invoke (delegate { - this.progress_bar_pulse_timer.Stop (); - ShowSuccessPage (folder); - }); - }; - - SparkleShare.Controller.FolderFetchError += delegate { - Application.Invoke (delegate { - this.progress_bar_pulse_timer.Stop (); - ShowErrorPage (); - }); - }; - - - SparkleShare.Controller.FetchFolder (url, folder); - }; - - AddButton (reject_button); - AddButton (accept_button); - - layout_vertical.PackStart (header, false, false, 0); - layout_vertical.PackStart (information, false, false, 21); - layout_vertical.PackStart (new Label (""), false, false, 0); - layout_vertical.PackStart (table, false, false, 0); - layout_vertical.PackStart (new Label (""), false, false, 0); - layout_vertical.PackStart (question, false, false, 21); - - Add (layout_vertical); - ShowAll (); - } - - - // The page shown when syncing has failed - private void ShowErrorPage () - { - Reset (); - - VBox layout_vertical = new VBox (false, 0); - - Label header = new Label ("" + - _("Something went wrong…") + - "\n") { - UseMarkup = true, - Xalign = 0 - }; - - Button try_again_button = new Button (_("Try Again")) { - Sensitive = true - }; - - try_again_button.Clicked += delegate (object o, EventArgs args) { - ShowServerForm (); - }; - - AddButton (try_again_button); - - layout_vertical.PackStart (header, false, false, 0); - - Add (layout_vertical); - ShowAll (); - } - - - // The page shown when syncing has succeeded - private void ShowSuccessPage (string folder_name) - { - Reset (); - - UrgencyHint = true; - - PreviousServer = null; - PreviousFolder = null; - - if (!HasToplevelFocus) { - string title = String.Format (_("‘{0}’ has been successfully added"), folder_name); - string subtext = _(""); - - new SparkleBubble (title, subtext).Show (); - } - - VBox layout_vertical = new VBox (false, 0); - - Label header = new Label ("" + - _("Folder synced successfully!") + - "") { - UseMarkup = true, - Xalign = 0 - }; - - Label information = new Label ( - String.Format (_("Now you can access the synced files from ‘{0}’ in your SparkleShare folder."), - folder_name)) { - Xalign = 0, - Wrap = true, - UseMarkup = true - }; - - // A button that opens the synced folder - Button open_folder_button = new Button (_("Open Folder")); - - open_folder_button.Clicked += delegate { - SparkleShare.Controller.OpenSparkleShareFolder (folder_name); - }; - - Button finish_button = new Button (_("Finish")); - - finish_button.Clicked += delegate (object o, EventArgs args) { - Close (); - }; - - AddButton (open_folder_button); - AddButton (finish_button); - - layout_vertical.PackStart (header, false, false, 0); - layout_vertical.PackStart (information, false, false, 21); - - Add (layout_vertical); - ShowAll (); - } - - - // The page shown whilst syncing - private void ShowSyncingPage (string name) - { - Reset (); - - VBox layout_vertical = new VBox (false, 0); - - Label header = new Label ("" + - String.Format (_("Syncing folder ‘{0}’…"), name) + - "") { - UseMarkup = true, - Xalign = 0, - Wrap = true - }; - - Label information = new Label (_("This may take a while.\n") + - _("Are you sure it’s not coffee o'clock?")) { - UseMarkup = true, - Xalign = 0 - }; - - Button button = new Button () { - Sensitive = false, - Label = _("Finish") - }; - - button.Clicked += delegate { - Close (); - }; - - AddButton (button); - - layout_vertical.PackStart (header, false, false, 0); - layout_vertical.PackStart (information, false, false, 21); - - this.progress_bar_pulse_timer.Elapsed += delegate { - Application.Invoke (delegate { - progress_bar.Pulse (); - }); - }; - - if (this.progress_bar.Parent != null) - layout_vertical.Reparent(this.progress_bar); - - layout_vertical.PackStart (this.progress_bar, false, false, 54); - - Add (layout_vertical); - ShowAll (); - } - - - // The page shown when the setup has been completed - private void ShowCompletedPage () - { - Reset (); - - VBox layout_vertical = new VBox (false, 0); - - Label header = new Label ("" + - _("SparkleShare is ready to go!") + - "") { - UseMarkup = true, - Xalign = 0 - }; - - Label information = new Label (_("Now you can start accepting invitations from others. " + "\n" + - "Just click on invitations you get by email and " + - "we will take care of the rest.")) { - UseMarkup = true, - Wrap = true, - Xalign = 0 - }; - - - HBox link_wrapper = new HBox (false, 0); - LinkButton link = new LinkButton ("http://www.sparkleshare.org/", - _("Learn how to host your own SparkleServer")); - - link_wrapper.PackStart (link, false, false, 0); - - layout_vertical.PackStart (header, false, false, 0); - layout_vertical.PackStart (information, false, false, 21); - layout_vertical.PackStart (link_wrapper, false, false, 0); - - Button finish_button = new Button (_("Finish")); - - finish_button.Clicked += delegate (object o, EventArgs args) { - Close (); - }; - - AddButton (finish_button); - - Add (layout_vertical); - ShowAll (); - } - - - // Enables or disables the 'Next' button depending on the - // entries filled in by the user - private void CheckAccountForm () - { - if (NameEntry.Text.Length > 0 && - IsValidEmail (EmailEntry.Text)) { - - NextButton.Sensitive = true; - } else { - NextButton.Sensitive = false; - } - } - - - // Enables the Add button when the fields are - // filled in correctly - public void CheckServerForm (object o, EventArgs args) - { - CheckServerForm (); - } - - - // Enables the Add button when the fields are - // filled in correctly - public void CheckServerForm () - { - SyncButton.Sensitive = false; - - if (FolderEntry.ExampleTextActive || - (ServerEntry.Sensitive && ServerEntry.ExampleTextActive)) - return; - - bool IsFolder = !FolderEntry.Text.Trim ().Equals (""); - bool IsServer = !ServerEntry.Text.Trim ().Equals (""); - - if (ServerEntry.Sensitive == true) { - if (IsServer && IsFolder) - SyncButton.Sensitive = true; - } else if (IsFolder) { - SyncButton.Sensitive = true; - } - } - - - private TreeModel ServerEntryCompletion () - { - List hosts = SparkleShare.Controller.PreviousHosts; - - ListStore store = new ListStore (typeof (string)); - store.AppendValues ("user@localhost"); - store.AppendValues ("user@example.com"); - - foreach (string host in hosts) - store.AppendValues (host); - - return store; - } - - - private TreeModel FolderEntryCompletion () - { - ListStore store = new ListStore (typeof (string)); - store.AppendValues ("~/test.git"); - - foreach (string folder in SparkleShare.Controller.Folders) - store.AppendValues (folder); - - return store; - } - - - // Checks to see if an email address is valid - private bool IsValidEmail (string email) - { - Regex regex = new Regex (@"^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$", RegexOptions.IgnoreCase); - return regex.IsMatch (email); - } - } -} diff --git a/SparkleShare/SparkleInvitation.cs b/SparkleShare/SparkleInvitation.cs deleted file mode 100644 index 3f2ff2d6..00000000 --- a/SparkleShare/SparkleInvitation.cs +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/SparkleShare/SparkleSetup.cs b/SparkleShare/SparkleSetup.cs new file mode 100644 index 00000000..0e7ecb72 --- /dev/null +++ b/SparkleShare/SparkleSetup.cs @@ -0,0 +1,432 @@ +// SparkleShare, a collaboration and sharing tool. +// Copyright (C) 2010 Hylke Bons +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General private 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 private License for more details. +// +// You should have received a copy of the GNU General private License +// along with this program. If not, see . + + +using System; +using System.Diagnostics; +using System.IO; +using System.Text.RegularExpressions; +using System.Timers; +using System.Collections.Generic; + +using Gtk; +using Mono.Unix; + + +namespace SparkleShare { + + public class SparkleSetup : SparkleSetupWindow { + + public SparkleSetupController Controller = new SparkleSetupController (); + + private string SecondaryTextColor; + + private Entry NameEntry; + private Entry EmailEntry; + private SparkleEntry ServerEntry; + private SparkleEntry FolderEntry; + + private Button NextButton; + private Button SyncButton; + + private Table Table; + + private ProgressBar progress_bar = new ProgressBar () { PulseStep = 0.01 }; + private Timer progress_bar_pulse_timer = new Timer () { Interval = 25, Enabled = true }; + + + // Short alias for the translations + public static string _ (string s) + { + return Catalog.GetString (s); + } + + + public SparkleSetup () : base () + { + SecondaryTextColor = SparkleUIHelpers.GdkColorToHex (Style.Foreground (StateType.Insensitive)); + + Controller.ChangePageEvent += delegate (PageType type) { + Application.Invoke (delegate { + Reset (); + + switch (type) { + case PageType.Setup: + + Header = _("Welcome to SparkleShare!"); + Description = _("Before we can create a SparkleShare folder on this " + + "computer, we need a few bits of information from you."); + + Table = new Table (4, 2, true) { + RowSpacing = 6 + }; + + Label name_label = new Label ("" + _("Full Name:") + "") { + UseMarkup = true, + Xalign = 0 + }; + + NameEntry = new Entry (SparkleShare.Controller.UserName); + NameEntry.Changed += delegate { + CheckSetupPage (); + }; + + EmailEntry = new Entry (); + EmailEntry.Changed += delegate { + CheckSetupPage (); + }; + + Label email_label = new Label ("" + _("Email:") + "") { + UseMarkup = true, + Xalign = 0 + }; + + Table.Attach (name_label, 0, 1, 0, 1); + Table.Attach (NameEntry, 1, 2, 0, 1); + Table.Attach (email_label, 0, 1, 1, 2); + Table.Attach (EmailEntry, 1, 2, 1, 2); + + NextButton = new Button (_("Next")) { + Sensitive = false + }; + + NextButton.Clicked += delegate (object o, EventArgs args) { + string full_name = NameEntry.Text; + string email = EmailEntry.Text; + + Controller.SetupPageCompleted (full_name, email); + }; + + AddButton (NextButton); + Add (Table); + + CheckSetupPage (); + + break; + + case PageType.Add: + + Header = _("Where is your remote folder?"); + + Table = new Table (6, 2, false) { + RowSpacing = 12 + }; + + HBox layout_server = new HBox (true, 0); + + // Own server radiobutton + RadioButton radio_button = new RadioButton ("" + _("On my own server:") + ""); + (radio_button.Child as Label).UseMarkup = true; + + radio_button.Toggled += delegate { + if (radio_button.Active) { + FolderEntry.ExampleText = _("Folder"); + ServerEntry.Sensitive = true; + CheckAddPage (); + } else { + ServerEntry.Sensitive = false; + CheckAddPage (); + } + + ShowAll (); + }; + + // Own server entry + ServerEntry = new SparkleEntry () { }; + ServerEntry.Completion = new EntryCompletion(); + + ListStore server_store = new ListStore (typeof (string)); + + //TODO foreach (string host in SparkleShare.Controller.PreviousHosts) + // server_store.AppendValues (host); + + ServerEntry.Completion.Model = server_store; + ServerEntry.Completion.TextColumn = 0; + + if (!string.IsNullOrEmpty (Controller.PreviousServer)) { + ServerEntry.Text = Controller.PreviousServer; + ServerEntry.ExampleTextActive = false; + } else { + ServerEntry.ExampleText = _("address-to-server.com"); + } + + ServerEntry.Changed += delegate { + CheckAddPage (); + }; + + layout_server.Add (radio_button); + layout_server.Add (ServerEntry); + + Table.Attach (layout_server, 0, 2, 1, 2); + + // Github radiobutton + string github_text = "" + "Github" + "\n" + + "" + + _("Free hosting for Free and Open Source Software projects.") + "\n" + + _("Also has paid accounts for extra private space and bandwidth.") + + ""; + + RadioButton radio_button_github = new RadioButton (radio_button, github_text); + (radio_button_github.Child as Label).UseMarkup = true; + (radio_button_github.Child as Label).Wrap = true; + + radio_button_github.Toggled += delegate { + if (radio_button_github.Active) + FolderEntry.ExampleText = _("Username/Folder"); + }; + + + // Gitorious radiobutton + string gitorious_text = "" + _("Gitorious") + "\n" + + "" + + _("Completely Free as in Freedom infrastructure.") + "\n" + + _("Free accounts for Free and Open Source projects.") + + ""; + + RadioButton radio_button_gitorious = new RadioButton (radio_button, gitorious_text); + (radio_button_gitorious.Child as Label).UseMarkup = true; + (radio_button_gitorious.Child as Label).Wrap = true; + + radio_button_gitorious.Toggled += delegate { + if (radio_button_gitorious.Active) + FolderEntry.ExampleText = _("Project/Folder"); + }; + + + // GNOME radiobutton + string gnome_text = "" + _("The GNOME Project") + "\n"+ + "" + + _("GNOME is an easy to understand interface to your computer.") + "\n" + + _("Select this option if you’re a developer or designer working on GNOME.") + + ""; + + RadioButton radio_button_gnome = new RadioButton (radio_button, gnome_text); + (radio_button_gnome.Child as Label).UseMarkup = true; + (radio_button_gnome.Child as Label).Wrap = true; + + radio_button_gnome.Toggled += delegate { + if (radio_button_gnome.Active) + FolderEntry.ExampleText = _("Project"); + }; + + Table.Attach (radio_button_github, 0, 2, 2, 3); + Table.Attach (radio_button_gitorious, 0, 2, 3, 4); + Table.Attach (radio_button_gnome, 0, 2, 4, 5); + + // Folder label and entry + HBox layout_folder = new HBox (true, 0); + + Label folder_label = new Label (_("Folder Name:")) { + UseMarkup = true, + Xalign = 1 + }; + + FolderEntry = new SparkleEntry (); + FolderEntry.ExampleText = _("Folder"); + + FolderEntry.Changed += delegate { + CheckAddPage (); + }; + + layout_folder.PackStart (folder_label, true, true, 12); + layout_folder.PackStart (FolderEntry, true, true, 0); + + Table.Attach (layout_folder, 0, 2, 5, 6); + Add (Table); + + // Cancel button + Button cancel_button = new Button (_("Cancel")); + + cancel_button.Clicked += delegate { + Close (); + }; + + + // Sync button + SyncButton = new Button (_("Sync")); + + SyncButton.Clicked += delegate { + string server = ServerEntry.Text; + string folder_name = FolderEntry.Text; + + if (radio_button_gitorious.Active) + server = "gitorious.org"; + + if (radio_button_github.Active) + server = "github.com"; + + if (radio_button_gnome.Active) + server = "gnome.org"; + + Controller.AddPageCompleted (server, folder_name); + }; + + AddButton (cancel_button); + AddButton (SyncButton); + + CheckAddPage (); + + break; + + case PageType.Syncing: + + Header = String.Format (_("Syncing folder ‘{0}’…"), Controller.SyncingFolder); + Description = _("This may take a while." + Environment.NewLine) + + _("Are you sure it’s not coffee o'clock?"); + + Button button = new Button () { + Sensitive = false, + Label = _("Finish") + }; + + button.Clicked += delegate { + Close (); + }; + + AddButton (button); + + this.progress_bar_pulse_timer.Elapsed += delegate { + Application.Invoke (delegate { + progress_bar.Pulse (); + }); + }; + + if (this.progress_bar.Parent != null) + (this.progress_bar.Parent as Container).Remove (this.progress_bar); + + VBox bar_wrapper = new VBox (false , 0); + bar_wrapper.PackStart (this.progress_bar, false, false, 0); + + Add (bar_wrapper); + + break; + + case PageType.Error: + + string n = Environment.NewLine; + + Header = _("Something went wrong") + "…"; + Description = "We don't know exactly what the problem is, " + + "but we can try to help you pinpoint it."; + + + Label l = new Label ( + "First, have you tried turning it off and on again?" + n + + n + + Controller.SyncingFolder +" is the address we've compiled from the information " + + "you entered. Does this look correct?" + n + + n + + "The host needs to know who you are. Have you uploaded the key that sits in your SparkleShare folder?"); + + + + l.Xpad = 12; + l.Wrap = true; + + + + Button try_again_button = new Button (_("Try Again")) { + Sensitive = true + }; + + try_again_button.Clicked += delegate { + Controller.ErrorPageCompleted (); + }; + + AddButton (try_again_button); + Add (l); + + break; + + case PageType.Finished: + + UrgencyHint = true; + + if (!HasToplevelFocus) { + string title = String.Format (_("‘{0}’ has been successfully added"), Controller.SyncingFolder); + string subtext = _(""); + + //TODO new SparkleBubble (title, subtext).Show (); + } + + Header = _("Folder synced successfully!"); + Description = _("Access the synced files from your SparkleShare folder."); + + // A button that opens the synced folder + Button open_folder_button = new Button (_("Open Folder")); + + open_folder_button.Clicked += delegate { + SparkleShare.Controller.OpenSparkleShareFolder (Controller.SyncingFolder); + }; + + Button finish_button = new Button (_("Finish")); + + finish_button.Clicked += delegate { + Close (); + }; + + Add (null); + + AddButton (open_folder_button); + AddButton (finish_button); + + break; + } + + ShowAll (); + }); + }; + + } + + + // Enables or disables the 'Next' button depending on the + // entries filled in by the user + private void CheckSetupPage () + { + if (NameEntry.Text.Length > 0 && + SparkleShare.Controller.IsValidEmail (EmailEntry.Text)) { + + NextButton.Sensitive = true; + } else { + NextButton.Sensitive = false; + } + } + + + // Enables or disables the 'Next' button depending on the + // entries filled in by the user + public void CheckAddPage () + { + SyncButton.Sensitive = false; + + if (FolderEntry.ExampleTextActive || + (ServerEntry.Sensitive && ServerEntry.ExampleTextActive)) + return; + + bool IsFolder = !FolderEntry.Text.Trim ().Equals (""); + bool IsServer = !ServerEntry.Text.Trim ().Equals (""); + + if (ServerEntry.Sensitive == true) { + if (IsServer && IsFolder) + SyncButton.Sensitive = true; + } else if (IsFolder) { + SyncButton.Sensitive = true; + } + } + + } +} diff --git a/SparkleShare/SparkleSetupController.cs b/SparkleShare/SparkleSetupController.cs new file mode 100644 index 00000000..02cd880e --- /dev/null +++ b/SparkleShare/SparkleSetupController.cs @@ -0,0 +1,142 @@ +// SparkleShare, a collaboration and sharing tool. +// Copyright (C) 2010 Hylke Bons +// +// 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 . + + +using System; +using System.IO; + +namespace SparkleShare { + + public enum PageType { + Setup, + Add, + Syncing, + Error, + Finished + } + + + public class SparkleSetupController { + + public event ChangePageEventHandler ChangePageEvent; + public delegate void ChangePageEventHandler (PageType page); + + public string PreviousServer { + get { + return this.previous_server; + } + } + + public string PreviousFolder { + get { + return this.previous_folder; + } + } + + public string SyncingFolder { + get { + return this.syncing_folder; + } + } + + public PageType PreviousPage { + get { + return this.previous_page; + } + } + + private string previous_server = ""; + private string previous_folder = ""; + private string syncing_folder = ""; + private PageType previous_page; + + public SparkleSetupController () + { + ChangePageEvent += delegate (PageType page) { + this.previous_page = page; + }; + } + + + public void ShowAddPage () + { + if (ChangePageEvent != null) + ChangePageEvent (PageType.Add); + } + + + public void ShowSetupPage () + { + if (ChangePageEvent != null) + ChangePageEvent (PageType.Setup); + } + + + public void SetupPageCompleted (string full_name, string email) + { + SparkleShare.Controller.UserName = full_name; + SparkleShare.Controller.UserEmail = email; + + SparkleShare.Controller.GenerateKeyPair (); + SparkleShare.Controller.UpdateState (); + + if (ChangePageEvent != null) + ChangePageEvent (PageType.Add); + } + + + public void AddPageCompleted (string server, string folder_name) + { + this.syncing_folder = Path.GetFileNameWithoutExtension (folder_name); + this.previous_server = server; + this.previous_folder = folder_name; + + if (ChangePageEvent != null) + ChangePageEvent (PageType.Syncing); + + SparkleShare.Controller.FolderFetched += delegate { + if (ChangePageEvent != null) + ChangePageEvent (PageType.Finished); + + this.syncing_folder = ""; + }; + + SparkleShare.Controller.FolderFetchError += delegate { + if (ChangePageEvent != null) + ChangePageEvent (PageType.Error); + + this.syncing_folder = ""; + }; + + SparkleShare.Controller.FetchFolder (server, this.syncing_folder); + } + + + public void ErrorPageCompleted () + { + if (ChangePageEvent != null) + ChangePageEvent (PageType.Add); + } + + + public void FinishedPageCompleted () + { + this.previous_server = ""; + this.previous_folder = ""; + SparkleShare.Controller.UpdateState (); + } + } +} diff --git a/SparkleShare/SparkleWindow.cs b/SparkleShare/SparkleSetupWindow.cs similarity index 77% rename from SparkleShare/SparkleWindow.cs rename to SparkleShare/SparkleSetupWindow.cs index 9f510a20..8ccac09b 100644 --- a/SparkleShare/SparkleWindow.cs +++ b/SparkleShare/SparkleSetupWindow.cs @@ -28,21 +28,26 @@ using SparkleLib; namespace SparkleShare { - public class SparkleWindow : Window { + public class SparkleSetupWindow : Window { private HBox HBox; private VBox VBox; private VBox Wrapper; private HButtonBox Buttons; + public string Header; + public string Description; - public SparkleWindow () : base ("") + public Container Content; + + public SparkleSetupWindow () : base ("") { Title = Catalog.GetString ("SparkleShare Setup"); BorderWidth = 0; IconName = "folder-sparkleshare"; Resizable = false; WindowPosition = WindowPosition.Center; + Deletable = false; SetSizeRequest (680, 440); @@ -104,13 +109,35 @@ namespace SparkleShare { new public void Add (Widget widget) { - Wrapper.PackStart (widget, true, true, 0); + Label header = new Label ("" + Header + "") { + UseMarkup = true, + Xalign = 0 + }; + + Label description = new Label (Description) { + Xalign = 0, + Wrap = true + }; + + VBox layout_vertical = new VBox (false, 0); + layout_vertical.PackStart (header, false, false, 0); + + if (!string.IsNullOrEmpty (Description)) + layout_vertical.PackStart (description, false, false, 21); + + if (widget != null) + layout_vertical.PackStart (widget, true, true, 21); + + Wrapper.PackStart (layout_vertical, true, true, 0); ShowAll (); } public void Reset () { + Header = ""; + Description = ""; + if (Wrapper.Children.Length > 0) Wrapper.Remove (Wrapper.Children [0]); @@ -122,7 +149,9 @@ namespace SparkleShare { new public void ShowAll () { - Present (); + + Present (); + base.ShowAll (); } diff --git a/SparkleShare/SparkleShare.csproj b/SparkleShare/SparkleShare.csproj index 839d9223..079ec8de 100644 --- a/SparkleShare/SparkleShare.csproj +++ b/SparkleShare/SparkleShare.csproj @@ -37,22 +37,6 @@ - - - - - - - - - - - - - - - - {2C914413-B31C-4362-93C7-1AE34F09112A} @@ -74,4 +58,24 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/SparkleShare/SparkleStatusIcon.cs b/SparkleShare/SparkleStatusIcon.cs index 3c29c866..8090febf 100644 --- a/SparkleShare/SparkleStatusIcon.cs +++ b/SparkleShare/SparkleStatusIcon.cs @@ -223,16 +223,16 @@ namespace SparkleShare { sync_item.Activated += delegate { Application.Invoke (delegate { - if (SparkleUI.Intro == null) { - SparkleUI.Intro = new SparkleIntro (); - SparkleUI.Intro.ShowServerForm (true); + if (SparkleUI.Setup == null) { + SparkleUI.Setup = new SparkleSetup (); + SparkleUI.Setup.Controller.ShowAddPage (); } - if (!SparkleUI.Intro.Visible) - SparkleUI.Intro.ShowServerForm (true); + if (!SparkleUI.Setup.Visible) + SparkleUI.Setup.Controller.ShowAddPage (); - SparkleUI.Intro.ShowAll (); - SparkleUI.Intro.Present (); + //SparkleUI.Intro.ShowAll (); + //SparkleUI.Intro.Present (); }); }; @@ -275,8 +275,13 @@ namespace SparkleShare { MenuItem about_item = new MenuItem (_("About SparkleShare")); about_item.Activated += delegate { - SparkleAbout about = new SparkleAbout (); - about.ShowAll (); + Application.Invoke (delegate { + if (SparkleUI.About == null) + SparkleUI.About = new SparkleAbout (); + + SparkleUI.About.ShowAll (); + SparkleUI.About.Present (); + }); }; Menu.Add (about_item); diff --git a/SparkleShare/SparkleStatusIconController.cs b/SparkleShare/SparkleStatusIconController.cs new file mode 100644 index 00000000..0353c214 --- /dev/null +++ b/SparkleShare/SparkleStatusIconController.cs @@ -0,0 +1,86 @@ +// SparkleShare, a collaboration and sharing tool. +// Copyright (C) 2010 Hylke Bons +// +// 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 . + + +using System; +using System.IO; + +namespace SparkleShare { + + public enum IconState { + Idle, + Syncing, + Error + } + + + public class SparkleStatusIconController { + + public delegate void UpdateStatusLineEventHandler (); + + public event UpdateMenuEventHandler UpdateMenuEvent; + public delegate void UpdateMenuEventHandler (IconState state); + + public IconState CurrentState = IconState.Idle; + + public string [] Folders { + get { + return SparkleShare.Controller.Folders.ToArray (); + } + } + + public string FolderSize { + get { + return SparkleShare.Controller.FolderSize; + } + } + + public SparkleStatusIconController () + { + SparkleShare.Controller.FolderSizeChanged += delegate { + if (UpdateMenuEvent != null) + UpdateMenuEvent (CurrentState); + }; + + SparkleShare.Controller.FolderListChanged += delegate { + if (UpdateMenuEvent != null) + UpdateMenuEvent (CurrentState); + }; + + SparkleShare.Controller.OnIdle += delegate { + if (CurrentState != IconState.Error) + CurrentState = IconState.Idle; + + if (UpdateMenuEvent != null) + UpdateMenuEvent (CurrentState); + }; + + SparkleShare.Controller.OnSyncing += delegate { + CurrentState = IconState.Syncing; + + if (UpdateMenuEvent != null) + UpdateMenuEvent (IconState.Syncing); + }; + + SparkleShare.Controller.OnError += delegate { + CurrentState = IconState.Error; + + if (UpdateMenuEvent != null) + UpdateMenuEvent (IconState.Error); + }; + } + } +} diff --git a/SparkleShare/SparkleUI.cs b/SparkleShare/SparkleUI.cs index 60494f7b..5c7dad0a 100644 --- a/SparkleShare/SparkleUI.cs +++ b/SparkleShare/SparkleUI.cs @@ -34,7 +34,8 @@ namespace SparkleShare { public static SparkleStatusIcon StatusIcon; public static SparkleEventLog EventLog; - public static SparkleIntro Intro; + public static SparkleSetup Setup; + public static SparkleAbout About; // Short alias for the translations @@ -56,76 +57,14 @@ namespace SparkleShare { StatusIcon = new SparkleStatusIcon (); if (SparkleShare.Controller.FirstRun) { - Intro = new SparkleIntro (); - Intro.ShowAccountForm (); + Setup = new SparkleSetup (); + Setup.Controller.ShowSetupPage (); } SparkleShare.Controller.OnQuitWhileSyncing += delegate { // TODO: Pop up a warning when quitting whilst syncing }; - - SparkleShare.Controller.OnInvitation += delegate (string server, string folder, string token) { - Application.Invoke (delegate { - SparkleIntro intro = new SparkleIntro (); - intro.ShowInvitationPage (server, folder, token); - }); - }; - - // Show a bubble when there are new changes - SparkleShare.Controller.NotificationRaised += delegate (string user_name, string user_email, - string message, string repository_path) { - Application.Invoke (delegate { - if (EventLog != null) - EventLog.UpdateEvents (); - - if (!SparkleShare.Controller.NotificationsEnabled) - return; - - SparkleBubble bubble = new SparkleBubble (user_name, message); - string avatar_file_path = SparkleShare.Controller.GetAvatar (user_email, 36); - - if (avatar_file_path != null) - bubble.Icon = new Gdk.Pixbuf (avatar_file_path); - else - bubble.Icon = SparkleUIHelpers.GetIcon ("avatar-default", 36); - - bubble.Show (); - }); - }; - - // Show a bubble when there was a conflict - SparkleShare.Controller.ConflictNotificationRaised += delegate { - Application.Invoke (delegate { - string title = _("Ouch! Mid-air collision!"); - string subtext = _("Don't worry, SparkleShare made a copy of each conflicting file."); - - new SparkleBubble (title, subtext).Show (); - }); - }; - - SparkleShare.Controller.AvatarFetched += delegate { - Application.Invoke (delegate { - if (EventLog != null) - EventLog.UpdateEvents (); - }); - }; - - SparkleShare.Controller.OnIdle += delegate { - Application.Invoke (delegate { - if (EventLog != null) - EventLog.UpdateEvents (); - }); - }; - - SparkleShare.Controller.FolderListChanged += delegate { - Application.Invoke (delegate { - if (EventLog != null) { - EventLog.UpdateChooser (); - EventLog.UpdateEvents (); - } - }); - }; - } + } // Runs the application public void Run () diff --git a/data/Makefile.am b/data/Makefile.am index 24edd829..69b419e6 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -5,7 +5,8 @@ SUBDIRS = \ dist_pixmaps_DATA = \ sparkleshare-gnome.svg \ sparkleshare-mist.svg \ - side-splash.png + side-splash.png \ + about.png pixmapsdir = $(pkgdatadir)/pixmaps/ diff --git a/data/about.png b/data/about.png new file mode 100644 index 00000000..89f7d71f Binary files /dev/null and b/data/about.png differ