From b6b481d7380d7dab6708fff6784d33f66349c7c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Jerna=C5=9B?= Date: Thu, 2 Dec 2010 22:31:35 +0100 Subject: [PATCH 01/19] Get data root dif info from configure Also fixes the path to the about dialog pixmap. --- SparkleLib/Defines.cs.in | 1 + SparkleLib/SparklePaths.cs | 2 +- SparkleShare/SparkleDialog.cs | 6 +++--- SparkleShare/SparkleLinController.cs | 4 ++-- SparkleShare/SparkleWindow.cs | 2 +- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/SparkleLib/Defines.cs.in b/SparkleLib/Defines.cs.in index f5beeba7..7ef0803c 100644 --- a/SparkleLib/Defines.cs.in +++ b/SparkleLib/Defines.cs.in @@ -22,6 +22,7 @@ namespace SparkleLib { public const string VERSION = "@VERSION@"; public const string LOCALE_DIR = "@prefix@/share/locale"; + public const string DATAROOTDIR = "@expanded_datadir@"; public const string GETTEXT_PACKAGE = "@GETTEXT_PACKAGE@"; public const string PREFIX = "@prefix@"; public const string OPEN_COMMAND = "xdg-open"; diff --git a/SparkleLib/SparklePaths.cs b/SparkleLib/SparklePaths.cs index c45adc01..45ed4ff0 100644 --- a/SparkleLib/SparklePaths.cs +++ b/SparkleLib/SparklePaths.cs @@ -40,7 +40,7 @@ namespace SparkleLib { public static string SparkleLocalIconPath = SparkleHelpers.CombineMore (SparkleConfigPath, "icons", "hicolor"); - public static string SparkleIconPath = SparkleHelpers.CombineMore (Defines.PREFIX, "share", "sparkleshare", + public static string SparkleIconPath = SparkleHelpers.CombineMore (Defines.DATAROOTDIR, "sparkleshare", "icons"); diff --git a/SparkleShare/SparkleDialog.cs b/SparkleShare/SparkleDialog.cs index 6189788e..ba2eb681 100644 --- a/SparkleShare/SparkleDialog.cs +++ b/SparkleShare/SparkleDialog.cs @@ -194,9 +194,9 @@ GNU Lesser General Public License for more details."; */ vbox.PackStart (new HSeparator (), false, false, 0); vbox.PackStart (button_bar, false, false, 0); - string image_path = SparkleHelpers.CombineMore (Defines.PREFIX, "share", "pixmaps", - "sparkleshare-about.png"); - + string image_path = SparkleHelpers.CombineMore (Defines.DATAROOTDIR, "sparkleshare", + "pixmaps", "sparkleshare-about.png"); + System.Console.WriteLine(image_path); wrapper.PackStart (new Image (image_path), false, false, 0); wrapper.PackStart (vbox, true, true, 0); diff --git a/SparkleShare/SparkleLinController.cs b/SparkleShare/SparkleLinController.cs index ba26ecae..228278a4 100644 --- a/SparkleShare/SparkleLinController.cs +++ b/SparkleShare/SparkleLinController.cs @@ -146,7 +146,7 @@ namespace SparkleShare { Directory.CreateDirectory (SparklePaths.SparklePath); SparkleHelpers.DebugInfo ("Controller", "Created '" + SparklePaths.SparklePath + "'"); - string icon_file_path = SparkleHelpers.CombineMore (Defines.PREFIX, "share", "icons", "hicolor", + string icon_file_path = SparkleHelpers.CombineMore (Defines.DATAROOTDIR, "icons", "hicolor", "48x48", "apps", "folder-sparkleshare.png"); string gvfs_command_path = SparkleHelpers.CombineMore (Path.VolumeSeparatorChar.ToString (), @@ -196,4 +196,4 @@ namespace SparkleShare { } -} \ No newline at end of file +} diff --git a/SparkleShare/SparkleWindow.cs b/SparkleShare/SparkleWindow.cs index 4860f88a..5183f480 100644 --- a/SparkleShare/SparkleWindow.cs +++ b/SparkleShare/SparkleWindow.cs @@ -48,7 +48,7 @@ namespace SparkleShare { HBox = new HBox (false, 6); - string image_path = SparkleHelpers.CombineMore (Defines.PREFIX, "share", "sparkleshare", + string image_path = SparkleHelpers.CombineMore (Defines.DATAROOTDIR, "sparkleshare", "pixmaps", "side-splash.png"); Image side_splash = new Image (image_path); From 00fe9600d4e6bea6fa47ea71b1c32bddd6af6bff Mon Sep 17 00:00:00 2001 From: Hylke Bons Date: Sat, 11 Dec 2010 18:43:47 +0100 Subject: [PATCH 02/19] Clean up MacOS project file --- SparkleShare/Mac/SparkleShare/AppDelegate.cs | 155 ------------------ SparkleShare/Mac/SparkleShare/Info.plist | 4 +- SparkleShare/Mac/SparkleShare/Main.cs | 148 +++++++++++++++++ .../Mac/SparkleShare/MainMenu.xib.designer.cs | 5 - .../Mac/SparkleShare/SparkleShare.csproj | 13 -- 5 files changed, 151 insertions(+), 174 deletions(-) diff --git a/SparkleShare/Mac/SparkleShare/AppDelegate.cs b/SparkleShare/Mac/SparkleShare/AppDelegate.cs index 77d455bd..e69de29b 100644 --- a/SparkleShare/Mac/SparkleShare/AppDelegate.cs +++ b/SparkleShare/Mac/SparkleShare/AppDelegate.cs @@ -1,155 +0,0 @@ -using System; -using System.Drawing; -using MonoMac.Foundation; -using MonoMac.AppKit; -using MonoMac.ObjCRuntime; -using SparkleLib; - -namespace SparkleShare -{ - public partial class AppDelegate : NSApplicationDelegate - { - - MainWindowController mainWindowController; - NSStatusItem StatusItem; - - NSMenu Menu; - NSMenuItem FolderMenuItem; - NSMenuItem [] FolderMenuItems; - NSMenuItem SyncMenuItem; - NSMenuItem NotificationsMenuItem; - NSMenuItem AboutMenuItem; - NSMenuItem QuitMenuItem; - - - public AppDelegate () - { - } - - public override void FinishedLaunching (NSObject notification) - { - - // mainWindowController = new MainWindowController (); - // mainWindowController.Window.MakeKeyAndOrderFront (this); - - // SparkleStatusIcon = new SparkleStatusIcon (); - - // SparkleRepo repo = new SparkleRepo ("/Users/hbons/SparkleShare/SparkleShare-Test"); - - StatusItem = NSStatusBar.SystemStatusBar.CreateStatusItem (32); - - StatusItem.Enabled = true; - StatusItem.Image = NSImage.ImageNamed ("sparkleshare-idle.png"); - StatusItem.AlternateImage = NSImage.ImageNamed ("sparkleshare-idle-focus.png"); - StatusItem.Image.Size = new SizeF (13, 13); - StatusItem.AlternateImage.Size = new SizeF (13, 13); - StatusItem.HighlightMode = true; - - Menu = new NSMenu (); - - - Menu.AddItem (new NSMenuItem () { Title="Up to date (102 ᴍʙ)", Enabled = true }); - Menu.AddItem (NSMenuItem.SeparatorItem); - - - FolderMenuItem = new NSMenuItem () { - Title="SparkleShare", Enabled = true, - Action = new Selector ("ddd") - }; - - FolderMenuItem.Activated += delegate { - Console.WriteLine ("DDDD"); - }; - - FolderMenuItem.Image = NSImage.ImageNamed ("NSFolder"); - FolderMenuItem.Image.Size = new SizeF (16, 16); - - Menu.AddItem (FolderMenuItem); - - FolderMenuItems = new NSMenuItem [2] { - new NSMenuItem () { Title = "gnome-design" }, - new NSMenuItem () { Title = "tango-icons" } - }; - - foreach (NSMenuItem item in FolderMenuItems) { - - item.Activated += delegate { - - }; - - item.Image = NSImage.ImageNamed ("NSFolder"); - Menu.AddItem (item); - }; - - - Menu.AddItem (NSMenuItem.SeparatorItem); - - - SyncMenuItem = new NSMenuItem () { - Title = "Sync Remote Folder..." - }; - - SyncMenuItem.Activated += delegate { - - }; - - Menu.AddItem (SyncMenuItem); - - - Menu.AddItem (NSMenuItem.SeparatorItem); - - - NotificationsMenuItem = new NSMenuItem () { - Title = "Show Notifications", - State = NSCellStateValue.On - }; - - NotificationsMenuItem.Activated += delegate { - - //StatusItem.Image = NSImage.ImageNamed ("NSComputer"); - if (NotificationsMenuItem.State == NSCellStateValue.On) - - NotificationsMenuItem.State = NSCellStateValue.Off; - - else - - NotificationsMenuItem.State = NSCellStateValue.On; - - }; - - Menu.AddItem (NotificationsMenuItem); - - - Menu.AddItem (NSMenuItem.SeparatorItem); - - - AboutMenuItem = new NSMenuItem () { - Title = "About" - }; - - AboutMenuItem.Activated += delegate { - - }; - - Menu.AddItem (AboutMenuItem); - - - Menu.AddItem (NSMenuItem.SeparatorItem); - - - QuitMenuItem = new NSMenuItem () { - Title = "Quit" - }; - - QuitMenuItem.Activated += delegate { - Environment.Exit (0); - }; - - Menu.AddItem (QuitMenuItem); - - StatusItem.Menu = Menu; - - } - } -} - diff --git a/SparkleShare/Mac/SparkleShare/Info.plist b/SparkleShare/Mac/SparkleShare/Info.plist index 16ec0ef3..f2caa9e3 100644 --- a/SparkleShare/Mac/SparkleShare/Info.plist +++ b/SparkleShare/Mac/SparkleShare/Info.plist @@ -8,7 +8,7 @@ /opt/local/bin CFBundleIdentifier - com.yourcompany.SparkleShare + org.sparkleshare.sparkleshare CFBundleName SparkleShare CFBundleVersion @@ -19,5 +19,7 @@ MainMenu NSPrincipalClass NSApplication + LSBackgroundOnly + diff --git a/SparkleShare/Mac/SparkleShare/Main.cs b/SparkleShare/Mac/SparkleShare/Main.cs index f54dc597..abdc2be4 100644 --- a/SparkleShare/Mac/SparkleShare/Main.cs +++ b/SparkleShare/Mac/SparkleShare/Main.cs @@ -14,5 +14,153 @@ namespace SparkleShare NSApplication.Main (args); } } + + + [MonoMac.Foundation.Register("AppDelegate")] + public partial class AppDelegate : NSApplicationDelegate + { + + //MainWindowController mainWindowController; + NSStatusItem StatusItem; + + NSMenu Menu; + NSMenuItem FolderMenuItem; + NSMenuItem [] FolderMenuItems; + NSMenuItem SyncMenuItem; + NSMenuItem NotificationsMenuItem; + NSMenuItem AboutMenuItem; + NSMenuItem QuitMenuItem; + + + public AppDelegate () + { + } + + public override void FinishedLaunching (NSObject notification) + { + + // mainWindowController = new MainWindowController (); + // mainWindowController.Window.MakeKeyAndOrderFront (this); + + // SparkleStatusIcon = new SparkleStatusIcon (); + + // SparkleRepo repo = new SparkleRepo ("/Users/hbons/SparkleShare/SparkleShare-Test"); + + StatusItem = NSStatusBar.SystemStatusBar.CreateStatusItem (32); + + StatusItem.Enabled = true; + StatusItem.Image = NSImage.ImageNamed ("sparkleshare-idle.png"); + StatusItem.AlternateImage = NSImage.ImageNamed ("sparkleshare-idle-focus.png"); + StatusItem.Image.Size = new SizeF (13, 13); + StatusItem.AlternateImage.Size = new SizeF (13, 13); + StatusItem.HighlightMode = true; + + Menu = new NSMenu (); + + + Menu.AddItem (new NSMenuItem () { Title="Up to date (102 ᴍʙ)", Enabled = true }); + Menu.AddItem (NSMenuItem.SeparatorItem); + + + FolderMenuItem = new NSMenuItem () { + Title="SparkleShare", Enabled = true, + Action = new Selector ("ddd") + }; + + FolderMenuItem.Activated += delegate { + Console.WriteLine ("DDDD"); + }; + + FolderMenuItem.Image = NSImage.ImageNamed ("NSFolder"); + FolderMenuItem.Image.Size = new SizeF (16, 16); + + Menu.AddItem (FolderMenuItem); + + FolderMenuItems = new NSMenuItem [2] { + new NSMenuItem () { Title = "gnome-design" }, + new NSMenuItem () { Title = "tango-icons" } + }; + + foreach (NSMenuItem item in FolderMenuItems) { + + item.Activated += delegate { + + }; + + item.Image = NSImage.ImageNamed ("NSFolder"); + Menu.AddItem (item); + }; + + + Menu.AddItem (NSMenuItem.SeparatorItem); + + + SyncMenuItem = new NSMenuItem () { + Title = "Sync Remote Folder..." + }; + + SyncMenuItem.Activated += delegate { + + }; + + Menu.AddItem (SyncMenuItem); + + + Menu.AddItem (NSMenuItem.SeparatorItem); + + + NotificationsMenuItem = new NSMenuItem () { + Title = "Show Notifications", + State = NSCellStateValue.On + }; + + NotificationsMenuItem.Activated += delegate { + + //StatusItem.Image = NSImage.ImageNamed ("NSComputer"); + if (NotificationsMenuItem.State == NSCellStateValue.On) + + NotificationsMenuItem.State = NSCellStateValue.Off; + + else + + NotificationsMenuItem.State = NSCellStateValue.On; + + }; + + Menu.AddItem (NotificationsMenuItem); + + + Menu.AddItem (NSMenuItem.SeparatorItem); + + + AboutMenuItem = new NSMenuItem () { + Title = "About" + }; + + AboutMenuItem.Activated += delegate { + + }; + + Menu.AddItem (AboutMenuItem); + + + Menu.AddItem (NSMenuItem.SeparatorItem); + + + QuitMenuItem = new NSMenuItem () { + Title = "Quit" + }; + + QuitMenuItem.Activated += delegate { + Environment.Exit (0); + }; + + Menu.AddItem (QuitMenuItem); + + StatusItem.Menu = Menu; + + } + } + } diff --git a/SparkleShare/Mac/SparkleShare/MainMenu.xib.designer.cs b/SparkleShare/Mac/SparkleShare/MainMenu.xib.designer.cs index 01952cd1..93a0d735 100644 --- a/SparkleShare/Mac/SparkleShare/MainMenu.xib.designer.cs +++ b/SparkleShare/Mac/SparkleShare/MainMenu.xib.designer.cs @@ -10,9 +10,4 @@ namespace SparkleShare { - - // Should subclass MonoMac.AppKit.NSResponder - [MonoMac.Foundation.Register("AppDelegate")] - public partial class AppDelegate { - } } diff --git a/SparkleShare/Mac/SparkleShare/SparkleShare.csproj b/SparkleShare/Mac/SparkleShare/SparkleShare.csproj index 8387f87f..3780b5b2 100644 --- a/SparkleShare/Mac/SparkleShare/SparkleShare.csproj +++ b/SparkleShare/Mac/SparkleShare/SparkleShare.csproj @@ -46,25 +46,12 @@ - - MainWindow.xib - - - MainWindow.xib - - - MainWindow.xib - - - MainMenu.xib - MainMenu.xib - From dea016d2e5134d839a537ac34522be5ac27cb4b3 Mon Sep 17 00:00:00 2001 From: Hylke Bons Date: Tue, 14 Dec 2010 20:22:13 +0100 Subject: [PATCH 03/19] [osx] Add event log window prototype --- SparkleShare/Mac/SparkleShare/Main.cs | 64 ++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/SparkleShare/Mac/SparkleShare/Main.cs b/SparkleShare/Mac/SparkleShare/Main.cs index abdc2be4..9ff8630d 100644 --- a/SparkleShare/Mac/SparkleShare/Main.cs +++ b/SparkleShare/Mac/SparkleShare/Main.cs @@ -3,6 +3,7 @@ using System.Drawing; using MonoMac.Foundation; using MonoMac.AppKit; using MonoMac.ObjCRuntime; +using MonoMac.WebKit; namespace SparkleShare { @@ -11,6 +12,7 @@ namespace SparkleShare static void Main (string[] args) { NSApplication.Init (); + NSApplication.SharedApplication.ActivateIgnoringOtherApps (true); NSApplication.Main (args); } } @@ -31,13 +33,24 @@ namespace SparkleShare NSMenuItem AboutMenuItem; NSMenuItem QuitMenuItem; - + NSTextField text; + NSWindow window; + NSButton button; + NSButton button2; + + WebView web_view; + + public AppDelegate () { } public override void FinishedLaunching (NSObject notification) { + + + + // mainWindowController = new MainWindowController (); // mainWindowController.Window.MakeKeyAndOrderFront (this); @@ -84,7 +97,54 @@ namespace SparkleShare foreach (NSMenuItem item in FolderMenuItems) { item.Activated += delegate { - + + + + + button = new NSButton (new RectangleF (16, 12, 120, 31)) { + Title = "Open Folder", + BezelStyle = NSBezelStyle.Rounded + + }; + + button2 = new NSButton (new RectangleF (480 - 120 - 16, 12, 120, 31)) { + Title = "Close", + BezelStyle = NSBezelStyle.Rounded + + }; + + window = new NSWindow (new RectangleF (0, 0, 480, 640), (NSWindowStyle) (1 | (1 << 1) | (1 << 2) | (1 << 3)), 0, false); + + bool minimizeBox = true; + bool maximizeBox = false; +window.StyleMask = (NSWindowStyle)(1 | (1 << 1) | (minimizeBox ? 4 : 1) | (maximizeBox ? 8 : 1)); + + + web_view = new WebView (new RectangleF (0, 12 + 31 + 16, 480, 640 - (12 + 31 + 16)), "", ""); + web_view.MainFrameUrl = "http://www.google.nl/"; + + + window.ContentView.AddSubview (button); + window.ContentView.AddSubview (button2); + window.ContentView.AddSubview (web_view); + + window.MaxSize = new SizeF (480, 640); + window.MinSize = new SizeF (480, 640); + + window.Title = "Recent Events in 'gnome-design'"; + + window.HasShadow = true; + + window.BackingType = NSBackingStore.Buffered; + + + + + window.MakeKeyAndOrderFront (this); + window.Center (); + + + }; item.Image = NSImage.ImageNamed ("NSFolder"); From 0e2472cd7916c51bc5d0918d833cd655c4a5325f Mon Sep 17 00:00:00 2001 From: Hylke Bons Date: Tue, 14 Dec 2010 21:26:57 +0100 Subject: [PATCH 04/19] [osx] don't allow resizeing of the event log --- SparkleShare/Mac/SparkleShare/Main.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/SparkleShare/Mac/SparkleShare/Main.cs b/SparkleShare/Mac/SparkleShare/Main.cs index 9ff8630d..515ac15b 100644 --- a/SparkleShare/Mac/SparkleShare/Main.cs +++ b/SparkleShare/Mac/SparkleShare/Main.cs @@ -113,11 +113,16 @@ namespace SparkleShare }; - window = new NSWindow (new RectangleF (0, 0, 480, 640), (NSWindowStyle) (1 | (1 << 1) | (1 << 2) | (1 << 3)), 0, false); - - bool minimizeBox = true; + + bool minimizeBox = true; bool maximizeBox = false; -window.StyleMask = (NSWindowStyle)(1 | (1 << 1) | (minimizeBox ? 4 : 1) | (maximizeBox ? 8 : 1)); +NSWindowStyle style = (NSWindowStyle)(1 | (1 << 1) | (minimizeBox ? 4 : 1) | (maximizeBox ? 8 : 1)); + + +window = new NSWindow (new RectangleF (0, 0, 480, 640), + style, 0, false); + + web_view = new WebView (new RectangleF (0, 12 + 31 + 16, 480, 640 - (12 + 31 + 16)), "", ""); @@ -134,7 +139,7 @@ window.StyleMask = (NSWindowStyle)(1 | (1 << 1) | (minimizeBox ? 4 : 1) | (maxim window.Title = "Recent Events in 'gnome-design'"; window.HasShadow = true; - + window.DefaultButtonCell = button2.Cell; window.BackingType = NSBackingStore.Buffered; From 7a60042c48177b90b6f63d67a451d33fd3286205 Mon Sep 17 00:00:00 2001 From: Hylke Bons Date: Fri, 17 Dec 2010 00:38:51 +0100 Subject: [PATCH 05/19] Some more messing around with [osx] --- SparkleShare/Mac/SparkleShare/Info.plist | 2 +- SparkleShare/Mac/SparkleShare/Layout.cs | 298 ++ SparkleShare/Mac/SparkleShare/Main.cs | 83 +- SparkleShare/Mac/SparkleShare/MainMenu.xib | 3203 +---------------- .../Mac/SparkleShare/MainMenu.xib.designer.cs | 5 + .../Mac/SparkleShare/SparkleShare.csproj | 2 + .../Mac/SparkleShare/sparkleshare.icns | Bin 0 -> 143098 bytes 7 files changed, 452 insertions(+), 3141 deletions(-) create mode 100644 SparkleShare/Mac/SparkleShare/Layout.cs create mode 100644 SparkleShare/Mac/SparkleShare/sparkleshare.icns diff --git a/SparkleShare/Mac/SparkleShare/Info.plist b/SparkleShare/Mac/SparkleShare/Info.plist index f2caa9e3..553e5dec 100644 --- a/SparkleShare/Mac/SparkleShare/Info.plist +++ b/SparkleShare/Mac/SparkleShare/Info.plist @@ -20,6 +20,6 @@ NSPrincipalClass NSApplication LSBackgroundOnly - + diff --git a/SparkleShare/Mac/SparkleShare/Layout.cs b/SparkleShare/Mac/SparkleShare/Layout.cs new file mode 100644 index 00000000..56bccafd --- /dev/null +++ b/SparkleShare/Mac/SparkleShare/Layout.cs @@ -0,0 +1,298 @@ +// +// Layout.cs +// +// Author: +// Michael Hutchinson +// +// Copyright (c) 2010 Novell, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Drawing; +using MonoMac.AppKit; +using System.Linq; +namespace MonoDevelop.Platform.Mac +{ + interface ILayout + { + LayoutRequest BeginLayout (); + void EndLayout (LayoutRequest request, PointF origin, SizeF allocation); + } + + class LayoutRequest + { + public SizeF Size { get; set; } + public bool Visible { get; set; } + public bool ExpandWidth { get; set; } + public bool ExpandHeight { get; set; } + } + + abstract class LayoutBox : IEnumerable, ILayout + { + List children = new List (); + + public float Spacing { get; set; } + public float PadLeft { get; set; } + public float PadRight { get; set; } + public float PadTop { get; set; } + public float PadBottom { get; set; } + public LayoutAlign Align { get; set; } + + public LayoutDirection Direction { get; set; } + + public LayoutBox (LayoutDirection direction, float spacing) : this (direction, spacing, 0) + { + } + + public LayoutBox (LayoutDirection direction, float spacing, float padding) + { + PadLeft = PadRight = PadTop = PadBottom = padding; + this.Direction = direction; + this.Spacing = spacing; + this.Align = LayoutAlign.Center; + } + + public int Count { get { return children.Count; } } + + bool IsHorizontal { get { return Direction == LayoutDirection.Horizontal; } } + + public IEnumerator GetEnumerator () + { + return children.GetEnumerator (); + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator () + { + return children.GetEnumerator (); + } + + public void Add (ILayout child) + { + children.Add (child); + OnChildAdded (child); + } + + ContainerLayoutRequest request = new ContainerLayoutRequest (); + + public virtual LayoutRequest BeginLayout () + { + float width = 0; + float height = 0; + + request.ChildRequests.Clear (); + request.ChildRequests.AddRange (children.Select (c => c.BeginLayout ())); + + foreach (var r in request.ChildRequests) { + if (!r.Visible) + continue; + request.Visible = true; + if (r.ExpandWidth) + request.ExpandWidth = true; + if (r.ExpandHeight) + request.ExpandHeight = true; + + if (IsHorizontal) { + if (width != 0) + width += Spacing; + width += r.Size.Width; + height = Math.Max (height, r.Size.Height); + } else { + if (height != 0) + height += Spacing; + height += r.Size.Height; + width = Math.Max (width, r.Size.Width); + } + } + + request.Size = new SizeF (width + PadLeft + PadRight, height + PadTop + PadBottom); + return request; + } + + public virtual void EndLayout (LayoutRequest request, PointF origin, SizeF allocation) + { + var childRequests = ((ContainerLayoutRequest) request).ChildRequests; + + allocation = new SizeF (allocation.Width - PadLeft - PadRight, allocation.Height - PadBottom - PadTop); + origin = new PointF (origin.X + PadLeft, origin.Y + PadBottom); + + var size = request.Size; + size.Height -= (PadTop + PadBottom); + size.Width -= (PadLeft + PadRight); + + int wExpandCount = 0; + int hExpandCount = 0; + int visibleCount = 0; + foreach (var childRequest in childRequests) { + if (childRequest.Visible) + visibleCount++; + else + continue; + if (childRequest.ExpandWidth) + wExpandCount++; + if (childRequest.ExpandHeight) + hExpandCount++; + } + + float wExpand = 0; + if (allocation.Width > size.Width) { + wExpand = allocation.Width - size.Width; + if (wExpandCount > 0) + wExpand /= wExpandCount; + } + float hExpand = 0; + if (allocation.Height > size.Height) { + hExpand = allocation.Height - size.Height; + if (hExpandCount > 0) + hExpand /= hExpandCount; + } + + if (Direction == LayoutDirection.Horizontal) { + float pos = PadLeft; + if (wExpandCount == 0) { + if (Align == LayoutAlign.End) + pos += wExpand; + else if (Align == LayoutAlign.Center) + pos += wExpand / 2; + } + for (int i = 0; i < childRequests.Count; i++) { + var child = children[i]; + var childReq = childRequests[i]; + if (!childReq.Visible) + continue; + + var childSize = new SizeF (childReq.Size.Width, allocation.Height); + if (childReq.ExpandWidth) { + childSize.Width += wExpand; + } else if (hExpandCount == 0 && Align == LayoutAlign.Fill) { + childSize.Width += wExpand / visibleCount; + } + + child.EndLayout (childReq, new PointF (pos, origin.Y), childSize); + pos += childSize.Width + Spacing; + } + } else { + float pos = PadBottom; + if (hExpandCount == 0) { + if (Align == LayoutAlign.End) + pos += hExpand; + else if (Align == LayoutAlign.Center) + pos += hExpand / 2; + } + for (int i = 0; i < childRequests.Count; i++) { + var child = children[i]; + var childReq = childRequests[i]; + if (!childReq.Visible) + continue; + + var childSize = new SizeF (allocation.Width, childReq.Size.Height); + if (childReq.ExpandHeight) { + childSize.Height += hExpand; + } else if (hExpandCount == 0 && Align == LayoutAlign.Fill) { + childSize.Height += hExpand / visibleCount; + } + + child.EndLayout (childReq, new PointF (origin.X, pos), childSize); + pos += childSize.Height + Spacing; + } + } + } + + protected abstract void OnChildAdded (ILayout child); + + class ContainerLayoutRequest : LayoutRequest + { + public List ChildRequests = new List (); + } + } + + public enum LayoutAlign + { + Begin, Center, End, Fill + } + + public enum LayoutDirection + { + Horizontal, Vertical + } + + abstract class LayoutAlignment : ILayout + { + public LayoutAlignment () + { + XAlign = YAlign = LayoutAlign.Center; + } + + public LayoutAlign XAlign { get; set; } + public LayoutAlign YAlign { get; set; } + public bool ExpandHeight { get; set; } + public bool ExpandWidth { get; set; } + public float MinHeight { get; set; } + public float MinWidth { get; set; } + public float PadLeft { get; set; } + public float PadRight { get; set; } + public float PadTop { get; set; } + public float PadBottom { get; set; } + public bool Visible { get; set; } + + LayoutRequest request = new LayoutRequest (); + + public virtual LayoutRequest BeginLayout () + { + request.Size = new SizeF (MinWidth + PadLeft + PadRight, MinHeight + PadTop + PadBottom); + request.ExpandHeight = this.ExpandHeight; + request.ExpandWidth = this.ExpandWidth; + request.Visible = this.Visible; + return request; + } + + public virtual void EndLayout (LayoutRequest request, PointF origin, SizeF allocation) + { + var frame = new RectangleF (origin.X + PadLeft, origin.Y + PadBottom, + allocation.Width - PadLeft - PadRight, allocation.Height - PadTop - PadBottom); + + if (allocation.Height > request.Size.Height) { + if (YAlign != LayoutAlign.Fill) { + frame.Height = request.Size.Height - PadTop - PadBottom; + if (YAlign == LayoutAlign.Center) { + frame.Y += (allocation.Height - request.Size.Height) / 2; + } else if (YAlign == LayoutAlign.End) { + frame.Y += (allocation.Height - request.Size.Height); + } + } + } + + if (allocation.Width > request.Size.Width) { + if (XAlign != LayoutAlign.Fill) { + frame.Width = request.Size.Width - PadLeft - PadRight; + if (XAlign == LayoutAlign.Center) { + frame.X += (allocation.Width - request.Size.Width) / 2; + } else if (XAlign == LayoutAlign.End) { + frame.X += (allocation.Width - request.Size.Width); + } + } + } + + OnLayoutEnded (frame); + } + + protected abstract void OnLayoutEnded (RectangleF frame); + } +} \ No newline at end of file diff --git a/SparkleShare/Mac/SparkleShare/Main.cs b/SparkleShare/Mac/SparkleShare/Main.cs index 515ac15b..c97dd14c 100644 --- a/SparkleShare/Mac/SparkleShare/Main.cs +++ b/SparkleShare/Mac/SparkleShare/Main.cs @@ -1,9 +1,11 @@ using System; using System.Drawing; +using System.Timers; using MonoMac.Foundation; using MonoMac.AppKit; using MonoMac.ObjCRuntime; using MonoMac.WebKit; +using MonoMac.Growl; namespace SparkleShare { @@ -13,15 +15,16 @@ namespace SparkleShare { NSApplication.Init (); NSApplication.SharedApplication.ActivateIgnoringOtherApps (true); + NSApplication.SharedApplication.applicationIconImage = NSImage.ImageNamed ("sparkleshare.icns"); NSApplication.Main (args); } } - [MonoMac.Foundation.Register("AppDelegate")] + public partial class AppDelegate : NSApplicationDelegate { - + //MainWindowController mainWindowController; NSStatusItem StatusItem; @@ -33,25 +36,37 @@ namespace SparkleShare NSMenuItem AboutMenuItem; NSMenuItem QuitMenuItem; - NSTextField text; + NSWindow window; NSButton button; NSButton button2; WebView web_view; + NSDockTile tile; + int i = 0; + /* public override NSMenu ApplicationDockMenu (NSApplication app) + { + + return (NSMenu) Menu; + + } + */ public AppDelegate () { } + + + public override void FinishedLaunching (NSObject notification) { - - - - + /* tile = NSApplication.SharedApplication.DockTile; + tile.BadgeLabel = "!"; +tile.Display (); + */ // mainWindowController = new MainWindowController (); // mainWindowController.Window.MakeKeyAndOrderFront (this); @@ -59,7 +74,7 @@ namespace SparkleShare // SparkleRepo repo = new SparkleRepo ("/Users/hbons/SparkleShare/SparkleShare-Test"); - StatusItem = NSStatusBar.SystemStatusBar.CreateStatusItem (32); + StatusItem = NSStatusBar.SystemStatusBar.CreateStatusItem (28); StatusItem.Enabled = true; StatusItem.Image = NSImage.ImageNamed ("sparkleshare-idle.png"); @@ -75,11 +90,33 @@ namespace SparkleShare Menu.AddItem (NSMenuItem.SeparatorItem); + Timer timer = new Timer () { + Interval = 500 + }; + + + FolderMenuItem = new NSMenuItem () { Title="SparkleShare", Enabled = true, Action = new Selector ("ddd") }; + + timer.Elapsed += delegate { + FolderMenuItem.InvokeOnMainThread (delegate { + + if (i == 0){ + StatusItem.Image = NSImage.ImageNamed ("sparkleshare-idle-focus.png"); + i = 1; + }else{ + StatusItem.Image = NSImage.ImageNamed ("sparkleshare-idle.png"); + i = 0; + } + + /*FolderMenuItem.Title+="Z";Menu.Update ();*/}); + }; + + timer.Start (); FolderMenuItem.Activated += delegate { Console.WriteLine ("DDDD"); }; @@ -90,7 +127,7 @@ namespace SparkleShare Menu.AddItem (FolderMenuItem); FolderMenuItems = new NSMenuItem [2] { - new NSMenuItem () { Title = "gnome-design" }, + new NSMenuItem () { Title = "gnome-design (2)" }, new NSMenuItem () { Title = "tango-icons" } }; @@ -139,29 +176,36 @@ window = new NSWindow (new RectangleF (0, 0, 480, 640), window.Title = "Recent Events in 'gnome-design'"; window.HasShadow = true; - window.DefaultButtonCell = button2.Cell; + //window.DefaultButtonCell = button2.Cell; window.BackingType = NSBackingStore.Buffered; - + NSApplication.SharedApplication.ActivateIgnoringOtherApps (true); window.MakeKeyAndOrderFront (this); window.Center (); + + }; item.Image = NSImage.ImageNamed ("NSFolder"); Menu.AddItem (item); }; + + + + + Menu.AddItem (NSMenuItem.SeparatorItem); SyncMenuItem = new NSMenuItem () { - Title = "Sync Remote Folder..." + Title = "Add Remote Folder..." }; SyncMenuItem.Activated += delegate { @@ -209,7 +253,7 @@ window = new NSWindow (new RectangleF (0, 0, 480, 640), Menu.AddItem (AboutMenuItem); - Menu.AddItem (NSMenuItem.SeparatorItem); + // Menu.AddItem (NSMenuItem.SeparatorItem); QuitMenuItem = new NSMenuItem () { @@ -220,11 +264,20 @@ window = new NSWindow (new RectangleF (0, 0, 480, 640), Environment.Exit (0); }; - Menu.AddItem (QuitMenuItem); + //Menu.AddItem (QuitMenuItem); StatusItem.Menu = Menu; - + + + + NSApplication.SharedApplication.ActivateIgnoringOtherApps (true); + + } + + + + } } diff --git a/SparkleShare/Mac/SparkleShare/MainMenu.xib b/SparkleShare/Mac/SparkleShare/MainMenu.xib index 0a42fa19..ed428a77 100644 --- a/SparkleShare/Mac/SparkleShare/MainMenu.xib +++ b/SparkleShare/Mac/SparkleShare/MainMenu.xib @@ -2,7 +2,7 @@ 1060 - 10D573 + 10D2162 762 1038.29 460.00 @@ -61,45 +61,6 @@ MacCocoaApp YES - - - About SparkleShare - - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Preferences… - , - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - Services @@ -179,1058 +140,6 @@ _NSAppleMenu - - - File - - 1048576 - 2147483647 - - - submenuAction: - - File - - YES - - - New - n - 1048576 - 2147483647 - - - - - - Open… - o - 1048576 - 2147483647 - - - - - - Open Recent - - 1048576 - 2147483647 - - - submenuAction: - - Open Recent - - YES - - - Clear Menu - - 1048576 - 2147483647 - - - - - _NSRecentDocumentsMenu - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Close - w - 1048576 - 2147483647 - - - - - - Save - s - 1048576 - 2147483647 - - - - - - Save As… - S - 1179648 - 2147483647 - - - - - - Revert to Saved - - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Page Setup... - P - 1179648 - 2147483647 - - - - - - - Print… - p - 1048576 - 2147483647 - - - - - - - - - Edit - - 1048576 - 2147483647 - - - submenuAction: - - Edit - - YES - - - Undo - z - 1048576 - 2147483647 - - - - - - Redo - Z - 1179648 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Cut - x - 1048576 - 2147483647 - - - - - - Copy - c - 1048576 - 2147483647 - - - - - - Paste - v - 1048576 - 2147483647 - - - - - - Paste and Match Style - V - 1572864 - 2147483647 - - - - - - Delete - - 1048576 - 2147483647 - - - - - - Select All - a - 1048576 - 2147483647 - - - - - - YES - YES - - - 1048576 - 2147483647 - - - - - - Find - - 1048576 - 2147483647 - - - submenuAction: - - Find - - YES - - - Find… - f - 1048576 - 2147483647 - - - 1 - - - - Find Next - g - 1048576 - 2147483647 - - - 2 - - - - Find Previous - G - 1179648 - 2147483647 - - - 3 - - - - Use Selection for Find - e - 1048576 - 2147483647 - - - 7 - - - - Jump to Selection - j - 1048576 - 2147483647 - - - - - - - - - Spelling and Grammar - - 1048576 - 2147483647 - - - submenuAction: - - Spelling and Grammar - - YES - - - Show Spelling and Grammar - : - 1048576 - 2147483647 - - - - - - Check Document Now - ; - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Check Spelling While Typing - - 1048576 - 2147483647 - - - - - - Check Grammar With Spelling - - 1048576 - 2147483647 - - - - - - Correct Spelling Automatically - - 2147483647 - - - - - - - - - Substitutions - - 1048576 - 2147483647 - - - submenuAction: - - Substitutions - - YES - - - Show Substitutions - - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Smart Copy/Paste - f - 1048576 - 2147483647 - - - 1 - - - - Smart Quotes - g - 1048576 - 2147483647 - - - 2 - - - - Smart Dashes - - 2147483647 - - - - - - Smart Links - G - 1179648 - 2147483647 - - - 3 - - - - Text Replacement - - 2147483647 - - - - - - - - - Transformations - - 2147483647 - - - submenuAction: - - Transformations - - YES - - - Make Upper Case - - 2147483647 - - - - - - Make Lower Case - - 2147483647 - - - - - - Capitalize - - 2147483647 - - - - - - - - - Speech - - 1048576 - 2147483647 - - - submenuAction: - - Speech - - YES - - - Start Speaking - - 1048576 - 2147483647 - - - - - - Stop Speaking - - 1048576 - 2147483647 - - - - - - - - - - - - Format - - 2147483647 - - - submenuAction: - - Format - - YES - - - Font - - 2147483647 - - - submenuAction: - - Font - - YES - - - Show Fonts - t - 1048576 - 2147483647 - - - - - - Bold - b - 1048576 - 2147483647 - - - 2 - - - - Italic - i - 1048576 - 2147483647 - - - 1 - - - - Underline - u - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Bigger - + - 1048576 - 2147483647 - - - 3 - - - - Smaller - - - 1048576 - 2147483647 - - - 4 - - - - YES - YES - - - 2147483647 - - - - - - Kern - - 2147483647 - - - submenuAction: - - Kern - - YES - - - Use Default - - 2147483647 - - - - - - Use None - - 2147483647 - - - - - - Tighten - - 2147483647 - - - - - - Loosen - - 2147483647 - - - - - - - - - Ligature - - 2147483647 - - - submenuAction: - - Ligature - - YES - - - Use Default - - 2147483647 - - - - - - Use None - - 2147483647 - - - - - - Use All - - 2147483647 - - - - - - - - - Baseline - - 2147483647 - - - submenuAction: - - Baseline - - YES - - - Use Default - - 2147483647 - - - - - - Superscript - - 2147483647 - - - - - - Subscript - - 2147483647 - - - - - - Raise - - 2147483647 - - - - - - Lower - - 2147483647 - - - - - - - - - YES - YES - - - 2147483647 - - - - - - Show Colors - C - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Copy Style - c - 1572864 - 2147483647 - - - - - - Paste Style - v - 1572864 - 2147483647 - - - - - _NSFontMenu - - - - - Text - - 2147483647 - - - submenuAction: - - Text - - YES - - - Align Left - { - 1048576 - 2147483647 - - - - - - Center - | - 1048576 - 2147483647 - - - - - - Justify - - 2147483647 - - - - - - Align Right - } - 1048576 - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - Writing Direction - - 2147483647 - - - submenuAction: - - Writing Direction - - YES - - - YES - Paragraph - - 2147483647 - - - - - - CURlZmF1bHQ - - 2147483647 - - - - - - CUxlZnQgdG8gUmlnaHQ - - 2147483647 - - - - - - CVJpZ2h0IHRvIExlZnQ - - 2147483647 - - - - - - YES - YES - - - 2147483647 - - - - - - YES - Selection - - 2147483647 - - - - - - CURlZmF1bHQ - - 2147483647 - - - - - - CUxlZnQgdG8gUmlnaHQ - - 2147483647 - - - - - - CVJpZ2h0IHRvIExlZnQ - - 2147483647 - - - - - - - - - YES - YES - - - 2147483647 - - - - - - Show Ruler - - 2147483647 - - - - - - Copy Ruler - c - 1310720 - 2147483647 - - - - - - Paste Ruler - v - 1310720 - 2147483647 - - - - - - - - - - - - View - - 1048576 - 2147483647 - - - submenuAction: - - View - - YES - - - Show Toolbar - t - 1572864 - 2147483647 - - - - - - Customize Toolbar… - - 1048576 - 2147483647 - - - - - - Window @@ -1340,142 +249,6 @@ 39 - - - print: - - - - 86 - - - - runPageLayout: - - - - 87 - - - - clearRecentDocuments: - - - - 127 - - - - orderFrontStandardAboutPanel: - - - - 142 - - - - performClose: - - - - 193 - - - - toggleContinuousSpellChecking: - - - - 222 - - - - undo: - - - - 223 - - - - copy: - - - - 224 - - - - checkSpelling: - - - - 225 - - - - paste: - - - - 226 - - - - stopSpeaking: - - - - 227 - - - - cut: - - - - 228 - - - - showGuessPanel: - - - - 230 - - - - redo: - - - - 231 - - - - selectAll: - - - - 232 - - - - startSpeaking: - - - - 233 - - - - delete: - - - - 235 - performZoom: @@ -1484,94 +257,6 @@ 240 - - - performFindPanelAction: - - - - 241 - - - - centerSelectionInVisibleArea: - - - - 245 - - - - toggleGrammarChecking: - - - - 347 - - - - toggleSmartInsertDelete: - - - - 355 - - - - toggleAutomaticQuoteSubstitution: - - - - 356 - - - - toggleAutomaticLinkDetection: - - - - 357 - - - - saveDocument: - - - - 362 - - - - saveDocumentAs: - - - - 363 - - - - revertDocumentToSaved: - - - - 364 - - - - runToolbarCustomizationPalette: - - - - 365 - - - - toggleToolbarShown: - - - - 366 - hide: @@ -1596,190 +281,6 @@ 370 - - - newDocument: - - - - 373 - - - - openDocument: - - - - 374 - - - - addFontTrait: - - - - 421 - - - - addFontTrait: - - - - 422 - - - - modifyFont: - - - - 423 - - - - orderFrontFontPanel: - - - - 424 - - - - modifyFont: - - - - 425 - - - - raiseBaseline: - - - - 426 - - - - lowerBaseline: - - - - 427 - - - - copyFont: - - - - 428 - - - - subscript: - - - - 429 - - - - superscript: - - - - 430 - - - - tightenKerning: - - - - 431 - - - - underline: - - - - 432 - - - - orderFrontColorPanel: - - - - 433 - - - - useAllLigatures: - - - - 434 - - - - loosenKerning: - - - - 435 - - - - pasteFont: - - - - 436 - - - - unscript: - - - - 437 - - - - useStandardKerning: - - - - 438 - - - - useStandardLigatures: - - - - 439 - - - - turnOffLigatures: - - - - 440 - - - - turnOffKerning: - - - - 441 - terminate: @@ -1788,94 +289,6 @@ 449 - - - toggleAutomaticSpellingCorrection: - - - - 456 - - - - orderFrontSubstitutionsPanel: - - - - 458 - - - - toggleAutomaticDashSubstitution: - - - - 461 - - - - toggleAutomaticTextReplacement: - - - - 463 - - - - uppercaseWord: - - - - 464 - - - - capitalizeWord: - - - - 467 - - - - lowercaseWord: - - - - 468 - - - - pasteAsPlainText: - - - - 486 - - - - performFindPanelAction: - - - - 487 - - - - performFindPanelAction: - - - - 488 - - - - performFindPanelAction: - - - - 489 - showHelp: @@ -1884,110 +297,6 @@ 493 - - - alignCenter: - - - - 518 - - - - pasteRuler: - - - - 519 - - - - toggleRuler: - - - - 520 - - - - alignRight: - - - - 521 - - - - copyRuler: - - - - 522 - - - - alignJustified: - - - - 523 - - - - alignLeft: - - - - 524 - - - - makeBaseWritingDirectionNatural: - - - - 525 - - - - makeBaseWritingDirectionLeftToRight: - - - - 526 - - - - makeBaseWritingDirectionRightToLeft: - - - - 527 - - - - makeTextWritingDirectionNatural: - - - - 528 - - - - makeTextWritingDirectionLeftToRight: - - - - 529 - - - - makeTextWritingDirectionRightToLeft: - - - - 530 - delegate @@ -2029,25 +338,12 @@ YES - - - - - + - - 19 - - - YES - - - - 56 @@ -2057,326 +353,39 @@ - - 217 - - - YES - - - - - - 83 - - - YES - - - - - - 81 - - - YES - - - - - - - - - - - - - - - - 75 - - - - - 80 - - - - - 78 - - - - - 72 - - - - - 82 - - - - - 124 - - - YES - - - - - - 77 - - - - - 73 - - - - - 79 - - - - - 112 - - - - - 74 - - - - - 125 - - - YES - - - - - - 126 - - - - - 205 - - - YES - - - - - - - - - - - - - - - - - - - - 202 - - - - - 198 - - - - - 207 - - - - - 214 - - - - - 199 - - - - - 203 - - - - - 197 - - - - - 206 - - - - - 215 - - - - - 218 - - - YES - - - - - - 216 - - - YES - - - - - - 200 - - - YES - - - - - - - - - - - 219 - - - - - 201 - - - - - 204 - - - - - 220 - - - YES - - - - - - - - - - 213 - - - - - 210 - - - - - 221 - - - - - 208 - - - - - 209 - - - 57 YES - - - - - - - - + + + + - - 58 - - - - - 134 - - - - - 150 - - - 136 - 144 - - + 420 + + - 129 - - + 533 + + - 143 - - - - - 236 - + 149 + @@ -2389,8 +398,13 @@ - 149 - + 144 + + + + + 150 + @@ -2398,460 +412,16 @@ + + 134 + + + 130 - - 24 - - - YES - - - - - - - - - 92 - - - - - 5 - - - - - 239 - - - - - 23 - - - - - 295 - - - YES - - - - - - 296 - - - YES - - - - - - - 297 - - - - - 298 - - - - - 211 - - - YES - - - - - - 212 - - - YES - - - - - - - 195 - - - - - 196 - - - - - 346 - - - - - 348 - - - YES - - - - - - 349 - - - YES - - - - - - - - - - - - 350 - - - - - 351 - - - - - 354 - - - - - 375 - - - YES - - - - - - 376 - - - YES - - - - - - - 377 - - - YES - - - - - - 388 - - - YES - - - - - - - - - - - - - - - - - - - - - 389 - - - - - 390 - - - - - 391 - - - - - 392 - - - - - 393 - - - - - 394 - - - - - 395 - - - - - 396 - - - - - 397 - - - YES - - - - - - 398 - - - YES - - - - - - 399 - - - YES - - - - - - 400 - - - - - 401 - - - - - 402 - - - - - 403 - - - - - 404 - - - - - 405 - - - YES - - - - - - - - - - 406 - - - - - 407 - - - - - 408 - - - - - 409 - - - - - 410 - - - - - 411 - - - YES - - - - - - - - 412 - - - - - 413 - - - - - 414 - - - - - 415 - - - YES - - - - - - - - - 416 - - - - - 417 - - - - - 418 - - - - - 419 - - - - - 420 - - - - - 450 - - - YES - - - - - - 451 - - - YES - - - - - - - - 452 - - - - - 453 - - - - - 454 - - - - - 457 - - - - - 459 - - - - - 460 - - - - - 462 - - - - - 465 - - - - - 466 - - - - - 485 - - - 490 @@ -2861,6 +431,47 @@ + + 19 + + + YES + + + + + + 24 + + + YES + + + + + + + + + 23 + + + + + 239 + + + + + 5 + + + + + 92 + + + 491 @@ -2875,154 +486,6 @@ - - 496 - - - YES - - - - - - 497 - - - YES - - - - - - - - - - - - - - - 498 - - - - - 499 - - - - - 500 - - - - - 501 - - - - - 502 - - - - - 503 - - - YES - - - - - - 504 - - - - - 505 - - - - - 506 - - - - - 507 - - - - - 508 - - - YES - - - - - - - - - - - - - - 509 - - - - - 510 - - - - - 511 - - - - - 512 - - - - - 513 - - - - - 514 - - - - - 515 - - - - - 516 - - - - - 517 - - - - - 533 - - - @@ -3030,17 +493,7 @@ YES -3.IBPluginDependency - 112.IBPluginDependency - 112.ImportedFromIB2 - 124.IBPluginDependency - 124.ImportedFromIB2 - 125.IBPluginDependency - 125.ImportedFromIB2 - 125.editorWindowContentRectSynchronizationRect - 126.IBPluginDependency - 126.ImportedFromIB2 - 129.IBPluginDependency - 129.ImportedFromIB2 + 130.IBEditorWindowLastContentRect 130.IBPluginDependency 130.ImportedFromIB2 130.editorWindowContentRectSynchronizationRect @@ -3050,8 +503,6 @@ 134.ImportedFromIB2 136.IBPluginDependency 136.ImportedFromIB2 - 143.IBPluginDependency - 143.ImportedFromIB2 144.IBPluginDependency 144.ImportedFromIB2 145.IBPluginDependency @@ -3062,71 +513,8 @@ 150.ImportedFromIB2 19.IBPluginDependency 19.ImportedFromIB2 - 195.IBPluginDependency - 195.ImportedFromIB2 - 196.IBPluginDependency - 196.ImportedFromIB2 - 197.IBPluginDependency - 197.ImportedFromIB2 - 198.IBPluginDependency - 198.ImportedFromIB2 - 199.IBPluginDependency - 199.ImportedFromIB2 - 200.IBEditorWindowLastContentRect - 200.IBPluginDependency - 200.ImportedFromIB2 - 200.editorWindowContentRectSynchronizationRect - 201.IBPluginDependency - 201.ImportedFromIB2 - 202.IBPluginDependency - 202.ImportedFromIB2 - 203.IBPluginDependency - 203.ImportedFromIB2 - 204.IBPluginDependency - 204.ImportedFromIB2 - 205.IBEditorWindowLastContentRect - 205.IBPluginDependency - 205.ImportedFromIB2 - 205.editorWindowContentRectSynchronizationRect - 206.IBPluginDependency - 206.ImportedFromIB2 - 207.IBPluginDependency - 207.ImportedFromIB2 - 208.IBPluginDependency - 208.ImportedFromIB2 - 209.IBPluginDependency - 209.ImportedFromIB2 - 210.IBPluginDependency - 210.ImportedFromIB2 - 211.IBPluginDependency - 211.ImportedFromIB2 - 212.IBPluginDependency - 212.ImportedFromIB2 - 212.editorWindowContentRectSynchronizationRect - 213.IBPluginDependency - 213.ImportedFromIB2 - 214.IBPluginDependency - 214.ImportedFromIB2 - 215.IBPluginDependency - 215.ImportedFromIB2 - 216.IBPluginDependency - 216.ImportedFromIB2 - 217.IBPluginDependency - 217.ImportedFromIB2 - 218.IBPluginDependency - 218.ImportedFromIB2 - 219.IBPluginDependency - 219.ImportedFromIB2 - 220.IBEditorWindowLastContentRect - 220.IBPluginDependency - 220.ImportedFromIB2 - 220.editorWindowContentRectSynchronizationRect - 221.IBPluginDependency - 221.ImportedFromIB2 23.IBPluginDependency 23.ImportedFromIB2 - 236.IBPluginDependency - 236.ImportedFromIB2 239.IBPluginDependency 239.ImportedFromIB2 24.IBEditorWindowLastContentRect @@ -3138,155 +526,25 @@ 29.ImportedFromIB2 29.WindowOrigin 29.editorWindowContentRectSynchronizationRect - 295.IBPluginDependency - 296.IBEditorWindowLastContentRect - 296.IBPluginDependency - 296.editorWindowContentRectSynchronizationRect - 297.IBPluginDependency - 298.IBPluginDependency - 346.IBPluginDependency - 346.ImportedFromIB2 - 348.IBPluginDependency - 348.ImportedFromIB2 - 349.IBEditorWindowLastContentRect - 349.IBPluginDependency - 349.ImportedFromIB2 - 349.editorWindowContentRectSynchronizationRect - 350.IBPluginDependency - 350.ImportedFromIB2 - 351.IBPluginDependency - 351.ImportedFromIB2 - 354.IBPluginDependency - 354.ImportedFromIB2 - 375.IBPluginDependency - 376.IBEditorWindowLastContentRect - 376.IBPluginDependency - 377.IBPluginDependency - 388.IBEditorWindowLastContentRect - 388.IBPluginDependency - 389.IBPluginDependency - 390.IBPluginDependency - 391.IBPluginDependency - 392.IBPluginDependency - 393.IBPluginDependency - 394.IBPluginDependency - 395.IBPluginDependency - 396.IBPluginDependency - 397.IBPluginDependency - 398.IBPluginDependency - 399.IBPluginDependency - 400.IBPluginDependency - 401.IBPluginDependency - 402.IBPluginDependency - 403.IBPluginDependency - 404.IBPluginDependency - 405.IBPluginDependency - 406.IBPluginDependency - 407.IBPluginDependency - 408.IBPluginDependency - 409.IBPluginDependency - 410.IBPluginDependency - 411.IBPluginDependency - 412.IBPluginDependency - 413.IBPluginDependency - 414.IBPluginDependency - 415.IBPluginDependency - 416.IBPluginDependency - 417.IBPluginDependency - 418.IBPluginDependency - 419.IBPluginDependency - 450.IBPluginDependency - 451.IBEditorWindowLastContentRect - 451.IBPluginDependency - 452.IBPluginDependency - 453.IBPluginDependency - 454.IBPluginDependency - 457.IBPluginDependency - 459.IBPluginDependency - 460.IBPluginDependency - 462.IBPluginDependency - 465.IBPluginDependency - 466.IBPluginDependency - 485.IBPluginDependency 490.IBPluginDependency 491.IBEditorWindowLastContentRect 491.IBPluginDependency 492.IBPluginDependency - 496.IBPluginDependency - 497.IBEditorWindowLastContentRect - 497.IBPluginDependency - 498.IBPluginDependency - 499.IBPluginDependency 5.IBPluginDependency 5.ImportedFromIB2 - 500.IBPluginDependency - 501.IBPluginDependency - 502.IBPluginDependency - 503.IBPluginDependency - 504.IBPluginDependency - 505.IBPluginDependency - 506.IBPluginDependency - 507.IBPluginDependency - 508.IBEditorWindowLastContentRect - 508.IBPluginDependency - 509.IBPluginDependency - 510.IBPluginDependency - 511.IBPluginDependency - 512.IBPluginDependency - 513.IBPluginDependency - 514.IBPluginDependency - 515.IBPluginDependency - 516.IBPluginDependency - 517.IBPluginDependency 56.IBPluginDependency 56.ImportedFromIB2 57.IBEditorWindowLastContentRect 57.IBPluginDependency 57.ImportedFromIB2 57.editorWindowContentRectSynchronizationRect - 58.IBPluginDependency - 58.ImportedFromIB2 - 72.IBPluginDependency - 72.ImportedFromIB2 - 73.IBPluginDependency - 73.ImportedFromIB2 - 74.IBPluginDependency - 74.ImportedFromIB2 - 75.IBPluginDependency - 75.ImportedFromIB2 - 77.IBPluginDependency - 77.ImportedFromIB2 - 78.IBPluginDependency - 78.ImportedFromIB2 - 79.IBPluginDependency - 79.ImportedFromIB2 - 80.IBPluginDependency - 80.ImportedFromIB2 - 81.IBEditorWindowLastContentRect - 81.IBPluginDependency - 81.ImportedFromIB2 - 81.editorWindowContentRectSynchronizationRect - 82.IBPluginDependency - 82.ImportedFromIB2 - 83.IBPluginDependency - 83.ImportedFromIB2 92.IBPluginDependency 92.ImportedFromIB2 YES com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{522, 812}, {146, 23}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - + {{581, 686}, {64, 6}} com.apple.InterfaceBuilder.CocoaPlugin {{436, 809}, {64, 6}} @@ -3310,214 +568,29 @@ com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{753, 187}, {275, 113}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{608, 612}, {275, 83}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{453, 408}, {254, 283}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{187, 434}, {243, 243}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{608, 612}, {167, 43}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{753, 217}, {238, 103}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{608, 612}, {241, 103}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{613, 618}, {194, 73}} + {{470, 649}, {194, 73}} com.apple.InterfaceBuilder.CocoaPlugin {{525, 802}, {197, 73}} - {{346, 722}, {402, 20}} + {{346, 722}, {256, 20}} com.apple.InterfaceBuilder.CocoaPlugin {74, 862} {{6, 978}, {478, 20}} com.apple.InterfaceBuilder.CocoaPlugin - {{563, 648}, {231, 43}} - com.apple.InterfaceBuilder.CocoaPlugin - {{475, 832}, {234, 43}} + {{541, 699}, {194, 23}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{746, 287}, {220, 133}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{608, 612}, {215, 63}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - {{497, 648}, {83, 43}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{580, 408}, {175, 283}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{753, 197}, {170, 63}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{684, 668}, {142, 23}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{674, 260}, {204, 183}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{878, 180}, {164, 173}} - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{355, 508}, {183, 183}} + {{358, 599}, {213, 123}} com.apple.InterfaceBuilder.CocoaPlugin {{23, 794}, {245, 183}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{411, 488}, {196, 203}} - com.apple.InterfaceBuilder.CocoaPlugin - - {{145, 474}, {199, 203}} - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - @@ -3595,83 +668,6 @@ AppKit.framework/Headers/NSUserInterfaceItemSearching.h - - NSBrowser - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSBrowser.h - - - - NSControl - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSControl.h - - - - NSDocument - NSObject - - YES - - YES - printDocument: - revertDocumentToSaved: - runPageLayout: - saveDocument: - saveDocumentAs: - saveDocumentTo: - - - YES - id - id - id - id - id - id - - - - IBFrameworkSource - AppKit.framework/Headers/NSDocument.h - - - - NSDocument - - IBFrameworkSource - AppKit.framework/Headers/NSDocumentScripting.h - - - - NSDocumentController - NSObject - - YES - - YES - clearRecentDocuments: - newDocument: - openDocument: - saveAllDocuments: - - - YES - id - id - id - id - - - - IBFrameworkSource - AppKit.framework/Headers/NSDocumentController.h - - NSFontManager NSObject @@ -3680,22 +676,6 @@ AppKit.framework/Headers/NSFontManager.h - - NSFormatter - NSObject - - IBFrameworkSource - Foundation.framework/Headers/NSFormatter.h - - - - NSMatrix - NSControl - - IBFrameworkSource - AppKit.framework/Headers/NSMatrix.h - - NSMenu NSObject @@ -3712,14 +692,6 @@ AppKit.framework/Headers/NSMenuItem.h - - NSMovieView - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSMovieView.h - - NSObject @@ -3741,7 +713,10 @@ NSObject - + + IBFrameworkSource + AppKit.framework/Headers/NSControl.h + NSObject @@ -3809,7 +784,7 @@ NSObject - + IBFrameworkSource AppKit.framework/Headers/NSTableView.h @@ -3976,27 +951,6 @@ AppKit.framework/Headers/NSResponder.h - - NSTableView - NSControl - - - - NSText - NSView - - IBFrameworkSource - AppKit.framework/Headers/NSText.h - - - - NSTextView - NSText - - IBFrameworkSource - AppKit.framework/Headers/NSTextView.h - - NSView @@ -4072,4 +1026,3 @@ - diff --git a/SparkleShare/Mac/SparkleShare/MainMenu.xib.designer.cs b/SparkleShare/Mac/SparkleShare/MainMenu.xib.designer.cs index 93a0d735..01952cd1 100644 --- a/SparkleShare/Mac/SparkleShare/MainMenu.xib.designer.cs +++ b/SparkleShare/Mac/SparkleShare/MainMenu.xib.designer.cs @@ -10,4 +10,9 @@ namespace SparkleShare { + + // Should subclass MonoMac.AppKit.NSResponder + [MonoMac.Foundation.Register("AppDelegate")] + public partial class AppDelegate { + } } diff --git a/SparkleShare/Mac/SparkleShare/SparkleShare.csproj b/SparkleShare/Mac/SparkleShare/SparkleShare.csproj index 3780b5b2..71fcd61c 100644 --- a/SparkleShare/Mac/SparkleShare/SparkleShare.csproj +++ b/SparkleShare/Mac/SparkleShare/SparkleShare.csproj @@ -50,6 +50,7 @@ MainMenu.xib + @@ -62,6 +63,7 @@ + diff --git a/SparkleShare/Mac/SparkleShare/sparkleshare.icns b/SparkleShare/Mac/SparkleShare/sparkleshare.icns new file mode 100644 index 0000000000000000000000000000000000000000..c55016677490078cb1558d7412637ff82861f2cc GIT binary patch literal 143098 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 G{r~{NC%D7_ literal 0 HcmV?d00001 From 46a46a1e05a40c3bbfe81373e693a78e1998e175 Mon Sep 17 00:00:00 2001 From: Hylke Bons Date: Fri, 17 Dec 2010 18:06:57 +0100 Subject: [PATCH 06/19] [osx] Implement a proper SparkleLog class --- SparkleShare/Mac/SparkleShare/Main.cs | 94 ++--- SparkleShare/Mac/SparkleShare/SparkleLog.cs | 123 ++++++ .../Mac/SparkleShare/SparkleShare.csproj | 8 + SparkleShare/Mac/SparkleShare/idle-active.png | Bin 0 -> 732 bytes SparkleShare/Mac/SparkleShare/idle.png | Bin 0 -> 797 bytes SparkleShare/Mac/SparkleShare/idle0.png | Bin 0 -> 803 bytes SparkleShare/Mac/SparkleShare/idle1.png | Bin 0 -> 822 bytes SparkleShare/Mac/SparkleShare/idle2.png | Bin 0 -> 818 bytes SparkleShare/Mac/SparkleShare/idle3.png | Bin 0 -> 831 bytes SparkleShare/Mac/SparkleShare/idle4.png | Bin 0 -> 826 bytes data/sparkleshare-gnome.svg | 360 ++++++++++++++++-- 11 files changed, 491 insertions(+), 94 deletions(-) create mode 100644 SparkleShare/Mac/SparkleShare/SparkleLog.cs create mode 100644 SparkleShare/Mac/SparkleShare/idle-active.png create mode 100644 SparkleShare/Mac/SparkleShare/idle.png create mode 100644 SparkleShare/Mac/SparkleShare/idle0.png create mode 100644 SparkleShare/Mac/SparkleShare/idle1.png create mode 100644 SparkleShare/Mac/SparkleShare/idle2.png create mode 100644 SparkleShare/Mac/SparkleShare/idle3.png create mode 100644 SparkleShare/Mac/SparkleShare/idle4.png diff --git a/SparkleShare/Mac/SparkleShare/Main.cs b/SparkleShare/Mac/SparkleShare/Main.cs index c97dd14c..2a7fb72f 100644 --- a/SparkleShare/Mac/SparkleShare/Main.cs +++ b/SparkleShare/Mac/SparkleShare/Main.cs @@ -35,6 +35,8 @@ namespace SparkleShare NSMenuItem NotificationsMenuItem; NSMenuItem AboutMenuItem; NSMenuItem QuitMenuItem; + + SparkleLog Log; NSWindow window; @@ -77,10 +79,10 @@ tile.Display (); StatusItem = NSStatusBar.SystemStatusBar.CreateStatusItem (28); StatusItem.Enabled = true; - StatusItem.Image = NSImage.ImageNamed ("sparkleshare-idle.png"); - StatusItem.AlternateImage = NSImage.ImageNamed ("sparkleshare-idle-focus.png"); - StatusItem.Image.Size = new SizeF (13, 13); - StatusItem.AlternateImage.Size = new SizeF (13, 13); + StatusItem.Image = NSImage.ImageNamed ("idle.png"); + StatusItem.AlternateImage = NSImage.ImageNamed ("idle-active.png"); + StatusItem.Image.Size = new SizeF (16 , 16); + StatusItem.AlternateImage.Size = new SizeF (16, 16); StatusItem.HighlightMode = true; Menu = new NSMenu (); @@ -91,7 +93,7 @@ tile.Display (); Timer timer = new Timer () { - Interval = 500 + Interval = 60 }; @@ -104,13 +106,19 @@ tile.Display (); timer.Elapsed += delegate { FolderMenuItem.InvokeOnMainThread (delegate { + + StatusItem.Image = NSImage.ImageNamed ("idle" + i + ".png"); + StatusItem.Image.Size = new SizeF (16 , 16); - if (i == 0){ - StatusItem.Image = NSImage.ImageNamed ("sparkleshare-idle-focus.png"); - i = 1; + StatusItem.AlternateImage = NSImage.ImageNamed ("idle" + i + ".png"); + StatusItem.AlternateImage.Size = new SizeF (16 , 16); + + if (i < 4){ + i++; }else{ - StatusItem.Image = NSImage.ImageNamed ("sparkleshare-idle.png"); - i = 0; + + // StatusItem.Image = NSImage.ImageNamed ("sparkleshare-idle.png"); + i = 0; } /*FolderMenuItem.Title+="Z";Menu.Update ();*/}); @@ -121,7 +129,7 @@ tile.Display (); Console.WriteLine ("DDDD"); }; - FolderMenuItem.Image = NSImage.ImageNamed ("NSFolder"); + FolderMenuItem.Image = NSImage.ImageNamed ("sparkleshare.icns"); FolderMenuItem.Image.Size = new SizeF (16, 16); Menu.AddItem (FolderMenuItem); @@ -133,73 +141,15 @@ tile.Display (); foreach (NSMenuItem item in FolderMenuItems) { - item.Activated += delegate { - - - - - button = new NSButton (new RectangleF (16, 12, 120, 31)) { - Title = "Open Folder", - BezelStyle = NSBezelStyle.Rounded - - }; - - button2 = new NSButton (new RectangleF (480 - 120 - 16, 12, 120, 31)) { - Title = "Close", - BezelStyle = NSBezelStyle.Rounded - - }; - - - bool minimizeBox = true; - bool maximizeBox = false; -NSWindowStyle style = (NSWindowStyle)(1 | (1 << 1) | (minimizeBox ? 4 : 1) | (maximizeBox ? 8 : 1)); - - -window = new NSWindow (new RectangleF (0, 0, 480, 640), - style, 0, false); - - - - - web_view = new WebView (new RectangleF (0, 12 + 31 + 16, 480, 640 - (12 + 31 + 16)), "", ""); - web_view.MainFrameUrl = "http://www.google.nl/"; - - - window.ContentView.AddSubview (button); - window.ContentView.AddSubview (button2); - window.ContentView.AddSubview (web_view); - - window.MaxSize = new SizeF (480, 640); - window.MinSize = new SizeF (480, 640); - - window.Title = "Recent Events in 'gnome-design'"; - - window.HasShadow = true; - //window.DefaultButtonCell = button2.Cell; - window.BackingType = NSBackingStore.Buffered; - - - NSApplication.SharedApplication.ActivateIgnoringOtherApps (true); - - window.MakeKeyAndOrderFront (this); - window.Center (); - - - - - - }; + item.Image = NSImage.ImageNamed ("NSFolder"); + item.Image.Size = new SizeF (16, 16); Menu.AddItem (item); }; - - - - + Log = new SparkleLog ("bla"); Menu.AddItem (NSMenuItem.SeparatorItem); diff --git a/SparkleShare/Mac/SparkleShare/SparkleLog.cs b/SparkleShare/Mac/SparkleShare/SparkleLog.cs new file mode 100644 index 00000000..30ae9fde --- /dev/null +++ b/SparkleShare/Mac/SparkleShare/SparkleLog.cs @@ -0,0 +1,123 @@ +// SparkleShare, an instant update workflow to Git. +// Copyright (C) 2010 Hylke Bons +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + + +using System; +using System.Drawing; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using MonoMac.Foundation; +using MonoMac.AppKit; +using MonoMac.ObjCRuntime; +using MonoMac.WebKit; + +namespace SparkleShare { + + public class SparkleLog : NSWindow { + + public readonly string LocalPath; + + private WebView WebView; + private NSButton CloseButton; + private NSButton OpenFolderButton; + + + public SparkleLog (string path) : base () + { + + LocalPath = path; + + + bool minimizeBox = true; + bool maximizeBox = false; + + + SetFrame (new RectangleF (0, 0, 480, 640), true); + + StyleMask = (NSWindowStyle)(1 | (1 << 1) | (minimizeBox ? 4 : 1) | (maximizeBox ? 8 : 1)); + MaxSize = new SizeF (480, 640); + MinSize = new SizeF (480, 640); + HasShadow = true; + BackingType = NSBackingStore.Buffered; + + Center (); + + ContentView.AddSubview (CreateEventLog ()); + + OpenFolderButton = new NSButton (new RectangleF (16, 12, 120, 31)) { + Title = "Open Folder", + BezelStyle = NSBezelStyle.Rounded + }; + + OpenFolderButton.Activated += delegate { + // SparkleShare.Controller.OpenSparkleShareFolder (LocalPath); + }; + + ContentView.AddSubview (OpenFolderButton); + + + CloseButton = new NSButton (new RectangleF (480 - 120 - 16, 12, 120, 31)) { + Title = "Close", + BezelStyle = NSBezelStyle.Rounded + }; + + CloseButton.Activated += delegate { + Close (); + }; + + ContentView.AddSubview (CloseButton); + + + string name = System.IO.Path.GetFileName (LocalPath); + Title = String.Format ("Recent Events in ‘{0}’", name); + + NSApplication.SharedApplication.ActivateIgnoringOtherApps (true); + MakeKeyAndOrderFront (this); + + } + + + new public void Close () + { + + InvokeOnMainThread (delegate { + base.Close (); + }); + + } + + + public void UpdateEventLog () + { + + } + + + private WebView CreateEventLog () + { + + RectangleF frame = new RectangleF (0, 12 + 31 + 16, 480, 640 - (12 + 31 + 16)); + + WebView = new WebView (frame, "", ""); + WebView.MainFrameUrl = "http://www.google.nl/"; + + return WebView; + + } + + } + +} diff --git a/SparkleShare/Mac/SparkleShare/SparkleShare.csproj b/SparkleShare/Mac/SparkleShare/SparkleShare.csproj index 71fcd61c..f577a283 100644 --- a/SparkleShare/Mac/SparkleShare/SparkleShare.csproj +++ b/SparkleShare/Mac/SparkleShare/SparkleShare.csproj @@ -51,6 +51,7 @@ MainMenu.xib
+ @@ -64,6 +65,13 @@ + + + + + + + diff --git a/SparkleShare/Mac/SparkleShare/idle-active.png b/SparkleShare/Mac/SparkleShare/idle-active.png new file mode 100644 index 0000000000000000000000000000000000000000..ca826a08abe07c13e2ebddada751e408728e4de4 GIT binary patch literal 732 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4sBf%ipdZ&9wTFR$vDnka zF~p*G>Ew<2&VeGw>etVk=EC0Dq2MvkfMa&cQTYUenMd!mMyi-?Q{z$l?>yZrVy%gy zm{QP^iwoXfn6&MErCsy#xLe-^_C0x`cHj2ena`}C_Da+w2Gw9Hce z6~2Drk;CUS0*yUb%UCwd=4Y0fx8J~0A~i|j+gn|q{XMgr4&Qku`}CD`ANOwWy;o#5 zZkVf_CUwMGNoFmt;ibpY-Ak_f-_PUTwo5qNOKwWY%3Zwnr$fU}HctWy?9#naw>tjg zpS%Z3@z<|Zg+;$iYQF6yZn|~eRo8v@K85+rvXOh=ZIoQ9)OmTg)g|{sJy%aw#BWJu zoA`{0VWm&&o5_c3jE)1**TueC!HN%VOQ?O|DfxNx=t~Q8*7nD}i44=ee~Q?vdzW$E u#4Y!2+T#yR-O{h(ed(q=*BsAH_ZWY;w6yDoC>a1Fm%-E3&t;ucLK6Uz$s>CJ literal 0 HcmV?d00001 diff --git a/SparkleShare/Mac/SparkleShare/idle.png b/SparkleShare/Mac/SparkleShare/idle.png new file mode 100644 index 0000000000000000000000000000000000000000..ebb7f00b39736a15ceebe9eb9f7cdbff76959694 GIT binary patch literal 797 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4sBf%ipdZ&9wTFR$af_#m zV~9oX(n-GFA%!CC^FMztQ!QO{#=yL`hUiOzd**RIE1xO%fQHPR-grX}~bP3>Ct}S~0u6AGb zy-arRhF{t%wPe$+BVwyh9($&C^_4$ET<-p~v|n7`yIiH@&P(*pIk7rK2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4sBf%ipdZ&9wTFR$ahIoy zV~9oX(n)8%LlQ-f)xZBLHk~u-jEhko59{qE+gs1&-DRy?Qt?t-!tZ@au7u=YLvVDVdEt*LG8bi-pmdOZ)v z{BxDG2n!cgoas@ZCFJ;eevSy2NOyb<>zgQP--{Z?=jRtGi5%LNtM=YckgvUR(&-?* z=|A`F_fN~2Gk0!&J5yKliq*4ak1JaL?f7}rW@!*-!_QXNHn!lNluI+b=8A57qL9h3 zt=rWt|L(I_30+sFHr@|5zjS@amD}D`C3EiX-D|J2;+EIL!|vCvT^AHQw{7dft;Zw| z@181Zm!DTyEYu_kqi5#yS_+>#D1_as!y>lmBP&7J$- TFhLiXMi@L@{an^LB{Ts5_fST? literal 0 HcmV?d00001 diff --git a/SparkleShare/Mac/SparkleShare/idle1.png b/SparkleShare/Mac/SparkleShare/idle1.png new file mode 100644 index 0000000000000000000000000000000000000000..863cc299952fbf7e762b7583e6a8a8618942f6dc GIT binary patch literal 822 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4sBf%ipdZ&9wTFR$@vNtd zV~9oX(n;Rg!igen^Yf)tJcRbBNJy`2+%ol&S>UXcX?=QLi=<;a%$fc%9rRXQ!Qmx( zWWGX}i{`6Cu`iuO*5(zhT#yicwO3kv=8}Vb4^EsZRMb5AWYfpkd8a?`eg806>CpcZ z>=RC<=_|dm+pu=+_t+^C^G`p`Z)T8USoF;HG{a%9E3dY!Th7inrDMXW7xhtjHbMtp zZjSyPqWSji)+-+!Xv=y>XZ9R zw}-3?+gKMFz0I|yH*K)o=1D{ve^)Ji3v$wXJonPFd z?2(G;QsS!B^471sG~Hdqu3kCg p;}qhga~H$$fH%sQPh8<=buJYD@<);T3K0RRwySiArL literal 0 HcmV?d00001 diff --git a/SparkleShare/Mac/SparkleShare/idle2.png b/SparkleShare/Mac/SparkleShare/idle2.png new file mode 100644 index 0000000000000000000000000000000000000000..7b8cdcfc30b2ca8f35d66e8c825731a8884ff240 GIT binary patch literal 818 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4sBf%ipdZ&9wTFR$@ua7V zV~9oX(#ifFlM5w|+n;}ZIw{%YM&iUq*|hE3%*G$dsWM9~=Cc@%6tE{u>U8#W8 z8d;XTCA_Lj>|IKvE(dX$HofJ&bm)@FTIUCgynVl1S5*6a_ch-y+kf+(|E`?(p4mRo zYoq*21~;2JS=Gz~p@GqXi-fMdc{4qVftNv*+058suSTV~(b){$292c#NzdFWrDuz5 z*xCI({o&g)iRzd87>UXRnPKp^`A|xf?S5?{{{PxKjygb#_*nxfAN8*kBai;D^EWPdLLR6 zs~*2$4r5YvWW4^T%EF1ugxUDr+|&&+(Xm)gmF6@FSX6=qAP zS5__++MxO{qvm*ehWFfKZ_6Hk{%LXhqT|6$KelW*aAWatKl2~T4>SIlKiC@X(y~06 zpOb~@%a{1ahwtnWe&Bw0;V2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4sBf%ipdZ&9wTFR$@tUWL zV~9oX(#iX?gA+yC=Iifto79nPGS%mL-mH+K`YB2##}rs&dzM{tJ*aRi>ax;5&O9p( zrLaOlNA``O0@==&S&l9gZFigA6|+!qw}pjA{*`BSe6uFqyL07W`R^a+e$V+XW8vg= z^1lb8hlCrW<~oMPY5Ql17=^}0Y%pW~!7$;`rqetZRF_ojzHYMhEQ6Dmr;~ZT>E#_N zjc)AkuOBu49H@V}jZO9d!|jEZP3=twAK2e$5!$6`%jn!}88_WqMoxl3LF%sOyNGE8 z7H{;XdI5FsN_JBcj1%eZ5qGnk@XG!Aq?|yJoZHWCetyZzF#o#5>8(=Py=*@>KaW@w zCb_$Ub9Y?&x}Z$&2g17R*ETYUyR}Km+xmaKTRkm%{?7jo6lXSPdObB-y}HcW;onUY zhPHKvB}o&cx2vt#Q?oVhYsD+hm;XfCjb@rPbY!<3j`y$-dF1oYU?RbBVrFJ8ZW`o0jU2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4sBf%ipdZ&9wTFR$@uH`T zV~9oX(#fZ@g##sy)|d0>9rJV-U!=<-y4tr@?ZTOq3CAWa^60+Zq|xzU@eZwNzoJCA zZq4n_5`8OO@-Qf5MSYWrr|WC4+$?duxvosU;uFt3U!>x*+&89T+jr~z)%%Kfdb#|N zZ)JFNGR1z;J7(+J^!+ZLzp~AKZ={pM2X8kZ&?J#iWB6*H#JVczv|Z`-m=m*~DvZ-4hEWQJ-kz2^GlYv119-^N~< qu?O~L=?T{D*8BhCm8Jj5t^3QKO#h~sASwn-It-q!elF{r5}E*;Ax}*J literal 0 HcmV?d00001 diff --git a/data/sparkleshare-gnome.svg b/data/sparkleshare-gnome.svg index 820af8c3..a7d050e3 100644 --- a/data/sparkleshare-gnome.svg +++ b/data/sparkleshare-gnome.svg @@ -16,7 +16,7 @@ inkscape:export-xdpi="90.000000" inkscape:export-ydpi="90.000000" inkscape:output_extension="org.inkscape.output.svg.inkscape" - inkscape:version="0.47 r22583" + inkscape:version="0.48.0 r9654" sodipodi:docname="sparkleshare-gnome.svg" sodipodi:version="0.32" style="display:inline;enable-background:new" @@ -30,9 +30,9 @@ guidetolerance="10000" height="300px" id="base" - inkscape:current-layer="layer18" - inkscape:cx="452.99246" - inkscape:cy="152.00765" + inkscape:current-layer="layer20" + inkscape:cx="363.28616" + inkscape:cy="119.67008" inkscape:document-units="px" inkscape:grid-bbox="true" inkscape:pageopacity="0.0" @@ -40,9 +40,9 @@ inkscape:showpageshadow="false" inkscape:snap-bbox="true" inkscape:snap-nodes="false" - inkscape:window-height="805" - inkscape:window-width="1332" - inkscape:window-x="412" + inkscape:window-height="778" + inkscape:window-width="1280" + inkscape:window-x="0" inkscape:window-y="0" inkscape:zoom="1" objecttolerance="10000" @@ -2561,6 +2561,46 @@ inkscape:label="small sizes" id="layer20" inkscape:groupmode="layer"> + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Date: Fri, 17 Dec 2010 20:18:22 +0100 Subject: [PATCH 07/19] [osx] Implement a proper SparkleStatusIcon class --- SparkleShare/Mac/SparkleShare/Main.cs | 152 +------- SparkleShare/Mac/SparkleShare/SparkleLog.cs | 18 +- .../Mac/SparkleShare/SparkleShare.csproj | 1 + .../Mac/SparkleShare/SparkleStatusIcon.cs | 361 ++++++++++++++++++ 4 files changed, 375 insertions(+), 157 deletions(-) create mode 100644 SparkleShare/Mac/SparkleShare/SparkleStatusIcon.cs diff --git a/SparkleShare/Mac/SparkleShare/Main.cs b/SparkleShare/Mac/SparkleShare/Main.cs index 2a7fb72f..74b271e6 100644 --- a/SparkleShare/Mac/SparkleShare/Main.cs +++ b/SparkleShare/Mac/SparkleShare/Main.cs @@ -38,13 +38,7 @@ namespace SparkleShare SparkleLog Log; - - NSWindow window; - NSButton button; - NSButton button2; - - WebView web_view; - NSDockTile tile; + int i = 0; @@ -60,11 +54,13 @@ namespace SparkleShare } - + SparkleStatusIcon StatusIcon; public override void FinishedLaunching (NSObject notification) { + StatusIcon = new SparkleStatusIcon (); + /* tile = NSApplication.SharedApplication.DockTile; tile.BadgeLabel = "!"; tile.Display (); @@ -76,148 +72,10 @@ tile.Display (); // SparkleRepo repo = new SparkleRepo ("/Users/hbons/SparkleShare/SparkleShare-Test"); - StatusItem = NSStatusBar.SystemStatusBar.CreateStatusItem (28); + //StatusItem = NSStatusBar.SystemStatusBar.CreateStatusItem (28); - StatusItem.Enabled = true; - StatusItem.Image = NSImage.ImageNamed ("idle.png"); - StatusItem.AlternateImage = NSImage.ImageNamed ("idle-active.png"); - StatusItem.Image.Size = new SizeF (16 , 16); - StatusItem.AlternateImage.Size = new SizeF (16, 16); - StatusItem.HighlightMode = true; - Menu = new NSMenu (); - - - Menu.AddItem (new NSMenuItem () { Title="Up to date (102 ᴍʙ)", Enabled = true }); - Menu.AddItem (NSMenuItem.SeparatorItem); - - - Timer timer = new Timer () { - Interval = 60 - }; - - - FolderMenuItem = new NSMenuItem () { - Title="SparkleShare", Enabled = true, - Action = new Selector ("ddd") - }; - - - timer.Elapsed += delegate { - FolderMenuItem.InvokeOnMainThread (delegate { - - StatusItem.Image = NSImage.ImageNamed ("idle" + i + ".png"); - StatusItem.Image.Size = new SizeF (16 , 16); - - StatusItem.AlternateImage = NSImage.ImageNamed ("idle" + i + ".png"); - StatusItem.AlternateImage.Size = new SizeF (16 , 16); - - if (i < 4){ - i++; - }else{ - - // StatusItem.Image = NSImage.ImageNamed ("sparkleshare-idle.png"); - i = 0; - } - - /*FolderMenuItem.Title+="Z";Menu.Update ();*/}); - }; - - timer.Start (); - FolderMenuItem.Activated += delegate { - Console.WriteLine ("DDDD"); - }; - - FolderMenuItem.Image = NSImage.ImageNamed ("sparkleshare.icns"); - FolderMenuItem.Image.Size = new SizeF (16, 16); - - Menu.AddItem (FolderMenuItem); - - FolderMenuItems = new NSMenuItem [2] { - new NSMenuItem () { Title = "gnome-design (2)" }, - new NSMenuItem () { Title = "tango-icons" } - }; - - foreach (NSMenuItem item in FolderMenuItems) { - - - - item.Image = NSImage.ImageNamed ("NSFolder"); - item.Image.Size = new SizeF (16, 16); - Menu.AddItem (item); - }; - - - Log = new SparkleLog ("bla"); - - Menu.AddItem (NSMenuItem.SeparatorItem); - - - SyncMenuItem = new NSMenuItem () { - Title = "Add Remote Folder..." - }; - - SyncMenuItem.Activated += delegate { - - }; - - Menu.AddItem (SyncMenuItem); - - - Menu.AddItem (NSMenuItem.SeparatorItem); - - - NotificationsMenuItem = new NSMenuItem () { - Title = "Show Notifications", - State = NSCellStateValue.On - }; - - NotificationsMenuItem.Activated += delegate { - - //StatusItem.Image = NSImage.ImageNamed ("NSComputer"); - if (NotificationsMenuItem.State == NSCellStateValue.On) - - NotificationsMenuItem.State = NSCellStateValue.Off; - - else - - NotificationsMenuItem.State = NSCellStateValue.On; - - }; - - Menu.AddItem (NotificationsMenuItem); - - - Menu.AddItem (NSMenuItem.SeparatorItem); - - - AboutMenuItem = new NSMenuItem () { - Title = "About" - }; - - AboutMenuItem.Activated += delegate { - - }; - - Menu.AddItem (AboutMenuItem); - - - // Menu.AddItem (NSMenuItem.SeparatorItem); - - - QuitMenuItem = new NSMenuItem () { - Title = "Quit" - }; - - QuitMenuItem.Activated += delegate { - Environment.Exit (0); - }; - - //Menu.AddItem (QuitMenuItem); - - StatusItem.Menu = Menu; - NSApplication.SharedApplication.ActivateIgnoringOtherApps (true); diff --git a/SparkleShare/Mac/SparkleShare/SparkleLog.cs b/SparkleShare/Mac/SparkleShare/SparkleLog.cs index 30ae9fde..ce433148 100644 --- a/SparkleShare/Mac/SparkleShare/SparkleLog.cs +++ b/SparkleShare/Mac/SparkleShare/SparkleLog.cs @@ -17,8 +17,6 @@ using System; using System.Drawing; -using System.Collections.Generic; -using System.Text.RegularExpressions; using MonoMac.Foundation; using MonoMac.AppKit; using MonoMac.ObjCRuntime; @@ -39,22 +37,22 @@ namespace SparkleShare { { LocalPath = path; - - - bool minimizeBox = true; - bool maximizeBox = false; SetFrame (new RectangleF (0, 0, 480, 640), true); - StyleMask = (NSWindowStyle)(1 | (1 << 1) | (minimizeBox ? 4 : 1) | (maximizeBox ? 8 : 1)); + Center (); + + StyleMask = (NSWindowStyle.Closable | + NSWindowStyle.Miniaturizable | + NSWindowStyle.Titled); + MaxSize = new SizeF (480, 640); MinSize = new SizeF (480, 640); HasShadow = true; BackingType = NSBackingStore.Buffered; - - Center (); - + + ContentView.AddSubview (CreateEventLog ()); OpenFolderButton = new NSButton (new RectangleF (16, 12, 120, 31)) { diff --git a/SparkleShare/Mac/SparkleShare/SparkleShare.csproj b/SparkleShare/Mac/SparkleShare/SparkleShare.csproj index f577a283..f39ee51d 100644 --- a/SparkleShare/Mac/SparkleShare/SparkleShare.csproj +++ b/SparkleShare/Mac/SparkleShare/SparkleShare.csproj @@ -52,6 +52,7 @@ + diff --git a/SparkleShare/Mac/SparkleShare/SparkleStatusIcon.cs b/SparkleShare/Mac/SparkleShare/SparkleStatusIcon.cs new file mode 100644 index 00000000..2843f96c --- /dev/null +++ b/SparkleShare/Mac/SparkleShare/SparkleStatusIcon.cs @@ -0,0 +1,361 @@ +// SparkleShare, an instant update workflow to Git. +// Copyright (C) 2010 Hylke Bons +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; +using System.Drawing; +using System.Timers; +using MonoMac.Foundation; +using MonoMac.AppKit; +using MonoMac.ObjCRuntime; + +namespace SparkleShare { + + // The statusicon that stays in the + // user's notification area + public class SparkleStatusIcon : NSObject { + + private Timer Animation; + private int FrameNumber; + private string StateText; + + private NSStatusItem StatusItem; + private NSMenu Menu; + private NSMenuItem StateMenuItem; + private NSMenuItem FolderMenuItem; + private NSMenuItem [] FolderMenuItems; + private NSMenuItem SyncMenuItem; + private NSMenuItem NotificationsMenuItem; + private NSMenuItem AboutMenuItem; + private NSMenuItem QuitMenuItem; + + + public string _ (string s) + { + return s; + } + + + public SparkleStatusIcon () : base () + { + + Animation = CreateAnimation (); + + StatusItem = NSStatusBar.SystemStatusBar.CreateStatusItem (28); + + SetNormalState (); + CreateMenu (); + +/* SparkleShare.Controller.FolderSizeChanged += delegate { + Application.Invoke (delegate { + UpdateMenu (); + }); + }; + + SparkleShare.Controller.FolderListChanged += delegate { + Application.Invoke (delegate { + SetNormalState (); + CreateMenu (); + }); + }; + + SparkleShare.Controller.OnIdle += delegate { + Application.Invoke (delegate { + SetNormalState (); + UpdateMenu (); + }); + }; + + SparkleShare.Controller.OnSyncing += delegate { + Application.Invoke (delegate { + SetAnimationState (); + UpdateMenu (); + }); + }; + + SparkleShare.Controller.OnError += delegate { + Application.Invoke (delegate { + SetNormalState (true); + UpdateMenu (); + }); + }; +*/ + } + + + // Creates the Animation that handles the syncing animation + private Timer CreateAnimation () + { + + FrameNumber = 0; + + Timer Animation = new Timer () { + Interval = 35 + }; + + Animation.Elapsed += delegate { + + if (FrameNumber < 4) + FrameNumber++; + else + FrameNumber = 0; + + InvokeOnMainThread (delegate { + + StatusItem.AlternateImage = NSImage.ImageNamed ("idle" + FrameNumber + ".png"); + StatusItem.AlternateImage.Size = new SizeF (16, 16); + + StatusItem.Image = NSImage.ImageNamed ("idle" + FrameNumber + ".png"); + StatusItem.Image.Size = new SizeF (16, 16); + + }); + + }; + + 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 (); + }; + + FolderMenuItem.Image = NSImage.ImageNamed ("sparkleshare.icns"); + FolderMenuItem.Image.Size = new SizeF (16, 16); + + Menu.AddItem (FolderMenuItem); + + + FolderMenuItems = new NSMenuItem [2] { + new NSMenuItem () { Title = "gnome-design" }, + new NSMenuItem () { Title = "tango-icons" } + }; + + +// if (SparkleShare.Controller.Folders.Count > 0) { + + +// foreach (string path in SparkleShare.Controller.Folders) { + + foreach (NSMenuItem item in FolderMenuItems) { + +// if (repo.HasUnsyncedChanges) +// folder_action.IconName = "dialog-error"; + + item.Image = NSImage.ImageNamed ("NSFolder"); + item.Image.Size = new SizeF (16, 16); + + item.Activated += delegate { + + }; + + item.Activated += OpenEventLogDelegate (item.Title); + + Menu.AddItem (item); + + }; + + // } else { + + // TODO: No Remote Folders Yet + + // } + + Menu.AddItem (NSMenuItem.SeparatorItem); + + + SyncMenuItem = new NSMenuItem () { + Title = "Add Remote Folder..." + }; + +// if (SparkleShare.Controller.FirstRun) +// SyncMenuItem.Enabled = false; + + SyncMenuItem.Activated += delegate { + // TODO + }; + + Menu.AddItem (SyncMenuItem); + + + Menu.AddItem (NSMenuItem.SeparatorItem); + + + NotificationsMenuItem = new NSMenuItem () { + Title = "Show Notifications", + State = NSCellStateValue.On + }; + +// if (SparkleShare.Controller.NotificationsEnabled) +// NotificationsMenuItem.State = NSCellStateValue.On; +// else +// NotificationsMenuItem.State = NSCellStateValue.On; + NotificationsMenuItem.Activated += delegate { +// SparkleShare.Controller.ToggleNotifications (); + }; + + Menu.AddItem (NotificationsMenuItem); + + + Menu.AddItem (NSMenuItem.SeparatorItem); + + + AboutMenuItem = new NSMenuItem () { + Title = "About" + }; + + AboutMenuItem.Activated += delegate { + // TODO + }; + + Menu.AddItem (AboutMenuItem); + + StatusItem.Menu = Menu; + + } + + + // A method reference that makes sure that opening the + // event log for each repository works correctly + private EventHandler OpenEventLogDelegate (string path) + { + + return delegate { + + SparkleLog log = null; //SparkleUI.OpenLogs.Find (delegate (SparkleLog l) { return l.LocalPath.Equals (path); }); + + // Check whether the log is already open, create a new one if + //that's not the case or present it to the user if it is + if (log == null) { + + log = new SparkleLog (path); + + /*log.Hidden += delegate { + + SparkleUI.OpenLogs.Remove (log); + log.Destroy (); + + }; + + SparkleUI.OpenLogs.Add (log);*/ + + } + + }; + + } + + + public void UpdateMenu () + { + + StateMenuItem.Title = StateText; + + } + + + // The state when there's nothing going on + private void SetNormalState () + { + + SetNormalState (false); + + } + + + // The state when there's nothing going on + private void SetNormalState (bool error) + { + + Animation.Stop (); + + if (false /* SparkleShare.Controller.Folders.Count == 0 */) { + + StateText = _("Welcome to SparkleShare!"); + InvokeOnMainThread (delegate { + + StatusItem.Image = NSImage.ImageNamed ("idle.png"); + StatusItem.Image.Size = new SizeF (16, 16); + + StatusItem.AlternateImage = NSImage.ImageNamed ("idle-active.png"); + StatusItem.AlternateImage.Size = new SizeF (16, 16); + + }); + + } else { + + if (error) { + + StateText = _("Not everything is synced"); + InvokeOnMainThread (delegate { + //Pixbuf = SparkleUIHelpers.GetIcon ("sparkleshare-syncing-error", 24); + }); + + } else { + + StateText = _("Up to date") + " ("/* + SparkleShare.Controller.FolderSize + ")" */; + InvokeOnMainThread (delegate { + + StatusItem.Image = NSImage.ImageNamed ("idle.png"); + StatusItem.Image.Size = new SizeF (16, 16); + + StatusItem.AlternateImage = NSImage.ImageNamed ("idle-active.png"); + StatusItem.AlternateImage.Size = new SizeF (16, 16); + + }); + + } + + } + + } + + + // The state when animating + private void SetAnimationState () + { + + StateText = _("Syncing…"); + + if (!Animation.Enabled) + Animation.Start (); + + } + + } + +} + + From 5a7c1f11291851a8143e16c60fe6fac4f6456b91 Mon Sep 17 00:00:00 2001 From: Hylke Bons Date: Fri, 17 Dec 2010 20:23:59 +0100 Subject: [PATCH 08/19] [osx, statusicon] Highlight icon when selected --- SparkleShare/Mac/SparkleShare/SparkleStatusIcon.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/SparkleShare/Mac/SparkleShare/SparkleStatusIcon.cs b/SparkleShare/Mac/SparkleShare/SparkleStatusIcon.cs index 2843f96c..f3b0bd1d 100644 --- a/SparkleShare/Mac/SparkleShare/SparkleStatusIcon.cs +++ b/SparkleShare/Mac/SparkleShare/SparkleStatusIcon.cs @@ -54,10 +54,14 @@ namespace SparkleShare { Animation = CreateAnimation (); StatusItem = NSStatusBar.SystemStatusBar.CreateStatusItem (28); + StatusItem.HighlightMode = true; + SetNormalState (); CreateMenu (); + + /* SparkleShare.Controller.FolderSizeChanged += delegate { Application.Invoke (delegate { UpdateMenu (); From 6a8ca90271c35d2522fbc8d87eff8186d72c102b Mon Sep 17 00:00:00 2001 From: Hylke Bons Date: Sat, 18 Dec 2010 00:14:51 +0100 Subject: [PATCH 09/19] Update README for [osx] --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index f74683d6..642f1184 100644 --- a/README +++ b/README @@ -94,7 +94,7 @@ Build on OSX: Get the Mono Framework, Monodevelop, and MacPorts. Install git-core, automake and intltool using 'port install'. - +Make sure that git or a symbolic link to git is in /usr/bin. Frequently Asked Question ========================= From cd60a858259314ffca44fe4563c0a24cfdf34441 Mon Sep 17 00:00:00 2001 From: Hylke Bons Date: Sat, 18 Dec 2010 01:01:00 +0100 Subject: [PATCH 10/19] Add proper OS detection --- SparkleShare/SparkleShare.cs | 49 +++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/SparkleShare/SparkleShare.cs b/SparkleShare/SparkleShare.cs index e2579056..d5e7fc9b 100644 --- a/SparkleShare/SparkleShare.cs +++ b/SparkleShare/SparkleShare.cs @@ -25,6 +25,7 @@ using SparkleLib; using SparkleLib.Options; using System.Text; + namespace SparkleShare { // This is SparkleShare! @@ -83,16 +84,16 @@ namespace SparkleShare { if (show_help) ShowHelp (p); - - switch (Environment.OSVersion.Platform) { + + switch (SparkleShare.Platform ()) { case PlatformID.Unix: SetProcessName ("sparkleshare"); - Controller = new SparkleLinController (); + //Controller = new SparkleLinController (); break; case PlatformID.MacOSX: - //Controller = new SparkleMacController (); + Controller = new SparkleMacController (); break; case PlatformID.Win32NT: @@ -148,6 +149,11 @@ namespace SparkleShare { } + + // Strange magic needed by SetProcessName () + [DllImport ("libc")] + private static extern int prctl (int option, byte [] arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5); + // Sets the Unix process name to 'sparkleshare' instead of 'mono' private static void SetProcessName (string name) @@ -169,12 +175,37 @@ namespace SparkleShare { } } - - - // Strange magic needed by SetProcessName - [DllImport ("libc")] - private static extern int prctl (int option, byte [] arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5); + + // Strange magic needed by Platform () + [DllImport ("libc")] + static extern int uname (IntPtr buf); + + + static PlatformID Platform () { + + IntPtr buf = IntPtr.Zero; + + try { + + buf = Marshal.AllocHGlobal (8192); + + if (uname (buf) == 0 && Marshal.PtrToStringAnsi (buf) == "Darwin") + return PlatformID.MacOSX; + + } catch { + + } finally { + + if (buf != IntPtr.Zero) + Marshal.FreeHGlobal (buf); + + } + + return Environment.OSVersion.Platform; + + } + } } From 5ae4ba3638a2ecbdb6aed53649b2feb8ac60952c Mon Sep 17 00:00:00 2001 From: Hylke Bons Date: Sat, 18 Dec 2010 01:01:43 +0100 Subject: [PATCH 11/19] [osx] Hook things up --- SparkleLib/SparklePaths.cs | 2 +- SparkleShare/Mac/SparkleShare/Info.plist | 2 + SparkleShare/Mac/SparkleShare/Main.cs | 100 ++++++------------ .../{ => Pixmaps}/idle-active.png | Bin .../Mac/SparkleShare/{ => Pixmaps}/idle.png | Bin .../Mac/SparkleShare/{ => Pixmaps}/idle0.png | Bin .../Mac/SparkleShare/{ => Pixmaps}/idle1.png | Bin .../Mac/SparkleShare/{ => Pixmaps}/idle2.png | Bin .../Mac/SparkleShare/{ => Pixmaps}/idle3.png | Bin .../Mac/SparkleShare/{ => Pixmaps}/idle4.png | Bin .../{ => Pixmaps}/sparkleshare-idle-focus.png | Bin .../{ => Pixmaps}/sparkleshare-idle.png | Bin .../{ => Pixmaps}/sparkleshare.icns | Bin .../Mac/SparkleShare/SparkleMacController.cs | 75 +++++++++++++ .../Mac/SparkleShare/SparkleShare.csproj | 33 ++++-- .../Mac/SparkleShare/SparkleStatusIcon.cs | 9 +- 16 files changed, 140 insertions(+), 81 deletions(-) rename SparkleShare/Mac/SparkleShare/{ => Pixmaps}/idle-active.png (100%) rename SparkleShare/Mac/SparkleShare/{ => Pixmaps}/idle.png (100%) rename SparkleShare/Mac/SparkleShare/{ => Pixmaps}/idle0.png (100%) rename SparkleShare/Mac/SparkleShare/{ => Pixmaps}/idle1.png (100%) rename SparkleShare/Mac/SparkleShare/{ => Pixmaps}/idle2.png (100%) rename SparkleShare/Mac/SparkleShare/{ => Pixmaps}/idle3.png (100%) rename SparkleShare/Mac/SparkleShare/{ => Pixmaps}/idle4.png (100%) rename SparkleShare/Mac/SparkleShare/{ => Pixmaps}/sparkleshare-idle-focus.png (100%) rename SparkleShare/Mac/SparkleShare/{ => Pixmaps}/sparkleshare-idle.png (100%) rename SparkleShare/Mac/SparkleShare/{ => Pixmaps}/sparkleshare.icns (100%) create mode 100644 SparkleShare/Mac/SparkleShare/SparkleMacController.cs diff --git a/SparkleLib/SparklePaths.cs b/SparkleLib/SparklePaths.cs index 45ed4ff0..138379f6 100644 --- a/SparkleLib/SparklePaths.cs +++ b/SparkleLib/SparklePaths.cs @@ -24,7 +24,7 @@ namespace SparkleLib { public static class SparklePaths { - public static string GitPath = GetGitPath (); + public static string GitPath = "/usr/bin/git"; // TODO: Don't hardcode this public static string HomePath = new UnixUserInfo (UnixEnvironment.UserName).HomeDirectory; diff --git a/SparkleShare/Mac/SparkleShare/Info.plist b/SparkleShare/Mac/SparkleShare/Info.plist index 553e5dec..4431992a 100644 --- a/SparkleShare/Mac/SparkleShare/Info.plist +++ b/SparkleShare/Mac/SparkleShare/Info.plist @@ -2,6 +2,8 @@ + CFBundleIconFile + sparkleshare.icns LSEnvironment PATH diff --git a/SparkleShare/Mac/SparkleShare/Main.cs b/SparkleShare/Mac/SparkleShare/Main.cs index 74b271e6..caaee850 100644 --- a/SparkleShare/Mac/SparkleShare/Main.cs +++ b/SparkleShare/Mac/SparkleShare/Main.cs @@ -1,3 +1,20 @@ +// SparkleShare, an instant update workflow to Git. +// Copyright (C) 2010 Hylke Bons +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + + using System; using System.Drawing; using System.Timers; @@ -5,88 +22,39 @@ using MonoMac.Foundation; using MonoMac.AppKit; using MonoMac.ObjCRuntime; using MonoMac.WebKit; -using MonoMac.Growl; -namespace SparkleShare -{ - class MainClass - { - static void Main (string[] args) - { - NSApplication.Init (); - NSApplication.SharedApplication.ActivateIgnoringOtherApps (true); - NSApplication.SharedApplication.applicationIconImage = NSImage.ImageNamed ("sparkleshare.icns"); - NSApplication.Main (args); - } +namespace SparkleShare { + + public partial class AppDelegate : NSApplicationDelegate { + // Workaround to be able to work with SparkleUI as the main class } - - - public partial class AppDelegate : NSApplicationDelegate + + public class SparkleUI : AppDelegate { - //MainWindowController mainWindowController; - NSStatusItem StatusItem; - - NSMenu Menu; - NSMenuItem FolderMenuItem; - NSMenuItem [] FolderMenuItems; - NSMenuItem SyncMenuItem; - NSMenuItem NotificationsMenuItem; - NSMenuItem AboutMenuItem; - NSMenuItem QuitMenuItem; - - SparkleLog Log; - - - int i = 0; + public SparkleStatusIcon StatusIcon; - /* public override NSMenu ApplicationDockMenu (NSApplication app) + public SparkleUI () { + + NSApplication.Init (); + //NSApplication.SharedApplication.ActivateIgnoringOtherApps (true); + //NSApplication.SharedApplication.applicationIconImage = NSImage.ImageNamed ("sparkleshare.icns"); - return (NSMenu) Menu; - - } - */ - public AppDelegate () - { + //StatusIcon = new SparkleStatusIcon (); + } - - SparkleStatusIcon StatusIcon; - - public override void FinishedLaunching (NSObject notification) + + public void Run () { - StatusIcon = new SparkleStatusIcon (); - - /* tile = NSApplication.SharedApplication.DockTile; - tile.BadgeLabel = "!"; -tile.Display (); - */ - // mainWindowController = new MainWindowController (); - // mainWindowController.Window.MakeKeyAndOrderFront (this); - - // SparkleStatusIcon = new SparkleStatusIcon (); - - // SparkleRepo repo = new SparkleRepo ("/Users/hbons/SparkleShare/SparkleShare-Test"); - - //StatusItem = NSStatusBar.SystemStatusBar.CreateStatusItem (28); - - - - - - NSApplication.SharedApplication.ActivateIgnoringOtherApps (true); - + NSApplication.Main (new string [0]); } - - - } } - diff --git a/SparkleShare/Mac/SparkleShare/idle-active.png b/SparkleShare/Mac/SparkleShare/Pixmaps/idle-active.png similarity index 100% rename from SparkleShare/Mac/SparkleShare/idle-active.png rename to SparkleShare/Mac/SparkleShare/Pixmaps/idle-active.png diff --git a/SparkleShare/Mac/SparkleShare/idle.png b/SparkleShare/Mac/SparkleShare/Pixmaps/idle.png similarity index 100% rename from SparkleShare/Mac/SparkleShare/idle.png rename to SparkleShare/Mac/SparkleShare/Pixmaps/idle.png diff --git a/SparkleShare/Mac/SparkleShare/idle0.png b/SparkleShare/Mac/SparkleShare/Pixmaps/idle0.png similarity index 100% rename from SparkleShare/Mac/SparkleShare/idle0.png rename to SparkleShare/Mac/SparkleShare/Pixmaps/idle0.png diff --git a/SparkleShare/Mac/SparkleShare/idle1.png b/SparkleShare/Mac/SparkleShare/Pixmaps/idle1.png similarity index 100% rename from SparkleShare/Mac/SparkleShare/idle1.png rename to SparkleShare/Mac/SparkleShare/Pixmaps/idle1.png diff --git a/SparkleShare/Mac/SparkleShare/idle2.png b/SparkleShare/Mac/SparkleShare/Pixmaps/idle2.png similarity index 100% rename from SparkleShare/Mac/SparkleShare/idle2.png rename to SparkleShare/Mac/SparkleShare/Pixmaps/idle2.png diff --git a/SparkleShare/Mac/SparkleShare/idle3.png b/SparkleShare/Mac/SparkleShare/Pixmaps/idle3.png similarity index 100% rename from SparkleShare/Mac/SparkleShare/idle3.png rename to SparkleShare/Mac/SparkleShare/Pixmaps/idle3.png diff --git a/SparkleShare/Mac/SparkleShare/idle4.png b/SparkleShare/Mac/SparkleShare/Pixmaps/idle4.png similarity index 100% rename from SparkleShare/Mac/SparkleShare/idle4.png rename to SparkleShare/Mac/SparkleShare/Pixmaps/idle4.png diff --git a/SparkleShare/Mac/SparkleShare/sparkleshare-idle-focus.png b/SparkleShare/Mac/SparkleShare/Pixmaps/sparkleshare-idle-focus.png similarity index 100% rename from SparkleShare/Mac/SparkleShare/sparkleshare-idle-focus.png rename to SparkleShare/Mac/SparkleShare/Pixmaps/sparkleshare-idle-focus.png diff --git a/SparkleShare/Mac/SparkleShare/sparkleshare-idle.png b/SparkleShare/Mac/SparkleShare/Pixmaps/sparkleshare-idle.png similarity index 100% rename from SparkleShare/Mac/SparkleShare/sparkleshare-idle.png rename to SparkleShare/Mac/SparkleShare/Pixmaps/sparkleshare-idle.png diff --git a/SparkleShare/Mac/SparkleShare/sparkleshare.icns b/SparkleShare/Mac/SparkleShare/Pixmaps/sparkleshare.icns similarity index 100% rename from SparkleShare/Mac/SparkleShare/sparkleshare.icns rename to SparkleShare/Mac/SparkleShare/Pixmaps/sparkleshare.icns diff --git a/SparkleShare/Mac/SparkleShare/SparkleMacController.cs b/SparkleShare/Mac/SparkleShare/SparkleMacController.cs new file mode 100644 index 00000000..e954479c --- /dev/null +++ b/SparkleShare/Mac/SparkleShare/SparkleMacController.cs @@ -0,0 +1,75 @@ +// SparkleShare, an instant update workflow to Git. +// Copyright (C) 2010 Hylke Bons +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + + +using System; +using System.Diagnostics; +using System.IO; + +namespace SparkleShare { + + public class SparkleMacController : SparkleController { + + // Creates a .desktop entry in autostart folder to + // start SparkleShare automatically at login + public override void EnableSystemAutostart () + { + + + + } + + + // Installs a launcher so the user can launch SparkleShare + // from the Internet category if needed + public override void InstallLauncher () + { + + + + } + + + // Adds the SparkleShare folder to the user's + // list of bookmarked places + public override void AddToBookmarks () + { + + + + } + + + // Creates the SparkleShare folder in the user's home folder + public override bool CreateSparkleShareFolder () + { + + return true; + + } + + + // Opens the SparkleShare folder or an (optional) subfolder + public override void OpenSparkleShareFolder (string subfolder) + { + + + + } + + } + +} \ No newline at end of file diff --git a/SparkleShare/Mac/SparkleShare/SparkleShare.csproj b/SparkleShare/Mac/SparkleShare/SparkleShare.csproj index f39ee51d..85062258 100644 --- a/SparkleShare/Mac/SparkleShare/SparkleShare.csproj +++ b/SparkleShare/Mac/SparkleShare/SparkleShare.csproj @@ -44,6 +44,7 @@ False + @@ -53,6 +54,13 @@ + + SparkleShare.cs + + + SparkleController.cs + + @@ -63,16 +71,15 @@ - - - - - - - - - - + + + + + + + + + @@ -80,4 +87,10 @@ SparkleLib + + + + + + \ No newline at end of file diff --git a/SparkleShare/Mac/SparkleShare/SparkleStatusIcon.cs b/SparkleShare/Mac/SparkleShare/SparkleStatusIcon.cs index f3b0bd1d..f3d30f8e 100644 --- a/SparkleShare/Mac/SparkleShare/SparkleStatusIcon.cs +++ b/SparkleShare/Mac/SparkleShare/SparkleStatusIcon.cs @@ -20,6 +20,7 @@ using System.Timers; using MonoMac.Foundation; using MonoMac.AppKit; using MonoMac.ObjCRuntime; +using Mono.Unix; namespace SparkleShare { @@ -39,12 +40,12 @@ namespace SparkleShare { private NSMenuItem SyncMenuItem; private NSMenuItem NotificationsMenuItem; private NSMenuItem AboutMenuItem; - private NSMenuItem QuitMenuItem; - public string _ (string s) + // Short alias for the translations + public static string _ (string s) { - return s; + return Catalog.GetString (s); } @@ -57,7 +58,7 @@ namespace SparkleShare { StatusItem.HighlightMode = true; - SetNormalState (); + SetAnimationState (); CreateMenu (); From 388149706758d7914c68fcef0949f903187eb552 Mon Sep 17 00:00:00 2001 From: Hylke Bons Date: Sat, 18 Dec 2010 01:24:15 +0100 Subject: [PATCH 12/19] Cleanup platform detection some more --- SparkleShare/SparkleShare.cs | 50 ++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/SparkleShare/SparkleShare.cs b/SparkleShare/SparkleShare.cs index d5e7fc9b..9bf5bce5 100644 --- a/SparkleShare/SparkleShare.cs +++ b/SparkleShare/SparkleShare.cs @@ -85,7 +85,7 @@ namespace SparkleShare { ShowHelp (p); - switch (SparkleShare.Platform ()) { + switch (SparkleShare.Platform) { case PlatformID.Unix: SetProcessName ("sparkleshare"); @@ -180,30 +180,36 @@ namespace SparkleShare { // Strange magic needed by Platform () [DllImport ("libc")] static extern int uname (IntPtr buf); - - - static PlatformID Platform () { - - IntPtr buf = IntPtr.Zero; - - try { - - buf = Marshal.AllocHGlobal (8192); - - if (uname (buf) == 0 && Marshal.PtrToStringAnsi (buf) == "Darwin") - return PlatformID.MacOSX; - - } catch { - - } finally { - - if (buf != IntPtr.Zero) - Marshal.FreeHGlobal (buf); + + // This fixes the PlatformID enumeration for MacOSX in Environment.OSVersion.Platform, + // which is intentionally broken in Mono for hystorical reasons + static PlatformID Platform { + + get { + + IntPtr buf = IntPtr.Zero; + + try { + + buf = Marshal.AllocHGlobal (8192); + + if (uname (buf) == 0 && Marshal.PtrToStringAnsi (buf) == "Darwin") + return PlatformID.MacOSX; + + } catch { + + } finally { + + if (buf != IntPtr.Zero) + Marshal.FreeHGlobal (buf); + + } + + return Environment.OSVersion.Platform; + } - return Environment.OSVersion.Platform; - } } From 81b28a1e560e3be5694780d71ac5589131990e8b Mon Sep 17 00:00:00 2001 From: Hylke Bons Date: Sat, 18 Dec 2010 18:01:09 +0100 Subject: [PATCH 13/19] [controller] Fix folders not being removed --- SparkleShare/SparkleController.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/SparkleShare/SparkleController.cs b/SparkleShare/SparkleController.cs index eb6d00f4..571bfe4b 100644 --- a/SparkleShare/SparkleController.cs +++ b/SparkleShare/SparkleController.cs @@ -106,8 +106,7 @@ namespace SparkleShare { // Remove the repository when a delete event occurs watcher.Deleted += delegate (object o, FileSystemEventArgs args) { - if (Directory.Exists (args.FullPath)) - RemoveRepository (args.FullPath); + RemoveRepository (args.FullPath); }; From c75ac74764c80d60eccb7343f42bd7c53126ba71 Mon Sep 17 00:00:00 2001 From: Hylke Bons Date: Sat, 18 Dec 2010 21:37:50 +0100 Subject: [PATCH 14/19] More work on [osx] --- SparkleShare/Mac/SparkleShare/AppDelegate.cs | 0 SparkleShare/Mac/SparkleShare/Main.cs | 60 ------- SparkleShare/Mac/SparkleShare/MainWindow.cs | 35 ---- .../SparkleShare/MainWindow.xib.designer.cs | 23 --- .../Mac/SparkleShare/MainWindowController.cs | 46 ----- SparkleShare/Mac/SparkleShare/SparkleLog.cs | 18 +- .../Mac/SparkleShare/SparkleMacController.cs | 8 +- .../Mac/SparkleShare/SparkleShare.csproj | 6 +- .../Mac/SparkleShare/SparkleStatusIcon.cs | 128 ++++++------- SparkleShare/Mac/SparkleShare/SparkleUI.cs | 169 ++++-------------- .../Mac/SparkleShare/SparkleWindow.cs | 73 ++++++++ 11 files changed, 192 insertions(+), 374 deletions(-) delete mode 100644 SparkleShare/Mac/SparkleShare/AppDelegate.cs delete mode 100644 SparkleShare/Mac/SparkleShare/Main.cs delete mode 100644 SparkleShare/Mac/SparkleShare/MainWindow.cs delete mode 100644 SparkleShare/Mac/SparkleShare/MainWindow.xib.designer.cs delete mode 100644 SparkleShare/Mac/SparkleShare/MainWindowController.cs create mode 100644 SparkleShare/Mac/SparkleShare/SparkleWindow.cs diff --git a/SparkleShare/Mac/SparkleShare/AppDelegate.cs b/SparkleShare/Mac/SparkleShare/AppDelegate.cs deleted file mode 100644 index e69de29b..00000000 diff --git a/SparkleShare/Mac/SparkleShare/Main.cs b/SparkleShare/Mac/SparkleShare/Main.cs deleted file mode 100644 index caaee850..00000000 --- a/SparkleShare/Mac/SparkleShare/Main.cs +++ /dev/null @@ -1,60 +0,0 @@ -// SparkleShare, an instant update workflow to Git. -// Copyright (C) 2010 Hylke Bons -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - - -using System; -using System.Drawing; -using System.Timers; -using MonoMac.Foundation; -using MonoMac.AppKit; -using MonoMac.ObjCRuntime; -using MonoMac.WebKit; - -namespace SparkleShare { - - public partial class AppDelegate : NSApplicationDelegate { - // Workaround to be able to work with SparkleUI as the main class - } - - - public class SparkleUI : AppDelegate - { - - public SparkleStatusIcon StatusIcon; - - - public SparkleUI () - { - - NSApplication.Init (); - //NSApplication.SharedApplication.ActivateIgnoringOtherApps (true); - //NSApplication.SharedApplication.applicationIconImage = NSImage.ImageNamed ("sparkleshare.icns"); - - //StatusIcon = new SparkleStatusIcon (); - - } - - - public void Run () - { - - NSApplication.Main (new string [0]); - - } - - } - -} diff --git a/SparkleShare/Mac/SparkleShare/MainWindow.cs b/SparkleShare/Mac/SparkleShare/MainWindow.cs deleted file mode 100644 index 2cbe2ae5..00000000 --- a/SparkleShare/Mac/SparkleShare/MainWindow.cs +++ /dev/null @@ -1,35 +0,0 @@ - -using System; -using System.Collections.Generic; -using System.Linq; -using MonoMac.Foundation; -using MonoMac.AppKit; - -namespace SparkleShare -{ - public partial class MainWindow : MonoMac.AppKit.NSWindow - { - #region Constructors - - // Called when created from unmanaged code - public MainWindow (IntPtr handle) : base(handle) - { - Initialize (); - } - - // Called when created directly from a XIB file - [Export("initWithCoder:")] - public MainWindow (NSCoder coder) : base(coder) - { - Initialize (); - } - - // Shared initialization code - void Initialize () - { - } - - #endregion - } -} - diff --git a/SparkleShare/Mac/SparkleShare/MainWindow.xib.designer.cs b/SparkleShare/Mac/SparkleShare/MainWindow.xib.designer.cs deleted file mode 100644 index 2be04caa..00000000 --- a/SparkleShare/Mac/SparkleShare/MainWindow.xib.designer.cs +++ /dev/null @@ -1,23 +0,0 @@ -// ------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Mono Runtime Version: 2.0.50727.1433 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -// ------------------------------------------------------------------------------ - -namespace SparkleShare { - - - // Should subclass MonoMac.AppKit.NSWindow - [MonoMac.Foundation.Register("MainWindow")] - public partial class MainWindow { - } - - // Should subclass MonoMac.AppKit.NSWindowController - [MonoMac.Foundation.Register("MainWindowController")] - public partial class MainWindowController { - } -} diff --git a/SparkleShare/Mac/SparkleShare/MainWindowController.cs b/SparkleShare/Mac/SparkleShare/MainWindowController.cs deleted file mode 100644 index 22f30d23..00000000 --- a/SparkleShare/Mac/SparkleShare/MainWindowController.cs +++ /dev/null @@ -1,46 +0,0 @@ - -using System; -using System.Collections.Generic; -using System.Linq; -using MonoMac.Foundation; -using MonoMac.AppKit; - -namespace SparkleShare -{ - public partial class MainWindowController : MonoMac.AppKit.NSWindowController - { - #region Constructors - - // Called when created from unmanaged code - public MainWindowController (IntPtr handle) : base(handle) - { - Initialize (); - } - - // Called when created directly from a XIB file - [Export("initWithCoder:")] - public MainWindowController (NSCoder coder) : base(coder) - { - Initialize (); - } - - // Call to load from the XIB/NIB file - public MainWindowController () : base("MainWindow") - { - Initialize (); - } - - // Shared initialization code - void Initialize () - { - } - - #endregion - - //strongly typed window accessor - public new MainWindow Window { - get { return (MainWindow)base.Window; } - } - } -} - diff --git a/SparkleShare/Mac/SparkleShare/SparkleLog.cs b/SparkleShare/Mac/SparkleShare/SparkleLog.cs index ce433148..e666792a 100644 --- a/SparkleShare/Mac/SparkleShare/SparkleLog.cs +++ b/SparkleShare/Mac/SparkleShare/SparkleLog.cs @@ -61,7 +61,7 @@ namespace SparkleShare { }; OpenFolderButton.Activated += delegate { - // SparkleShare.Controller.OpenSparkleShareFolder (LocalPath); + SparkleShare.Controller.OpenSparkleShareFolder (LocalPath); }; ContentView.AddSubview (OpenFolderButton); @@ -73,7 +73,7 @@ namespace SparkleShare { }; CloseButton.Activated += delegate { - Close (); + PerformClose (this); }; ContentView.AddSubview (CloseButton); @@ -87,14 +87,16 @@ namespace SparkleShare { } - - new public void Close () + + public override void PerformClose (NSObject sender) { - - InvokeOnMainThread (delegate { - base.Close (); + + InvokeOnMainThread (delegate { + Console.WriteLine ("!!!!!!!!!!"); + SparkleUI.OpenLogs.Remove ((SparkleLog) this); + base.PerformClose (this); }); - + } diff --git a/SparkleShare/Mac/SparkleShare/SparkleMacController.cs b/SparkleShare/Mac/SparkleShare/SparkleMacController.cs index e954479c..7cdf0df7 100644 --- a/SparkleShare/Mac/SparkleShare/SparkleMacController.cs +++ b/SparkleShare/Mac/SparkleShare/SparkleMacController.cs @@ -15,6 +15,7 @@ // along with this program. If not, see . +using SparkleLib; using System; using System.Diagnostics; using System.IO; @@ -66,7 +67,12 @@ namespace SparkleShare { public override void OpenSparkleShareFolder (string subfolder) { - + string folder = Path.Combine (SparklePaths.SparklePath, subfolder); + + Process process = new Process (); + process.StartInfo.Arguments = folder.Replace (" ", "\\ "); // Escape space-characters + process.StartInfo.FileName = "open"; + process.Start (); } diff --git a/SparkleShare/Mac/SparkleShare/SparkleShare.csproj b/SparkleShare/Mac/SparkleShare/SparkleShare.csproj index 85062258..bc6e4845 100644 --- a/SparkleShare/Mac/SparkleShare/SparkleShare.csproj +++ b/SparkleShare/Mac/SparkleShare/SparkleShare.csproj @@ -47,7 +47,6 @@ - MainMenu.xib @@ -61,6 +60,8 @@ SparkleController.cs + + @@ -80,6 +81,9 @@ + + Pixmaps\side-splash.png + diff --git a/SparkleShare/Mac/SparkleShare/SparkleStatusIcon.cs b/SparkleShare/Mac/SparkleShare/SparkleStatusIcon.cs index f3d30f8e..a279f94f 100644 --- a/SparkleShare/Mac/SparkleShare/SparkleStatusIcon.cs +++ b/SparkleShare/Mac/SparkleShare/SparkleStatusIcon.cs @@ -58,45 +58,45 @@ namespace SparkleShare { StatusItem.HighlightMode = true; - SetAnimationState (); + SetNormalState (); CreateMenu (); -/* SparkleShare.Controller.FolderSizeChanged += delegate { - Application.Invoke (delegate { + SparkleShare.Controller.FolderSizeChanged += delegate { + InvokeOnMainThread (delegate { UpdateMenu (); }); }; SparkleShare.Controller.FolderListChanged += delegate { - Application.Invoke (delegate { + InvokeOnMainThread (delegate { SetNormalState (); CreateMenu (); }); }; SparkleShare.Controller.OnIdle += delegate { - Application.Invoke (delegate { + InvokeOnMainThread (delegate { SetNormalState (); UpdateMenu (); }); }; SparkleShare.Controller.OnSyncing += delegate { - Application.Invoke (delegate { + InvokeOnMainThread (delegate { SetAnimationState (); UpdateMenu (); }); }; SparkleShare.Controller.OnError += delegate { - Application.Invoke (delegate { + InvokeOnMainThread (delegate { SetNormalState (true); UpdateMenu (); }); }; -*/ + } @@ -119,10 +119,10 @@ namespace SparkleShare { InvokeOnMainThread (delegate { - StatusItem.AlternateImage = NSImage.ImageNamed ("idle" + FrameNumber + ".png"); + StatusItem.AlternateImage = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/idle" + FrameNumber + ".png"); StatusItem.AlternateImage.Size = new SizeF (16, 16); - StatusItem.Image = NSImage.ImageNamed ("idle" + FrameNumber + ".png"); + StatusItem.Image = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/idle" + FrameNumber + ".png"); StatusItem.Image.Size = new SizeF (16, 16); }); @@ -138,7 +138,7 @@ namespace SparkleShare { // user clicks the status icon public void CreateMenu () { - + Menu = new NSMenu (); StateMenuItem = new NSMenuItem () { @@ -154,49 +154,49 @@ namespace SparkleShare { }; FolderMenuItem.Activated += delegate { - // SparkleShare.Controller.OpenSparkleShareFolder (); + SparkleShare.Controller.OpenSparkleShareFolder (); }; - FolderMenuItem.Image = NSImage.ImageNamed ("sparkleshare.icns"); + //FolderMenuItem.Image = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/sparkleshare.icns"); + FolderMenuItem.Image = NSImage.ImageNamed ("NSFolder"); FolderMenuItem.Image.Size = new SizeF (16, 16); Menu.AddItem (FolderMenuItem); - - FolderMenuItems = new NSMenuItem [2] { - new NSMenuItem () { Title = "gnome-design" }, - new NSMenuItem () { Title = "tango-icons" } - }; - - -// if (SparkleShare.Controller.Folders.Count > 0) { + if (SparkleShare.Controller.Folders.Count > 0) { -// foreach (string path in SparkleShare.Controller.Folders) { - - foreach (NSMenuItem item in FolderMenuItems) { + FolderMenuItems = new NSMenuItem [SparkleShare.Controller.Folders.Count]; + Tasks = new EventHandler [SparkleShare.Controller.Folders.Count]; + + int i = 0; + + foreach (string path in SparkleShare.Controller.Folders) { // if (repo.HasUnsyncedChanges) // folder_action.IconName = "dialog-error"; - + + NSMenuItem item = new NSMenuItem (); + + item.Title = System.IO.Path.GetFileName (path); item.Image = NSImage.ImageNamed ("NSFolder"); item.Image.Size = new SizeF (16, 16); + + Tasks [i] = OpenEventLogDelegate(item.Title); + + FolderMenuItems [i] = item; + FolderMenuItems [i].Activated += Tasks [i]; + Menu.AddItem (FolderMenuItems [i]); - item.Activated += delegate { - - }; - - item.Activated += OpenEventLogDelegate (item.Title); - - Menu.AddItem (item); + i++; }; - // } else { + } else { // TODO: No Remote Folders Yet - // } + } Menu.AddItem (NSMenuItem.SeparatorItem); @@ -205,11 +205,11 @@ namespace SparkleShare { Title = "Add Remote Folder..." }; -// if (SparkleShare.Controller.FirstRun) -// SyncMenuItem.Enabled = false; + if (SparkleShare.Controller.FirstRun) + SyncMenuItem.Enabled = false; SyncMenuItem.Activated += delegate { - // TODO + SparkleWindow w = new SparkleWindow (); }; Menu.AddItem (SyncMenuItem); @@ -219,16 +219,21 @@ namespace SparkleShare { NotificationsMenuItem = new NSMenuItem () { - Title = "Show Notifications", - State = NSCellStateValue.On + Title = "Show Notifications" }; -// if (SparkleShare.Controller.NotificationsEnabled) -// NotificationsMenuItem.State = NSCellStateValue.On; -// else -// NotificationsMenuItem.State = NSCellStateValue.On; + if (SparkleShare.Controller.NotificationsEnabled) + NotificationsMenuItem.State = NSCellStateValue.On; + NotificationsMenuItem.Activated += delegate { -// SparkleShare.Controller.ToggleNotifications (); + + SparkleShare.Controller.ToggleNotifications (); + + if (SparkleShare.Controller.NotificationsEnabled) + NotificationsMenuItem.State = NSCellStateValue.On; + else + NotificationsMenuItem.State = NSCellStateValue.Off; + }; Menu.AddItem (NotificationsMenuItem); @@ -248,33 +253,30 @@ namespace SparkleShare { Menu.AddItem (AboutMenuItem); StatusItem.Menu = Menu; + StatusItem.Menu.Update (); + Console.WriteLine ("MENU UPDATED"); } - + + public delegate void Task(); + EventHandler [] Tasks; + // A method reference that makes sure that opening the // event log for each repository works correctly private EventHandler OpenEventLogDelegate (string path) { + return delegate { - SparkleLog log = null; //SparkleUI.OpenLogs.Find (delegate (SparkleLog l) { return l.LocalPath.Equals (path); }); + SparkleLog log = SparkleUI.OpenLogs.Find (delegate (SparkleLog l) { return l.LocalPath.Equals (path); }); // Check whether the log is already open, create a new one if - //that's not the case or present it to the user if it is + // that's not the case or present it to the user if it is if (log == null) { - log = new SparkleLog (path); - - /*log.Hidden += delegate { - - SparkleUI.OpenLogs.Remove (log); - log.Destroy (); - - }; - - SparkleUI.OpenLogs.Add (log);*/ + SparkleUI.OpenLogs.Add (new SparkleLog (path)); } @@ -306,15 +308,15 @@ namespace SparkleShare { Animation.Stop (); - if (false /* SparkleShare.Controller.Folders.Count == 0 */) { + if (SparkleShare.Controller.Folders.Count == 0) { StateText = _("Welcome to SparkleShare!"); InvokeOnMainThread (delegate { - StatusItem.Image = NSImage.ImageNamed ("idle.png"); + StatusItem.Image = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/idle.png"); StatusItem.Image.Size = new SizeF (16, 16); - StatusItem.AlternateImage = NSImage.ImageNamed ("idle-active.png"); + StatusItem.AlternateImage = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/idle-active.png"); StatusItem.AlternateImage.Size = new SizeF (16, 16); }); @@ -330,13 +332,13 @@ namespace SparkleShare { } else { - StateText = _("Up to date") + " ("/* + SparkleShare.Controller.FolderSize + ")" */; + StateText = _("Up to date") + " (" + SparkleShare.Controller.FolderSize + ")"; InvokeOnMainThread (delegate { - StatusItem.Image = NSImage.ImageNamed ("idle.png"); + StatusItem.Image = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/idle.png"); StatusItem.Image.Size = new SizeF (16, 16); - StatusItem.AlternateImage = NSImage.ImageNamed ("idle-active.png"); + StatusItem.AlternateImage = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/idle-active.png"); StatusItem.AlternateImage.Size = new SizeF (16, 16); }); diff --git a/SparkleShare/Mac/SparkleShare/SparkleUI.cs b/SparkleShare/Mac/SparkleShare/SparkleUI.cs index 8ce3cf2f..598cee4c 100644 --- a/SparkleShare/Mac/SparkleShare/SparkleUI.cs +++ b/SparkleShare/Mac/SparkleShare/SparkleUI.cs @@ -8,164 +8,59 @@ // // 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using Gtk; -using Mono.Unix; -using Mono.Unix.Native; -using SparkleLib; + using System; using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading; +using System.Drawing; +using System.Timers; +using MonoMac.Foundation; +using MonoMac.AppKit; +using MonoMac.ObjCRuntime; +using MonoMac.WebKit; namespace SparkleShare { - public class SparkleUI { - + public partial class AppDelegate : NSApplicationDelegate { + // Workaround to be able to work with SparkleUI as the main class + } + + + public class SparkleUI : AppDelegate + { + public static SparkleStatusIcon StatusIcon; public static List OpenLogs; - - - // Short alias for the translations - public static string _(string s) - { - return Catalog.GetString (s); - } - - + + public SparkleUI () { - // Initialize the application - Application.Init (); - - // Create the statusicon + NSApplication.Init (); + NSApplication.SharedApplication.ActivateIgnoringOtherApps (true); + //NSApplication.SharedApplication.applicationIconImage = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/sparkeshare.icns"); + + OpenLogs = new List (); StatusIcon = new SparkleStatusIcon (); - // Keep track of which event logs are open - SparkleUI.OpenLogs = new List (); - - SparkleShare.Controller.OnFirstRun += delegate { - Application.Invoke (delegate { - - SparkleIntro intro = new SparkleIntro (); - intro.ShowAll (); - - }); - }; - - SparkleShare.Controller.OnInvitation += delegate (string invitation_file_path) { - Application.Invoke (delegate { - - SparkleInvitation invitation = new SparkleInvitation (invitation_file_path); - invitation.Present (); - - }); - }; - - // Show a bubble when there are new changes - SparkleShare.Controller.NotificationRaised += delegate (SparkleCommit commit, string repository_path) { - - string file_name = ""; - string message = null; - - if (commit.Added.Count > 0) { - - foreach (string added in commit.Added) { - file_name = added; - break; - } - - message = String.Format (_("added ‘{0}’"), file_name); - - } - - if (commit.Edited.Count > 0) { - - foreach (string modified in commit.Edited) { - file_name = modified; - break; - } - - message = String.Format (_("edited ‘{0}’"), file_name); - - } - - if (commit.Deleted.Count > 0) { - - foreach (string removed in commit.Deleted) { - file_name = removed; - break; - } - - message = String.Format (_("deleted ‘{0}’"), file_name); - - } - - int changes_count = (commit.Added.Count + - commit.Edited.Count + - commit.Deleted.Count); - - if (changes_count > 1) - message += " + " + (changes_count - 1); - - - Application.Invoke (delegate { - - SparkleBubble bubble = new SparkleBubble (commit.UserName, message); - - string avatar_file_path = SparkleUIHelpers.GetAvatar (commit.UserEmail, 32); - - if (avatar_file_path != null) - bubble.Icon = new Gdk.Pixbuf (avatar_file_path); - else - bubble.Icon = SparkleUIHelpers.GetIcon ("avatar-default", 32); - -// bubble.AddAction ("", "Show Events", delegate { - -// SparkleLog log = new SparkleLog (repository_path); -// log.ShowAll (); - -// }); - -// 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."); - - SparkleBubble bubble = new SparkleBubble(title, subtext); -// bubble.Show (); - - }); - }; + + } - - // Runs the application + public void Run () { - - Application.Run (); - + + NSApplication.Main (new string [0]); + } - + } - -} \ No newline at end of file + +} diff --git a/SparkleShare/Mac/SparkleShare/SparkleWindow.cs b/SparkleShare/Mac/SparkleShare/SparkleWindow.cs new file mode 100644 index 00000000..fb8ebb9c --- /dev/null +++ b/SparkleShare/Mac/SparkleShare/SparkleWindow.cs @@ -0,0 +1,73 @@ +// SparkleShare, an instant update workflow to Git. +// Copyright (C) 2010 Hylke Bons +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + + +using System; +using System.Drawing; +using MonoMac.Foundation; +using MonoMac.AppKit; +using MonoMac.ObjCRuntime; +using MonoMac.WebKit; + +namespace SparkleShare { + + public class SparkleWindow : NSWindow { + + public readonly string LocalPath; + + private WebView WebView; + private NSButton CloseButton; + private NSButton OpenFolderButton; + + private NSImage SideSplash; + + public SparkleWindow () : base () + { + + SetFrame (new RectangleF (0, 0, 640, 480), true); + + Center (); + + StyleMask = (NSWindowStyle.Closable | + NSWindowStyle.Miniaturizable | + NSWindowStyle.Titled); + + MaxSize = new SizeF (640, 480); + MinSize = new SizeF (640, 480); + HasShadow = true; + BackingType = NSBackingStore.Buffered; + + SideSplash = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/side-splash.png"); + SideSplash.Size = new SizeF (150, 480); + + + NSText tv = new NSText (new RectangleF (200, 200, 200, 200)) { + Value = "TEST" + }; + + ContentView.AddSubview (new NSImageView (new RectangleF (0, 0, 150, 480)) { Image = SideSplash}); + ContentView.AddSubview (new NSTextField (new RectangleF (200, 100, 128, 31)) { BezelStyle = NSTextFieldBezelStyle.Rounded}); + + + + NSApplication.SharedApplication.ActivateIgnoringOtherApps (true); + MakeKeyAndOrderFront (this); + + } + + } + +} From a2eece8cd4f1a903fc2cec7c62de27cd36c25a93 Mon Sep 17 00:00:00 2001 From: Hylke Bons Date: Tue, 21 Dec 2010 18:28:30 +0100 Subject: [PATCH 15/19] [osx] Implement elegant log window managing --- SparkleShare/Mac/SparkleShare/SparkleLog.cs | 36 ++++++++++--------- .../Mac/SparkleShare/SparkleShare.csproj | 4 +-- .../Mac/SparkleShare/SparkleStatusIcon.cs | 13 +++---- SparkleShare/Mac/SparkleShare/SparkleUI.cs | 2 +- 4 files changed, 29 insertions(+), 26 deletions(-) diff --git a/SparkleShare/Mac/SparkleShare/SparkleLog.cs b/SparkleShare/Mac/SparkleShare/SparkleLog.cs index e666792a..a5203ebe 100644 --- a/SparkleShare/Mac/SparkleShare/SparkleLog.cs +++ b/SparkleShare/Mac/SparkleShare/SparkleLog.cs @@ -32,12 +32,13 @@ namespace SparkleShare { private NSButton CloseButton; private NSButton OpenFolderButton; - + public SparkleLog (string path) : base () { LocalPath = path; + Delegate = new LogDelegate (); SetFrame (new RectangleF (0, 0, 480, 640), true); @@ -73,7 +74,9 @@ namespace SparkleShare { }; CloseButton.Activated += delegate { - PerformClose (this); + InvokeOnMainThread (delegate { + PerformClose (this); + }); }; ContentView.AddSubview (CloseButton); @@ -82,23 +85,10 @@ namespace SparkleShare { string name = System.IO.Path.GetFileName (LocalPath); Title = String.Format ("Recent Events in ‘{0}’", name); - NSApplication.SharedApplication.ActivateIgnoringOtherApps (true); - MakeKeyAndOrderFront (this); + OrderFrontRegardless (); } - - public override void PerformClose (NSObject sender) - { - - InvokeOnMainThread (delegate { - Console.WriteLine ("!!!!!!!!!!"); - SparkleUI.OpenLogs.Remove ((SparkleLog) this); - base.PerformClose (this); - }); - - } - public void UpdateEventLog () { @@ -119,5 +109,19 @@ namespace SparkleShare { } } + + + public class LogDelegate : NSWindowDelegate { + + public override void WillClose (NSNotification notification) + { + + Console.WriteLine ("CLOSING " + (notification.Object as SparkleLog).LocalPath); + + SparkleUI.OpenLogs.Remove ((SparkleLog) notification.Object); + + } + + } } diff --git a/SparkleShare/Mac/SparkleShare/SparkleShare.csproj b/SparkleShare/Mac/SparkleShare/SparkleShare.csproj index bc6e4845..cc4f415f 100644 --- a/SparkleShare/Mac/SparkleShare/SparkleShare.csproj +++ b/SparkleShare/Mac/SparkleShare/SparkleShare.csproj @@ -81,6 +81,7 @@ + Pixmaps\side-splash.png @@ -94,7 +95,4 @@ - - - \ No newline at end of file diff --git a/SparkleShare/Mac/SparkleShare/SparkleStatusIcon.cs b/SparkleShare/Mac/SparkleShare/SparkleStatusIcon.cs index a279f94f..75c66227 100644 --- a/SparkleShare/Mac/SparkleShare/SparkleStatusIcon.cs +++ b/SparkleShare/Mac/SparkleShare/SparkleStatusIcon.cs @@ -270,15 +270,16 @@ namespace SparkleShare { return delegate { - SparkleLog log = SparkleUI.OpenLogs.Find (delegate (SparkleLog l) { return l.LocalPath.Equals (path); }); - + SparkleLog log = SparkleUI.OpenLogs.Find (delegate (SparkleLog l) { + return l.LocalPath.Equals (path); + }); + // Check whether the log is already open, create a new one if // that's not the case or present it to the user if it is - if (log == null) { - + if (log == null) SparkleUI.OpenLogs.Add (new SparkleLog (path)); - - } + else + log.OrderFrontRegardless (); }; diff --git a/SparkleShare/Mac/SparkleShare/SparkleUI.cs b/SparkleShare/Mac/SparkleShare/SparkleUI.cs index 598cee4c..adb7913c 100644 --- a/SparkleShare/Mac/SparkleShare/SparkleUI.cs +++ b/SparkleShare/Mac/SparkleShare/SparkleUI.cs @@ -43,7 +43,7 @@ namespace SparkleShare { NSApplication.Init (); NSApplication.SharedApplication.ActivateIgnoringOtherApps (true); - //NSApplication.SharedApplication.applicationIconImage = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/sparkeshare.icns"); + NSApplication.SharedApplication.applicationIconImage = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/sparkeshare.icns"); OpenLogs = new List (); StatusIcon = new SparkleStatusIcon (); From a67971ef0fe2977b6e49da3c013a96d5190de71c Mon Sep 17 00:00:00 2001 From: Hylke Bons Date: Tue, 21 Dec 2010 20:59:53 +0100 Subject: [PATCH 16/19] [osx] Fix some bugs an use sparkleshare.icns for the .app --- SparkleShare/Mac/SparkleShare/SparkleLog.cs | 15 +++--- .../Mac/SparkleShare/SparkleShare.csproj | 2 +- .../Mac/SparkleShare/SparkleStatusIcon.cs | 50 ++++++++++++++---- SparkleShare/Mac/SparkleShare/SparkleUI.cs | 9 ++-- .../{Pixmaps => }/sparkleshare.icns | Bin 5 files changed, 52 insertions(+), 24 deletions(-) rename SparkleShare/Mac/SparkleShare/{Pixmaps => }/sparkleshare.icns (100%) diff --git a/SparkleShare/Mac/SparkleShare/SparkleLog.cs b/SparkleShare/Mac/SparkleShare/SparkleLog.cs index a5203ebe..4052ce8b 100644 --- a/SparkleShare/Mac/SparkleShare/SparkleLog.cs +++ b/SparkleShare/Mac/SparkleShare/SparkleLog.cs @@ -32,7 +32,8 @@ namespace SparkleShare { private NSButton CloseButton; private NSButton OpenFolderButton; - + public SparkleLog (IntPtr handle) : base (handle) { } + public SparkleLog (string path) : base () { @@ -109,17 +110,17 @@ namespace SparkleShare { } } - - + + public class LogDelegate : NSWindowDelegate { public override void WillClose (NSNotification notification) { - Console.WriteLine ("CLOSING " + (notification.Object as SparkleLog).LocalPath); - - SparkleUI.OpenLogs.Remove ((SparkleLog) notification.Object); - + InvokeOnMainThread (delegate { + SparkleUI.OpenLogs.Remove ((SparkleLog) notification.Object); + }); + } } diff --git a/SparkleShare/Mac/SparkleShare/SparkleShare.csproj b/SparkleShare/Mac/SparkleShare/SparkleShare.csproj index cc4f415f..50a86364 100644 --- a/SparkleShare/Mac/SparkleShare/SparkleShare.csproj +++ b/SparkleShare/Mac/SparkleShare/SparkleShare.csproj @@ -81,10 +81,10 @@ - Pixmaps\side-splash.png + diff --git a/SparkleShare/Mac/SparkleShare/SparkleStatusIcon.cs b/SparkleShare/Mac/SparkleShare/SparkleStatusIcon.cs index 75c66227..9357f7f7 100644 --- a/SparkleShare/Mac/SparkleShare/SparkleStatusIcon.cs +++ b/SparkleShare/Mac/SparkleShare/SparkleStatusIcon.cs @@ -40,6 +40,9 @@ namespace SparkleShare { private NSMenuItem SyncMenuItem; private NSMenuItem NotificationsMenuItem; private NSMenuItem AboutMenuItem; + + private delegate void Task (); + private EventHandler [] Tasks; // Short alias for the translations @@ -51,7 +54,7 @@ namespace SparkleShare { public SparkleStatusIcon () : base () { - + Animation = CreateAnimation (); StatusItem = NSStatusBar.SystemStatusBar.CreateStatusItem (28); @@ -61,7 +64,8 @@ namespace SparkleShare { SetNormalState (); CreateMenu (); - + Menu.Delegate = new SparkleStatusIconMenuDelegate (); + SparkleShare.Controller.FolderSizeChanged += delegate { InvokeOnMainThread (delegate { @@ -259,15 +263,11 @@ namespace SparkleShare { } - public delegate void Task(); - EventHandler [] Tasks; - // A method reference that makes sure that opening the // event log for each repository works correctly private EventHandler OpenEventLogDelegate (string path) { - return delegate { SparkleLog log = SparkleUI.OpenLogs.Find (delegate (SparkleLog l) { @@ -276,10 +276,19 @@ namespace SparkleShare { // Check whether the log is already open, create a new one if // that's not the case or present it to the user if it is - if (log == null) - SparkleUI.OpenLogs.Add (new SparkleLog (path)); - else - log.OrderFrontRegardless (); + if (log == null) { + + InvokeOnMainThread (delegate { + SparkleUI.OpenLogs.Add (new SparkleLog (path)); + }); + + } else { + + InvokeOnMainThread (delegate { + log.OrderFrontRegardless (); + }); + + } }; @@ -363,6 +372,27 @@ namespace SparkleShare { } } + + + public class SparkleStatusIconMenuDelegate : NSMenuDelegate { + + public override void MenuWillHighlightItem (NSMenu menu, NSMenuItem item) { } + + public override void MenuWillOpen (NSMenu menu) + { + + Console.WriteLine ("OPENED"); + + InvokeOnMainThread (delegate { + + foreach (SparkleLog log in SparkleUI.OpenLogs) + log.OrderFrontRegardless (); + + }); + + } + + } } diff --git a/SparkleShare/Mac/SparkleShare/SparkleUI.cs b/SparkleShare/Mac/SparkleShare/SparkleUI.cs index adb7913c..9c69afff 100644 --- a/SparkleShare/Mac/SparkleShare/SparkleUI.cs +++ b/SparkleShare/Mac/SparkleShare/SparkleUI.cs @@ -42,14 +42,11 @@ namespace SparkleShare { { NSApplication.Init (); - NSApplication.SharedApplication.ActivateIgnoringOtherApps (true); - NSApplication.SharedApplication.applicationIconImage = new NSImage (NSBundle.MainBundle.ResourcePath + "/Pixmaps/sparkeshare.icns"); + + NSApplication.SharedApplication.applicationIconImage = NSImage.ImageNamed ("sparkleshare.icns"); - OpenLogs = new List (); + OpenLogs = new List (); StatusIcon = new SparkleStatusIcon (); - - - } diff --git a/SparkleShare/Mac/SparkleShare/Pixmaps/sparkleshare.icns b/SparkleShare/Mac/SparkleShare/sparkleshare.icns similarity index 100% rename from SparkleShare/Mac/SparkleShare/Pixmaps/sparkleshare.icns rename to SparkleShare/Mac/SparkleShare/sparkleshare.icns From e3b324e3c8be9c29fa0be014d69010591bf2ab5f Mon Sep 17 00:00:00 2001 From: Hylke Bons Date: Wed, 22 Dec 2010 00:01:36 +0100 Subject: [PATCH 17/19] [osx] Set a custom icon for ~/SparkleShare --- .../Mac/SparkleShare/SparkleMacController.cs | 24 +++++++++++++++---- SparkleShare/Mac/SparkleShare/SparkleUI.cs | 8 ++++--- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/SparkleShare/Mac/SparkleShare/SparkleMacController.cs b/SparkleShare/Mac/SparkleShare/SparkleMacController.cs index 7cdf0df7..3937009b 100644 --- a/SparkleShare/Mac/SparkleShare/SparkleMacController.cs +++ b/SparkleShare/Mac/SparkleShare/SparkleMacController.cs @@ -15,6 +15,9 @@ // along with this program. If not, see . +using MonoMac.Foundation; +using MonoMac.AppKit; +using MonoMac.ObjCRuntime; using SparkleLib; using System; using System.Diagnostics; @@ -24,12 +27,10 @@ namespace SparkleShare { public class SparkleMacController : SparkleController { - // Creates a .desktop entry in autostart folder to - // start SparkleShare automatically at login public override void EnableSystemAutostart () { - + // N/A } @@ -39,7 +40,7 @@ namespace SparkleShare { public override void InstallLauncher () { - + // N/A } @@ -58,8 +59,21 @@ namespace SparkleShare { public override bool CreateSparkleShareFolder () { - return true; + if (!Directory.Exists (SparklePaths.SparklePath)) { + + Directory.CreateDirectory (SparklePaths.SparklePath); + + NSWorkspace.SharedWorkspace.SetIconforFile (NSImage.ImageNamed ("sparkleshare.icns"), + SparklePaths.SparklePath, 0); + + return true; + } else { + + return false; + + } + } diff --git a/SparkleShare/Mac/SparkleShare/SparkleUI.cs b/SparkleShare/Mac/SparkleShare/SparkleUI.cs index 9c69afff..f551d6dd 100644 --- a/SparkleShare/Mac/SparkleShare/SparkleUI.cs +++ b/SparkleShare/Mac/SparkleShare/SparkleUI.cs @@ -36,6 +36,7 @@ namespace SparkleShare { public static SparkleStatusIcon StatusIcon; public static List OpenLogs; + public SparkleUI () @@ -43,8 +44,9 @@ namespace SparkleShare { NSApplication.Init (); - NSApplication.SharedApplication.applicationIconImage = NSImage.ImageNamed ("sparkleshare.icns"); - + NSApplication.SharedApplication.applicationIconImage + = NSImage.ImageNamed ("sparkleshare.icns"); + OpenLogs = new List (); StatusIcon = new SparkleStatusIcon (); @@ -59,5 +61,5 @@ namespace SparkleShare { } } - + } From 924390faffc9a8a6d786052bdceb9bbb47b1d27e Mon Sep 17 00:00:00 2001 From: Hylke Bons Date: Wed, 22 Dec 2010 16:18:20 +0100 Subject: [PATCH 18/19] [main] Fix compiler error on Linux --- SparkleShare/Mac/SparkleShare/SparkleWindow.cs | 4 ---- SparkleShare/SparkleShare.cs | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/SparkleShare/Mac/SparkleShare/SparkleWindow.cs b/SparkleShare/Mac/SparkleShare/SparkleWindow.cs index fb8ebb9c..053687f5 100644 --- a/SparkleShare/Mac/SparkleShare/SparkleWindow.cs +++ b/SparkleShare/Mac/SparkleShare/SparkleWindow.cs @@ -28,10 +28,6 @@ namespace SparkleShare { public readonly string LocalPath; - private WebView WebView; - private NSButton CloseButton; - private NSButton OpenFolderButton; - private NSImage SideSplash; public SparkleWindow () : base () diff --git a/SparkleShare/SparkleShare.cs b/SparkleShare/SparkleShare.cs index 9bf5bce5..5e707832 100644 --- a/SparkleShare/SparkleShare.cs +++ b/SparkleShare/SparkleShare.cs @@ -89,11 +89,11 @@ namespace SparkleShare { case PlatformID.Unix: SetProcessName ("sparkleshare"); - //Controller = new SparkleLinController (); + Controller = new SparkleLinController (); break; case PlatformID.MacOSX: - Controller = new SparkleMacController (); + //Controller = new SparkleMacController (); break; case PlatformID.Win32NT: From c647b818cdd312a19530178f3505cfdcab902797 Mon Sep 17 00:00:00 2001 From: Hylke Bons Date: Wed, 22 Dec 2010 17:27:18 +0100 Subject: [PATCH 19/19] [osx] Make webkit draw the event log --- SparkleShare/SparkleController.cs | 274 +++++++++++++++++++++++++++++- 1 file changed, 270 insertions(+), 4 deletions(-) diff --git a/SparkleShare/SparkleController.cs b/SparkleShare/SparkleController.cs index 571bfe4b..25f5b16e 100644 --- a/SparkleShare/SparkleController.cs +++ b/SparkleShare/SparkleController.cs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . + using Mono.Unix; using SparkleLib; using System; @@ -25,6 +26,10 @@ using System.Threading; using System.Text.RegularExpressions; using System.Xml; +using System.Net; +using System.Security.Cryptography; +using System.Text; + namespace SparkleShare { public abstract class SparkleController { @@ -203,20 +208,21 @@ namespace SparkleShare { } - public List GetLog (string path) + public List GetLog (string name) { + string path = Path.Combine (SparklePaths.SparklePath, name); int log_size = 30; - List list = new List (); + List list = new List (); foreach (SparkleRepo repo in Repositories) { if (repo.LocalPath.Equals (path)) { foreach (SparkleCommit commit in repo.GetCommits (log_size)) - list.Add ((ChangeSet) commit); - + list.Add (commit); + return list; } @@ -228,6 +234,179 @@ namespace SparkleShare { } + public string GetHTMLLog (string name) + { + + List commits = GetLog (name); + + List activity_days = new List (); + + foreach (SparkleCommit commit in commits) { + + GetAvatar (commit.UserEmail, 32); + + bool commit_inserted = false; + foreach (ActivityDay stored_activity_day in activity_days) { + + if (stored_activity_day.DateTime.Year == commit.DateTime.Year && + stored_activity_day.DateTime.Month == commit.DateTime.Month && + stored_activity_day.DateTime.Day == commit.DateTime.Day) { + + stored_activity_day.Add (commit); + commit_inserted = true; + break; + + } + + } + + if (!commit_inserted) { + + ActivityDay activity_day = new ActivityDay (commit.DateTime); + activity_day.Add (commit); + activity_days.Add (activity_day); + + } + + } + + + + + StreamReader reader; + + reader = new StreamReader (Defines.PREFIX + "/share/sparkleshare/html/event-log.html"); + string event_log_html = reader.ReadToEnd (); + reader.Close (); + + reader = new StreamReader (Defines.PREFIX + "/share/sparkleshare/html/day-entry.html"); + string day_entry_html = reader.ReadToEnd (); + reader.Close (); + + reader = new StreamReader (Defines.PREFIX + "/share/sparkleshare/html/event-entry.html"); + string event_entry_html = reader.ReadToEnd (); + reader.Close (); + + + + + string event_log = ""; + + foreach (ActivityDay activity_day in activity_days) { + + string event_entries = ""; + + foreach (SparkleCommit change_set in activity_day) { + + string event_entry = ""; + event_entries += event_entry_html.Replace ("", event_entry) + .Replace ("", change_set.UserName) + .Replace ("", "file://" +GetAvatar (change_set.UserEmail, 32) ) + .Replace ("", change_set.DateTime.ToString ("H:mm")); + + } + + + + string day_entry = ""; + + DateTime today = DateTime.Now; + DateTime yesterday = DateTime.Now.AddDays (-1); + + if (today.Day == activity_day.DateTime.Day && + today.Month == activity_day.DateTime.Month && + today.Year == activity_day.DateTime.Year) { + + day_entry = day_entry_html.Replace ("", "Today"); + + } else if (yesterday.Day == activity_day.DateTime.Day && + yesterday.Month == activity_day.DateTime.Month && + yesterday.Year == activity_day.DateTime.Year) { + + day_entry = day_entry_html.Replace ("", "Yesterday"); + + } else { + + day_entry = day_entry_html.Replace ("", + "" + activity_day.DateTime.ToString ("ddd MMM d, yyyy") + ""); + + } + + event_log += day_entry.Replace ("", event_entries); + + + } + + string html = event_log_html.Replace ("", event_log); + + return html; + + } + + // Creates a folder in the user's home folder to store configuration private void CreateConfigurationFolders () { @@ -819,6 +998,76 @@ namespace SparkleShare { } + + + // Gets the avatar for a specific email address and size + public static string GetAvatar (string email, int size) + { + + string avatar_path = SparkleHelpers.CombineMore (SparklePaths.SparkleLocalIconPath, + size + "x" + size, "status"); + + if (!Directory.Exists (avatar_path)) { + + Directory.CreateDirectory (avatar_path); + SparkleHelpers.DebugInfo ("Config", "Created '" + avatar_path + "'"); + + } + + string avatar_file_path = SparkleHelpers.CombineMore (avatar_path, "avatar-" + email); + + if (File.Exists (avatar_file_path)) { + + return avatar_file_path; + + } else { + + // Let's try to get the person's gravatar for next time + WebClient web_client = new WebClient (); + Uri uri = new Uri ("http://www.gravatar.com/avatar/" + GetMD5 (email) + + ".jpg?s=" + size + "&d=404"); + + string tmp_file_path = SparkleHelpers.CombineMore (SparklePaths.SparkleTmpPath, email + size); + + if (!File.Exists (tmp_file_path)) { + + web_client.DownloadFileAsync (uri, tmp_file_path); + + web_client.DownloadFileCompleted += delegate { + + if (File.Exists (avatar_file_path)) + File.Delete (avatar_file_path); + + FileInfo tmp_file_info = new FileInfo (tmp_file_path); + + if (tmp_file_info.Length > 255) + File.Move (tmp_file_path, avatar_file_path); + + }; + + } + + // Fall back to a generic icon if there is no gravatar + if (File.Exists (avatar_file_path)) + return avatar_file_path; + else + return null; + + } + + } + + + // Creates an MD5 hash of input + public static string GetMD5 (string s) + { + MD5 md5 = new MD5CryptoServiceProvider (); + Byte[] bytes = ASCIIEncoding.Default.GetBytes (s); + Byte[] encodedBytes = md5.ComputeHash (bytes); + return BitConverter.ToString (encodedBytes).ToLower ().Replace ("-", ""); + } + + } @@ -826,4 +1075,21 @@ namespace SparkleShare { } + + // All commits that happened on a day + public class ActivityDay : List + { + + public DateTime DateTime; + + public ActivityDay (DateTime date_time) + { + + DateTime = date_time; + DateTime = new DateTime (DateTime.Year, DateTime.Month, DateTime.Day); + + } + + } + } \ No newline at end of file
"; + + if (change_set.Edited.Count > 0) { + + event_entry += "
Edited
"; + + foreach (string file_path in change_set.Edited) { + + if (File.Exists (SparkleHelpers.CombineMore (SparklePaths.SparklePath ,name , file_path))) { + + event_entry += "
" + file_path + "
"; + + } else { + + event_entry += "
" + SparkleHelpers.CombineMore (SparklePaths.SparklePath, name, file_path) + "
"; + + } + + } + + } + + + if (change_set.Added.Count > 0) { + + event_entry += "
Added
"; + + foreach (string file_path in change_set.Added) { + + if (File.Exists (SparkleHelpers.CombineMore (SparklePaths.SparklePath ,name , file_path))) { + + event_entry += "
" + file_path + "
"; + + } else { + + event_entry += "
" + SparkleHelpers.CombineMore (SparklePaths.SparklePath ,name , file_path) + "
"; + + } + + } + + } + + if (change_set.Deleted.Count > 0) { + + event_entry += "
Deleted
"; + + foreach (string file_path in change_set.Deleted) { + + if (File.Exists (SparkleHelpers.CombineMore (SparklePaths.SparklePath ,name , file_path))) { + + event_entry += "
" + file_path + "
"; + + } else { + + event_entry += "
" + SparkleHelpers.CombineMore (SparklePaths.SparklePath ,name , file_path) + "
"; + + } + + } + + } +Console.WriteLine(GetAvatar (change_set.UserEmail, 32)); + event_entry += "