Merge branch 'uicontrollers'

This commit is contained in:
Hylke Bons 2011-07-15 18:03:41 +01:00
commit 43a90151d0
33 changed files with 1967 additions and 2073 deletions

View file

@ -24,6 +24,7 @@ Contributors:
Jakub Steiner <jimmac@redhat.com>
Kristi Tsukida <kristi.tsukida@gmail.com>
Lapo Calamandrei <calamandrei@gmail.com>
Lars Falk-Petersen <dev@falk-petersen.no>
Luis Cordova <cordoval@gmail.com>
Łukasz Jernaś <deejay1@srem.org>
Michael Monreal <michael.monreal@gmail.com>

View file

@ -22,7 +22,7 @@ SOURCES = \
SparkleHelpers.cs \
SparkleListenerBase.cs \
SparkleListenerIrc.cs \
SparkleListenerTcp.cs \
SparkleListenerTcp.cs \
SparkleOptions.cs \
SparklePaths.cs \
SparkleRepoBase.cs \

View file

@ -2,19 +2,15 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>TicketVersion</key>
<integer>1</integer>
<key>AllNotifications</key>
<array>
<string>Start</string>
<string>Stop</string>
<string>Info</string>
</array>
<key>DefaultNotifications</key>
<array>
<string>Start</string>
<string>Stop</string>
<string>Info</string>
</array>
<key>TicketVersion</key>
<integer>1</integer>
<key>AllNotifications</key>
<array>
<string>Event</string>
</array>
<key>DefaultNotifications</key>
<array>
<string>Event</string>
</array>
</dict>
</plist>

View file

@ -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);
}
}

View file

@ -1,58 +0,0 @@
// SparkleShare, a collaboration and sharing tool.
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using 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);
}
});
}
}
}

View file

@ -0,0 +1,64 @@
// SparkleShare, a collaboration and sharing tool.
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using 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);
}
});
};
}
}
}

View file

@ -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<SparkleChangeSet> 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 ("<!-- $body-font-family -->", "Lucida Grande");
html = html.Replace ("<!-- $day-entry-header-font-size -->", "13.6px");
html = html.Replace ("<!-- $body-font-size -->", "13.4px");
html = html.Replace ("<!-- $secondary-font-color -->", "#bbb");
html = html.Replace ("<!-- $small-color -->", "#ddd");
html = html.Replace ("<!-- $day-entry-header-background-color -->", "#f5f5f5");
html = html.Replace ("<!-- $a-color -->", "#0085cf");
html = html.Replace ("<!-- $a-hover-color -->", "#009ff8");
html = html.Replace ("<!-- $no-buddy-icon-background-image -->",
"file://" + Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "avatar-default.png"));
html = html.Replace ("<!-- $document-added-background-image -->",
"file://" + Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "document-added-12.png"));
html = html.Replace ("<!-- $document-deleted-background-image -->",
"file://" + Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "document-deleted-12.png"));
html = html.Replace ("<!-- $document-edited-background-image -->",
"file://" + Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "document-edited-12.png"));
html = html.Replace ("<!-- $document-moved-background-image -->",
"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 ("<!-- $body-font-family -->", "Lucida Grande");
HTML = HTML.Replace ("<!-- $day-entry-header-font-size -->", "13.6px");
HTML = HTML.Replace ("<!-- $body-font-size -->", "13.4px");
HTML = HTML.Replace ("<!-- $secondary-font-color -->", "#bbb");
HTML = HTML.Replace ("<!-- $small-color -->", "#ddd");
HTML = HTML.Replace ("<!-- $day-entry-header-background-color -->", "#f5f5f5");
HTML = HTML.Replace ("<!-- $a-color -->", "#0085cf");
HTML = HTML.Replace ("<!-- $a-hover-color -->", "#009ff8");
HTML = HTML.Replace ("<!-- $no-buddy-icon-background-image -->",
"file://" + Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "avatar-default.png"));
HTML = HTML.Replace ("<!-- $document-added-background-image -->",
"file://" + Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "document-added-12.png"));
HTML = HTML.Replace ("<!-- $document-deleted-background-image -->",
"file://" + Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "document-deleted-12.png"));
HTML = HTML.Replace ("<!-- $document-edited-background-image -->",
"file://" + Path.Combine (NSBundle.MainBundle.ResourcePath, "Pixmaps", "document-edited-12.png"));
HTML = HTML.Replace ("<!-- $document-moved-background-image -->",
"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 ();
});
}
}

View file

@ -1,445 +0,0 @@
// SparkleShare, a collaboration and sharing tool.
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using 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 its 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 ();
}
}
}

View file

@ -0,0 +1,368 @@
// SparkleShare, a collaboration and sharing tool.
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using 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 its 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 ();
});
};
}
}
}

View file

@ -28,7 +28,7 @@ using Mono.Unix;
namespace SparkleShare {
public class SparkleWindow : NSWindow {
public class SparkleSetupWindow : NSWindow {
public List <NSButton> 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);

View file

@ -62,7 +62,7 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\bin\Meebey.SmartIrc4net.dll</HintPath>
</Reference>
<Reference Include="SparkleLib, Version=0.2.3.0, Culture=neutral, PublicKeyToken=null">
<Reference Include="SparkleLib, Version=0.2.4.0, Culture=neutral, PublicKeyToken=null">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\bin\SparkleLib.dll</HintPath>
</Reference>
@ -77,8 +77,6 @@
<Compile Include="..\SparkleController.cs">
<Link>SparkleController.cs</Link>
</Compile>
<Compile Include="SparkleWindow.cs" />
<Compile Include="SparkleIntro.cs" />
<Compile Include="SparkleMacController.cs" />
<Compile Include="SparkleStatusIcon.cs" />
<Compile Include="SparkleUI.cs" />
@ -87,10 +85,25 @@
</Compile>
<Compile Include="SparkleAbout.cs" />
<Compile Include="SparkleAlert.cs" />
<Compile Include="SparkleBubble.cs" />
<Compile Include="SparkleMacWatcher.cs" />
<Compile Include="SparkleEventLog.cs" />
<Compile Include="SparkleBadger.cs" />
<Compile Include="SparkleBubbles.cs" />
<Compile Include="SparkleSetup.cs" />
<Compile Include="SparkleSetupWindow.cs" />
<Compile Include="..\SparkleBubblesController.cs">
<Link>SparkleBubblesController.cs</Link>
</Compile>
<Compile Include="..\SparkleEventLogController.cs">
<Link>SparkleEventLogController.cs</Link>
</Compile>
<Compile Include="..\SparkleSetupController.cs">
<Link>SparkleSetupController.cs</Link>
</Compile>
<Compile Include="..\SparkleStatusIconController.cs">
<Link>SparkleStatusIconController.cs</Link>
</Compile>
<Compile Include="SparkleAboutController.cs" />
</ItemGroup>
<ItemGroup>
<Page Include="MainMenu.xib" />
@ -246,6 +259,9 @@
<Content Include="..\..\po\zh_TW.po">
<Link>Translations\zh_TW.po</Link>
</Content>
<Content Include="..\..\data\about.png">
<Link>Pixmaps\about.png</Link>
</Content>
</ItemGroup>
<ItemGroup>
<Folder Include="Pixmaps\" />

View file

@ -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 ();
}
}

View file

@ -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 ();
}
}
}

View file

@ -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

View file

@ -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 ("<small><span fgcolor='#f57900'>{0}: {1}</span></small>", _("A newer version is available"), new_version);
this.version.ShowAll ();
this.updates.Markup = String.Format ("<span font_size='small' fgcolor='#f57900'>{0}</span>",
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 ("<small><span fgcolor='#4e9a06'>{0}</span></small>", _("You are running the latest version."));
this.version.ShowAll ();
this.updates.Markup = String.Format ("<span font_size='small' fgcolor='#4e9a06'>{0}</span>",
_("You are running the latest version."));
this.updates.ShowAll ();
});
};
SparkleShare.Controller.CheckForNewVersion ();
Controller.CheckingForNewVersionEvent += delegate {
Application.Invoke (delegate {
this.updates.Markup = String.Format ("<span font_size='small' fgcolor='#4e9a06'>{0}</span>",
_("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 = "<span font_size='xx-large'>SparkleShare</span>\n<span fgcolor='" + secondary_text_color + "'><small>" + SparkleShare.Controller.Version + "</small></span>",
Xalign = 0,
Xpad = 18,
Ypad = 18
};
box.Add (header);
this.version = new Label () {
Markup = String.Format ("<small>{0}</small>", _("Checking for updates...")),
Label version = new Label () {
Markup = "<span font_size='small' fgcolor='white'>" +
"version " + Controller.RunningVersion +
"</span>",
Xalign = 0,
Xpad = 18,
Ypad = 22,
Xpad = 300
};
this.updates = new Label () {
Markup = "<span font_size='small' fgcolor='" + secondary_text_color + "'>" +
_("Checking for updates...") +
"</span>",
Xalign = 0,
Xpad = 300
};
Label copyright = new Label () {
Markup = "<span font_size='small' fgcolor='white'>" +
"Copyright © 2010" + DateTime.Now.Year + " " +
"Hylke Bons and others." +
"</span>",
Xalign = 0,
Xpad = 300
};
Label license = new Label () {
Xalign = 0,
Xpad = 18,
Ypad = 0,
LineWrap = true,
Wrap = true,
LineWrapMode = Pango.WrapMode.Word,
Markup = "<small>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.</small>"
Markup = "<span font_size='small' fgcolor='white'>" +
"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." +
"</span>",
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);
}
}
}

View file

@ -0,0 +1,95 @@
// SparkleShare, a collaboration and sharing tool.
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using 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);
}
}
}

View file

@ -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);
// }
}
}

View file

@ -0,0 +1,45 @@
// SparkleShare, a collaboration and sharing tool.
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using 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));
};
}
}
}

View file

@ -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<string> PreviousHosts {
get {
List<string> hosts = SparkleConfig.DefaultConfig.Hosts;
hosts.Sort ();
return hosts;
}
}
public List<string> UnsyncedFolders {
get {
List<string> unsynced_folders = new List<string> ();
@ -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",

View file

@ -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;

View file

@ -0,0 +1,119 @@
// SparkleShare, a collaboration and sharing tool.
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using 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<SparkleChangeSet> 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);
};
}
}
}

View file

@ -1,50 +0,0 @@
// SparkleShare, a collaboration and sharing tool.
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using Gtk;
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 = "<b>" + title + "</b>\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);
}
}
}

View file

@ -1,721 +0,0 @@
// SparkleShare, a collaboration and sharing tool.
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General 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 <http://www.gnu.org/licenses/>.
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 ("<span size='large'><b>" +
_("Welcome to SparkleShare!") +
"</b></span>") {
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 ("<b>" + _("Full Name:") + "</b>") {
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 ("<b>" + _("Email:") + "</b>") {
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 ("<span size='large'><b>" +
_("Where is your remote folder?") +
"</b></span>") {
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 ("<b>" + _("On my own server:") + "</b>");
layout_server.Add (radio_button);
layout_server.Add (ServerEntry);
string github_text = "<b>" + "Github" + "</b>\n" +
"<span fgcolor='" + SecondaryTextColor + "' size='small'>" +
_("Free hosting for Free and Open Source Software projects.") + "\n" +
_("Also has paid accounts for extra private space and bandwidth.") +
"</span>";
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 = "<b>" + _("The GNOME Project") + "</b>\n" +
"<span fgcolor='" + SecondaryTextColor + "' size='small'>" +
_("GNOME is an easy to understand interface to your computer.") + "\n" +
_("Select this option if youre a developer or designer working on GNOME.") +
"</span>";
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 = "<b>" + _("Gitorious") + "</b>\n" +
"<span fgcolor='" + SecondaryTextColor + "' size='small'>" +
_("Completely Free as in Freedom infrastructure.") + "\n" +
_("Free accounts for Free and Open Source projects.") +
"</span>";
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 ("<span size='large'><b>" +
_("Invitation received!") +
"</b></span>") {
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 ("<b>" + server + "</b>") {
UseMarkup = true,
Xalign = 0
};
Label folder_label = new Label (_("Folder Name:")) {
Xalign = 0
};
Label folder_text = new Label ("<b>" + folder + "</b>") {
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 ("<span size='large'><b>" +
_("Something went wrong…") +
"</b></span>\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 ("<span size='large'><b>" +
_("Folder synced successfully!") +
"</b></span>") {
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 ("<span size='large'><b>" +
String.Format (_("Syncing folder {0}’…"), name) +
"</b></span>") {
UseMarkup = true,
Xalign = 0,
Wrap = true
};
Label information = new Label (_("This may take a while.\n") +
_("Are you sure its 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 ("<span size='large'><b>" +
_("SparkleShare is ready to go!") +
"</b></span>") {
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<string> 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);
}
}
}

View file

@ -1,5 +0,0 @@

View file

@ -0,0 +1,432 @@
// SparkleShare, a collaboration and sharing tool.
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General 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 <http://www.gnu.org/licenses/>.
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 ("<b>" + _("Full Name:") + "</b>") {
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 ("<b>" + _("Email:") + "</b>") {
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 ("<b>" + _("On my own server:") + "</b>");
(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 = "<b>" + "Github" + "</b>\n" +
"<span fgcolor='" + SecondaryTextColor + "' size='small'>" +
_("Free hosting for Free and Open Source Software projects.") + "\n" +
_("Also has paid accounts for extra private space and bandwidth.") +
"</span>";
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 = "<b>" + _("Gitorious") + "</b>\n" +
"<span fgcolor='" + SecondaryTextColor + "' size='small'>" +
_("Completely Free as in Freedom infrastructure.") + "\n" +
_("Free accounts for Free and Open Source projects.") +
"</span>";
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 = "<b>" + _("The GNOME Project") + "</b>\n"+
"<span fgcolor='" + SecondaryTextColor + "' size='small'>" +
_("GNOME is an easy to understand interface to your computer.") + "\n" +
_("Select this option if youre a developer or designer working on GNOME.") +
"</span>";
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 its 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;
}
}
}
}

View file

@ -0,0 +1,142 @@
// SparkleShare, a collaboration and sharing tool.
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using 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 ();
}
}
}

View file

@ -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 ("<span size='large'><b>" + Header + "</b></span>") {
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 ();
}

View file

@ -37,22 +37,6 @@
<Reference Include="System" />
<Reference Include="Mono.Posix" />
</ItemGroup>
<ItemGroup>
<Compile Include="SparkleBubble.cs" />
<Compile Include="SparkleIntro.cs" />
<Compile Include="SparkleShare.cs" />
<Compile Include="SparkleSpinner.cs" />
<Compile Include="SparkleStatusIcon.cs" />
<Compile Include="SparkleUI.cs" />
<Compile Include="SparkleWindow.cs" />
<Compile Include="SparkleEntry.cs" />
<Compile Include="SparkleEventLog.cs" />
<Compile Include="SparkleUIHelpers.cs" />
<Compile Include="SparkleInfobar.cs" />
<Compile Include="SparkleController.cs" />
<Compile Include="SparkleAbout.cs" />
<Compile Include="SparkleLinController.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SparkleLib\SparkleLib.csproj">
<Project>{2C914413-B31C-4362-93C7-1AE34F09112A}</Project>
@ -74,4 +58,24 @@
</Properties>
</MonoDevelop>
</ProjectExtensions>
<ItemGroup>
<Compile Include="SparkleBubbles.cs" />
<Compile Include="SparkleBubblesController.cs" />
<Compile Include="SparkleController.cs" />
<Compile Include="SparkleEntry.cs" />
<Compile Include="SparkleLinController.cs" />
<Compile Include="SparkleSetup.cs" />
<Compile Include="SparkleSetupController.cs" />
<Compile Include="SparkleSetupWindow.cs" />
<Compile Include="SparkleShare.cs" />
<Compile Include="SparkleSpinner.cs" />
<Compile Include="SparkleStatusIcon.cs" />
<Compile Include="SparkleStatusIconController.cs" />
<Compile Include="SparkleUI.cs" />
<Compile Include="SparkleUIHelpers.cs" />
<Compile Include="SparkleEventLogController.cs" />
<Compile Include="SparkleEventLog.cs" />
<Compile Include="SparkleAboutController.cs" />
<Compile Include="SparkleAbout.cs" />
</ItemGroup>
</Project>

View file

@ -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);

View file

@ -0,0 +1,86 @@
// SparkleShare, a collaboration and sharing tool.
// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using 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);
};
}
}
}

View file

@ -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 ()

View file

@ -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/

BIN
data/about.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB