summaryrefslogtreecommitdiff
path: root/SparkleShare/Mac/SparkleEventLog.cs
diff options
context:
space:
mode:
Diffstat (limited to 'SparkleShare/Mac/SparkleEventLog.cs')
-rwxr-xr-xSparkleShare/Mac/SparkleEventLog.cs419
1 files changed, 419 insertions, 0 deletions
diff --git a/SparkleShare/Mac/SparkleEventLog.cs b/SparkleShare/Mac/SparkleEventLog.cs
new file mode 100755
index 0000000..6ea3c73
--- /dev/null
+++ b/SparkleShare/Mac/SparkleEventLog.cs
@@ -0,0 +1,419 @@
+// SparkleShare, a collaboration and sharing tool.
+// Copyright (C) 2010 Hylke Bons <hylkebons@gmail.com>
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+using System;
+using System.Drawing;
+using System.IO;
+using System.Threading;
+
+using MonoMac.Foundation;
+using MonoMac.AppKit;
+using MonoMac.ObjCRuntime;
+using MonoMac.WebKit;
+
+namespace SparkleShare {
+
+ public class SparkleEventLog : NSWindow {
+
+ public SparkleEventLogController Controller = new SparkleEventLogController ();
+ public float TitlebarHeight;
+
+ private WebView web_view;
+ private NSBox background;
+ private NSBox cover;
+ private NSPopUpButton popup_button;
+ private NSProgressIndicator progress_indicator;
+ private NSTextField size_label, size_label_value, history_label, history_label_value;
+ private NSButton hidden_close_button;
+
+
+ public SparkleEventLog (IntPtr handle) : base (handle) { }
+
+ public SparkleEventLog () : base ()
+ {
+ Title = "Recent Changes";
+ Delegate = new SparkleEventsDelegate ();
+
+ int min_width = 480;
+ int min_height = 640;
+ int height = (int) (NSScreen.MainScreen.Frame.Height * 0.85);
+
+ float x = (float) (NSScreen.MainScreen.Frame.Width * 0.61);
+ float y = (float) (NSScreen.MainScreen.Frame.Height * 0.5 - (height * 0.5));
+
+ SetFrame (
+ new RectangleF (
+ new PointF (x, y),
+ new SizeF (min_width, height)),
+ true);
+
+ StyleMask = (NSWindowStyle.Closable | NSWindowStyle.Miniaturizable |
+ NSWindowStyle.Titled | NSWindowStyle.Resizable);
+
+ MinSize = new SizeF (min_width, min_height);
+ HasShadow = true;
+ BackingType = NSBackingStore.Buffered;
+ TitlebarHeight = Frame.Height - ContentView.Frame.Height;
+ Level = NSWindowLevel.Floating;
+
+
+ this.web_view = new WebView (new RectangleF (0, 0, 481, 579), "", "") {
+ Frame = new RectangleF (new PointF (0, 0),
+ new SizeF (ContentView.Frame.Width, ContentView.Frame.Height - 39))
+ };
+
+ this.cover = new NSBox () {
+ Frame = new RectangleF (
+ new PointF (-1, -1),
+ new SizeF (Frame.Width + 2, this.web_view.Frame.Height + 1)),
+ FillColor = NSColor.White,
+ BorderType = NSBorderType.NoBorder,
+ BoxType = NSBoxType.NSBoxCustom
+ };
+
+ this.hidden_close_button = new NSButton () {
+ KeyEquivalentModifierMask = NSEventModifierMask.CommandKeyMask,
+ KeyEquivalent = "w"
+ };
+
+ this.hidden_close_button.Activated += delegate {
+ Controller.WindowClosed ();
+ };
+
+
+ this.size_label = new NSTextField () {
+ Alignment = NSTextAlignment.Right,
+ BackgroundColor = NSColor.WindowBackground,
+ Bordered = false,
+ Editable = false,
+ Frame = new RectangleF (
+ new PointF (0, ContentView.Frame.Height - 31),
+ new SizeF (60, 20)),
+ StringValue = "Size:"
+ };
+
+ this.size_label_value = new NSTextField () {
+ Alignment = NSTextAlignment.Left,
+ BackgroundColor = NSColor.WindowBackground,
+ Bordered = false,
+ Editable = false,
+ Frame = new RectangleF (
+ new PointF (60, ContentView.Frame.Height - 27),
+ new SizeF (60, 20)),
+ StringValue = "…",
+ Font = NSFont.FromFontName (SparkleUI.FontName + " Bold", NSFont.SystemFontSize)
+ };
+
+
+ this.history_label = new NSTextField () {
+ Alignment = NSTextAlignment.Right,
+ BackgroundColor = NSColor.WindowBackground,
+ Bordered = false,
+ Editable = false,
+ Frame = new RectangleF (
+ new PointF (130, ContentView.Frame.Height - 31),
+ new SizeF (60, 20)),
+ StringValue = "History:"
+ };
+
+ this.history_label_value = new NSTextField () {
+ Alignment = NSTextAlignment.Left,
+ BackgroundColor = NSColor.WindowBackground,
+ Bordered = false,
+ Editable = false,
+ Frame = new RectangleF (
+ new PointF (190, ContentView.Frame.Height - 27),
+ new SizeF (60, 20)
+ ),
+ StringValue = "…",
+ Font = NSFont.FromFontName (SparkleUI.FontName + " Bold", NSFont.SystemFontSize)
+ };
+
+ this.popup_button = new NSPopUpButton () {
+ Frame = new RectangleF (
+ new PointF (ContentView.Frame.Width - 156 - 12, ContentView.Frame.Height - 33),
+ new SizeF (156, 26)),
+ PullsDown = false
+ };
+
+ this.background = new NSBox () {
+ Frame = new RectangleF (
+ new PointF (-1, -1),
+ new SizeF (Frame.Width + 2, this.web_view.Frame.Height + 2)),
+ FillColor = NSColor.White,
+ BorderColor = NSColor.LightGray,
+ BoxType = NSBoxType.NSBoxCustom
+ };
+
+ this.progress_indicator = new NSProgressIndicator () {
+ Frame = new RectangleF (
+ new PointF (Frame.Width / 2 - 10, this.web_view.Frame.Height / 2 + 10),
+ new SizeF (20, 20)),
+ Style = NSProgressIndicatorStyle.Spinning
+ };
+
+ this.progress_indicator.StartAnimation (this);
+
+ ContentView.AddSubview (this.size_label);
+ ContentView.AddSubview (this.size_label_value);
+ ContentView.AddSubview (this.history_label);
+ ContentView.AddSubview (this.history_label_value);
+ ContentView.AddSubview (this.popup_button);
+ ContentView.AddSubview (this.progress_indicator);
+ ContentView.AddSubview (this.background);
+ ContentView.AddSubview (this.hidden_close_button);
+
+ (Delegate as SparkleEventsDelegate).WindowResized += delegate (SizeF new_window_size) {
+ Program.Controller.Invoke (() => Relayout (new_window_size));
+ };
+
+
+ // Hook up the controller events
+ Controller.HideWindowEvent += delegate {
+ Program.Controller.Invoke (() => {
+ this.progress_indicator.Hidden = true;
+ PerformClose (this);
+ });
+ };
+
+ Controller.ShowWindowEvent += delegate {
+ Program.Controller.Invoke (() => OrderFrontRegardless ());
+ };
+
+ Controller.UpdateChooserEvent += delegate (string [] folders) {
+ Program.Controller.Invoke (() => UpdateChooser (folders));
+ };
+
+ Controller.UpdateChooserEnablementEvent += delegate (bool enabled) {
+ Program.Controller.Invoke (() => { this.popup_button.Enabled = enabled; });
+ };
+
+ Controller.UpdateContentEvent += delegate (string html) {
+ Program.Controller.Invoke (() => {
+ this.cover.RemoveFromSuperview ();
+ this.progress_indicator.Hidden = true;
+ UpdateContent (html);
+ });
+ };
+
+ Controller.ContentLoadingEvent += delegate {
+ Program.Controller.Invoke (() => {
+ this.web_view.RemoveFromSuperview ();
+ // FIXME: Hack to hide that the WebView sometimes doesn't disappear
+ ContentView.AddSubview (this.cover);
+ this.progress_indicator.Hidden = false;
+ this.progress_indicator.StartAnimation (this);
+ });
+ };
+
+ Controller.UpdateSizeInfoEvent += delegate (string size, string history_size) {
+ Program.Controller.Invoke (() => {
+ this.size_label_value.StringValue = size;
+ this.history_label_value.StringValue = history_size;
+ });
+ };
+
+ Controller.ShowSaveDialogEvent += delegate (string file_name, string target_folder_path) {
+ Program.Controller.Invoke (() => {
+ NSSavePanel panel = new NSSavePanel () {
+ DirectoryUrl = new NSUrl (target_folder_path, true),
+ NameFieldStringValue = file_name,
+ ParentWindow = this,
+ Title = "Restore from History",
+ PreventsApplicationTerminationWhenModal = false
+ };
+
+ if ((NSPanelButtonType) panel.RunModal () == NSPanelButtonType.Ok) {
+ string target_file_path = Path.Combine (panel.DirectoryUrl.RelativePath, panel.NameFieldStringValue);
+ Controller.SaveDialogCompleted (target_file_path);
+
+ } else {
+ Controller.SaveDialogCancelled ();
+ }
+ });
+ };
+ }
+
+
+ public void Relayout (SizeF new_window_size)
+ {
+ this.web_view.Frame = new RectangleF (this.web_view.Frame.Location,
+ new SizeF (new_window_size.Width, new_window_size.Height - TitlebarHeight - 39));
+
+ this.cover.Frame = new RectangleF (this.cover.Frame.Location,
+ new SizeF (new_window_size.Width, new_window_size.Height - TitlebarHeight - 39));
+
+ this.background.Frame = new RectangleF (this.background.Frame.Location,
+ new SizeF (new_window_size.Width, new_window_size.Height - TitlebarHeight - 37));
+
+ this.size_label.Frame = new RectangleF (
+ new PointF (this.size_label.Frame.X, new_window_size.Height - TitlebarHeight - 30),
+ this.size_label.Frame.Size);
+
+ this.size_label_value.Frame = new RectangleF (
+ new PointF (this.size_label_value.Frame.X, new_window_size.Height - TitlebarHeight - 27),
+ this.size_label_value.Frame.Size);
+
+ this.history_label.Frame = new RectangleF (
+ new PointF (this.history_label.Frame.X, new_window_size.Height - TitlebarHeight - 30),
+ this.history_label.Frame.Size);
+
+ this.history_label_value.Frame = new RectangleF (
+ new PointF (this.history_label_value.Frame.X, new_window_size.Height - TitlebarHeight - 27),
+ this.history_label_value.Frame.Size);
+
+ this.progress_indicator.Frame = new RectangleF (
+ new PointF (new_window_size.Width / 2 - 10, this.web_view.Frame.Height / 2 + 10),
+ this.progress_indicator.Frame.Size);
+
+ this.popup_button.RemoveFromSuperview (); // Needed to prevent redraw glitches
+
+ this.popup_button.Frame = new RectangleF (
+ new PointF (new_window_size.Width - this.popup_button.Frame.Width - 12, new_window_size.Height - TitlebarHeight - 33),
+ this.popup_button.Frame.Size);
+
+ ContentView.AddSubview (this.popup_button);
+ }
+
+
+ public void UpdateChooser (string [] folders)
+ {
+ if (folders == null)
+ folders = Controller.Folders;
+
+ this.popup_button.RemoveAllItems ();
+
+ this.popup_button.AddItem ("Summary");
+ this.popup_button.Menu.AddItem (NSMenuItem.SeparatorItem);
+
+ int row = 2;
+ foreach (string folder in folders) {
+ this.popup_button.AddItem (folder);
+
+ if (folder.Equals (Controller.SelectedFolder))
+ this.popup_button.SelectItem (row);
+
+ row++;
+ }
+
+ this.popup_button.AddItems (folders);
+
+ this.popup_button.Activated += delegate {
+ Program.Controller.Invoke (() => {
+ if (this.popup_button.IndexOfSelectedItem == 0)
+ Controller.SelectedFolder = null;
+ else
+ Controller.SelectedFolder = this.popup_button.SelectedItem.Title;
+ });
+ };
+ }
+
+
+ public void UpdateContent (string html)
+ {
+ string pixmaps_path = "file://" + NSBundle.MainBundle.ResourcePath;
+
+ html = html.Replace ("<!-- $body-font-family -->", "Helvetica Neue");
+ html = html.Replace ("<!-- $day-entry-header-font-size -->", "13.6px");
+ html = html.Replace ("<!-- $body-font-size -->", "13.4px");
+ html = html.Replace ("<!-- $secondary-font-color -->", "#bbb");
+ html = html.Replace ("<!-- $small-color -->", "#ddd");
+ html = html.Replace ("<!-- $small-font-size -->", "10px");
+ html = html.Replace ("<!-- $day-entry-header-background-color -->", "#f5f5f5");
+ html = html.Replace ("<!-- $a-color -->", "#009ff8");
+ html = html.Replace ("<!-- $a-hover-color -->", "#009ff8");
+ html = html.Replace ("<!-- $pixmaps-path -->", pixmaps_path);
+ html = html.Replace ("<!-- $document-added-background-image -->", pixmaps_path + "/document-added-12.png");
+ html = html.Replace ("<!-- $document-deleted-background-image -->", pixmaps_path + "/document-deleted-12.png");
+ html = html.Replace ("<!-- $document-edited-background-image -->", pixmaps_path + "/document-edited-12.png");
+ html = html.Replace ("<!-- $document-moved-background-image -->", pixmaps_path + "/document-moved-12.png");
+
+ this.web_view = new WebView (new RectangleF (0, 0, 481, 579), "", "") {
+ Frame = new RectangleF (new PointF (0, 0), new SizeF (ContentView.Frame.Width, ContentView.Frame.Height - 39))
+ };
+
+ this.web_view.MainFrame.LoadHtmlString (html, new NSUrl (""));
+
+ this.web_view.PolicyDelegate = new SparkleWebPolicyDelegate ();
+ ContentView.AddSubview (this.web_view);
+
+ (this.web_view.PolicyDelegate as SparkleWebPolicyDelegate).LinkClicked += delegate (string href) {
+ if (href.StartsWith ("file:///"))
+ href = href.Substring (7);
+
+ Controller.LinkClicked (href);
+ };
+
+ this.progress_indicator.Hidden = true;
+ }
+
+
+ public override void OrderFrontRegardless ()
+ {
+ NSApplication.SharedApplication.ActivateIgnoringOtherApps (true);
+ MakeKeyAndOrderFront (this);
+
+ if (Program.UI != null)
+ Program.UI.UpdateDockIconVisibility ();
+
+ base.OrderFrontRegardless ();
+ }
+
+
+ public override void PerformClose (NSObject sender)
+ {
+ base.OrderOut (this);
+
+ if (Program.UI != null)
+ Program.UI.UpdateDockIconVisibility ();
+
+ return;
+ }
+ }
+
+
+ public class SparkleEventsDelegate : NSWindowDelegate {
+
+ public event WindowResizedHandler WindowResized = delegate { };
+ public delegate void WindowResizedHandler (SizeF new_window_size);
+
+ public override SizeF WillResize (NSWindow sender, SizeF to_frame_size)
+ {
+ WindowResized (to_frame_size);
+ return to_frame_size;
+ }
+
+ public override bool WindowShouldClose (NSObject sender)
+ {
+ (sender as SparkleEventLog).Controller.WindowClosed ();
+ return false;
+ }
+ }
+
+
+ public class SparkleWebPolicyDelegate : WebPolicyDelegate {
+
+ public event LinkClickedHandler LinkClicked = delegate { };
+ public delegate void LinkClickedHandler (string href);
+
+ public override void DecidePolicyForNavigation (WebView web_view, NSDictionary action_info,
+ NSUrlRequest request, WebFrame frame, NSObject decision_token)
+ {
+ LinkClicked (request.Url.ToString ());
+ }
+ }
+}