windows: clean up statusicon somewhat

This commit is contained in:
Hylke Bons 2012-03-03 00:43:29 +00:00
parent 4cee4c3804
commit 4f48167d73
11 changed files with 146 additions and 450 deletions

22
NEWS
View file

@ -1,23 +1,23 @@
0.8.3 for Linux and Mac (Sun Mar 4 2012):
Hylke:
- Invites feature: link to a host with one click
- Implement sparklshare:// protocol handlers for invites
- "Add SparkleShare to login items" checkbox on the last tutorial page
- Text entries aren't being reset when selecting plugins in the setup dialog
- A variety of new default avatars (GNOME style)
- More useful hints below the entries in the setup dialog
- Breadcrumbs for paths in the event log: directories can be clicked
- Allow backends to be in separate binaries (by Shish)
- If the dock icon is visible and has a count badge, open event log on click
- Add previously successfully used hosts as plugins
- Invites feature: link to a host with one click
- Implement sparklshare:// protocol handlers for invites
- "Add SparkleShare to login items" checkbox on the last tutorial page
- Text entries aren't being reset when selecting plugins in the setup dialog
- A variety of new default avatars (GNOME style)
- More useful hints below the entries in the setup dialog
- Breadcrumbs for paths in the event log: directories can be clicked
- Allow backends to be in separate binaries (by Shish)
- If the dock icon is visible and has a count badge, open event log on click
- Add previously successfully used hosts as plugins
0.8.2 for Linux and Mac (Sat Feb 11 2012):
Hylke:
- Use the more reliable and less resource intensive FSEvents on Mac.
- Improvements to the reconnect mechanism of the notification system
- Improvements to the reconnect mechanism of the notification system
0.8.1 for Linux and Mac (Sun Jan 29 2012):

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -58,7 +58,7 @@
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.XML" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\SparkleAnnouncement.cs">
@ -146,8 +146,8 @@
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>
<MonoDevelop>
<Properties InternalTargetFrameworkVersion="3.5">
<MonoDevelop.Autotools.MakefileInfo IntegrationEnabled="true" RelativeMakefileName="Makefile.am">
<Properties>
<MonoDevelop.Autotools.MakefileInfo RelativeMakefileName="Makefile.am">
<BuildFilesVar Sync="true" Name="SOURCES" />
<DeployFilesVar />
<ResourcesVar />

View file

@ -1,128 +0,0 @@
// SparkleShare, an instant update workflow to Git.
// 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.Windows.Forms;
using System.Drawing;
using System.IO;
namespace Notifications
{
public partial class Notification : Form
{
private Timer animationTimer;
private int startPosX;
private int startPosY;
//public new Gdk.Pixbuf Icon;
public Notification ()
{
InitializeComponent ();
TopMost = true;
ShowInTaskbar = false;
animationTimer = new Timer ();
animationTimer.Interval = 50;
animationTimer.Tick += timer_Tick;
}
public Notification (string title, string subtext)
: this()
{
this.title.Text = title;
this.subtext.Text = subtext;
}
protected override void OnLoad (EventArgs e)
{
// Move window out of screen
startPosX = Screen.PrimaryScreen.WorkingArea.Width - Width;
startPosY = Screen.PrimaryScreen.WorkingArea.Height;
SetDesktopLocation (startPosX, startPosY);
base.OnLoad (e);
// Begin animation
animationTimer.Start ();
}
protected override void OnShown (EventArgs e)
{
base.OnShown (e);
// hacky way to move the image from a Gdk.Pixbuf to a winforms bitmap
string Filename = Path.GetTempFileName ();
File.Delete (Filename);
Filename = Path.ChangeExtension (Filename, "bmp");
if (File.Exists (Filename))
File.Delete (Filename);
//this.Icon.Save (Filename, "bmp");
using (Stream s = File.OpenRead (Filename))
pictureBox1.Image = Bitmap.FromStream (s);
File.Delete (Filename);
}
void timer_Tick (object sender, EventArgs e)
{
startPosY -= 5;
if (startPosY < Screen.PrimaryScreen.WorkingArea.Height - Height)
animationTimer.Stop ();
else
SetDesktopLocation (startPosX, startPosY);
}
public void AddAction (string action, string label, ActionHandler handler)
{
}
public void RemoveAction (string action)
{
}
public void ClearActions ()
{
}
}
public enum Urgency : byte
{
Low = 0,
Normal,
Critical
}
public class ActionArgs : EventArgs
{
private string action;
public string Action
{
get { return action; }
}
public ActionArgs (string action)
{
this.action = action;
}
}
public delegate void ActionHandler (object o, ActionArgs args);
}

View file

@ -1,96 +0,0 @@
namespace Notifications
{
partial class Notification
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.pictureBox1 = new System.Windows.Forms.PictureBox ();
this.title = new System.Windows.Forms.Label ();
this.subtext = new System.Windows.Forms.Label ();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit ();
this.SuspendLayout ();
//
// pictureBox1
//
this.pictureBox1.Location = new System.Drawing.Point (12, 12);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size (40, 42);
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
//
// title
//
this.title.AutoSize = true;
this.title.Font = new System.Drawing.Font ("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.title.Location = new System.Drawing.Point (58, 9);
this.title.Name = "title";
this.title.Size = new System.Drawing.Size (28, 13);
this.title.TabIndex = 1;
this.title.Text = "title";
//
// subtext
//
this.subtext.AutoSize = true;
this.subtext.Location = new System.Drawing.Point (58, 22);
this.subtext.MaximumSize = new System.Drawing.Size (171, 0);
this.subtext.Name = "subtext";
this.subtext.Size = new System.Drawing.Size (41, 13);
this.subtext.TabIndex = 2;
this.subtext.Text = "subtext";
//
// Notification
//
this.AutoScaleDimensions = new System.Drawing.SizeF (6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size (241, 64);
this.ControlBox = false;
this.Controls.Add (this.subtext);
this.Controls.Add (this.title);
this.Controls.Add (this.pictureBox1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "Notification";
this.Opacity = 0.8;
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit ();
this.ResumeLayout (false);
this.PerformLayout ();
}
#endregion
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.Label title;
private System.Windows.Forms.Label subtext;
}
}

View file

@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View file

@ -70,7 +70,7 @@ namespace SparkleShare {
public void UpdateChooser ()
{
this.combo_box.Items.Add (_ ("All Folders"));
this.combo_box.Items.Add (_ ("All Projects"));
this.combo_box.Items.Add ("");
foreach (string folder_name in Program.Controller.Folders)

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -31,8 +31,6 @@
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<ApplicationIcon>..\..\data\icons\sparkleshare.ico</ApplicationIcon>
<StartupObject>
</StartupObject>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -44,7 +42,6 @@
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
@ -65,14 +62,14 @@
<HintPath>..\..\tools\gettext-cs-utils\Gettext.CsUtils\Core\Gettext.Cs\bin\Release\Gettext.Cs.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.configuration" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.XML" />
<Reference Include="System.Configuration" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\SparkleLib\windows\GlobalAssemblyInfo.cs">
@ -130,9 +127,6 @@
<Compile Include="SparkleAbout.Designer.cs">
<DependentUpon>SparkleAbout.cs</DependentUpon>
</Compile>
<Compile Include="SparkleBubble.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="..\SparkleSetupController.cs" />
<Compile Include="..\SparkleUI.cs" />
<Compile Include="..\SparkleAboutController.cs" />
@ -163,15 +157,15 @@
</Compile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\SparkleLib\Windows\SparkleLib.csproj">
<ProjectReference Include="..\..\SparkleLib\windows\SparkleLib.csproj">
<Project>{2C914413-B31C-4362-93C7-1AE34F09112A}</Project>
<Name>SparkleLib</Name>
</ProjectReference>
</ItemGroup>
<ProjectExtensions>
<MonoDevelop>
<Properties InternalTargetFrameworkVersion="3.5">
<MonoDevelop.Autotools.MakefileInfo IntegrationEnabled="true" RelativeMakefileName="Makefile.am">
<Properties>
<MonoDevelop.Autotools.MakefileInfo RelativeMakefileName="Makefile.am">
<BuildFilesVar Sync="true" Name="SOURCES" />
<DeployFilesVar />
<ResourcesVar />

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -35,9 +35,6 @@
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\sparkleshare-invite-open.cs">
<Link>sparkleshare-invite-open.cs</Link>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

View file

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{1DB5492D-B897-4A5E-8DD7-175EC65F52F2}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>SparkleShareInviteOpen</RootNamespace>
<AssemblyName>SparkleShareInviteOpen</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ApplicationIcon>..\..\..\data\icons\sparkleshare.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\..\bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\..\bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\sparkleshare-invite-open.cs">
<Link>sparkleshare-invite-open.cs</Link>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View file

@ -16,22 +16,20 @@
using System;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using SparkleLib;
using System.Windows.Forms;
using System.Drawing;
using System.Runtime.InteropServices;
namespace SparkleShare {
// The statusicon that stays in the
// user's notification area
public class SparkleStatusIcon : IDisposable {
public SparkleStatusIconController Controller = new SparkleStatusIconController();
private Timer Animation;
private Bitmap [] AnimationFrames;
private int FrameNumber;
@ -61,28 +59,28 @@ namespace SparkleShare {
SetNormalState ();
Program.Controller.FolderListChanged += delegate {
status_icon.ContextMenuStrip.SafeInvoke ((Action)delegate {
status_icon.ContextMenuStrip.SafeInvoke ((Action) delegate {
SetNormalState ();
CreateMenu ();
});
};
Program.Controller.OnIdle += delegate {
status_icon.ContextMenuStrip.SafeInvoke ((Action)delegate {
status_icon.ContextMenuStrip.SafeInvoke ((Action) delegate {
SetNormalState ();
UpdateMenu ();
});
};
Program.Controller.OnSyncing += delegate {
status_icon.ContextMenuStrip.SafeInvoke ((Action)delegate {
status_icon.ContextMenuStrip.SafeInvoke ((Action) delegate {
SetAnimationState ();
UpdateMenu ();
});
};
Program.Controller.OnError += delegate {
status_icon.ContextMenuStrip.SafeInvoke ((Action)delegate {
status_icon.ContextMenuStrip.SafeInvoke ((Action) delegate {
SetNormalState (true);
UpdateMenu ();
});
@ -90,6 +88,10 @@ namespace SparkleShare {
}
[DllImport("user32.dll", EntryPoint = "DestroyIcon")]
static extern bool DestroyIcon(IntPtr hIcon);
// Slices up the graphic that contains the
// animation frames.
private Bitmap [] CreateAnimationFrames ()
@ -104,16 +106,6 @@ namespace SparkleShare {
return animation_frames;
}
[DllImport("user32.dll", EntryPoint = "DestroyIcon")]
static extern bool DestroyIcon(IntPtr hIcon);
private Icon GetIconFromBitmap (Bitmap bitmap)
{
IntPtr unmanagedIcon = bitmap.GetHicon();
Icon icon = (Icon)Icon.FromHandle(unmanagedIcon).Clone();
DestroyIcon(unmanagedIcon);
return icon;
}
// Creates the Animation that handles the syncing animation
private Timer CreateAnimation ()
@ -130,8 +122,8 @@ namespace SparkleShare {
else
FrameNumber = 0;
status_icon.ContextMenuStrip.SafeInvoke ((Action)delegate {
this.status_icon.Icon = GetIconFromBitmap( AnimationFrames [FrameNumber]);
status_icon.ContextMenuStrip.SafeInvoke ((Action) delegate {
this.status_icon.Icon = GetIconFromBitmap (AnimationFrames [FrameNumber]);
});
};
@ -156,7 +148,7 @@ namespace SparkleShare {
};
folder_item.Click += delegate {
Program.Controller.OpenSparkleShareFolder ();
Controller.SparkleShareClicked ();
};
Menu.Items.Add (folder_item);
@ -182,7 +174,7 @@ namespace SparkleShare {
}
} else {
ToolStripMenuItem no_folders_item = new ToolStripMenuItem (_ ("No Remote Folders Yet")) {
ToolStripMenuItem no_folders_item = new ToolStripMenuItem (_("No projects yet")) {
Enabled = false
};
@ -192,24 +184,25 @@ namespace SparkleShare {
Menu.Items.Add (new ToolStripSeparator ());
// Opens the wizard to add a new remote folder
ToolStripMenuItem sync_item = new ToolStripMenuItem (_ ("Add Hosted Project…"));
ToolStripMenuItem sync_item = new ToolStripMenuItem (_("Add Hosted Project…"));
if (Program.Controller.FirstRun)
sync_item.Enabled = false;
sync_item.Click += delegate {
Controller.AddHostedProjectClicked();
Controller.AddHostedProjectClicked ();
};
Menu.Items.Add (sync_item);
Menu.Items.Add (new ToolStripSeparator ());
ToolStripMenuItem recent_events_item = new ToolStripMenuItem (_ ("Open Recent Events"));
ToolStripMenuItem recent_events_item = new ToolStripMenuItem (_("View Recent Changes…"));
if (Program.Controller.Folders.Count < 1)
recent_events_item.Enabled = false;
recent_events_item.Click += delegate {
// Controller.OpenRecentEventsClicked ();
if (SparkleUI.EventLog == null)
SparkleUI.EventLog = new SparkleEventLog ();
@ -222,9 +215,9 @@ namespace SparkleShare {
ToolStripMenuItem notify_item;
if (Program.Controller.NotificationsEnabled)
notify_item = new ToolStripMenuItem (_ ("Turn Notifications Off"));
notify_item = new ToolStripMenuItem (_("Turn Notifications Off"));
else
notify_item = new ToolStripMenuItem (_ ("Turn Notifications On"));
notify_item = new ToolStripMenuItem (_("Turn Notifications On"));
notify_item.Click += delegate {
Program.Controller.ToggleNotifications ();
@ -234,8 +227,8 @@ namespace SparkleShare {
Menu.Items.Add (notify_item);
Menu.Items.Add (new ToolStripSeparator ());
// A menu item that takes the user to http://www.sparkleshare.org/
ToolStripMenuItem about_item = new ToolStripMenuItem (_ ("About SparkleShare"));
ToolStripMenuItem about_item = new ToolStripMenuItem (_("About SparkleShare"));
about_item.Click += delegate {
if (SparkleUI.About == null)
@ -249,7 +242,7 @@ namespace SparkleShare {
Menu.Items.Add (new ToolStripSeparator ());
// A menu item that quits the application
ToolStripMenuItem quit_item = new ToolStripMenuItem (_ ("Quit"));
ToolStripMenuItem quit_item = new ToolStripMenuItem (_("Quit"));
quit_item.Click += delegate {
Program.Controller.Quit ();
@ -260,23 +253,16 @@ namespace SparkleShare {
status_icon.ContextMenuStrip = Menu;
}
public void ShowBalloon (string title, string subtext, string image_path)
{
// TODO: Use the image pointed to by image_path
status_icon.BalloonTipText = title;
status_icon.BalloonTipText = subtext;
// TODO: Use the image pointed to by image_path
status_icon.BalloonTipIcon = ToolTipIcon.None;
status_icon.ShowBalloonTip (2 * 1000);
}
// A method reference that makes sure that opening the
// event log for each repository works correctly
private EventHandler OpenFolderDelegate (string name)
{
return delegate {
Program.Controller.OpenSparkleShareFolder (name);
};
status_icon.ShowBalloonTip (5 * 1000);
}
@ -313,7 +299,7 @@ namespace SparkleShare {
this.status_icon.Icon = GetIconFromBitmap (Icons.sparkleshare_syncing_error_24);
});
} else {
StateText = _("Up to date") + " (" + FolderSize + ")";
StateText = _("Files up to date") + Controller.FolderSize;
status_icon.ContextMenuStrip.SafeInvoke ((Action)delegate {
this.status_icon.Icon = GetIconFromBitmap (AnimationFrames [0]);
});
@ -322,6 +308,14 @@ namespace SparkleShare {
}
#region IDisposable Members
public void Dispose ()
{
this.status_icon.Dispose ();
}
#endregion
// The state when animating
private void SetAnimationState ()
{
@ -331,56 +325,60 @@ namespace SparkleShare {
Animation.Start ();
}
public string FolderSize
// A method reference that makes sure that opening the
// event log for each repository works correctly
private EventHandler OpenFolderDelegate (string name)
{
get
{
double size = 0;
foreach (SparkleRepoBase repo in Program.Controller.Repositories)
size += repo.Size + repo.HistorySize;
return Program.Controller.FormatSize(size);
}
return delegate {
Controller.SubfolderClicked (name);
};
}
#region IDisposable Members
public void Dispose ()
private Icon GetIconFromBitmap (Bitmap bitmap)
{
status_icon.Dispose ();
}
IntPtr unmanaged_icon = bitmap.GetHicon ();
Icon icon = (Icon) Icon.FromHandle (unmanaged_con).Clone ();
DestroyIcon (unmanaged_icon);
#endregion
return icon;
}
}
public static class ControlExtention {
public static void SafeInvoke (this Control uiElement, Action updater, bool forceSynchronous)
{
if (uiElement == null) {
//throw new ArgumentNullException ("uiElement");
return;
}
if (uiElement.InvokeRequired) {
if (forceSynchronous) {
uiElement.Invoke ((Action)delegate { SafeInvoke (uiElement, updater, forceSynchronous); });
public static void SafeInvoke (this Control ui_element,
Action updater, bool force_synchronous)
{
if (ui_element == null)
return;
if (ui_element.InvokeRequired) {
if (force_synchronous) {
ui_element.Invoke ((Action) delegate {
SafeInvoke (ui_element, updater, force_synchronous);
});
} else {
uiElement.BeginInvoke ((Action)delegate { SafeInvoke (uiElement, updater, forceSynchronous); });
ui_element.BeginInvoke ((Action) delegate {
SafeInvoke (ui_element, updater, force_synchronous);
});
}
} else {
if (uiElement.IsDisposed) {
if (ui_element.IsDisposed)
throw new ObjectDisposedException ("Control is already disposed.");
}
updater ();
}
}
public static void SafeInvoke (this Control uiElement, Action updater)
{
uiElement.SafeInvoke (updater, false);
}
public static void SafeInvoke (this Control ui_element, Action updater)
{
ui_element.SafeInvoke (updater, false);
}
}
}