diff --git a/Growl Connectors/NET/libraries/Growl.Connector.dll b/Growl Connectors/NET/libraries/Growl.Connector.dll index 107a6df..fb35940 100644 Binary files a/Growl Connectors/NET/libraries/Growl.Connector.dll and b/Growl Connectors/NET/libraries/Growl.Connector.dll differ diff --git a/Growl Connectors/NET/libraries/Growl.CoreLibrary.dll b/Growl Connectors/NET/libraries/Growl.CoreLibrary.dll index 8067d10..16059a4 100644 Binary files a/Growl Connectors/NET/libraries/Growl.CoreLibrary.dll and b/Growl Connectors/NET/libraries/Growl.CoreLibrary.dll differ diff --git a/Growl Extras/Feed Monitor/Feed Monitor Deployment/Feed Monitor Deployment.vdproj b/Growl Extras/Feed Monitor/Feed Monitor Deployment/Feed Monitor Deployment.vdproj index 2efbb9f..90827fc 100644 --- a/Growl Extras/Feed Monitor/Feed Monitor Deployment/Feed Monitor Deployment.vdproj +++ b/Growl Extras/Feed Monitor/Feed Monitor Deployment/Feed Monitor Deployment.vdproj @@ -278,14 +278,14 @@ { "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:Feed Monitor" - "ProductCode" = "8:{112838BB-CDED-4071-AB0D-865F82874302}" - "PackageCode" = "8:{B67AFFBF-0CCE-41B9-88E8-74A41DE9618C}" + "ProductCode" = "8:{BD7EE876-9F0E-4C2D-8B25-BDA55F54A594}" + "PackageCode" = "8:{FA534258-825F-4AA3-843E-7B3521B408C5}" "UpgradeCode" = "8:{E8D784D8-949E-4CC9-BA80-A316D25574D7}" "RestartWWWService" = "11:FALSE" "RemovePreviousVersions" = "11:TRUE" "DetectNewerInstalledVersion" = "11:TRUE" "InstallAllUsers" = "11:FALSE" - "ProductVersion" = "8:1.0.2" + "ProductVersion" = "8:1.0.4" "Manufacturer" = "8:element code project" "ARPHELPTELEPHONE" = "8:" "ARPHELPLINK" = "8:" diff --git a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/FeedListView.cs b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/FeedListView.cs index 324955b..d47e563 100644 --- a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/FeedListView.cs +++ b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/FeedListView.cs @@ -20,8 +20,9 @@ public FeedListView(IContainer container) this.SuspendLayout(); - this.OwnerDraw = true; this.DoubleBuffered = true; + this.OwnerDraw = true; + this.DrawItem += new DrawListViewItemEventHandler(FeedListView_DrawItem); // columns ColumnHeader nameHeader = new ColumnHeader(); @@ -39,8 +40,6 @@ public FeedListView(IContainer container) this.ShowItemToolTips = true; this.LabelWrap = false; - this.DrawItem += new DrawListViewItemEventHandler(FeedListView_DrawItem); - // uncomment this to use custom tool tips //this.ShowItemToolTips = false; this.ItemMouseHover += new ListViewItemMouseHoverEventHandler(FeedListView_ItemMouseHover); @@ -56,15 +55,11 @@ void FeedListView_DrawItem(object sender, DrawListViewItemEventArgs e) Feed feed = (Feed) e.Item.Tag; // draw the background and focus rectangle for selected and non-selected states - if ((e.State & ListViewItemStates.Selected) != 0) + e.DrawBackground(); + if (e.Item.Selected) { e.Graphics.FillRectangle(System.Drawing.Brushes.LightGray, e.Bounds); - e.DrawFocusRectangle(); - } - else - { - e.DrawBackground(); - e.DrawFocusRectangle(); + ControlPaint.DrawFocusRectangle(e.Graphics, e.Bounds); } // draw icon diff --git a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/MainComponent.cs b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/MainComponent.cs index afe23bd..703416a 100644 --- a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/MainComponent.cs +++ b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/MainComponent.cs @@ -108,7 +108,7 @@ private void InitializeFeeds() List savedFeeds = SettingsPersister.Read(); foreach (Feed feed in savedFeeds) { - AddFeed(feed.Url, feed.PollInterval); + AddFeed(feed); } if (this.feeds.Count == 0) @@ -120,11 +120,21 @@ private void InitializeFeeds() } } + public void AddFeed(Feed feed) + { + AddFeed(feed.Url, feed.PollInterval, feed.CustomName, feed.Username, feed.Password); + } + public void AddFeed(string url, int pollInterval) + { + AddFeed(url, pollInterval, null, null, null); + } + + private void AddFeed(string url, int pollInterval, string customName, string username, string password) { try { - Feed feed = Feed.Create(url, pollInterval); + Feed feed = Feed.Create(url, pollInterval, customName, username, password); feed.FeedRetrieved += new EventHandler(feed_FeedRetrieved); feed.FeedUpdated += new EventHandler(feed_FeedUpdated); feed.FeedError += new EventHandler(feed_FeedError); diff --git a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/MainForm.Designer.cs b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/MainForm.Designer.cs index fe0e926..dce36db 100644 --- a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/MainForm.Designer.cs +++ b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/MainForm.Designer.cs @@ -33,13 +33,13 @@ private void InitializeComponent() this.labelAddFeed = new System.Windows.Forms.Label(); this.contextMenu = new System.Windows.Forms.ContextMenuStrip(this.components); this.checkNowToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.removeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.setIntervalToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.oneMinuteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.twoMinutesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.fiveMinutesToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); this.tenMinutesToolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem(); this.thirtyMinutesToolStripMenuItem3 = new System.Windows.Forms.ToolStripMenuItem(); + this.removeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.panel1 = new System.Windows.Forms.Panel(); this.labelAdd = new System.Windows.Forms.Label(); this.label1 = new System.Windows.Forms.Label(); @@ -89,22 +89,15 @@ private void InitializeComponent() this.removeToolStripMenuItem}); this.contextMenu.Name = "contextMenu"; this.contextMenu.ShowImageMargin = false; - this.contextMenu.Size = new System.Drawing.Size(128, 92); + this.contextMenu.Size = new System.Drawing.Size(107, 70); // // checkNowToolStripMenuItem // this.checkNowToolStripMenuItem.Name = "checkNowToolStripMenuItem"; - this.checkNowToolStripMenuItem.Size = new System.Drawing.Size(127, 22); + this.checkNowToolStripMenuItem.Size = new System.Drawing.Size(106, 22); this.checkNowToolStripMenuItem.Text = "Check Now"; this.checkNowToolStripMenuItem.Click += new System.EventHandler(this.checkNowToolStripMenuItem_Click); // - // removeToolStripMenuItem - // - this.removeToolStripMenuItem.Name = "removeToolStripMenuItem"; - this.removeToolStripMenuItem.Size = new System.Drawing.Size(127, 22); - this.removeToolStripMenuItem.Text = "Remove"; - this.removeToolStripMenuItem.Click += new System.EventHandler(this.removeToolStripMenuItem_Click); - // // setIntervalToolStripMenuItem // this.setIntervalToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { @@ -114,13 +107,13 @@ private void InitializeComponent() this.tenMinutesToolStripMenuItem2, this.thirtyMinutesToolStripMenuItem3}); this.setIntervalToolStripMenuItem.Name = "setIntervalToolStripMenuItem"; - this.setIntervalToolStripMenuItem.Size = new System.Drawing.Size(127, 22); + this.setIntervalToolStripMenuItem.Size = new System.Drawing.Size(106, 22); this.setIntervalToolStripMenuItem.Text = "Set Interval"; // // oneMinuteToolStripMenuItem // this.oneMinuteToolStripMenuItem.Name = "oneMinuteToolStripMenuItem"; - this.oneMinuteToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.oneMinuteToolStripMenuItem.Size = new System.Drawing.Size(126, 22); this.oneMinuteToolStripMenuItem.Tag = "1"; this.oneMinuteToolStripMenuItem.Text = "1 minute"; this.oneMinuteToolStripMenuItem.Click += new System.EventHandler(this.oneMinuteToolStripMenuItem_Click); @@ -128,7 +121,7 @@ private void InitializeComponent() // twoMinutesToolStripMenuItem // this.twoMinutesToolStripMenuItem.Name = "twoMinutesToolStripMenuItem"; - this.twoMinutesToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.twoMinutesToolStripMenuItem.Size = new System.Drawing.Size(126, 22); this.twoMinutesToolStripMenuItem.Tag = "2"; this.twoMinutesToolStripMenuItem.Text = "2 minutes"; this.twoMinutesToolStripMenuItem.Click += new System.EventHandler(this.twoMinutesToolStripMenuItem_Click); @@ -136,7 +129,7 @@ private void InitializeComponent() // fiveMinutesToolStripMenuItem1 // this.fiveMinutesToolStripMenuItem1.Name = "fiveMinutesToolStripMenuItem1"; - this.fiveMinutesToolStripMenuItem1.Size = new System.Drawing.Size(152, 22); + this.fiveMinutesToolStripMenuItem1.Size = new System.Drawing.Size(126, 22); this.fiveMinutesToolStripMenuItem1.Tag = "5"; this.fiveMinutesToolStripMenuItem1.Text = "5 minutes"; this.fiveMinutesToolStripMenuItem1.Click += new System.EventHandler(this.fiveMinutesToolStripMenuItem1_Click); @@ -144,7 +137,7 @@ private void InitializeComponent() // tenMinutesToolStripMenuItem2 // this.tenMinutesToolStripMenuItem2.Name = "tenMinutesToolStripMenuItem2"; - this.tenMinutesToolStripMenuItem2.Size = new System.Drawing.Size(152, 22); + this.tenMinutesToolStripMenuItem2.Size = new System.Drawing.Size(126, 22); this.tenMinutesToolStripMenuItem2.Tag = "10"; this.tenMinutesToolStripMenuItem2.Text = "10 minutes"; this.tenMinutesToolStripMenuItem2.Click += new System.EventHandler(this.tenMinutesToolStripMenuItem2_Click); @@ -152,11 +145,18 @@ private void InitializeComponent() // thirtyMinutesToolStripMenuItem3 // this.thirtyMinutesToolStripMenuItem3.Name = "thirtyMinutesToolStripMenuItem3"; - this.thirtyMinutesToolStripMenuItem3.Size = new System.Drawing.Size(152, 22); + this.thirtyMinutesToolStripMenuItem3.Size = new System.Drawing.Size(126, 22); this.thirtyMinutesToolStripMenuItem3.Tag = "30"; this.thirtyMinutesToolStripMenuItem3.Text = "30 minutes"; this.thirtyMinutesToolStripMenuItem3.Click += new System.EventHandler(this.thirtyMinutesToolStripMenuItem3_Click); // + // removeToolStripMenuItem + // + this.removeToolStripMenuItem.Name = "removeToolStripMenuItem"; + this.removeToolStripMenuItem.Size = new System.Drawing.Size(106, 22); + this.removeToolStripMenuItem.Text = "Remove"; + this.removeToolStripMenuItem.Click += new System.EventHandler(this.removeToolStripMenuItem_Click); + // // panel1 // this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); diff --git a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Properties/AssemblyInfo.cs b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Properties/AssemblyInfo.cs index 29b7468..aa168da 100644 --- a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Properties/AssemblyInfo.cs +++ b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Properties/AssemblyInfo.cs @@ -33,4 +33,4 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.1.0")] +[assembly: AssemblyFileVersion("1.0.4.0")] diff --git a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/Feed.cs b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/Feed.cs index 9df3133..9a50ba6 100644 --- a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/Feed.cs +++ b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/Feed.cs @@ -17,9 +17,12 @@ public class Feed : IDisposable private const string _nullResultErrorMessage = "The returned stream was null."; private const string _parseErrorMessage = "Unable to parse feed."; - private string name; + private string actualName; + private string customName; private Uri url; private int pollInterval; + private string username; + private string password; private DateTime lastCheckForUpdates; private DateTimeOffset feedLastUpdated; private WebClient webclient; @@ -29,14 +32,22 @@ private Feed() { } public static Feed Create(string url, int pollInterval) { - return new Feed(url, pollInterval, DateTime.MaxValue); + return Create(url, pollInterval, null, null, null); } - private Feed(string url, int pollInterval, DateTime lastCheckForUpdates) + public static Feed Create(string url, int pollInterval, string customName, string username, string password) { - this.name = LOADING; + return new Feed(url, pollInterval, customName, username, password, DateTime.MaxValue); + } + + private Feed(string url, int pollInterval, string customName, string username, string password, DateTime lastCheckForUpdates) + { + this.actualName = LOADING; + this.customName = customName; this.url = new Uri(url); this.pollInterval = pollInterval; + this.username = username; + this.password = password; this.lastCheckForUpdates = lastCheckForUpdates; this.feedLastUpdated = DateTimeOffset.MaxValue; @@ -56,7 +67,26 @@ public string Name { get { - return this.name; + if (this.actualName == LOADING || String.IsNullOrEmpty(this.customName)) + return this.actualName; + else + return this.customName; + } + } + + public string ActualName + { + get + { + return this.actualName; + } + } + + public string CustomName + { + get + { + return this.customName; } } @@ -81,6 +111,22 @@ public int PollInterval } } + public string Username + { + get + { + return this.username; + } + } + + public string Password + { + get + { + return this.password; + } + } + void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { this.timer.Stop(); @@ -91,6 +137,7 @@ public void CheckForUpdates() { if (!this.webclient.IsBusy) { + this.webclient.Credentials = new NetworkCredential(this.username, this.password); this.webclient.Headers.Add(System.Net.HttpRequestHeader.UserAgent, "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)"); this.webclient.OpenReadAsync(this.url); this.lastCheckForUpdates = DateTime.Now; @@ -130,6 +177,7 @@ void webclient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e) if (info != null) { + info.CustomTitle = this.CustomName; info.Url = this.Url; OnFeedRetrieved(info); } @@ -165,11 +213,11 @@ void webclient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e) /// protected void OnFeedRetrieved(FeedInfo feed) { - this.name = feed.Title; + this.actualName = feed.ActualTitle; DateTimeOffset mostRecentItem = this.feedLastUpdated; if (mostRecentItem == DateTimeOffset.MaxValue) mostRecentItem = DateTimeOffset.MinValue; - System.Diagnostics.Debug.WriteLine(String.Format("Feed Retrieved: {0} - Most Recent Item: {1}", this.name, mostRecentItem)); + System.Diagnostics.Debug.WriteLine(String.Format("Feed Retrieved: {0} - Most Recent Item: {1}", this.Name, mostRecentItem)); if (FeedRetrieved != null) { diff --git a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/FeedInfo.cs b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/FeedInfo.cs index 9498c9f..305f7c3 100644 --- a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/FeedInfo.cs +++ b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/FeedInfo.cs @@ -7,7 +7,8 @@ namespace GrowlExtras.FeedMonitor { public class FeedInfo { - string title; + string actualTitle; + string customTitle; string url; List items; @@ -15,11 +16,34 @@ public string Title { get { - return this.title; + if (String.IsNullOrEmpty(this.customTitle)) + return this.actualTitle; + else + return this.customTitle; + } + } + + public string ActualTitle + { + get + { + return this.actualTitle; + } + set + { + this.actualTitle = value; + } + } + + public string CustomTitle + { + get + { + return this.customTitle; } set { - this.title = value; + this.customTitle = value; } } diff --git a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/GenericFeedParser.cs b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/GenericFeedParser.cs index f5b2f57..05c5bd7 100644 --- a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/GenericFeedParser.cs +++ b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/GenericFeedParser.cs @@ -36,7 +36,7 @@ public FeedInfo Parse(XmlReader reader) if (!parsingItems && name.ToLowerInvariant() == "title") { reader.Read(); - info.Title = reader.Value; + info.ActualTitle = reader.Value; } if (name.ToLowerInvariant() == "item" || name.ToLowerInvariant() == "entry") diff --git a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/SettingsPersister.cs b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/SettingsPersister.cs index 1a28b84..bd6cba3 100644 --- a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/SettingsPersister.cs +++ b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/SettingsPersister.cs @@ -46,9 +46,12 @@ public static void Persist(List feeds) foreach (Feed feed in feeds) { FeedElement fe = new FeedElement(); - fe.Name = feed.Name; + fe.Name = feed.ActualName; fe.Url = feed.Url; fe.PollInterval = feed.PollInterval; + fe.CustomName = feed.CustomName; + fe.Username = feed.Username; + fe.Password = feed.Password; section.Feeds.Add(fe); } @@ -72,7 +75,7 @@ public static List Read() { foreach (FeedElement fe in section.Feeds) { - Feed feed = Feed.Create(fe.Url, fe.PollInterval); + Feed feed = Feed.Create(fe.Url, fe.PollInterval, fe.CustomName, fe.Username, fe.Password); feeds.Add(feed); } } @@ -190,6 +193,45 @@ public int PollInterval this["pollinterval"] = value; } } + + [ConfigurationProperty("customname", IsRequired = false)] + public string CustomName + { + get + { + return (string)this["customname"]; + } + set + { + this["customname"] = value; + } + } + + [ConfigurationProperty("username", IsRequired = false)] + public string Username + { + get + { + return (string)this["username"]; + } + set + { + this["username"] = value; + } + } + + [ConfigurationProperty("password", IsRequired = false)] + public string Password + { + get + { + return (string)this["password"]; + } + set + { + this["password"] = value; + } + } } } } diff --git a/Growl Extras/Growl Display SDK/libraries/Growl.CoreLibrary.dll b/Growl Extras/Growl Display SDK/libraries/Growl.CoreLibrary.dll index 8067d10..16059a4 100644 Binary files a/Growl Extras/Growl Display SDK/libraries/Growl.CoreLibrary.dll and b/Growl Extras/Growl Display SDK/libraries/Growl.CoreLibrary.dll differ diff --git a/Growl Extras/Growl Display SDK/libraries/Growl.DisplayStyle.dll b/Growl Extras/Growl Display SDK/libraries/Growl.DisplayStyle.dll index 223275e..eaac910 100644 Binary files a/Growl Extras/Growl Display SDK/libraries/Growl.DisplayStyle.dll and b/Growl Extras/Growl Display SDK/libraries/Growl.DisplayStyle.dll differ diff --git a/Growl/Growl.Connector/ConnectorBase.cs b/Growl/Growl.Connector/ConnectorBase.cs index d8cd3bc..8887fd3 100644 --- a/Growl/Growl.Connector/ConnectorBase.cs +++ b/Growl/Growl.Connector/ConnectorBase.cs @@ -316,6 +316,14 @@ private void ReadCallback(IAsyncResult iar) if (length > 0) { string response = System.Text.Encoding.UTF8.GetString(state.Buffer, 0, length); + state.Response += response; + + // read additional data + while (state.Stream.DataAvailable) + { + AsyncCallback callback = new AsyncCallback(ReadCallback); + state.Stream.BeginRead(state.Buffer, 0, state.Buffer.Length, callback, state); + } if (state.Delegate != null) state.Delegate(response); @@ -481,6 +489,11 @@ public static TcpState FromConnectState(ConnectState cs, NetworkStream stream, b /// The buffer to hold the response /// public byte[] Buffer; + + /// + /// Holds the response text + /// + public string Response; } } } diff --git a/Growl/Growl.Connector/Properties/AssemblyInfo.cs b/Growl/Growl.Connector/Properties/AssemblyInfo.cs index 221dbe2..8619699 100644 --- a/Growl/Growl.Connector/Properties/AssemblyInfo.cs +++ b/Growl/Growl.Connector/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("2.0.0.0")] -[assembly: AssemblyFileVersion("2.0.0.21")] +[assembly: AssemblyFileVersion("2.0.0.22")] [assembly: AssemblyInformationalVersion("2.0")] diff --git a/Growl/Growl.CoreLibrary/ImageConverter.cs b/Growl/Growl.CoreLibrary/ImageConverter.cs index e423bb1..a682d63 100644 --- a/Growl/Growl.CoreLibrary/ImageConverter.cs +++ b/Growl/Growl.CoreLibrary/ImageConverter.cs @@ -47,13 +47,7 @@ public static System.Drawing.Image ImageFromBytes(byte[] bytes) System.IO.MemoryStream ms = new System.IO.MemoryStream(bytes, false); using (ms) { - ms.Position = 0; - System.Drawing.Image tempImage = System.Drawing.Bitmap.FromStream(ms); - // dont close stream yet, first create a copy - using (tempImage) - { - image = new Bitmap(tempImage); - } + image = ImageFromStream(ms); } } } @@ -81,12 +75,7 @@ public static System.Drawing.Image ImageFromUrl(string url) System.IO.FileStream fs = new System.IO.FileStream(uri.LocalPath, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite); using (fs) { - System.Drawing.Image tempImage = System.Drawing.Bitmap.FromStream(fs); - // dont close stream yet, first create a copy - using (tempImage) - { - image = new Bitmap(tempImage); - } + image = ImageFromStream(fs); } } else @@ -98,13 +87,7 @@ public static System.Drawing.Image ImageFromUrl(string url) System.IO.MemoryStream ms = new System.IO.MemoryStream(bytes, false); using (ms) { - ms.Position = 0; - System.Drawing.Image tempImage = System.Drawing.Bitmap.FromStream(ms); - // dont close stream yet, first create a copy - using (tempImage) - { - image = new Bitmap(tempImage); - } + image = ImageFromStream(ms); } } } @@ -116,6 +99,38 @@ public static System.Drawing.Image ImageFromUrl(string url) return image; } + private static System.Drawing.Image ImageFromStream(System.IO.Stream stream) + { + System.Drawing.Image image = null; + try + { + stream.Position = 0; + System.Drawing.Image tempImage = System.Drawing.Bitmap.FromStream(stream); + // dont close stream yet, first create a copy + using (tempImage) + { + image = new Bitmap(tempImage); + } + } + catch + { + // the file could be an .ico file that is not usable by the Image class, so try that just in case + try + { + stream.Position = 0; + Icon icon = new Icon(stream); + if (icon != null) image = icon.ToBitmap(); + } + catch + { + // give up - we cant open this file type + } + } + + return image; + } + + /* I AM JUST SAVING THIS FOR NOW private byte[] ConvertToBytes2(Bitmap bmp) { diff --git a/Growl/Growl.CoreLibrary/Properties/AssemblyInfo.cs b/Growl/Growl.CoreLibrary/Properties/AssemblyInfo.cs index 1375f5e..adf8e0f 100644 --- a/Growl/Growl.CoreLibrary/Properties/AssemblyInfo.cs +++ b/Growl/Growl.CoreLibrary/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("2.0.0.0")] -[assembly: AssemblyFileVersion("2.0.0.21")] +[assembly: AssemblyFileVersion("2.0.0.22")] [assembly: AssemblyInformationalVersion("2.0")] diff --git a/Growl/Growl.Daemon/AsyncSocket.cs b/Growl/Growl.Daemon/AsyncSocket.cs index a99b625..ab657a8 100644 --- a/Growl/Growl.Daemon/AsyncSocket.cs +++ b/Growl/Growl.Daemon/AsyncSocket.cs @@ -1781,7 +1781,7 @@ public void Close() { flags |= kClosed; - ThreadPool.QueueUserWorkItem(new WaitCallback(Close)); + ThreadPool.QueueUserWorkItem(new WaitCallback(Close), null); } /// diff --git a/Growl/Growl.Daemon/MessageHandler.cs b/Growl/Growl.Daemon/MessageHandler.cs index 71a20a3..e05ebec 100644 --- a/Growl/Growl.Daemon/MessageHandler.cs +++ b/Growl/Growl.Daemon/MessageHandler.cs @@ -816,9 +816,9 @@ public void SocketDidRead(AsyncSocket socket, byte[] readBytes, long tag) { WriteError(socket, gEx.ErrorCode, gEx.Message, gEx.AdditionalInfo); } - catch + catch(Exception ex) { - WriteError(socket, ErrorCode.INVALID_REQUEST, ErrorDescription.MALFORMED_REQUEST); + WriteError(socket, ErrorCode.INVALID_REQUEST, ErrorDescription.MALFORMED_REQUEST, ex.Message); } } @@ -1201,6 +1201,8 @@ private void ParseEncryptedMessage(byte[] bytes) //byte[] decryptedBytes = Cryptography.Decrypt(encryptionKey, this.iv, encryptedBytes, this.encryptionAlgorithm); byte[] decryptedBytes = this.key.Decrypt(encryptedBytes, this.iv); + string x = Encoding.UTF8.GetString(decryptedBytes); + System.IO.MemoryStream stream = new System.IO.MemoryStream(decryptedBytes); using (stream) { @@ -1224,16 +1226,6 @@ private void ParseEncryptedMessage(byte[] bytes) WriteError(socket, ErrorCode.INVALID_REQUEST, ErrorDescription.NO_NOTIFICATIONS_REGISTERED); } } - else - { - // otherwise, check the number of resource pointers we got and start reading those - this.pointersExpected = GetNumberOfPointers(); - if (this.pointersExpected > 0) - { - this.pointersExpectedRemaining = this.pointersExpected; - this.currentPointer = 1; - } - } break; } else @@ -1291,13 +1283,6 @@ private void ParseEncryptedMessage(byte[] bytes) } else { - // otherwise, check the number of resource pointers we got and start reading those - this.pointersExpected = GetNumberOfPointers(); - if (this.pointersExpected > 0) - { - this.pointersExpectedRemaining = this.pointersExpected; - this.currentPointer = 1; - } break; } } @@ -1313,6 +1298,14 @@ private void ParseEncryptedMessage(byte[] bytes) } } } + + // now that we have read the stream, check for any embedded resources + this.pointersExpected = GetNumberOfPointers(); + if (this.pointersExpected > 0) + { + this.pointersExpectedRemaining = this.pointersExpected; + this.currentPointer = 1; + } } } } diff --git a/Growl/Growl.Daemon/Properties/AssemblyInfo.cs b/Growl/Growl.Daemon/Properties/AssemblyInfo.cs index 9c8b5c0..9d83420 100644 --- a/Growl/Growl.Daemon/Properties/AssemblyInfo.cs +++ b/Growl/Growl.Daemon/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("2.0.0.0")] -[assembly: AssemblyFileVersion("2.0.0.21")] +[assembly: AssemblyFileVersion("2.0.0.22")] [assembly: AssemblyInformationalVersion("2.0")] diff --git a/Growl/Growl.Daemon/RequestInfo.cs b/Growl/Growl.Daemon/RequestInfo.cs index a1010c5..c007eba 100644 --- a/Growl/Growl.Daemon/RequestInfo.cs +++ b/Growl/Growl.Daemon/RequestInfo.cs @@ -169,5 +169,15 @@ internal List HandlingInfo return this.handlingInfo; } } + + public bool WasForwarded() + { + if (this.previousReceivedHeaders != null && this.previousReceivedHeaders.Count > 0) + { + return true; + } + else + return false; + } } } diff --git a/Growl/Growl.Daemon/Subscriber.cs b/Growl/Growl.Daemon/Subscriber.cs index ca1fd32..7a7cd9d 100644 --- a/Growl/Growl.Daemon/Subscriber.cs +++ b/Growl/Growl.Daemon/Subscriber.cs @@ -144,15 +144,6 @@ internal set } } - /// - /// Generates a UUID for a subscriber - /// - /// UUID (string) - public static string GenerateID() - { - return System.Guid.NewGuid().ToString(); - } - /// /// Converts the object to a list of headers /// diff --git a/Growl/Growl.DisplayStyle/NotificationLite.cs b/Growl/Growl.DisplayStyle/NotificationLite.cs index 7c2ce6d..2056b5c 100644 --- a/Growl/Growl.DisplayStyle/NotificationLite.cs +++ b/Growl/Growl.DisplayStyle/NotificationLite.cs @@ -54,6 +54,11 @@ public class NotificationLite /// public int Duration; + /// + /// The name of the machine where the notification originated + /// + public string OriginMachineName; + /// /// Creates a new instance, copying the property values /// of the . @@ -69,6 +74,8 @@ public static NotificationLite Clone(NotificationLite original) n.Description = original.Description; n.Priority = original.Priority; n.Sticky = original.Sticky; + n.Duration = original.Duration; + n.OriginMachineName = original.OriginMachineName; return n; } } diff --git a/Growl/Growl.DisplayStyle/NotificationWindow.cs b/Growl/Growl.DisplayStyle/NotificationWindow.cs index b48b88e..adb1003 100644 --- a/Growl/Growl.DisplayStyle/NotificationWindow.cs +++ b/Growl/Growl.DisplayStyle/NotificationWindow.cs @@ -11,6 +11,9 @@ namespace Growl.DisplayStyle /// public class NotificationWindow : Form { + private const int WS_EX_TOOLWINDOW = 0x80; + private const int WS_EX_APPWINDOW = 0x40000; + /// /// Fires after Load but before BeforeShown /// @@ -137,6 +140,22 @@ public NotificationWindow() this.displayTimer.Tick += new EventHandler(displayTimer_Tick); } + /// + /// Overridden to set the WS_EX_TOOLWINDOW style bit so that notification windows don't + /// show up in the Alt-Tab list. + /// + /// + protected override CreateParams CreateParams + { + get + { + CreateParams cp = base.CreateParams; + cp.ExStyle |= WS_EX_TOOLWINDOW; // turn on WS_EX_TOOLWINDOW style bit + cp.ExStyle &= ~WS_EX_APPWINDOW; // turn off WS_EX_APPWINDOW style bit + return cp; + } + } + /// /// Raises the , , and events. /// diff --git a/Growl/Growl.DisplayStyle/Properties/AssemblyInfo.cs b/Growl/Growl.DisplayStyle/Properties/AssemblyInfo.cs index c1f2cc1..c947020 100644 --- a/Growl/Growl.DisplayStyle/Properties/AssemblyInfo.cs +++ b/Growl/Growl.DisplayStyle/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("2.0.0.0")] -[assembly: AssemblyFileVersion("2.0.0.21")] +[assembly: AssemblyFileVersion("2.0.0.22")] [assembly: AssemblyInformationalVersion("2.0")] diff --git a/Growl/Growl.Displays.Plain/Properties/AssemblyInfo.cs b/Growl/Growl.Displays.Plain/Properties/AssemblyInfo.cs index dd00c01..1faab59 100644 --- a/Growl/Growl.Displays.Plain/Properties/AssemblyInfo.cs +++ b/Growl/Growl.Displays.Plain/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("2.0.0.0")] -[assembly: AssemblyFileVersion("2.0.0.21")] +[assembly: AssemblyFileVersion("2.0.0.22")] [assembly: AssemblyInformationalVersion("2.0")] diff --git a/Growl/Growl.Displays.Smokestack/Properties/AssemblyInfo.cs b/Growl/Growl.Displays.Smokestack/Properties/AssemblyInfo.cs index d97212e..420b149 100644 --- a/Growl/Growl.Displays.Smokestack/Properties/AssemblyInfo.cs +++ b/Growl/Growl.Displays.Smokestack/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("2.0.0.0")] -[assembly: AssemblyFileVersion("2.0.0.21")] +[assembly: AssemblyFileVersion("2.0.0.22")] [assembly: AssemblyInformationalVersion("2.0")] diff --git a/Growl/Growl.Displays.Standard/Properties/AssemblyInfo.cs b/Growl/Growl.Displays.Standard/Properties/AssemblyInfo.cs index d6a2869..80958cb 100644 --- a/Growl/Growl.Displays.Standard/Properties/AssemblyInfo.cs +++ b/Growl/Growl.Displays.Standard/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("2.0.0.0")] -[assembly: AssemblyFileVersion("2.0.0.21")] +[assembly: AssemblyFileVersion("2.0.0.22")] [assembly: AssemblyInformationalVersion("2.0")] diff --git a/Growl/Growl.Displays.Standard/StandardWindow.cs b/Growl/Growl.Displays.Standard/StandardWindow.cs index 01421a3..b1dd104 100644 --- a/Growl/Growl.Displays.Standard/StandardWindow.cs +++ b/Growl/Growl.Displays.Standard/StandardWindow.cs @@ -153,7 +153,8 @@ public override void SetNotification(Notification n) this.descriptionLabel.Width = this.descriptionLabel.Width - offset; } - this.applicationNameLabel.Text = n.ApplicationName; + string applicationNameFormat = (!String.IsNullOrEmpty(n.OriginMachineName) ? "{0} on {1}" : "{0}"); + this.applicationNameLabel.Text = String.Format(applicationNameFormat, n.ApplicationName, n.OriginMachineName); this.titleLabel.Text = n.Title; this.descriptionLabel.Text = n.Description.Replace("\n", "\r\n"); this.Sticky = n.Sticky; diff --git a/Growl/Growl.Displays.Toast/Properties/AssemblyInfo.cs b/Growl/Growl.Displays.Toast/Properties/AssemblyInfo.cs index 0d2f54f..7b50a7a 100644 --- a/Growl/Growl.Displays.Toast/Properties/AssemblyInfo.cs +++ b/Growl/Growl.Displays.Toast/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("2.0.0.0")] -[assembly: AssemblyFileVersion("2.0.0.21")] +[assembly: AssemblyFileVersion("2.0.0.22")] [assembly: AssemblyInformationalVersion("2.0")] diff --git a/Growl/Growl.Displays.Visor/Properties/AssemblyInfo.cs b/Growl/Growl.Displays.Visor/Properties/AssemblyInfo.cs index 82aac7f..859e531 100644 --- a/Growl/Growl.Displays.Visor/Properties/AssemblyInfo.cs +++ b/Growl/Growl.Displays.Visor/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("2.0.0.0")] -[assembly: AssemblyFileVersion("2.0.0.21")] +[assembly: AssemblyFileVersion("2.0.0.22")] [assembly: AssemblyInformationalVersion("2.0")] diff --git a/Growl/Growl.Localization.de-DE/Growl.Localization.de-DE.csproj b/Growl/Growl.Localization.de-DE/Growl.Localization.de-DE.csproj new file mode 100644 index 0000000..870572b --- /dev/null +++ b/Growl/Growl.Localization.de-DE/Growl.Localization.de-DE.csproj @@ -0,0 +1,56 @@ + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {774E3560-B4CA-4041-A21E-A9437FD3C932} + Library + Properties + Growl + Growl + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + Designer + + + + + + del "$(ProjectDir)$(OutDir)Growl.dll" +del "$(ProjectDir)$(OutDir)Growl.pdb" +xcopy "$(ProjectDir)$(OutDir)*.*" "$(SolutionDir)Growl\$(OutDir)" /E /Y /C + + \ No newline at end of file diff --git a/Growl/Growl.Localization.de-DE/Properties.Resources.de-DE.resx b/Growl/Growl.Localization.de-DE/Properties.Resources.de-DE.resx new file mode 100644 index 0000000..11272cb --- /dev/null +++ b/Growl/Growl.Localization.de-DE/Properties.Resources.de-DE.resx @@ -0,0 +1,883 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +text/microsoft-resx + + +2.0 + + +System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + +System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + +Growl (gestoppt) +Tooltip for notify icon when Growl is not running + + +(build: {0}) +About tab: build number information - Placeholder {0} is the actual build number + + +Displays, Extensions und Updates: +About tab: Growl website label + + +Growl v{0} +About tab: name and version - Placeholder {0} is the actual version number + + +Icons: +About tab: Icons + + +VistaICO Aero Pack - +About tab: VistaICO label + + +Original idea, inspiration, and logo: +About tab: original Growl + + +Growl fr OSX - +About tab: Growl for OSX + + +Hostname: +Add Computer form: Address label + + +Format: +Add Computer form: Format label + + +Benachrichtigungen weiterleiten +Add Computer form title - when fowarding + + +Benachrichtigungen abonnieren +Add Computer form title - when subscribing + + +[Hier klicken um einen nicht in der Liste aufgef�hrten +Computer hinzuzuf�gen] +Add Computer form: click to add a computer not detected by Bonjour + + +Name: +Add Computer form: Name label + + +Passwort: +Add Computer form: Password label + + +Port: +Add Computer form: Port label + + +(Alle Benachrichtigungen) +Applications tab: list item for application-wide preferences + + +Noch keine Programme registriert. + +Wenn ein Programm das Growl unterst�tzt sich anmeldet um Benachrichtigungen zu senden, erscheint es in der Liste auf der linken Seite und Sie k�nnen dann seine Einstellungen �ndern. +Applications tab: shown when no applications are registered + + +Display: +Applications tab: display preference label + + +Aktiv: +Applications tab: enabled preference label + + +Weiterleiten: +Applications tab: forwarding preference label + + +Priorit�t: +Applications tab: priority preference label + + +Kl�nge: +Applications tab: sound preference label + + +Sticky: +Applications tab: sticky preference label + + +Programm entfernen +Applications tab: 'Remove Applications' context menu item + + +Abbrechen +Any 'Cancel' button + + +L�schen +Any 'Clear' button + + +Schlie�en +Any 'Close' button + + +Sp�ter +Any 'Later' button + + +OK +Any 'OK' button + + +Vorschau +Any 'Preview' button + + +Speichern +Any 'Save' button + + +Ja +Any 'Yes' button + + +Weiterleitung ausw�hlen +Choose Forwarding form title + + +[Standard] +The name displayed for the '[Default]' preference option + + +Growl konnte nicht gestartet weden +MessageBox caption shown if Growl fails to start + + +Der TCP-Port von Growl ist schon belegt ({0}). + + +Wenn schon eine andere Version von Growl l�uft, beenden Sie diese bitte und versuchen Sie es nochmal. +MessageBox text shown if Growl fails to start the GNTP listener. Placeholder {0} is the port number. + + +Der UDP-Port von Growl ist schon belegt ({0}). + +Wenn schon eine andere Version von Growl l�uft, beenden Sie diese bitte und versuchen Sie es nochmal. +MessageBox text shown if Growl fails to start the UDPlistener. Placeholder {0} is the port number. + + +Growl ist angehalten +General tab: Displayed when Growl is paused + + +Growl l�uft +General tab: Displayed when Growl is running + + +Growl ist beendet +General tab: Displaysed when Growl is stopped + + +Growl automatisch beim Login starten +General tab: auto start checkbox text + + +Display: +General tab: Default Display label + + +Klang: +General tab: Default Sound label + + +Standardeinstellungen +General tab: Default Settings group box title + + +Nach {0} Sekunden "unt�tig" setzten +General tab: Radio button text for 'consider me idle after x seconds' - Placeholder {0} is where the TextBox will go + + +Mich niemals "unt�tig" oder "abwesend" setzten +General tab: Radio button text for 'never consider me idle' + + +Abwesenheitseinstellungen +General tab: Idle Settings group box title + + +(Keine benachrichtigungen f�r dieses Datum) +History tab: shown when sorted by date and the date had no notifications + + +Anzahl der Tage +History tab: Number of Days + + +Programm +History tab: sort by application radio button label + + +Datum +History tab: sort by date radio button label + + +Sortierung +History tab: Sort By + + +format +The string 'format' (used in forward list view to show protocol format) + + +Empfangen am +The string 'Received At' (used in History for each past notification to indicate the date/time the notification was received) + + +Empfangen von +The string 'Received From' (used in History for each past notification item to indicate which application sent the notification) + + +Heute +The string 'Today' (used in History view for the current day) + + +Gestern +ry view for yesterday's date) + + +Lade Liste der Programme... +Loading progress indicator: Application list + + +Lade Display '{0}' ... +Loading progress indicator for a specific display - Placeholder {0} is the display name + + +Lade Displays... +Loading progress indicator: Displays + + +Lade Verlauf... +Loading progress indicator: History + + +Initialisiere... +Loading progress indicator: Initializing + + +Lade Einstellungen... +Loading progress indicator: Preferences + + +Bereit +Loading progress indicator: Ready + + +Starte Growl... +Loading progress indicator: Starting + + +Sie haben {0} Nachrichten verpasst, w�hrend Sie abwesend waren. +Missed Notifications Summary: the summary text - Placeholder {0} is the number of notifications missed. + + +Benachrichtigungen an andere Computer weiterleiten +Network tab: checkbox text for 'forward notifications to other computers' + + +Computer entfernen +Network tab: 'Remove Computer' context menu item + + +Benachrichtigungen von anderen Computern abonnieren +Network tab: checkbox text for 'subscribe to notifications from other computers' + + +Auf Updates pr�fen +Notify icon context menu: Check for updates + + +Schlie�en +Notify icon context menu: Exit + + +Growl anhalten +Notify icon context menu: Pause + + +Einstellungen +Notify icon context menu: Settings + + +Growl fortsetzen +Notify icon context menu: Unpause + + +Growl (angehalten) +Tooltip for notificy icon when Growl is paused + + +Growl +Tooltip for notify icon when Growl is running + + +Falsch +Enabled Pref: False + + +Wahr +Enabled Pref: True + + +Ausw�hlen... +Forwarding Pref: Choose + + +Nicht weiterleiten +Forwarding Pref: Never + + +Notfall +Priority Pref: Emergency + + +Hoch +Priority Pref: High + + +Niedrig +Priority Pref: Low + + +Normal +Priority Pref: Normal + + +Sehr niedrig +Priority Pref: Very Low + + +Keine +Sound Pref: None + + +Immer +Sticky Pref: Always + + +Niemals +Sticky Pref: Never + + +Wenn unt�tig +Sticky Pref: When Idle + + +GNTP +GNTP protocol name (used in forwarding dropdown, etc) + + +UDP +UDP protocol name (used in forwarding dropdown, etc) + + +Netzwerk-Benachrichtigungen erlauben +Security tab: checkbox text for 'allow network notificaions' + + +Clients erlauben, Benachrichtigungen zu abonnieren +Security tab: checkbox text for 'allows subscriptions' + + +Benachrichtungen von Websites erlauben +Security tab: checkbox text for 'allow web notifications' + + +Beschreibung: +Security tab: Password Manager 'Description' label + + +Bearbeiten +Security tab: Password Manager 'Edit' context menu item + + +Bite geben Sie unten Ihr Passwort und eine Passwortbeschreibung ein. +Security tab: Password Manager instructions + + +Passwort: +Security tab: Password Manager 'Password' label + + +Passwort-Manager +Security tab: Password Manager title + + +Lokale Programme ben�tigen ein Passwort +Security tab: checkbox text for 'require password for local apps' + + +Growl +Settings form title + + +Lade... +The loading progress indicator shown on the initial splash screen. + + +Growl f�r Windows +The name of the application shown on the initial splash screen + + +Version: {0} +The version informatino shown on the initial splash screen. Placeholder {0} is the version number. + + +Growl +The application name used for system notifications + + +Das Programm '{0}' hat sich f�r Benachrichtigungen registriert. +Notification text when an application registers. Placeholder {0} is the application name. + + +Programm-Registration +The title used for the system notification when an application registers + + +Der Client '{0}' hat die Weiterleitung von Benachrichtigungen abonniert. +Notification text when a client subscribes to notifications. Placeholder {0} is the subscribing client's name. + + +Client Abonnement +The title used for the system notification when a client subscribes to notifications + + +Das ist eine Vorschau des Displays '{0}'. +Notification text shown for preview notifications - Placeholder {0} is the actual display name + + +Display Vorschau +The title used for preview notifications + + +Growl l�uft +Notification text shown when Growl starts + + +Growl +The title used for the system notification when Growl starts + + +�ber +'About' tab title + + +Programme +'Applications' tab title + + +Displays +'Displays' tab title + + +Allgemein +'General' tab title + + +Verlauf +'History' tab title + + +Netzwerk +'Network' tab title + + +Sicherheit +'Security' tab title + + +Download abgeschlossen. Installation wird gestartet... +Check for Updates form: displayed when the update has finished downloading and the installation is starting + + +Update herunterladen... +Check for Updates form: displayed while an update is downloading + + +Auf Updates �berpr�fen +Check for Updates form title + + +Growl ist aktuell. Jetzige Version: {1} +Check for Updates form: displayed when Growl is up-to-date. Placeholder {0} is any newer version number, {1} is the current up-to-date version number + + +Version {0} von Growl verf�gbar. Wollen Sie Growl auf die neuesteVersion updaten? (Aktuelle Version: {1}) +Check for Updates form: displayed when an update is available. Placeholder {0} is the newer version number, {1} is the current version number + + + Set as Default + Any 'Set as Default' button + + + Author: + Displays tab: created by label + + + Mute all sounds + General tab: mute all sounds label + + + When a Growl-enabled application registers to send notifications, it will appear in the list to the left and you will be able to customize its settings. + Applications tab: shown when no applications are registered + + + Mute + Notify icon context menu: Mute + + + Unmute + Notify icon context menu: Unmute + + + Application Name + Applications tab: Header text for applications list box + + + Notification Type + Applications tab: Header text for notifications list box + + + Display Name + Displays tab: Header text for displays list box + + + seconds + The string 'seconds' (Used in Duration preference) + + + Duration: + Applications tab: duration preference label + + + Display '{0}' is already installed. + Display installer: message shown if a display is already installed when attempting to install again + + + The definition file '{0}' is invalid.\n\nThe display could not be installed. + Display installer: message shown if the definition file is malformed. {0} is the path to the file + + + The installation of the display was cancelled.\n\nThe display was not installed. + Display installer: message shown if the download is cancelled by the user + + + An error occurred while downloading the display files.\n\nThe display was not installed. + Display installer: message shown if the download of the display files fails for any reason + + + Install Display + Display installer: form title + + + Installing display... + Display installer: displayed while the display is being installed + + + The display '{0}' was installed successfully. + Display installer: text of the notification shown when a new display is installed. {0} is the name of the installed display. + + + New Display Installed + Display installer: title of the notification shown when a new display is installed + + + The definition file '{0}' does not exist.\n\nThe display could not be installed. + Display installer: message shown if the definition file could not be found. {0} is the file path + + + Do you want to install the following display?\n\nName: {0}\nAuthor: {1}\nDescription: {2} + Display installer: displayed when a click-to-install link is clicked. {0} is the name of the display, {1} is the author, and {2} is the description + + + Find & install additional displays + Displays tab: text that links to the GFW website to find more displays + + + Click here to forward notifications to +an iPhone + Add computer form: click to forward notification to iphone + + + Click here to forward notifications to +an email account + Add computer form: click to add email forwarding + + + Click here to forward notifications +to Twitter + Add computer form: click to forward notifications to Twitter + + + [Any Priority] + Configure iPhone Forwarding: label for combobox choice for forwarding all notification priorities + + + Only forward when priority is at least: + Configure iPhone Forwarding: label for minimum priority + + + Description: + Configure iPhone Forwarding: 'Description' label + + + API Key: + Configure iPhone Forwarding: 'API Key' label + + + Only forward when idle or away + Configure iphone forwarding: 'only forward when idle' checkbox text + + + [Any Priority] + Configure Twitter Forwarding: label for combobox choice for forwarding all notification priorities + + + Only forward when priority is at least: + Configure Twitter Forwarding: label for minimum priority + + + Password: + Configure Twitter Forwarding: 'Password' label + + + Username: + Configure Twitter Forwarding: 'Username' label + + + Format: + Configure Twitter Forwarding: 'Format' label + + + Only forward when idle or away + Configure Twitter forwarding: 'only forward when idle' checkbox text + + + Always + The string 'Always' + + + Idle Only + The string 'Idle Only' + + + Edit + Network tab: 'Edit' context menu item + + + You have successfully configured Growl to forward notifications to Prowl + Text of Prowl confirmation notification sent to confirm successful configuration + + + Prowl Test + Title of Prowl confirmation notification sent to confirm successful configuration + + + [Any Priority] + Configure Email Forwarding: label for combobox choice for forwarding all notification priorities + + + Only forward when priority is at least: + Configure Email Forwarding: label for minimum priority + + + Description: + Configure Email Forwarding: 'Description' label + + + Email Address: + Configure Email Forwarding: 'Email Address' label + + + SMTP Settings: + Configure Email Forwarding: 'SMTP Settings' label + + + edit + Configure Email Forwarding: 'edit' link + + + Only forward when idle or away + Configure Email forwarding: 'only forward when idle' checkbox text + + + Server: + Configure Email forwarding SMTP Settings: 'Server' label + + + Port: + Configure Email forwarding SMTP Settings: 'Port' label + + + Use Authentication + Configure Email forwarding SMTP Settings: 'Use Authentication' checkbox text + + + Use SSL + Configure Email forwarding SMTP Settings: 'Use SSL' checkbox text + + + Username: + Configure Email forwarding SMTP Settings: 'Username' label + + + Password: + Configure Email forwarding SMTP Settings: 'Password' label + + + done + Configure Email forwarding SMTP Settings: 'done' link + + + Application + History tab: Column header for Application column + + + Text + History tab: Column header for Text column + + + Timestamp + History tab: Column header for Timestamp column + + + Title + History tab: Column header for Title column + + + Details View + History tab: Details View context menu option + + + Tile View + History tab: Tile View context menu option + + + No + Any 'No' button + + \ No newline at end of file diff --git a/Growl/Growl.Localization.de-DE/Properties/AssemblyInfo.cs b/Growl/Growl.Localization.de-DE/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..16fd871 --- /dev/null +++ b/Growl/Growl.Localization.de-DE/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Growl.Localization.de-DE")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("element code project")] +[assembly: AssemblyProduct("Growl.Localization.de-DE")] +[assembly: AssemblyCopyright("Copyright © element code project 2009")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("de-DE")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("b30bea1c-88dd-4a2a-8524-9e6b66f5ddc0")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Growl/Growl.Localization.en-GB/Growl.Localization.en-GB.csproj b/Growl/Growl.Localization.en-GB/Growl.Localization.en-GB.csproj index ad84ec0..2aeebdb 100644 --- a/Growl/Growl.Localization.en-GB/Growl.Localization.en-GB.csproj +++ b/Growl/Growl.Localization.en-GB/Growl.Localization.en-GB.csproj @@ -31,7 +31,6 @@ - diff --git a/Growl/Growl.Localization.en-GB/Properties.Resources.en-GB.resx b/Growl/Growl.Localization.en-GB/Properties.Resources.en-GB.resx index 99feba0..8b2ce46 100644 --- a/Growl/Growl.Localization.en-GB/Properties.Resources.en-GB.resx +++ b/Growl/Growl.Localization.en-GB/Properties.Resources.en-GB.resx @@ -166,8 +166,8 @@ Add Computer form title - when subscribing - [Click here to manually add a computer -that is not in this list] + Click here to manually add a computer +that is not in this list Add Computer form: click to add a computer not detected by Bonjour @@ -186,10 +186,8 @@ that is not in this list] (All notifications) Applications tab: list item for application-wide preferences - - No applications have registered yet. - -When a Growl-enabled application registers to send notifications, it will appear in the list to the left and you will be able to customize its settings. + + No Applications Have Registered Yet Applications tab: shown when no applications are registered @@ -292,21 +290,17 @@ If another version of Growl is already running, please close that version and tr Automatically start Growl at login General tab: auto start checkbox text - - Display: - General tab: Default Display label - - - Sound: + + Default Sound: General tab: Default Sound label - - Default Settings - General tab: Default Settings group box title + + Sound Settings + General tab: Sound Settings group box title - Consider me idle after {0} seconds - General tab: Radio button text for 'consider me idle after x seconds' - Placeholder {0} is where the TextBox will go + Consider me idle after seconds + General tab: Radio button text for 'consider me idle after x seconds' Never consider me idle or away @@ -333,8 +327,8 @@ If another version of Growl is already running, please close that version and tr History tab: sort by date radio button label - Sort By - History tab: Sort By + Group By + History tab: Group By format @@ -397,8 +391,8 @@ If another version of Growl is already running, please close that version and tr Network tab: checkbox text for 'forward notifications to other computers' - Remove Computer - Network tab: 'Remove Computer' context menu item + Remove + Network tab: 'Remove' context menu item Subscribe to notifications from other computers @@ -417,8 +411,8 @@ If another version of Growl is already running, please close that version and tr Notify icon context menu: Pause - Settings - Notify icon context menu: Settings + Open Growl + Notify icon context menu: Open Growl (formerly Settings) Unpause Growl @@ -628,4 +622,255 @@ If another version of Growl is already running, please close that version and tr Version {0} of Growl is available. Would you like to update Growl to the latest version? (Current version: {1}) Check for Updates form: displayed when an update is available. Placeholder {0} is the newer version number, {1} is the current version number + + Set as Default + Any 'Set as Default' button + + + Author: + Displays tab: created by label + + + Mute all sounds + General tab: mute all sounds label + + + When a Growl-enabled application registers to send notifications, it will appear in the list to the left and you will be able to customize its settings. + Applications tab: shown when no applications are registered + + + Mute + Notify icon context menu: Mute + + + Unmute + Notify icon context menu: Unmute + + + Application Name + Applications tab: Header text for applications list box + + + Notification Type + Applications tab: Header text for notifications list box + + + Display Name + Displays tab: Header text for displays list box + + + seconds + The string 'seconds' (Used in Duration preference) + + + Duration: + Applications tab: duration preference label + + + Display '{0}' is already installed. + Display installer: message shown if a display is already installed when attempting to install again + + + The definition file '{0}' is invalid.\n\nThe display could not be installed. + Display installer: message shown if the definition file is malformed. {0} is the path to the file + + + The installation of the display was cancelled.\n\nThe display was not installed. + Display installer: message shown if the download is cancelled by the user + + + An error occurred while downloading the display files.\n\nThe display was not installed. + Display installer: message shown if the download of the display files fails for any reason + + + Install Display + Display installer: form title + + + Installing display... + Display installer: displayed while the display is being installed + + + The display '{0}' was installed successfully. + Display installer: text of the notification shown when a new display is installed. {0} is the name of the installed display. + + + New Display Installed + Display installer: title of the notification shown when a new display is installed + + + The definition file '{0}' does not exist.\n\nThe display could not be installed. + Display installer: message shown if the definition file could not be found. {0} is the file path + + + Do you want to install the following display?\n\nName: {0}\nAuthor: {1}\nDescription: {2} + Display installer: displayed when a click-to-install link is clicked. {0} is the name of the display, {1} is the author, and {2} is the description + + + Find & install additional displays + Displays tab: text that links to the GFW website to find more displays + + + Click here to forward notifications to +an iPhone + Add computer form: click to forward notification to iphone + + + Click here to forward notifications to +an email account + Add computer form: click to add email forwarding + + + Click here to forward notifications +to Twitter + Add computer form: click to forward notifications to Twitter + + + [Any Priority] + Configure iPhone Forwarding: label for combobox choice for forwarding all notification priorities + + + Only forward when priority is at least: + Configure iPhone Forwarding: label for minimum priority + + + Description: + Configure iPhone Forwarding: 'Description' label + + + API Key: + Configure iPhone Forwarding: 'API Key' label + + + Only forward when idle or away + Configure iphone forwarding: 'only forward when idle' checkbox text + + + [Any Priority] + Configure Twitter Forwarding: label for combobox choice for forwarding all notification priorities + + + Only forward when priority is at least: + Configure Twitter Forwarding: label for minimum priority + + + Password: + Configure Twitter Forwarding: 'Password' label + + + Username: + Configure Twitter Forwarding: 'Username' label + + + Format: + Configure Twitter Forwarding: 'Format' label + + + Only forward when idle or away + Configure Twitter forwarding: 'only forward when idle' checkbox text + + + Always + The string 'Always' + + + Idle Only + The string 'Idle Only' + + + Edit + Network tab: 'Edit' context menu item + + + You have successfully configured Growl to forward notifications to Prowl + Text of Prowl confirmation notification sent to confirm successful configuration + + + Prowl Test + Title of Prowl confirmation notification sent to confirm successful configuration + + + [Any Priority] + Configure Email Forwarding: label for combobox choice for forwarding all notification priorities + + + Only forward when priority is at least: + Configure Email Forwarding: label for minimum priority + + + Description: + Configure Email Forwarding: 'Description' label + + + Email Address: + Configure Email Forwarding: 'Email Address' label + + + SMTP Settings: + Configure Email Forwarding: 'SMTP Settings' label + + + edit + Configure Email Forwarding: 'edit' link + + + Only forward when idle or away + Configure Email forwarding: 'only forward when idle' checkbox text + + + Server: + Configure Email forwarding SMTP Settings: 'Server' label + + + Port: + Configure Email forwarding SMTP Settings: 'Port' label + + + Use Authentication + Configure Email forwarding SMTP Settings: 'Use Authentication' checkbox text + + + Use SSL + Configure Email forwarding SMTP Settings: 'Use SSL' checkbox text + + + Username: + Configure Email forwarding SMTP Settings: 'Username' label + + + Password: + Configure Email forwarding SMTP Settings: 'Password' label + + + done + Configure Email forwarding SMTP Settings: 'done' link + + + Application + History tab: Column header for Application column + + + Text + History tab: Column header for Text column + + + Timestamp + History tab: Column header for Timestamp column + + + Title + History tab: Column header for Title column + + + Details View + History tab: Details View context menu option + + + Tile View + History tab: Tile View context menu option + + + No + Any 'No' button + \ No newline at end of file diff --git a/Growl/Growl.Localization.ja-JP/Growl.Localization.ja-JP.csproj b/Growl/Growl.Localization.ja-JP/Growl.Localization.ja-JP.csproj index 11379f7..66514c1 100644 --- a/Growl/Growl.Localization.ja-JP/Growl.Localization.ja-JP.csproj +++ b/Growl/Growl.Localization.ja-JP/Growl.Localization.ja-JP.csproj @@ -31,7 +31,6 @@ - diff --git a/Growl/Growl.Localization.ja-JP/Properties.Resources.ja-JP.resx b/Growl/Growl.Localization.ja-JP/Properties.Resources.ja-JP.resx index 74a5ce7..4564686 100644 --- a/Growl/Growl.Localization.ja-JP/Properties.Resources.ja-JP.resx +++ b/Growl/Growl.Localization.ja-JP/Properties.Resources.ja-JP.resx @@ -628,4 +628,255 @@ Growlのバージョン{0}が利用可能です。Growlを最新版にアップデートしますか? (最新版:{1}) Check for Updates form: displayed when an update is available. Placeholder {0} is the newer version number, {1} is the current version number + + Set as Default + Any 'Set as Default' button + + + Author: + Displays tab: created by label + + + Mute all sounds + General tab: mute all sounds label + + + When a Growl-enabled application registers to send notifications, it will appear in the list to the left and you will be able to customize its settings. + Applications tab: shown when no applications are registered + + + Mute + Notify icon context menu: Mute + + + Unmute + Notify icon context menu: Unmute + + + Application Name + Applications tab: Header text for applications list box + + + Notification Type + Applications tab: Header text for notifications list box + + + Display Name + Displays tab: Header text for displays list box + + + seconds + The string 'seconds' (Used in Duration preference) + + + Duration: + Applications tab: duration preference label + + + Display '{0}' is already installed. + Display installer: message shown if a display is already installed when attempting to install again + + + The definition file '{0}' is invalid.\n\nThe display could not be installed. + Display installer: message shown if the definition file is malformed. {0} is the path to the file + + + The installation of the display was cancelled.\n\nThe display was not installed. + Display installer: message shown if the download is cancelled by the user + + + An error occurred while downloading the display files.\n\nThe display was not installed. + Display installer: message shown if the download of the display files fails for any reason + + + Install Display + Display installer: form title + + + Installing display... + Display installer: displayed while the display is being installed + + + The display '{0}' was installed successfully. + Display installer: text of the notification shown when a new display is installed. {0} is the name of the installed display. + + + New Display Installed + Display installer: title of the notification shown when a new display is installed + + + The definition file '{0}' does not exist.\n\nThe display could not be installed. + Display installer: message shown if the definition file could not be found. {0} is the file path + + + Do you want to install the following display?\n\nName: {0}\nAuthor: {1}\nDescription: {2} + Display installer: displayed when a click-to-install link is clicked. {0} is the name of the display, {1} is the author, and {2} is the description + + + Find & install additional displays + Displays tab: text that links to the GFW website to find more displays + + + Click here to forward notifications to +an iPhone + Add computer form: click to forward notification to iphone + + + Click here to forward notifications to +an email account + Add computer form: click to add email forwarding + + + Click here to forward notifications +to Twitter + Add computer form: click to forward notifications to Twitter + + + [Any Priority] + Configure iPhone Forwarding: label for combobox choice for forwarding all notification priorities + + + Only forward when priority is at least: + Configure iPhone Forwarding: label for minimum priority + + + Description: + Configure iPhone Forwarding: 'Description' label + + + API Key: + Configure iPhone Forwarding: 'API Key' label + + + Only forward when idle or away + Configure iphone forwarding: 'only forward when idle' checkbox text + + + [Any Priority] + Configure Twitter Forwarding: label for combobox choice for forwarding all notification priorities + + + Only forward when priority is at least: + Configure Twitter Forwarding: label for minimum priority + + + Password: + Configure Twitter Forwarding: 'Password' label + + + Username: + Configure Twitter Forwarding: 'Username' label + + + Format: + Configure Twitter Forwarding: 'Format' label + + + Only forward when idle or away + Configure Twitter forwarding: 'only forward when idle' checkbox text + + + Always + The string 'Always' + + + Idle Only + The string 'Idle Only' + + + Edit + Network tab: 'Edit' context menu item + + + You have successfully configured Growl to forward notifications to Prowl + Text of Prowl confirmation notification sent to confirm successful configuration + + + Prowl Test + Title of Prowl confirmation notification sent to confirm successful configuration + + + [Any Priority] + Configure Email Forwarding: label for combobox choice for forwarding all notification priorities + + + Only forward when priority is at least: + Configure Email Forwarding: label for minimum priority + + + Description: + Configure Email Forwarding: 'Description' label + + + Email Address: + Configure Email Forwarding: 'Email Address' label + + + SMTP Settings: + Configure Email Forwarding: 'SMTP Settings' label + + + edit + Configure Email Forwarding: 'edit' link + + + Only forward when idle or away + Configure Email forwarding: 'only forward when idle' checkbox text + + + Server: + Configure Email forwarding SMTP Settings: 'Server' label + + + Port: + Configure Email forwarding SMTP Settings: 'Port' label + + + Use Authentication + Configure Email forwarding SMTP Settings: 'Use Authentication' checkbox text + + + Use SSL + Configure Email forwarding SMTP Settings: 'Use SSL' checkbox text + + + Username: + Configure Email forwarding SMTP Settings: 'Username' label + + + Password: + Configure Email forwarding SMTP Settings: 'Password' label + + + done + Configure Email forwarding SMTP Settings: 'done' link + + + Application + History tab: Column header for Application column + + + Text + History tab: Column header for Text column + + + Timestamp + History tab: Column header for Timestamp column + + + Title + History tab: Column header for Title column + + + Details View + History tab: Details View context menu option + + + Tile View + History tab: Tile View context menu option + + + No + Any 'No' button + diff --git a/Growl/Growl.Localization.nb-NO/Growl.Localization.nb-NO.csproj b/Growl/Growl.Localization.nb-NO/Growl.Localization.nb-NO.csproj new file mode 100644 index 0000000..4428c2e --- /dev/null +++ b/Growl/Growl.Localization.nb-NO/Growl.Localization.nb-NO.csproj @@ -0,0 +1,56 @@ + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {BED0DDCE-6C19-4487-86A0-CD58F2DC5F66} + Library + Properties + Growl + Growl + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + Designer + + + + + + del "$(ProjectDir)$(OutDir)Growl.dll" +del "$(ProjectDir)$(OutDir)Growl.pdb" +xcopy "$(ProjectDir)$(OutDir)*.*" "$(SolutionDir)Growl\$(OutDir)" /E /Y /C + + \ No newline at end of file diff --git a/Growl/Growl.Localization.nb-NO/Properties.Resources.nb-NO.resx b/Growl/Growl.Localization.nb-NO/Properties.Resources.nb-NO.resx new file mode 100644 index 0000000..96b80f8 --- /dev/null +++ b/Growl/Growl.Localization.nb-NO/Properties.Resources.nb-NO.resx @@ -0,0 +1,872 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Growl (Ikke Aktiv) + Tooltip for notify icon when Growl is not running + + + (build: {0}) + About tab: build number information - Placeholder {0} is the actual build number + + + Finn visningsmoduler, utvidelser og oppdateringer på: + About tab: Growl website label + + + Growl v{0} + About tab: name and version - Placeholder {0} is the actual version number + + + Ikoner: + About tab: Icons + + + VistaICO Aero Pack - + About tab: VistaICO label + + + Original ide, inspirasjon og logo: + About tab: original Growl + + + Growl for OSX - + About tab: Growl for OSX + + + Vertsnavn: + Add Computer form: Address label + + + Format: + Add Computer form: Format label + + + Videresend notifikasjoner + Add Computer form title - when fowarding + + + Abboner på notifikasjoner + Add Computer form title - when subscribing + + + Klikk her for å legge til en computer som ikke er i denne listen + Add Computer form: click to add a computer not detected by Bonjour + + + Navn: + Add Computer form: Name label + + + Passord: + Add Computer form: Password label + + + Port: + Add Computer form: Port label + + + (Alle notifikasjoner) + Applications tab: list item for application-wide preferences + + + Ingen applikasjoner har registrert seg enda + Applications tab: shown when no applications are registered + + + Visningsmodul: + Applications tab: display preference label + + + Aktiv: + Applications tab: enabled preference label + + + Videresend: + Applications tab: forwarding preference label + + + Prioritet: + Applications tab: priority preference label + + + Lyd: + Applications tab: sound preference label + + + Limt: + Applications tab: sticky preference label + + + Fjern Applikasjon + Applications tab: 'Remove Applications' context menu item + + + Avbryt + Any 'Cancel' button + + + Fjern + Any 'Clear' button + + + Lukk + Any 'Close' button + + + Senere + Any 'Later' button + + + OK + Any 'OK' button + + + Forhåndsvisning + Any 'Preview' button + + + Lagre + Any 'Save' button + + + Ja + Any 'Yes' button + + + Velg videresending + Choose Forwarding form title + + + [Standard] + The name displayed for the '[Default]' preference option + + + Growl kunne ikke starte + MessageBox caption shown if Growl fails to start + + + TCP Porten Growl bruker (TCP port {0}) er opptatt. + +Om en annen versjon av Growl kjører, vennligst lukk dene og prøv igjen + MessageBox text shown if Growl fails to start the GNTP listener. Placeholder {0} is the port number. + + + UDP Porten Growl bruker ({0}) er opptatt. + +Om en annen versjon av Growl kjører, vennligst lukk dene og prøv igjen + MessageBox text shown if Growl fails to start the UDPlistener. Placeholder {0} is the port number. + + + Ute til lunch. Tilbake etter pausen + General tab: Displayed when Growl is paused + + + Growl er aktiv + General tab: Displayed when Growl is running + + + Growl er inaktiv + General tab: Displaysed when Growl is stopped + + + Start Growl automatisk når du logger deg på + General tab: auto start checkbox text + + + Standard lyd: + General tab: Default Sound label + + + Lydinnstillinger + General tab: Sound Settings group box title + + + Anta at jeg er inaktiv etter sekunder + General tab: Radio button text for 'consider me idle after x seconds' + + + Lat som om jeg er her hele tiden + General tab: Radio button text for 'never consider me idle' + + + Gjør dette når jeg er borte: + General tab: Idle Settings group box title + + + (Ingen notifikasjoner denne dagen) + History tab: shown when sorted by date and the date had no notifications + + + Antall dager + History tab: Number of Days + + + Applikasjon + History tab: sort by application radio button label + + + Dato + History tab: sort by date radio button label + + + Sorter etter + History tab: Group By + + + format + The string 'format' (used in forward list view to show protocol format) + + + Mottatt den + The string 'Received At' (used in History for each past notification to indicate the date/time the notification was received) + + + Sendt av + The string 'Received From' (used in History for each past notification item to indicate which application sent the notification) + + + Idag + The string 'Today' (used in History view for the current day) + + + Igår + ry view for yesterday's date) + + + Henter applikasjonsliste... + Loading progress indicator: Application list + + + Henter visningsmodul '{0}' ... + Loading progress indicator for a specific display - Placeholder {0} is the display name + + + Henter visningsmoduler... + Loading progress indicator: Displays + + + Studerer historie... + Loading progress indicator: History + + + Initialiserer... + Loading progress indicator: Initializing + + + Sjekker preferanser... + Loading progress indicator: Preferences + + + Utført sjef! + Loading progress indicator: Ready + + + Starter Growl... + Loading progress indicator: Starting + + + Du gikk glipp av {0} notifikasjoner siden sist du var her. + Missed Notifications Summary: the summary text - Placeholder {0} is the number of notifications missed. + + + Send notifikasjonene videre til en annen maskin + Network tab: checkbox text for 'forward notifications to other computers' + + + Fjern + Network tab: 'Remove' context menu item + + + Abboner på notifikasjoner fra andre maskiner + Network tab: checkbox text for 'subscribe to notifications from other computers' + + + Sjekk for oppdateringer + Notify icon context menu: Check for updates + + + Exit + Notify icon context menu: Exit + + + Gi Growl en velfortjent pause fra all jobbinga... + Notify icon context menu: Pause + + + Åpne Growl + Notify icon context menu: Open Growl (formerly Settings) + + + Be Growl begynne å jobbe igjen + Notify icon context menu: Unpause + + + Growl (pause) + Tooltip for notificy icon when Growl is paused + + + Growl + Tooltip for notify icon when Growl is running + + + Nei + Enabled Pref: False + + + Ja + Enabled Pref: True + + + Velg... + Forwarding Pref: Choose + + + Ikke videresend + Forwarding Pref: Never + + + Kritisk + Priority Pref: Emergency + + + Høy + Priority Pref: High + + + Lav + Priority Pref: Low + + + Normal + Priority Pref: Normal + + + Svært lav + Priority Pref: Very Low + + + Ingen + Sound Pref: None + + + Alltid + Sticky Pref: Always + + + Aldri + Sticky Pref: Never + + + Når jeg er borte + Sticky Pref: When Idle + + + GNTP + GNTP protocol name (used in forwarding dropdown, etc) + + + UDP + UDP protocol name (used in forwarding dropdown, etc) + + + Tillat notifikasjoner fra nettverket + Security tab: checkbox text for 'allow network notificaions' + + + Tillat andre å abbonere på notifikasjoner + Security tab: checkbox text for 'allows subscriptions' + + + Tillat notifikasjoner fra nettsider + Security tab: checkbox text for 'allow web notifications' + + + Beskrivelse: + Security tab: Password Manager 'Description' label + + + Rediger + Security tab: Password Manager 'Edit' context menu item + + + Skriv inn ett passord, og en kort beskrivelse av passordet som ett passordhint. + Security tab: Password Manager instructions + + + Passord: + Security tab: Password Manager 'Password' label + + + Passordoversikt + Security tab: Password Manager title + + + Lokale applikasjoner må bruke passord: + Security tab: checkbox text for 'require password for local apps' + + + Growl + Settings form title + + + Jobber... + The loading progress indicator shown on the initial splash screen. + + + Growl for Windows + The name of the application shown on the initial splash screen + + + Versjon: {0} + The version informatino shown on the initial splash screen. Placeholder {0} is the version number. + + + Growl + The application name used for system notifications + + + Applikasjonen '{0}' har registert seg som en avsender. + Notification text when an application registers. Placeholder {0} is the application name. + + + Ny applikasjon! + The title used for the system notification when an application registers + + + Klienten '{0}' har tegnet ett abbonement på notifikasjoner. + Notification text when a client subscribes to notifications. Placeholder {0} is the subscribing client's name. + + + Ny abbonent! + The title used for the system notification when a client subscribes to notifications + + + Dette er en forhåndsvisning av '{0}'. + Notification text shown for preview notifications - Placeholder {0} is the actual display name + + + Vis meg hvordan Visningsmodulen ser ut + The title used for preview notifications + + + Growl aktivert + Notification text shown when Growl starts + + + Growl + The title used for the system notification when Growl starts + + + Om + 'About' tab title + + + Applikasjoner + 'Applications' tab title + + + Visningsmoduler + 'Displays' tab title + + + Generelt + 'General' tab title + + + Historikk + 'History' tab title + + + Nettverk + 'Network' tab title + + + Sikkerhet + 'Security' tab title + + + Nedlastning fullført. Starter installasjon... + Check for Updates form: displayed when the update has finished downloading and the installation is starting + + + Henter oppdatering.. + Check for Updates form: displayed while an update is downloading + + + Sjekk oppdateringer + Check for Updates form title + + + Nyeste Growl er innstallert. Nåværende versjon: {1} + Check for Updates form: displayed when Growl is up-to-date. Placeholder {0} is any newer version number, {1} is the current up-to-date version number + + + Versjon {0} av Growl er tilgjengelig. Vil du oppdatere til nyeste versjon? (Du har nå versjon: {1}) + Check for Updates form: displayed when an update is available. Placeholder {0} is the newer version number, {1} is the current version number + + + Bruk denne som standard + Any 'Set as Default' button + + + Laget av: + Displays tab: created by label + + + Vær stille + General tab: mute all sounds label + + + Når ett program med Growl tileggsfunskjonalitet registrerer seg som en avsender vil det dukke opp i listen til høyre, og du vil kunne endre applikasjonens innstillinger. + Applications tab: shown when no applications are registered + + + Stumt + Notify icon context menu: Mute + + + Gi stemmerett + Notify icon context menu: Unmute + + + Applikasjonsnavn + Applications tab: Header text for applications list box + + + Notifikasjonstype + Applications tab: Header text for notifications list box + + + Visningsnavn + Displays tab: Header text for displays list box + + + sekunder + The string 'seconds' (Used in Duration preference) + + + Varighet: + Applications tab: duration preference label + + + Visningsmodul '{0}' er allerede installert. + Display installer: message shown if a display is already installed when attempting to install again + + + Definisjonsfila '{0}' inneholder feil.\n\nVisninsgmodulen kunne ikke innstalleres + Display installer: message shown if the definition file is malformed. {0} is the path to the file + + + Installeringa av visningsmodulen ble avbrutt.\n\nVisningsmodulen ble ikke installert. + Display installer: message shown if the download is cancelled by the user + + + Det skjedde en feil ved henting av visningsmodulen.\n\nVisningsmodulen ble ikke installert. + Display installer: message shown if the download of the display files fails for any reason + + + Installer Visningsmodul + Display installer: form title + + + Installerer Visningsmodul... + Display installer: displayed while the display is being installed + + + Visningsmodulen '{0}' ble korrekt installert. + Display installer: text of the notification shown when a new display is installed. {0} is the name of the installed display. + + + Ny visningsmodul installert + Display installer: title of the notification shown when a new display is installed + + + Definisjonsfila '{0}' eksisterer ikke.\n\nVisningsmodulen ble ikke installert. + Display installer: message shown if the definition file could not be found. {0} is the file path + + + Ønsker du å installere denne?\n\nNavn: {0}\nLaget av: {1}\nBeskrivelse: {2} + Display installer: displayed when a click-to-install link is clicked. {0} is the name of the display, {1} is the author, and {2} is the description + + + Finn & flere visningsmoduler + Displays tab: text that links to the GFW website to find more displays + + + Aktiver videresending til iPhone + Add computer form: click to forward notification to iphone + + + Aktiver videresending til epost + Add computer form: click to add email forwarding + + + Aktiver videresending til Twitter + Add computer form: click to forward notifications to Twitter + + + [alle prioriteter] + Configure iPhone Forwarding: label for combobox choice for forwarding all notification priorities + + + Videresend kun når prioriteten er minst: + Configure iPhone Forwarding: label for minimum priority + + + Beskrivelse: + Configure iPhone Forwarding: 'Description' label + + + API Key: + Configure iPhone Forwarding: 'API Key' label + + + Videresend bare når du er utilgjengelig + Configure iphone forwarding: 'only forward when idle' checkbox text + + + [alle prioriteter] + Configure Twitter Forwarding: label for combobox choice for forwarding all notification priorities + + + Videresend kun når prioriteten er minst: + Configure Twitter Forwarding: label for minimum priority + + + Passord: + Configure Twitter Forwarding: 'Password' label + + + Brukernavn: + Configure Twitter Forwarding: 'Username' label + + + Format: + Configure Twitter Forwarding: 'Format' label + + + Videresend bare når du er utilgjengelig + Configure Twitter forwarding: 'only forward when idle' checkbox text + + + Alltid + The string 'Always' + + + Kun utilgjengelig + The string 'Idle Only' + + + Rediger + Network tab: 'Edit' context menu item + + + Videresending til Prowl er korrekt satt opp + Text of Prowl confirmation notification sent to confirm successful configuration + + + Test Prowl + Title of Prowl confirmation notification sent to confirm successful configuration + + + [alle prioriteter] + Configure Email Forwarding: label for combobox choice for forwarding all notification priorities + + + Videresend kun når prioriteten er minst: + Configure Email Forwarding: label for minimum priority + + + Beskrivelse: + Configure Email Forwarding: 'Description' label + + + Epost Adresse: + Configure Email Forwarding: 'Email Address' label + + + Utgående eposttjener (SMTP): + Configure Email Forwarding: 'SMTP Settings' label + + + rediger + Configure Email Forwarding: 'edit' link + + + Videresend bare når du er utilgjengelig + Configure Email forwarding: 'only forward when idle' checkbox text + + + Tjener: + Configure Email forwarding SMTP Settings: 'Server' label + + + Port: + Configure Email forwarding SMTP Settings: 'Port' label + + + Bruk autentisering + Configure Email forwarding SMTP Settings: 'Use Authentication' checkbox text + + + Bruk SSL + Configure Email forwarding SMTP Settings: 'Use SSL' checkbox text + + + Brukernavn: + Configure Email forwarding SMTP Settings: 'Username' label + + + Passord: + Configure Email forwarding SMTP Settings: 'Password' label + + + Utført! + Configure Email forwarding SMTP Settings: 'done' link + + + Applikasjon + History tab: Column header for Application column + + + Tekst + History tab: Column header for Text column + + + Tidsstempel + History tab: Column header for Timestamp column + + + Tittel + History tab: Column header for Title column + + + Detaljevisning + History tab: Details View context menu option + + + Rutevisning + History tab: Tile View context menu option + + + Nei + Any 'No' button + + \ No newline at end of file diff --git a/Growl/Growl.Localization.nb-NO/Properties/AssemblyInfo.cs b/Growl/Growl.Localization.nb-NO/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..0b3449e --- /dev/null +++ b/Growl/Growl.Localization.nb-NO/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Growl.Localization.no-NO")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("element code project")] +[assembly: AssemblyProduct("Growl.Localization.no-NO")] +[assembly: AssemblyCopyright("Copyright © element code project 2009")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("nb-NO")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("3953fdab-b085-46de-8cbf-6b3417769494")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Growl/Growl.Localization.nl-NL/Properties.Resources.nl-NL.resx b/Growl/Growl.Localization.nl-NL/Properties.Resources.nl-NL.resx index 1203df4..7941833 100644 --- a/Growl/Growl.Localization.nl-NL/Properties.Resources.nl-NL.resx +++ b/Growl/Growl.Localization.nl-NL/Properties.Resources.nl-NL.resx @@ -158,16 +158,16 @@ Add Computer form: Format label - Doorstuur notificaties + Meldingen doorsturen Add Computer form title - when fowarding - Geabonneerd op notificaties + Geabonneerd op meldingen Add Computer form title - when subscribing - [Klik hier om handmatig een computer -niet in de lijst toe te voegen] + [Klik hier om handmatig een niet gedetecteerde computer +aan de lijst toe te voegen] Add Computer form: click to add a computer not detected by Bonjour @@ -187,9 +187,7 @@ niet in de lijst toe te voegen] Applications tab: list item for application-wide preferences - Nog geen geregistreerde applicaties. - -Zodra een applicatie, met Growl ondersteuning, zich registreert zal deze in de lijst links verschijnen en kunnen de applicatie specifieke instellingen aangepast worden. + Nog geen geregistreerde applicaties. Applications tab: shown when no applications are registered @@ -305,7 +303,7 @@ Als er reeds een Growl versie actief is, sluit deze dan eerst en probeer het opn General tab: Default Settings group box title - Beschouw me als niet actief na {0} secondes + Beschouw me als niet actief na {0} seconde General tab: Radio button text for 'consider me idle after x seconds' - Placeholder {0} is where the TextBox will go @@ -361,11 +359,11 @@ Als er reeds een Growl versie actief is, sluit deze dan eerst en probeer het opn Loading progress indicator: Application list - Weergave '{0}' wordt geladen... + Display '{0}' wordt geladen... Loading progress indicator for a specific display - Placeholder {0} is the display name - Weergaves worden geladen... + Displays worden geladen... Loading progress indicator: Displays @@ -445,7 +443,7 @@ Als er reeds een Growl versie actief is, sluit deze dan eerst en probeer het opn Forwarding Pref: Choose - Niet doorsteuren + Niet doorsturen Forwarding Pref: Never @@ -497,11 +495,11 @@ Als er reeds een Growl versie actief is, sluit deze dan eerst en probeer het opn Security tab: checkbox text for 'allow network notificaions' - Het is toegestaan dat computers zich abonneren op notificaties + Het is toegestaan dat computers zich abonneren op meldingen Security tab: checkbox text for 'allows subscriptions' - Notificaties van websites toegestaan + Meldingen van websites toegestaan Security tab: checkbox text for 'allow web notifications' @@ -549,7 +547,7 @@ Als er reeds een Growl versie actief is, sluit deze dan eerst en probeer het opn The application name used for system notifications - De applicatie '{0}' heeft zich aangemeld om notificaties te sturen. + De applicatie '{0}' heeft zich aangemeld om meldingente sturen. Notification text when an application registers. Placeholder {0} is the application name. @@ -557,7 +555,7 @@ Als er reeds een Growl versie actief is, sluit deze dan eerst en probeer het opn The title used for the system notification when an application registers - De computer '{0}' heeft zich aangemeld om doorgestuurde notificaties te ontvangen. + De computer '{0}' heeft zich aangemeld om doorgestuurde meldingen te ontvangen. Notification text when a client subscribes to notifications. Placeholder {0} is the subscribing client's name. @@ -628,4 +626,252 @@ Als er reeds een Growl versie actief is, sluit deze dan eerst en probeer het opn Nieuwe versie {0} van Growl is beschikbaar. Wilt u Growl bijwerken naar de laatste versie? (huidige versie: {1}) Check for Updates form: displayed when an update is available. Placeholder {0} is the newer version number, {1} is the current version number + + Gebruik als standaard + Any 'Set as Default' button + + + Auteur: + Displays tab: created by label + + + Geen geluiden + General tab: mute all sounds label + + + Zodra een applicatie met Growl ondersteuning zich registreert zal deze in de lijst links verschijnen en kunnen de applicatie specifieke instellingen aangepast worden. + Applications tab: shown when no applications are registered + + + Geluid uit + Notify icon context menu: Mute + + + Geluid aan + Notify icon context menu: Unmute + + + Applicatienaam + Applications tab: Header text for applications list box + + + Melding Type + Applications tab: Header text for notifications list box + + + Display naam + Displays tab: Header text for displays list box + + + seconden + The string 'seconds' (Used in Duration preference) + + + Tijdsduur: + Applications tab: duration preference label + + + Display '{0}' is al geïnstalleerd. + Display installer: message shown if a display is already installed when attempting to install again + + + Het definitiebestand '{0}' is ongeldig.\n\nDe display kan niet geïnstalleerd worden. + Display installer: message shown if the definition file is malformed. {0} is the path to the file + + + De installatie van de display is afgebroken.\n\nDe display is niet geïnstalleerd. + Display installer: message shown if the download is cancelled by the user + + + Er is een fout opgetreden tijdens het downloaden van de display bestanden.\n\nDe display is niet geïnstalleerd. + Display installer: message shown if the download of the display files fails for any reason + + + Installeer display + Display installer: form title + + + Display aan het installeren... + Display installer: displayed while the display is being installed + + + Display '{0}' is succesvol geïnstalleerd. + Display installer: text of the notification shown when a new display is installed. {0} is the name of the installed display. + + + Nieuw display geïnstalleerd + Display installer: title of the notification shown when a new display is installed + + + Definitiebestand '{0}' bestaat niet.\n\nDe display kon niet worden geïnstalleerd. + Display installer: message shown if the definition file could not be found. {0} is the file path + + + Wil je de volgende display installeren?\n\nNaam: {0}\nAuteur: {1}\nOmschrijving: {2} + Display installer: displayed when a click-to-install link is clicked. {0} is the name of the display, {1} is the author, and {2} is the description + + + Vind & installeer meer displays + Displays tab: text that links to the GFW website to find more displays + + + Klik hier om meldingen door te sturen naar een iPhone + Add computer form: click to forward notification to iphone + + + Klik hier om meldingen door te sturen naar een email account + Add computer form: click to add email forwarding + + + Klik hier om meldingen door te sturen naar Twitter + Add computer form: click to forward notifications to Twitter + + + [Elke prioriteit] + Configure iPhone Forwarding: label for combobox choice for forwarding all notification priorities + + + Alleen doorsturen bij min. prioriteit van: + Configure iPhone Forwarding: label for minimum priority + + + Omschrijving: + Configure iPhone Forwarding: 'Description' label + + + API sleutel + Configure iPhone Forwarding: 'API Key' label + + + Alleen doorsturen bij afwezigheid + Configure iphone forwarding: 'only forward when idle' checkbox text + + + [Elke prioriteit] + Configure Twitter Forwarding: label for combobox choice for forwarding all notification priorities + + + Alleen doorsturen bij min. prioriteit van: + Configure Twitter Forwarding: label for minimum priority + + + Wachtwoord: + Configure Twitter Forwarding: 'Password' label + + + Gebruikersnaam: + Configure Twitter Forwarding: 'Username' label + + + Formaat: + Configure Twitter Forwarding: 'Format' label + + + Alleen doorsturen bij afwezigheid + Configure Twitter forwarding: 'only forward when idle' checkbox text + + + Altijd + The string 'Always' + + + Alleen inactief + The string 'Idle Only' + + + Bewerk + Network tab: 'Edit' context menu item + + + Je hebt Growl succesvol geconfigureerd om meldingen naar Prowl door te sturen. + Text of Prowl confirmation notification sent to confirm successful configuration + + + Prowl Test + Title of Prowl confirmation notification sent to confirm successful configuration + + + [Elke Prioriteit] + Configure Email Forwarding: label for combobox choice for forwarding all notification priorities + + + Alleen doorsturen bij min. prioriteit van: + Configure Email Forwarding: label for minimum priority + + + Omschrijving: + Configure Email Forwarding: 'Description' label + + + Emailadres: + Configure Email Forwarding: 'Email Address' label + + + SMTP instellingen + Configure Email Forwarding: 'SMTP Settings' label + + + bewerk + Configure Email Forwarding: 'edit' link + + + Alleen doorsturen bij afwezigheid of inactiviteit + Configure Email forwarding: 'only forward when idle' checkbox text + + + Server: + Configure Email forwarding SMTP Settings: 'Server' label + + + Poort: + Configure Email forwarding SMTP Settings: 'Port' label + + + Gebruik authenticatie + Configure Email forwarding SMTP Settings: 'Use Authentication' checkbox text + + + Gebruik SSL + Configure Email forwarding SMTP Settings: 'Use SSL' checkbox text + + + Gebruikersnaam: + Configure Email forwarding SMTP Settings: 'Username' label + + + Wachtwoord: + Configure Email forwarding SMTP Settings: 'Password' label + + + klaar + Configure Email forwarding SMTP Settings: 'done' link + + + Applicatie + History tab: Column header for Application column + + + Tekst + History tab: Column header for Text column + + + Tijdsaanduiding + History tab: Column header for Timestamp column + + + Titel + History tab: Column header for Title column + + + Detailoverzicht + History tab: Details View context menu option + + + Tile View + History tab: Tile View context menu option + + + Nee + Any 'No' button + \ No newline at end of file diff --git a/Growl/Growl.UDPLegacy/Properties/AssemblyInfo.cs b/Growl/Growl.UDPLegacy/Properties/AssemblyInfo.cs index 394143b..2c065b9 100644 --- a/Growl/Growl.UDPLegacy/Properties/AssemblyInfo.cs +++ b/Growl/Growl.UDPLegacy/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("2.0.0.0")] -[assembly: AssemblyFileVersion("2.0.0.21")] +[assembly: AssemblyFileVersion("2.0.0.22")] [assembly: AssemblyInformationalVersion("2.0")] diff --git a/Growl/Growl.sln b/Growl/Growl.sln index e5f1129..58ffaf2 100644 --- a/Growl/Growl.sln +++ b/Growl/Growl.sln @@ -35,6 +35,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Growl.Localization.ja-JP", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Growl.Displays.Plain", "Growl.Displays.Plain\Growl.Displays.Plain.csproj", "{FCE7A843-0E7E-4BF0-8FD1-08200A8A51A2}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Growl.Localization.de-DE", "Growl.Localization.de-DE\Growl.Localization.de-DE.csproj", "{774E3560-B4CA-4041-A21E-A9437FD3C932}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Growl.Localization.nb-NO", "Growl.Localization.nb-NO\Growl.Localization.nb-NO.csproj", "{BED0DDCE-6C19-4487-86A0-CD58F2DC5F66}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -107,6 +111,14 @@ Global {FCE7A843-0E7E-4BF0-8FD1-08200A8A51A2}.Debug|Any CPU.Build.0 = Debug|Any CPU {FCE7A843-0E7E-4BF0-8FD1-08200A8A51A2}.Release|Any CPU.ActiveCfg = Release|Any CPU {FCE7A843-0E7E-4BF0-8FD1-08200A8A51A2}.Release|Any CPU.Build.0 = Release|Any CPU + {774E3560-B4CA-4041-A21E-A9437FD3C932}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {774E3560-B4CA-4041-A21E-A9437FD3C932}.Debug|Any CPU.Build.0 = Debug|Any CPU + {774E3560-B4CA-4041-A21E-A9437FD3C932}.Release|Any CPU.ActiveCfg = Release|Any CPU + {774E3560-B4CA-4041-A21E-A9437FD3C932}.Release|Any CPU.Build.0 = Release|Any CPU + {BED0DDCE-6C19-4487-86A0-CD58F2DC5F66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BED0DDCE-6C19-4487-86A0-CD58F2DC5F66}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BED0DDCE-6C19-4487-86A0-CD58F2DC5F66}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BED0DDCE-6C19-4487-86A0-CD58F2DC5F66}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Growl/Growl/Growl.csproj b/Growl/Growl/Growl.csproj index 61c4bf3..efc4d8a 100644 --- a/Growl/Growl/Growl.csproj +++ b/Growl/Growl/Growl.csproj @@ -20,6 +20,7 @@ prompt 4 x86 + false pdbonly @@ -114,6 +115,12 @@ + + Form + + + InstallLanguage.cs + @@ -248,6 +255,10 @@ UpdateForm.cs Designer + + InstallLanguage.cs + Designer + Designer InstallDisplay.cs diff --git a/Growl/Growl/MainForm.Designer.cs b/Growl/Growl/MainForm.Designer.cs index 9f68480..238cbc5 100644 --- a/Growl/Growl/MainForm.Designer.cs +++ b/Growl/Growl/MainForm.Designer.cs @@ -16,76 +16,6 @@ partial class MainForm private void InitializeComponent() { this.components = new System.ComponentModel.Container(); - System.Windows.Forms.ListViewGroup listViewGroup1 = new System.Windows.Forms.ListViewGroup("Today", System.Windows.Forms.HorizontalAlignment.Left); - System.Windows.Forms.ListViewGroup listViewGroup2 = new System.Windows.Forms.ListViewGroup("Yesterday", System.Windows.Forms.HorizontalAlignment.Left); - System.Windows.Forms.ListViewGroup listViewGroup3 = new System.Windows.Forms.ListViewGroup("Monday", System.Windows.Forms.HorizontalAlignment.Left); - System.Windows.Forms.ListViewGroup listViewGroup4 = new System.Windows.Forms.ListViewGroup("Sunday", System.Windows.Forms.HorizontalAlignment.Left); - System.Windows.Forms.ListViewGroup listViewGroup5 = new System.Windows.Forms.ListViewGroup("Saturday", System.Windows.Forms.HorizontalAlignment.Left); - System.Windows.Forms.ListViewGroup listViewGroup6 = new System.Windows.Forms.ListViewGroup("Friday", System.Windows.Forms.HorizontalAlignment.Left); - System.Windows.Forms.ListViewGroup listViewGroup7 = new System.Windows.Forms.ListViewGroup("Thursday", System.Windows.Forms.HorizontalAlignment.Left); - System.Windows.Forms.ListViewGroup listViewGroup8 = new System.Windows.Forms.ListViewGroup("Today", System.Windows.Forms.HorizontalAlignment.Left); - System.Windows.Forms.ListViewGroup listViewGroup9 = new System.Windows.Forms.ListViewGroup("Yesterday", System.Windows.Forms.HorizontalAlignment.Left); - System.Windows.Forms.ListViewGroup listViewGroup10 = new System.Windows.Forms.ListViewGroup("Sunday", System.Windows.Forms.HorizontalAlignment.Left); - System.Windows.Forms.ListViewGroup listViewGroup11 = new System.Windows.Forms.ListViewGroup("Saturday", System.Windows.Forms.HorizontalAlignment.Left); - System.Windows.Forms.ListViewGroup listViewGroup12 = new System.Windows.Forms.ListViewGroup("Friday", System.Windows.Forms.HorizontalAlignment.Left); - System.Windows.Forms.ListViewGroup listViewGroup13 = new System.Windows.Forms.ListViewGroup("Thursday", System.Windows.Forms.HorizontalAlignment.Left); - System.Windows.Forms.ListViewGroup listViewGroup14 = new System.Windows.Forms.ListViewGroup("Wednesday", System.Windows.Forms.HorizontalAlignment.Left); - System.Windows.Forms.ListViewItem listViewItem1 = new System.Windows.Forms.ListViewItem(new string[] { - "(No notifications for this date)", - "", - ""}, -1); - System.Windows.Forms.ListViewItem listViewItem2 = new System.Windows.Forms.ListViewItem(new string[] { - "(No notifications for this date)", - "", - ""}, -1); - System.Windows.Forms.ListViewItem listViewItem3 = new System.Windows.Forms.ListViewItem(new string[] { - "(No notifications for this date)", - "", - ""}, -1); - System.Windows.Forms.ListViewItem listViewItem4 = new System.Windows.Forms.ListViewItem(new string[] { - "(No notifications for this date)", - "", - ""}, -1); - System.Windows.Forms.ListViewItem listViewItem5 = new System.Windows.Forms.ListViewItem(new string[] { - "(No notifications for this date)", - "", - ""}, -1); - System.Windows.Forms.ListViewItem listViewItem6 = new System.Windows.Forms.ListViewItem(new string[] { - "(No notifications for this date)", - "", - ""}, -1); - System.Windows.Forms.ListViewItem listViewItem7 = new System.Windows.Forms.ListViewItem(new string[] { - "(No notifications for this date)", - "", - ""}, -1); - System.Windows.Forms.ListViewItem listViewItem8 = new System.Windows.Forms.ListViewItem(new string[] { - "(No notifications for this date)", - "", - ""}, -1); - System.Windows.Forms.ListViewItem listViewItem9 = new System.Windows.Forms.ListViewItem(new string[] { - "(No notifications for this date)", - "", - ""}, -1); - System.Windows.Forms.ListViewItem listViewItem10 = new System.Windows.Forms.ListViewItem(new string[] { - "(No notifications for this date)", - "", - ""}, -1); - System.Windows.Forms.ListViewItem listViewItem11 = new System.Windows.Forms.ListViewItem(new string[] { - "(No notifications for this date)", - "", - ""}, -1); - System.Windows.Forms.ListViewItem listViewItem12 = new System.Windows.Forms.ListViewItem(new string[] { - "(No notifications for this date)", - "", - ""}, -1); - System.Windows.Forms.ListViewItem listViewItem13 = new System.Windows.Forms.ListViewItem(new string[] { - "(No notifications for this date)", - "", - ""}, -1); - System.Windows.Forms.ListViewItem listViewItem14 = new System.Windows.Forms.ListViewItem(new string[] { - "(No notifications for this date)", - "", - ""}, -1); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); this.panelGeneral = new System.Windows.Forms.Panel(); this.groupBox1 = new System.Windows.Forms.GroupBox(); @@ -1351,79 +1281,7 @@ private void InitializeComponent() this.historyListView.Font = new System.Drawing.Font("Trebuchet MS", 8.25F); this.historyListView.FullRowSelect = true; this.historyListView.GroupBy = Growl.UI.HistoryGroupItemsBy.Date; - listViewGroup1.Header = "Today"; - listViewGroup1.Name = "Today"; - listViewGroup2.Header = "Yesterday"; - listViewGroup2.Name = "Yesterday"; - listViewGroup3.Header = "Monday"; - listViewGroup3.Name = "Monday"; - listViewGroup4.Header = "Sunday"; - listViewGroup4.Name = "Sunday"; - listViewGroup5.Header = "Saturday"; - listViewGroup5.Name = "Saturday"; - listViewGroup6.Header = "Friday"; - listViewGroup6.Name = "Friday"; - listViewGroup7.Header = "Thursday"; - listViewGroup7.Name = "Thursday"; - listViewGroup8.Header = "Today"; - listViewGroup8.Name = "Today"; - listViewGroup9.Header = "Yesterday"; - listViewGroup9.Name = "Yesterday"; - listViewGroup10.Header = "Sunday"; - listViewGroup10.Name = "Sunday"; - listViewGroup11.Header = "Saturday"; - listViewGroup11.Name = "Saturday"; - listViewGroup12.Header = "Friday"; - listViewGroup12.Name = "Friday"; - listViewGroup13.Header = "Thursday"; - listViewGroup13.Name = "Thursday"; - listViewGroup14.Header = "Wednesday"; - listViewGroup14.Name = "Wednesday"; - this.historyListView.Groups.AddRange(new System.Windows.Forms.ListViewGroup[] { - listViewGroup1, - listViewGroup2, - listViewGroup3, - listViewGroup4, - listViewGroup5, - listViewGroup6, - listViewGroup7, - listViewGroup8, - listViewGroup9, - listViewGroup10, - listViewGroup11, - listViewGroup12, - listViewGroup13, - listViewGroup14}); this.historyListView.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None; - listViewItem1.Group = listViewGroup1; - listViewItem2.Group = listViewGroup2; - listViewItem3.Group = listViewGroup3; - listViewItem4.Group = listViewGroup4; - listViewItem5.Group = listViewGroup5; - listViewItem6.Group = listViewGroup6; - listViewItem7.Group = listViewGroup7; - listViewItem8.Group = listViewGroup8; - listViewItem9.Group = listViewGroup9; - listViewItem10.Group = listViewGroup10; - listViewItem11.Group = listViewGroup11; - listViewItem12.Group = listViewGroup12; - listViewItem13.Group = listViewGroup13; - listViewItem14.Group = listViewGroup14; - this.historyListView.Items.AddRange(new System.Windows.Forms.ListViewItem[] { - listViewItem1, - listViewItem2, - listViewItem3, - listViewItem4, - listViewItem5, - listViewItem6, - listViewItem7, - listViewItem8, - listViewItem9, - listViewItem10, - listViewItem11, - listViewItem12, - listViewItem13, - listViewItem14}); this.historyListView.LabelWrap = false; this.historyListView.Location = new System.Drawing.Point(196, 5); this.historyListView.MultiSelect = false; @@ -1594,6 +1452,7 @@ private void InitializeComponent() this.listControlDisplays.Size = new System.Drawing.Size(176, 264); this.listControlDisplays.TabIndex = 2; this.listControlDisplays.SelectedIndexChanged += new System.EventHandler(this.listControlDisplays_SelectedIndexChanged); + this.listControlDisplays.DoubleClick += new System.EventHandler(listControlDisplays_DoubleClick); // // buttonSetAsDefault // @@ -1662,7 +1521,7 @@ private void InitializeComponent() this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.MaximizeBox = false; this.MinimizeBox = false; - this.MinimumSize = new System.Drawing.Size(670, 393); + this.MinimumSize = new System.Drawing.Size(670, 400); this.Name = "MainForm"; this.Text = "Growl"; this.Load += new System.EventHandler(this.MainForm_Load); diff --git a/Growl/Growl/MainForm.cs b/Growl/Growl/MainForm.cs index 15fe31d..4b87347 100644 --- a/Growl/Growl/MainForm.cs +++ b/Growl/Growl/MainForm.cs @@ -99,6 +99,22 @@ public MainForm() idleAfterText = String.Format(idleAfterText, " "); // this leaves space for the textbox } this.radioButtonIdleAfter.Text = idleAfterText; + + try + { + KeysConverter kc = new KeysConverter(); + this.closeLastKeyCombo = (Keys)kc.ConvertFromString(Properties.Settings.Default.KeyboardShortcutCloseLast); + this.closeAllKeyCombo = (Keys)kc.ConvertFromString(Properties.Settings.Default.KeyboardShortcutCloseAll); + + this.closeLastHotKey = new HotKeyManager(this, this.closeLastKeyCombo); + this.closeAllHotKey = new HotKeyManager(this, this.closeAllKeyCombo); + + this.closeLastHotKey.Register(); + this.closeAllHotKey.Register(); + } + catch + { + } } # region visual style @@ -166,6 +182,8 @@ private void MainForm_Load(object sender, EventArgs e) int y = Screen.PrimaryScreen.WorkingArea.Bottom - this.Height; this.Location = new Point(x, y); } + + //StartInterceptingSystemBalloons(); } internal void InitializePreferences() @@ -508,9 +526,30 @@ protected override void Dispose(bool disposing) components.Dispose(); } - if (historyTrackBarToolTip != null) historyTrackBarToolTip.Dispose(); + if (historyTrackBarToolTip != null) + { + historyTrackBarToolTip.Dispose(); + historyTrackBarToolTip = null; + } + + if (historyTrackBarTimer != null) + { + historyTrackBarTimer.Dispose(); + historyTrackBarTimer = null; + } + + if (this.closeLastHotKey != null) + { + this.closeLastHotKey.Dispose(); + this.closeLastHotKey = null; + } + if (this.closeAllHotKey != null) + { + this.closeAllHotKey.Dispose(); + this.closeAllHotKey = null; + } - if (historyTrackBarTimer != null) historyTrackBarTimer.Dispose(); + //StopInterceptingSystemBalloons(); } base.Dispose(disposing); @@ -806,6 +845,16 @@ private void listControlDisplays_SelectedIndexChanged(object sender, EventArgs e } } + void listControlDisplays_DoubleClick(object sender, System.EventArgs e) + { + if (this.listControlDisplays.SelectedItem != null) + { + Display newDefault = (Display)this.listControlDisplays.SelectedItem; + this.controller.DefaultDisplay = newDefault; + this.listControlDisplays.Refresh(); + } + } + private void checkBoxEnableForwarding_CheckedChanged(object sender, EventArgs e) { Properties.Settings.Default.AllowForwarding = this.checkBoxEnableForwarding.Checked; @@ -1270,14 +1319,6 @@ private void StopInterceptingSystemBalloons() this.sbi = null; } } - - protected override void WndProc(ref Message m) - { - if (this.sbi != null) - sbi.ProcessWindowMessage(ref m); - - base.WndProc(ref m); - } * */ } } \ No newline at end of file diff --git a/Growl/Growl/Properties/AssemblyInfo.cs b/Growl/Growl/Properties/AssemblyInfo.cs index 7c361c6..38b7f98 100644 --- a/Growl/Growl/Properties/AssemblyInfo.cs +++ b/Growl/Growl/Properties/AssemblyInfo.cs @@ -33,6 +33,6 @@ // Revision // [assembly: AssemblyVersion("2.0.0.0")] -[assembly: AssemblyFileVersion("2.0.0.21")] -[assembly: AssemblyInformationalVersion("2.0rc1")] +[assembly: AssemblyFileVersion("2.0.0.22")] +[assembly: AssemblyInformationalVersion("2.0rc2")] [assembly: NeutralResourcesLanguageAttribute("en-US")] diff --git a/Growl/Growl/Properties/Resources.Designer.cs b/Growl/Growl/Properties/Resources.Designer.cs index 3d9ab72..5549a88 100644 --- a/Growl/Growl/Properties/Resources.Designer.cs +++ b/Growl/Growl/Properties/Resources.Designer.cs @@ -632,6 +632,15 @@ internal static string Button_Later { } } + /// + /// Looks up a localized string similar to No. + /// + internal static string Button_No { + get { + return ResourceManager.GetString("Button_No", resourceCulture); + } + } + /// /// Looks up a localized string similar to OK. /// @@ -1061,6 +1070,15 @@ internal static string History_Columns_Application { } } + /// + /// Looks up a localized string similar to Origin. + /// + internal static string History_Columns_Origin { + get { + return ResourceManager.GetString("History_Columns_Origin", resourceCulture); + } + } + /// /// Looks up a localized string similar to Text. /// @@ -1165,6 +1183,105 @@ internal static System.Drawing.Bitmap iphone { } } + /// + /// Looks up a localized string similar to The '{0}' language pack is already installed.. + /// + internal static string LanguageInstaller_AlreadyInstalled { + get { + return ResourceManager.GetString("LanguageInstaller_AlreadyInstalled", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The definition file '{0}' is invalid.\n\nThe language pack could not be installed.. + /// + internal static string LanguageInstaller_BadDefinitionFile { + get { + return ResourceManager.GetString("LanguageInstaller_BadDefinitionFile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The installation of the language pack was cancelled.\n\nThe language pack was not installed.. + /// + internal static string LanguageInstaller_DownloadCancelled { + get { + return ResourceManager.GetString("LanguageInstaller_DownloadCancelled", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to An error occurred while downloading the language pack files.\n\nThe language pack was not installed.. + /// + internal static string LanguageInstaller_DownloadError { + get { + return ResourceManager.GetString("LanguageInstaller_DownloadError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Install Language Pack. + /// + internal static string LanguageInstaller_FormTitle { + get { + return ResourceManager.GetString("LanguageInstaller_FormTitle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Installing language pack.... + /// + internal static string LanguageInstaller_Installing { + get { + return ResourceManager.GetString("LanguageInstaller_Installing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The '{0}' language pack was installed successfully.. + /// + internal static string LanguageInstaller_LanguageInstalledText { + get { + return ResourceManager.GetString("LanguageInstaller_LanguageInstalledText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Language Pack Installed. + /// + internal static string LanguageInstaller_LanguageInstalledTitle { + get { + return ResourceManager.GetString("LanguageInstaller_LanguageInstalledTitle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The definition file '{0}' does not exist.\n\nThe language pack could not be installed.. + /// + internal static string LanguageInstaller_NonexistentDefinitionFile { + get { + return ResourceManager.GetString("LanguageInstaller_NonexistentDefinitionFile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Do you want to install the language pack for the following language: {0}\n\nNOTE: Users running Vista or Windows 7 must have administrator privileges to install language packs.. + /// + internal static string LanguageInstaller_Prompt { + get { + return ResourceManager.GetString("LanguageInstaller_Prompt", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You must restart Growl for the changes to take effect.. + /// + internal static string LanguageInstaller_RestartRequiredText { + get { + return ResourceManager.GetString("LanguageInstaller_RestartRequiredText", resourceCulture); + } + } + internal static System.Drawing.Bitmap linux { get { object obj = ResourceManager.GetObject("linux", resourceCulture); diff --git a/Growl/Growl/Properties/Resources.resx b/Growl/Growl/Properties/Resources.resx index 213f0a6..1001c7c 100644 --- a/Growl/Growl/Properties/Resources.resx +++ b/Growl/Growl/Properties/Resources.resx @@ -220,6 +220,9 @@ ..\Resources\twitter.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\proxy.config;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + Growl (not running) Tooltip for notify icon when Growl is not running @@ -972,7 +975,56 @@ to Twitter Tile View History tab: Tile View context menu option - - ..\Resources\proxy.config;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 + + No + Any 'No' button + + + Origin + History tab: Column header for Origin column + + + The '{0}' language pack is already installed. + Language Pack installer: message shown if a language pack is already installed when attempting to install again. {0} is the name of the language + + + The definition file '{0}' is invalid.\n\nThe language pack could not be installed. + Language Pack installer: message shown if the definition file is malformed. {0} is the path to the file + + + The installation of the language pack was cancelled.\n\nThe language pack was not installed. + Language Pack installer: message shown if the download is cancelled by the user + + + An error occurred while downloading the language pack files.\n\nThe language pack was not installed. + Language Pack installer: message shown if the download of the language pack files fails for any reason + + + Install Language Pack + Language Pack installer: form title + + + Installing language pack... + Language Pack installer: displayed while the language pack is being installed + + + The '{0}' language pack was installed successfully. + Language Pack installer: text of the notification shown when a new language pack is installed. {0} is the name of the language. + + + You must restart Growl for the changes to take effect. + Language Pack installer: additional text of the notification shown when a new language pack is installed if Growl must be restarted. + + + Language Pack Installed + Language Pack installer: title of the notification shown when a new language pack is installed + + + The definition file '{0}' does not exist.\n\nThe language pack could not be installed. + Language Pack installer: message shown if the definition file could not be found. {0} is the file path + + + Do you want to install the language pack for the following language: {0}\n\nNOTE: Users running Vista or Windows 7 must have administrator privileges to install language packs. + Language Pack installer: displayed when a click-to-install link is clicked. {0} is the name of the language \ No newline at end of file diff --git a/Growl/Growl/Properties/Settings.Designer.cs b/Growl/Growl/Properties/Settings.Designer.cs index da02c18..68ccd4d 100644 --- a/Growl/Growl/Properties/Settings.Designer.cs +++ b/Growl/Growl/Properties/Settings.Designer.cs @@ -346,5 +346,17 @@ public bool DisableBonjour { this["DisableBonjour"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string MachineID { + get { + return ((string)(this["MachineID"])); + } + set { + this["MachineID"] = value; + } + } } } diff --git a/Growl/Growl/Properties/Settings.settings b/Growl/Growl/Properties/Settings.settings index 8b7e5de..dc9bcc4 100644 --- a/Growl/Growl/Properties/Settings.settings +++ b/Growl/Growl/Properties/Settings.settings @@ -77,5 +77,8 @@ False + + + \ No newline at end of file diff --git a/Growl/Growl/SystemBalloonIntercepter.dll b/Growl/Growl/SystemBalloonIntercepter.dll index 00f28a6..02dbf7b 100644 Binary files a/Growl/Growl/SystemBalloonIntercepter.dll and b/Growl/Growl/SystemBalloonIntercepter.dll differ diff --git a/Growl/Growl/UI/HistoryListView.cs b/Growl/Growl/UI/HistoryListView.cs index 5ab73ae..894b22a 100644 --- a/Growl/Growl/UI/HistoryListView.cs +++ b/Growl/Growl/UI/HistoryListView.cs @@ -385,8 +385,10 @@ public void Draw() if (detailColumns == null) { - int w = 100; - int x = (this.Width - (w * 2) - SCROLLBAR_WIDTH) / 2; + int w = 80; + int y = 60; + int x = (this.Width - (w * 2) - y - SCROLLBAR_WIDTH) / 2; + //int x = (this.Width - (w * 3) - SCROLLBAR_WIDTH); ColumnHeader titleHeader = new ColumnHeader(); titleHeader.Name = "TITLE"; @@ -405,8 +407,12 @@ public void Draw() dateHeader.Text = Properties.Resources.History_Columns_Timestamp; dateHeader.Width = w; dateHeader.Tag = DATETIME_COMPARISON_INDICATOR; + ColumnHeader originHeader = new ColumnHeader(); + originHeader.Name = "ORIGIN"; + originHeader.Text = Properties.Resources.History_Columns_Origin; + originHeader.Width = y; - this.detailColumns = new ColumnHeader[] { titleHeader, textHeader, appNameHeader, dateHeader }; + this.detailColumns = new ColumnHeader[] { titleHeader, textHeader, appNameHeader, dateHeader, originHeader }; } this.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Clickable; @@ -449,7 +455,9 @@ private List ApplyFilter() { if (StringContains(pn.Notification.ApplicationName, this.filter) || StringContains(pn.Notification.Title, this.filter) - || StringContains(pn.Notification.Description, this.filter)) + || StringContains(pn.Notification.Description, this.filter) + || StringContains(pn.Notification.OriginMachineName, this.filter) + ) { filteredList.Add(pn); } @@ -485,7 +493,6 @@ private ListViewItem CreateItem(PastNotification pn) if (pn.HasImage && !this.imageList.Images.ContainsKey(pn.ImageKey)) { - //System.Drawing.Image image = pn.Notification.GetImage(); System.Drawing.Image image = pn.Image; if (image != null) this.imageList.Images.Add(pn.ImageKey, image); @@ -494,9 +501,11 @@ private ListViewItem CreateItem(PastNotification pn) string title = Escape(pn.Notification.Title); string text = Escape(pn.Notification.Description); string appName = Escape(pn.Notification.ApplicationName); - string tooltip = String.Format("{0}\r\n{1}\r\n{4}: {2}\r\n{5}: {3}", pn.Notification.Title, pn.Notification.Description, pn.Notification.ApplicationName, pn.Timestamp.ToString(), Properties.Resources.LiteralString_ReceivedFrom, Properties.Resources.LiteralString_ReceivedAt); + string origin = (!String.IsNullOrEmpty(pn.Notification.OriginMachineName) ? pn.Notification.OriginMachineName : "Local Machine"); + string tooltipAppNameappName = Escape(String.Format("{0}{1}", pn.Notification.ApplicationName, (!String.IsNullOrEmpty(pn.Notification.OriginMachineName) ? String.Format("[{0}]", pn.Notification.OriginMachineName) : ""))); + string tooltip = String.Format("{0}\r\n{1}\r\n{4}: {2}\r\n{5}: {3}", pn.Notification.Title, pn.Notification.Description, tooltipAppNameappName, pn.Timestamp.ToString(), Properties.Resources.LiteralString_ReceivedFrom, Properties.Resources.LiteralString_ReceivedAt); - string[] items = new string[] { title, text, appName, pn.Timestamp.ToString() }; + string[] items = new string[] { title, text, appName, pn.Timestamp.ToString(), origin }; ListViewItem lvi = new ListViewItem(items, pn.ImageKey, this.Groups[groupName]); lvi.ToolTipText = tooltip; return lvi; @@ -574,7 +583,7 @@ private static string Escape(string input) void HistoryListView_Resize(object sender, EventArgs e) { - if (!this.isResizing) + if (!this.isResizing && this.Visible) { this.isResizing = true; try @@ -631,7 +640,6 @@ private void HistoryListView_ItemMouseHover(object sender, ListViewItemMouseHove { if (this.UseCustomToolTips) { - //System.Drawing.Point position = Cursor.Position; System.Drawing.Point position = this.PointToClient(Cursor.Position); position.Offset(0, Cursor.Current.Size.Height - 10); IntPtr handle = (IntPtr)typeof(ToolTip).GetProperty("Handle", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(this.tooltip, null); diff --git a/Growl/Growl/UI/ListControl.cs b/Growl/Growl/UI/ListControl.cs index 4617d40..862e96b 100644 --- a/Growl/Growl/UI/ListControl.cs +++ b/Growl/Growl/UI/ListControl.cs @@ -44,6 +44,12 @@ public ListControl() this.listbox.ForeColorChanged += new EventHandler(ListControl_ForeColorChanged); this.listbox.SelectedIndexChanged += new EventHandler(listbox_SelectedIndexChanged); this.listbox.MouseDown += new MouseEventHandler(listbox_MouseDown); + this.listbox.DoubleClick += new EventHandler(listbox_DoubleClick); + } + + void listbox_DoubleClick(object sender, EventArgs e) + { + this.OnDoubleClick(e); } void listbox_MouseDown(object sender, MouseEventArgs e) diff --git a/Growl/Growl/_source/ActivityMonitor.cs b/Growl/Growl/_source/ActivityMonitor.cs index c941619..6d6dced 100644 --- a/Growl/Growl/_source/ActivityMonitor.cs +++ b/Growl/Growl/_source/ActivityMonitor.cs @@ -242,7 +242,7 @@ void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e) { this.ResumedActivity(new ActivityMonitorEventArgs(ActivityMonitorEventReason.DesktopUnlocked)); this.isLocked = false; - StartTimer(); // start checking for idle again + MaybeStartTimer(); // start checking for idle again //Console.WriteLine("unlocked"); } } diff --git a/Growl/Growl/_source/ApplicationMain.cs b/Growl/Growl/_source/ApplicationMain.cs index ea3af67..04e60cd 100644 --- a/Growl/Growl/_source/ApplicationMain.cs +++ b/Growl/Growl/_source/ApplicationMain.cs @@ -7,6 +7,7 @@ namespace Growl static class ApplicationMain { public const int SIGNAL_RELOAD_DISPLAYS = 1; + public const int SIGNAL_UPDATE_LANGUAGE = 2; static Program program; static bool appIsAlreadyRunning; @@ -23,6 +24,7 @@ static void Main(string[] args) using (app) { int signalFlag = 0; + int signalValue = 0; appIsAlreadyRunning = app.IsAlreadyRunning; // handle protocol-triggered operations @@ -30,7 +32,7 @@ static void Main(string[] args) { string protocolArgument = args[0]; Installation.ProtocolHandler handler = new Growl.Installation.ProtocolHandler(appIsAlreadyRunning); - signalFlag = handler.Process(protocolArgument, ref queuedNotifications); + signalFlag = handler.Process(protocolArgument, ref queuedNotifications, ref signalValue); } if (!appIsAlreadyRunning) @@ -84,12 +86,11 @@ static void Main(string[] args) elog.WriteEntry(logtext, System.Diagnostics.EventLogEntryType.Error); MessageBox.Show(msgtext, "Growl - Fatal Exception", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1); } - Keyboard.Unhook(); } else { InternalNotification.SaveToDisk(ref queuedNotifications); - app.SignalFirstInstance(signalFlag); + app.SignalFirstInstance(signalFlag, signalValue); } } } @@ -99,12 +100,12 @@ static void program_ProgramRunning(object sender, EventArgs e) HandleSystemNotifications(); } - static void app_AnotherInstanceStarted(int signalFlag) + static void app_AnotherInstanceStarted(int signalFlag, int signalValue) { // show notification that growl is already running... Console.WriteLine("INSTANCE: growl is already running"); - program.AlreadyRunning(signalFlag); + program.AlreadyRunning(signalFlag, signalValue); HandleSystemNotifications(); } @@ -125,6 +126,14 @@ static void HandleSystemNotifications() queuedNotifications = null; } + static public bool HasProgramLaunchedYet + { + get + { + return (appIsAlreadyRunning || program != null); + } + } + static public Program Program { get diff --git a/Growl/Growl/_source/Controller.cs b/Growl/Growl/_source/Controller.cs index 5e01ea9..ec5c967 100644 --- a/Growl/Growl/_source/Controller.cs +++ b/Growl/Growl/_source/Controller.cs @@ -763,7 +763,7 @@ private void InvokeShowNotification(Growl.DisplayStyle.Notification notification if (this.synchronizingObject != null && this.synchronizingObject.InvokeRequired) { ShowNotificationDelegate snd = new ShowNotificationDelegate(ShowNotification); - this.synchronizingObject.BeginInvoke(snd, new object[] { notification, display, cbInfo, recordInMissedNotifications, requestInfo }); + this.synchronizingObject.Invoke(snd, new object[] { notification, display, cbInfo, recordInMissedNotifications, requestInfo }); } else { @@ -795,7 +795,7 @@ public void InvokeShowMissedNotifications(List missedNotificat if (this.synchronizingObject != null && this.synchronizingObject.InvokeRequired) { ShowMissedNotificationsDelegate smnd = new ShowMissedNotificationsDelegate(ShowMissedNotifications); - this.synchronizingObject.BeginInvoke(smnd, new object[] { missedNotifications }); + this.synchronizingObject.Invoke(smnd, new object[] { missedNotifications }); } else { @@ -813,7 +813,7 @@ private void InvokeRefreshActiveNotifications() if (this.synchronizingObject != null && this.synchronizingObject.InvokeRequired) { RefreshActiveNotificationsDelegate rand = new RefreshActiveNotificationsDelegate(RefreshActiveNotifications); - this.synchronizingObject.BeginInvoke(rand, null); + this.synchronizingObject.Invoke(rand, null); } else { @@ -879,6 +879,7 @@ Growl.Connector.Response gntpListener_NotifyReceived(Growl.Connector.Notificatio n.Sticky = sticky; n.Title = notification.Title; n.Duration = rn.Duration; + if (requestInfo.WasForwarded()) n.OriginMachineName = notification.MachineName; if (notification.Icon != null && notification.Icon.IsSet) { @@ -1035,6 +1036,7 @@ Growl.Connector.Response gntpListener_RegisterReceived(Growl.Connector.Applicati n.Sticky = false; // registration notifications are never sticky n.Title = Properties.Resources.SystemNotification_AppRegistered_Title; n.Image = ra.Icon; + if (requestInfo.WasForwarded()) n.OriginMachineName = application.MachineName; // handle custom attributes n.AddCustomTextAttributes(application.CustomTextAttributes); @@ -1343,7 +1345,7 @@ private void InvokeOnBonjourServiceUpdate(BonjourForwardDestination bfc) if (this.synchronizingObject != null && this.synchronizingObject.InvokeRequired) { OnBonjourServiceUpdateDelegate obsud = new OnBonjourServiceUpdateDelegate(OnBonjourServiceUpdate); - this.synchronizingObject.BeginInvoke(obsud, new object[] { bfc }); + this.synchronizingObject.Invoke(obsud, new object[] { bfc }); } else { @@ -1379,7 +1381,7 @@ private void InvokeOnForwardDestinationsUpdated() if (this.synchronizingObject != null && this.synchronizingObject.InvokeRequired) { OnForwardDestinationsUpdatedDelegate ofcud = new OnForwardDestinationsUpdatedDelegate(OnForwardDestinationsUpdated); - this.synchronizingObject.BeginInvoke(ofcud, null); + this.synchronizingObject.Invoke(ofcud, null); } else { @@ -1417,7 +1419,7 @@ private void InvokeOnSubscriptionsUpdated(bool countChanged) if (this.synchronizingObject != null && this.synchronizingObject.InvokeRequired) { OnSubscriptionsUpdatedDelegate osud = new OnSubscriptionsUpdatedDelegate(OnSubscriptionsUpdated); - this.synchronizingObject.BeginInvoke(osud, new object[] {countChanged}); + this.synchronizingObject.Invoke(osud, new object[] {countChanged}); } else { diff --git a/Growl/Growl/_source/Display.cs b/Growl/Growl/_source/Display.cs index 0e8be4d..6f5eed0 100644 --- a/Growl/Growl/_source/Display.cs +++ b/Growl/Growl/_source/Display.cs @@ -71,11 +71,6 @@ public virtual void ProcessNotification(DisplayStyle.Notification notification, { try { - //System.Threading.ParameterizedThreadStart pts = new System.Threading.ParameterizedThreadStart(DoShowNotification); - //System.Threading.Thread t = new System.Threading.Thread(pts); - //t.Start(notification); - - //this.display.HandleNotification(notification, this.name); bool done = this.display.ProcessNotification(notification, this.ActualName); // for any notifications that remain open (essentially, any visual notifications), add them to a list so we diff --git a/Growl/Growl/_source/DisplayLoader.cs b/Growl/Growl/_source/DisplayLoader.cs index b830a2f..904c24e 100644 --- a/Growl/Growl/_source/DisplayLoader.cs +++ b/Growl/Growl/_source/DisplayLoader.cs @@ -44,8 +44,14 @@ static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs ar string folder = (string)AppDomain.CurrentDomain.GetData(CURRENTLY_LOADING_DISPLAY_PATH); // get the assembly that we are looking for - Assembly assembly = referencedAssemblies[folder][args.Name]; - return assembly; + Assembly assembly; + Dictionary displayAssemblies; + if (referencedAssemblies.TryGetValue(folder, out displayAssemblies) && + displayAssemblies.TryGetValue(args.Name, out assembly)) + { + return assembly; + } + return null; } public DisplayLoader(string path) diff --git a/Growl/Growl/_source/DisplayStyleManager.cs b/Growl/Growl/_source/DisplayStyleManager.cs index 9051ada..6472cbf 100644 --- a/Growl/Growl/_source/DisplayStyleManager.cs +++ b/Growl/Growl/_source/DisplayStyleManager.cs @@ -62,8 +62,6 @@ public static void Load(string path) loadedDisplayStyle.SetGrowlApplicationPath(Application.StartupPath); loadedDisplayStyle.SetDisplayStylePath(directory.FullName); - loadedDisplayStyle.Load(); - currentlyLoadedDisplayStyles.Add(directory.FullName, loadedDisplayStyle); if (loadedDisplayStyle.Display.SettingsPanel != null) { @@ -72,6 +70,9 @@ public static void Load(string path) loadedDisplayStyle.Display.SettingsCollection = loadedDisplayStyle.Display.SettingsPanel.GetSettings(); } + loadedDisplayStyle.Load(); + currentlyLoadedDisplayStyles.Add(directory.FullName, loadedDisplayStyle); + /* REMOVED 07.23.2009 - this was left over from when displays were loaded into separate AppDomains Assembly a = Assembly.LoadFrom(displayLoader.SettingsPanelAssemblyLocation); object x = a.CreateInstance(displayLoader.SettingsPanelTypeName); diff --git a/Growl/Growl/_source/GNTPForwardDestination.cs b/Growl/Growl/_source/GNTPForwardDestination.cs index 875b894..e2ae7fe 100644 --- a/Growl/Growl/_source/GNTPForwardDestination.cs +++ b/Growl/Growl/_source/GNTPForwardDestination.cs @@ -99,7 +99,9 @@ internal override void ForwardNotification(Growl.Connector.Notification notifica growl.KeyHashAlgorithm = this.HashAlgorithm; growl.EncryptionAlgorithm = this.EncryptionAlgorithm; growl.ForwardedNotificationCallback += callbackFunction; - growl.Notify(notification, callbackInfo.Context); + CallbackContext context = null; + if (callbackInfo != null) context = callbackInfo.Context; + growl.Notify(notification, context); } } } diff --git a/Growl/Growl/_source/Installation/InstallDisplay.Designer.cs b/Growl/Growl/_source/Installation/InstallDisplay.Designer.cs index c02abe1..8f4a0b0 100644 --- a/Growl/Growl/_source/Installation/InstallDisplay.Designer.cs +++ b/Growl/Growl/_source/Installation/InstallDisplay.Designer.cs @@ -37,7 +37,7 @@ private void InitializeComponent() // this.InfoLabel.Location = new System.Drawing.Point(9, 9); this.InfoLabel.Name = "InfoLabel"; - this.InfoLabel.Size = new System.Drawing.Size(320, 90); + this.InfoLabel.Size = new System.Drawing.Size(320, 115); this.InfoLabel.TabIndex = 5; this.InfoLabel.Text = "Do you want to install the following display:"; this.InfoLabel.UseMnemonic = false; diff --git a/Growl/Growl/_source/Installation/InstallDisplay.cs b/Growl/Growl/_source/Installation/InstallDisplay.cs index fe08789..ad89190 100644 --- a/Growl/Growl/_source/Installation/InstallDisplay.cs +++ b/Growl/Growl/_source/Installation/InstallDisplay.cs @@ -34,7 +34,7 @@ public InstallDisplay() this.Text = Properties.Resources.DisplayInstaller_FormTitle; //this.InfoLabel.Text gets set below when displayed this.YesButton.Text = Properties.Resources.Button_Yes; - this.NoButton.Text = Properties.Resources.Button_Later; + this.NoButton.Text = Properties.Resources.Button_Cancel; this.OKButton.Text = Properties.Resources.Button_OK; this.BackColor = Color.FromArgb(240, 240, 240); @@ -108,7 +108,7 @@ public bool LaunchInstaller(string uri, bool appIsAlreadyRunning, ref List + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(InstallDisplay)); + this.progressBar1 = new System.Windows.Forms.ProgressBar(); + this.InfoLabel = new System.Windows.Forms.Label(); + this.OKButton = new Growl.UI.ButtonEx(); + this.NoButton = new Growl.UI.ButtonEx(); + this.YesButton = new Growl.UI.ButtonEx(); + this.SuspendLayout(); + // + // progressBar1 + // + this.progressBar1.ForeColor = System.Drawing.Color.Green; + this.progressBar1.Location = new System.Drawing.Point(9, 98); + this.progressBar1.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.progressBar1.Name = "progressBar1"; + this.progressBar1.Size = new System.Drawing.Size(320, 26); + this.progressBar1.TabIndex = 4; + this.progressBar1.Visible = false; + // + // InfoLabel + // + this.InfoLabel.Location = new System.Drawing.Point(9, 9); + this.InfoLabel.Name = "InfoLabel"; + this.InfoLabel.Size = new System.Drawing.Size(320, 115); + this.InfoLabel.TabIndex = 5; + this.InfoLabel.Text = "Do you want to install the following display:"; + this.InfoLabel.UseMnemonic = false; + // + // OKButton + // + this.OKButton.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("OKButton.BackgroundImage"))); + this.OKButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; + this.OKButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.OKButton.FlatAppearance.BorderSize = 0; + this.OKButton.FlatAppearance.MouseDownBackColor = System.Drawing.Color.Transparent; + this.OKButton.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Transparent; + this.OKButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.OKButton.Font = new System.Drawing.Font("Trebuchet MS", 10.25F, System.Drawing.FontStyle.Bold); + this.OKButton.ForeColor = System.Drawing.Color.WhiteSmoke; + this.OKButton.Location = new System.Drawing.Point(130, 128); + this.OKButton.Margin = new System.Windows.Forms.Padding(0); + this.OKButton.Name = "OKButton"; + this.OKButton.Size = new System.Drawing.Size(73, 32); + this.OKButton.TabIndex = 7; + this.OKButton.Text = "OK"; + this.OKButton.UseVisualStyleBackColor = true; + this.OKButton.Click += new System.EventHandler(this.OKButton_Click); + // + // NoButton + // + this.NoButton.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("NoButton.BackgroundImage"))); + this.NoButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; + this.NoButton.DialogResult = System.Windows.Forms.DialogResult.No; + this.NoButton.FlatAppearance.BorderSize = 0; + this.NoButton.FlatAppearance.MouseDownBackColor = System.Drawing.Color.Transparent; + this.NoButton.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Transparent; + this.NoButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.NoButton.Font = new System.Drawing.Font("Trebuchet MS", 10.25F, System.Drawing.FontStyle.Bold); + this.NoButton.ForeColor = System.Drawing.Color.WhiteSmoke; + this.NoButton.Location = new System.Drawing.Point(9, 128); + this.NoButton.Margin = new System.Windows.Forms.Padding(0); + this.NoButton.Name = "NoButton"; + this.NoButton.Size = new System.Drawing.Size(73, 32); + this.NoButton.TabIndex = 8; + this.NoButton.Text = "No"; + this.NoButton.UseVisualStyleBackColor = true; + this.NoButton.Visible = false; + this.NoButton.Click += new System.EventHandler(this.NoButton_Click); + // + // YesButton + // + this.YesButton.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("YesButton.BackgroundImage"))); + this.YesButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; + this.YesButton.DialogResult = System.Windows.Forms.DialogResult.Yes; + this.YesButton.FlatAppearance.BorderSize = 0; + this.YesButton.FlatAppearance.MouseDownBackColor = System.Drawing.Color.Transparent; + this.YesButton.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Transparent; + this.YesButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.YesButton.Font = new System.Drawing.Font("Trebuchet MS", 10.25F, System.Drawing.FontStyle.Bold); + this.YesButton.ForeColor = System.Drawing.Color.WhiteSmoke; + this.YesButton.Location = new System.Drawing.Point(256, 128); + this.YesButton.Margin = new System.Windows.Forms.Padding(0); + this.YesButton.Name = "YesButton"; + this.YesButton.Size = new System.Drawing.Size(73, 32); + this.YesButton.TabIndex = 6; + this.YesButton.Text = "Yes"; + this.YesButton.UseVisualStyleBackColor = true; + this.YesButton.Visible = false; + this.YesButton.Click += new System.EventHandler(this.YesButton_Click); + // + // InstallDisplay + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 18F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(338, 165); + this.Controls.Add(this.OKButton); + this.Controls.Add(this.NoButton); + this.Controls.Add(this.YesButton); + this.Controls.Add(this.progressBar1); + this.Controls.Add(this.InfoLabel); + this.Font = new System.Drawing.Font("Trebuchet MS", 9F); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "InstallDisplay"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Install Display"; + this.ResumeLayout(false); + + } + + #endregion + + private Growl.UI.ButtonEx OKButton; + private Growl.UI.ButtonEx NoButton; + private Growl.UI.ButtonEx YesButton; + private System.Windows.Forms.ProgressBar progressBar1; + private System.Windows.Forms.Label InfoLabel; + } +} \ No newline at end of file diff --git a/Growl/Growl/_source/Installation/InstallLanguage.cs b/Growl/Growl/_source/Installation/InstallLanguage.cs new file mode 100644 index 0000000..a6d8f20 --- /dev/null +++ b/Growl/Growl/_source/Installation/InstallLanguage.cs @@ -0,0 +1,304 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.IO; +using System.Net; +using System.Text; +using System.Windows.Forms; +using System.Xml; + +namespace Growl.Installation +{ + public partial class InstallLanguage : Form + { + private const string USER_AGENT = "Growl for Windows - Lanaguage Pack AutoInstaller"; + private const string TEMP_FOLDER = "__temp"; + + private WebClientEx wc; + private string uri; + private bool appIsAlreadyRunning; + private string tempFolder; + private System.Threading.ManualResetEvent mre = new System.Threading.ManualResetEvent(false); + private System.Threading.AutoResetEvent are = new System.Threading.AutoResetEvent(false); + private DownloadProgressChangedEventArgs progress; + private object progress_lock = new object(); + private string errorMessage = null; + + public InstallLanguage() + { + InitializeComponent(); + + // localize text + this.Text = Properties.Resources.LanguageInstaller_FormTitle; + //this.InfoLabel.Text gets set below when displayed + this.YesButton.Text = Properties.Resources.Button_Yes; + this.NoButton.Text = Properties.Resources.Button_Cancel; + this.OKButton.Text = Properties.Resources.Button_OK; + + this.BackColor = Color.FromArgb(240, 240, 240); + } + + public bool LaunchInstaller(string uri, bool appIsAlreadyRunning, ref List queuedNotifications, ref int cultureCodeHash) + { + bool languageInstalled = false; + this.uri = uri; + this.appIsAlreadyRunning = appIsAlreadyRunning; + this.tempFolder = Path.Combine(Utility.UserSettingFolder, TEMP_FOLDER); + + try + { + this.wc = new WebClientEx(); + wc.Headers.Add("User-Agent", USER_AGENT); + + byte[] data = wc.DownloadData(this.uri); + string definition = Encoding.UTF8.GetString(data).Trim(); + LanguageInfo info = LanguageInfo.Parse(definition); + if (info != null) + { + this.InfoLabel.Text = String.Format(Utility.GetResourceString(Properties.Resources.LanguageInstaller_Prompt), info.Name); + this.YesButton.Visible = true; + this.NoButton.Visible = true; + this.OKButton.Visible = false; + DialogResult result = this.ShowDialog(); + if (result == DialogResult.Yes) + { + this.InfoLabel.Text = Utility.GetResourceString(Properties.Resources.LanguageInstaller_Installing); + this.progressBar1.Value = 0; + this.progressBar1.Visible = true; + this.YesButton.Enabled = false; + this.NoButton.Enabled = false; + this.Show(); + this.Refresh(); + + if (Directory.Exists(this.tempFolder)) + Directory.Delete(this.tempFolder, true); + Directory.CreateDirectory(this.tempFolder); + string zipFileName = Path.Combine(this.tempFolder, String.Format("{0}.zip", System.Guid.NewGuid().ToString())); + info.LocalZipFileLocation = zipFileName; + + wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged); + wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompleted); + + StartDownload(info); + + Utility.WriteDebugInfo(String.Format("Downloading language pack '{0}' to {1}", info.Name, info.LocalZipFileLocation)); + + System.Threading.WaitHandle[] handles = new System.Threading.WaitHandle[] { are, mre }; + while (System.Threading.WaitHandle.WaitAny(handles) == 0) + { + lock (this.progress_lock) + { + this.progressBar1.Value = this.progress.ProgressPercentage; + Application.DoEvents(); + } + } + + this.progressBar1.Value = 100; + Application.DoEvents(); + + Utility.WriteDebugInfo(String.Format("Finished downloading language pack '{0}' to {1}", info.Name, info.LocalZipFileLocation)); + + if (this.errorMessage == null) + { + // unzip files to the correct location + string languageFolder = Path.Combine(Application.StartupPath, info.CultureCode); + if (!ApplicationMain.HasProgramLaunchedYet || !Directory.Exists(languageFolder)) + { + Utility.WriteDebugInfo(String.Format("Language '{0}' downloaded - starting unzip.", info.Name)); + Unzipper.UnZipFiles(info.LocalZipFileLocation, languageFolder, false); + + //InternalNotification n = new InternalNotification(Properties.Resources.DisplayInstaller_NewDisplayInstalledTitle, String.Format(Utility.GetResourceString(Properties.Resources.DisplayInstaller_NewDisplayInstalledText), info.Name), info.Name); + string text = String.Format(Properties.Resources.LanguageInstaller_LanguageInstalledText, info.Name); + if (ApplicationMain.HasProgramLaunchedYet) text += (" " + Properties.Resources.LanguageInstaller_RestartRequiredText); + InternalNotification n = new InternalNotification(Properties.Resources.LanguageInstaller_LanguageInstalledTitle, Utility.GetResourceString(text), null); + queuedNotifications.Add(n); + + Properties.Settings.Default.CultureCode = info.CultureCode; + cultureCodeHash = info.CultureCode.GetHashCode(); + + languageInstalled = true; + + this.Close(); + } + else + { + // display with the same name aleady exists... + ShowMessage(String.Format(Utility.GetResourceString(Properties.Resources.LanguageInstaller_AlreadyInstalled), info.Name)); + } + + // clean up + Utility.WriteDebugInfo(String.Format("Deleteing '{0}' zip file at {1}", info.Name, info.LocalZipFileLocation)); + if (File.Exists(info.LocalZipFileLocation)) File.Delete(info.LocalZipFileLocation); + } + else + { + Utility.WriteDebugInfo(String.Format("Error downloading language pack '{0}'.", info.Name)); + ShowMessage(errorMessage); + } + } + } + else + { + // definition file was malformed + ShowMessage(String.Format(Utility.GetResourceString(Properties.Resources.LanguageInstaller_BadDefinitionFile), this.uri)); + } + } + catch (Exception ex) + { + // error downloading definition file + Utility.WriteDebugInfo(String.Format("Error downloading language pack. {0} - {1}", ex.Message, ex.StackTrace)); + ShowMessage(String.Format(Utility.GetResourceString(Properties.Resources.LanguageInstaller_NonexistentDefinitionFile), this.uri)); + } + return languageInstalled; + } + + private void StartDownload(object obj) + { + System.Diagnostics.Debug.WriteLine("InstallLanguage.StartDownload thread: " + System.Threading.Thread.CurrentThread.ManagedThreadId); + LanguageInfo info = (LanguageInfo)obj; + this.wc.DownloadFileAsync(new Uri(info.PackageUrl), info.LocalZipFileLocation, info); + } + + void wc_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) + { + if (e.Error != null) + { + Utility.WriteDebugInfo(e.Error.Message); + Utility.WriteDebugInfo(e.Error.StackTrace); + this.errorMessage = Utility.GetResourceString(Properties.Resources.LanguageInstaller_DownloadError); + } + else if (e.Cancelled) + { + this.errorMessage = Utility.GetResourceString(Properties.Resources.LanguageInstaller_DownloadCancelled); + } + else + { + // sometimes the downloaded file is still being written to disk. + // this will wait until the file is readable before returning. + LanguageInfo info = (LanguageInfo)e.UserState; + bool fileAvailable = false; + int counter = 0; + while (!fileAvailable && counter < 10) + { + counter++; + try + { + FileStream fs = File.OpenRead(info.LocalZipFileLocation); + using (fs) + { + fileAvailable = true; + } + } + catch + { + // wait a bit to allow the disk I/O to complete + System.Threading.Thread.Sleep(500); + } + } + } + + mre.Set(); + } + + void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) + { + lock (this.progress_lock) + { + this.progress = e; + are.Set(); + } + } + + private void ShowMessage(string message) + { + this.InfoLabel.Text = message; + this.progressBar1.Visible = false; + this.YesButton.Visible = false; + this.NoButton.Visible = false; + this.OKButton.Visible = true; + if (this.appIsAlreadyRunning) + { + this.Hide(); + DialogResult result = this.ShowDialog(); + } + else + { + this.Show(); + } + } + + private void NoButton_Click(object sender, EventArgs e) + { + this.Close(); + } + + private void OKButton_Click(object sender, EventArgs e) + { + this.Close(); + } + + private void YesButton_Click(object sender, EventArgs e) + { + + } + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (this.mre != null) mre.Close(); + if (this.are != null) are.Close(); + if (this.components != null) components.Dispose(); + } + base.Dispose(disposing); + } + + public class LanguageInfo + { + private LanguageInfo() { } + + public LanguageInfo(string name, string cultureCode, string packageUrl) + { + this.Name = name; + this.CultureCode = cultureCode; + this.PackageUrl = packageUrl; + } + + public readonly string Name; + public readonly string CultureCode; + public readonly string PackageUrl; + public string LocalZipFileLocation; + + public static LanguageInfo Parse(string data) + { + try + { + XmlDocument xml = new XmlDocument(); + xml.LoadXml(data); + + XmlElement root = xml.DocumentElement; + XmlElement nameNode = root["name"]; + XmlElement cultureCodeNode = root["culture"]; + XmlElement packageUrlNode = root["packageurl"]; + + string name = nameNode.InnerText.Trim(); + string cultureCode = cultureCodeNode.InnerText.Trim(); + string packageUrl = packageUrlNode.InnerText.Trim(); + + LanguageInfo info = new LanguageInfo(name, cultureCode, packageUrl); + return info; + } + catch + { + return null; + } + } + } + } +} \ No newline at end of file diff --git a/Growl/Growl/_source/Installation/InstallLanguage.resx b/Growl/Growl/_source/Installation/InstallLanguage.resx new file mode 100644 index 0000000..7e12424 --- /dev/null +++ b/Growl/Growl/_source/Installation/InstallLanguage.resx @@ -0,0 +1,462 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAJJt+AyOYfBAjmXwDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACeh + gwwnm4AWJZB5VyyIdm0qg3RtIn50bCd4cp8pdXDUKXhyoiR9c2kqgXNsK4ZzaySNdlYnm38cKaKFCAAA + AAAln4MBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAKZqAQSmGem4kb27RJmRu2iBcbv8bVWv/HVVt/xpWcv8eXXv/H2CA/x9hgf8dXnz/H114/x5c + dP8iYHP/J2Zu3SdzcL0qh3dhKJ6BKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAtm4Q+J3p0pyFda/gaUWn/GFVy/xlefv8ebpL/IXuj/yOFsP8okL//KZjJ/yqZ + yv8pmMn/KJPB/yaLuP8he6P/HWyO/xtlhv8dYoP/H113/yVlb+ErhXiAKqKGHwAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAruJgCLLeVBS+giT4pdnarIFdp+hhRbP8aYIL/IHif/yeNuv8uodT/Mq/m/zW4 + 8v82u/X/OMH6/znD/f84vvv/M7Tt/y2j1v8nj7z/IXeb/x1ph/8ea4v/IXeb/ySErv8jgq7/I3KY/yRo + euAqgHWBLKmKJiq3lgMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALq6QMCh8d6ogVmn7Fk5p/xpjhf8mi7n/MrDi/zjB + 9/86xPz/PMv//0DV//9B0///P9D//0HV//9A0f//Or33/yuPu/8aWnf/EDpN/w81Rf8RPlD/FUtg/xxi + gP8khKz/LaTX/zGz7P8tqN//J4Kv/yltfOAtj3tfLLeUCQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALZmEciJga+YWTWn/GV5//yaH + s/80tOb/P9X//0Th//9F4P//RNv//0Tc//9G4f//RuD//0Xc//9F3f//Orjq/yJnhv8PKTX/BAoO/wAA + Af8BAwP/AwsO/wYXHv8NLz3/F1Nt/yWDq/8wruf/OMz//znU//8yt+b/KoKm/y58ep0trIwaAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMZmGfRtV + aP8WVXT/J4u0/za56P9A1P//RuT//0no//9K5///Seb//0fj//9I4///SeT//0ro//9J5///Pb3q/yBY + c/8MFxv/BgkK/wEEBP8AAgP/AAID/wACBP8ABAX/AQcI/wUUGf8OLz7/Gl17/yubzf871v//QOn//zra + //8toMz/KnaD4TKjh0IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAALp2HbBtWaP8TS2b/Jou0/z7X//9I5v//Seb//0rn//9M6P//TOn//0rl//9J4///Seb//0ro + //9M6f//RNH7/ydrjP8PGR//Cw4Q/wgOEP8ECAr/AAMF/wADBP8AAwT/AAME/wACAv8AAgL/AAMD/wMK + Df8QOEr/KJPC/zrU//9A6P//P+r//zXB6v8ugZXtMJ6FSQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAMayQJiJibuQTTmn/F1Fp/yqXw/871P3/Q9n0/0vj+v9K4v7/TOb//0zn + //9M6P//S+j//0vn//9M6P//S+P//zaaxf8WKzf/DhIV/w4VGf8NFBf/Cg4R/wQHCP8AAwT/AAME/wAD + BP8AAwT/AAME/wACA/8AAAH/AgYH/w4zRP8gc5j/K57H/zGx2f84zvD/MsD0/yuAne4wnYZIAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMq6QJidrcNQVUGz/F1Rr/xhVb/8updX/OtX//znL + 9v9D0e//SuD6/0vl//9L4///Tej//0zo//9L5f//Ten//0nd//8wf6f/FCAm/xEYG/8VHiL/Fh0h/xEW + Gv8IDA3/AQMF/wADBP8AAwT/AAME/wADBP8AAwT/AAME/wACAv8EDxP/EDtM/xZPaf8YVXD/Gl58/yN7 + oP8ihLP/KG+B7jOli0EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMaGKYiRoc+AUTWf/E0VZ/xE9 + T/8USF//In2k/ymZx/8urd//N8b5/0Ta//9I4v//SuL//07n//9O6P//TOT//0zm//9M4f//OJ3L/xsy + Pv8aIST/ICku/x8oLf8YHiL/Cw8R/wEEBf8AAwT/AAME/wADBP8AAwT/AAME/wACA/8AAwP/DCo2/xhU + bP8XUmn/FlBp/xdSbP8aXXv/In2l/x92o/8nZ3DsMK6OKQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAysZIZK4F5hhpQ + Yv8MNUr/Bx4o/wQQFf8FFBr/Bhcg/wcXH/8MISz/EjxQ/xxniv8rm8v/P9L8/0zn//9Q6f//T+b//03m + //9M5f//TOf//0C25P8qVWz/JC0x/ygxNv8mMDX/GyMo/wwQEv8BAwT/AAME/wADBP8AAwT/AAME/wAD + BP8AAAD/BBEW/xVKYP8bYH3/I36l/yqaw/8xsdj/N8nu/zrS+f82x/L/Jou2/y17easvtZMEAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAM7aZDTqrki4spossJq6PIQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC24 + lxYzmIR3I15n3hNNbP8QQ1z/CBQa/wYKDP8GDBD/BQwP/wUKDf8IDhH/DRMW/xAUFv8RGx//HlBq/zu1 + 5v9P6P//VOz//VLq//5O5///S+T//0vl//9I1Pv/PZfB/zFRYv8uOT//KDE1/xwjKP8LEBL/AAMD/wAD + A/8AAwT/AAME/wADBP8AAQL/AAID/wwrN/8VTWP/HWiI/znM9v9A6v/9Pef//z3l//8+5P//P+f//zzi + //8skLL/L5WATAAAAAAAAAAAAAAAAAAAAAAAAAAAKreXBVGRg57Lx8n5r768+GuQi+JQenOYTXNtnUp/ + c5hBhXWUPoR1k0d9c5NWcWvZLk1c/xFTcf8vnMH/M4uz/yQ8Sv8eJiv/GCAk/xEZHf8NFBj/DBUY/xIa + Hv8YHSD/Hiow/y9ng/9Hv+3/U+v//Vbu//xU6//9UOn//0vj//9Dzv7/Rtn//0rV/v88lL//K1ht/xsq + Mv8UGx//CQwO/wACAv8AAwT/AAID/wACAv8AAQL/AAID/wUSGP8RPU7/FEph/xthf/9J4PP7XPv/+1H0 + //1C6//8O+b//zzg//8/5///Nszx/zCFisAvt5UGAAAAAAAAAAAAAAAAAAAAAC65mQtQZ2HnqYOM//z3 + +v/99/v/1MnQ/66grP+YiZX/loqV/6icpf+5p7D/h3+L/yBlfP9J0+D9Y////F3j/f1FjK//MkpX/ysz + N/8nMDX/Hygt/xYeIf8SGBz/GCMp/ytPZf9KrNn/XOr//GD3//pd9f/5WfD/+VPr//5J3v//ObXt/zm2 + 6/9E1///QMr8/y+by/8aWHb/DzJD/wcUGv8AAgP/AAEC/wEFB/8BBQf/AgkM/wYXHv8OM0L/FEZa/xRI + Xv8dXXr/WuPy+3P///+y///+oNni+lbO3PdE6f75POj//jzk//8xl7H+MZ6FRgAAAAAAAAAAAAAAAAAA + AAAtvJsFSX5ypWkyPP+Na3L/6eTm////////////+/v9//n5+v/8/P3//////4Cbp/86v878af///GX9 + //1k/f/8Wdj6/0mexv89boj/OVls/ztecP88YXT/Omd//zyDpf9Gqc//W+H8/WX6//tl+f/7ZPn/+17z + //hT6f/+RND7/y2Swv8nhK7/LprL/zCm2P8totb/KpzR/yOEsf8eb5T/ED9W/wUUHP8GFRv/CBwk/wso + NP8RQFL/E0NX/xJEV/8USV7/NYio/2X2/v1v6+79oqat/5t+h/93aXL9cJie+VvX4/hB8P/8Nbrd/y6R + hmEAAAAAAAAAAAAAAAAAAAAAAAAAADikizZnSE71ZS85/31XX//Y0NT////////////////////////7 + +v9agJD/RtPh/WX///pi+f/7Y/v/+2D1//pd6P/9Vs/1/1K74/9Npc//T6za/1nM9/9i5//9Zvj//Gf8 + //xm+//8Zvr//GT3//pe9P/5Uun//ju96/8fbZH/F1Zv/xpefP8eb5L/JYm2/zW47f9A0///QdT//zq6 + 5f8jcpT/DjVI/w84Sf8SQVT/FEZa/xJAU/8RQVT/F0pj/1fS5/5t9/b4ZoWN/GNRWv9oV1//dGFq/3xm + b/98foX9UMTY/TDL8v8wh4a6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASnpupm86RP9mMzz/c0lT/6yc + ov/a297/7PH0//r////7/v//TWp5/zOguP5h/P/7X/f/+172//tg+v/5Yfv/+WD2//li9f/6Ye3//WHo + //1k8v/7Z/r/+Wn9//tp/v/8Zfr//GT6//1h9v/6WOz//Ezk//8woc3/FU5m/xNEV/8TRln/HGWE/y+k + 1f9G2///U+///lry//td9v/5V+f7/D6fsv8UQVb/DzlK/xJBU/8TQlX/Ej9R/xRGXP9Np7v8bJWb+mlY + Xv9oX2b/X11m/25mb/93b3f/gHN7/2uBkv8kh6v/L3h30QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC+3 + mA9RcGe3bTlD/2o1P/9jMzv/Z0NL/3RcZf9+cXr/eXmD/ypOXv8VUGj/LX2Y/zOJpf80iaj/QanI/lbg + 9vtg+P/6XvL+/Frq8/xc7/76YPn/+17z//tT4/z8Sdb6/kPM9v5N0vv+VeL//lHm//9B0///IXed/xJA + U/8TRFf/E0VY/yB0mv9AzPn/Ve7/+2P5//to/P/8Z/n/+2n///xq///7Oo+i+wwsO/8QPE3/EkFT/xJB + VP8PQlf/NU5f/2piaf9eXWT/RFhm/0ZofP93cHr/e251/316gv+CdX3/Pk1e/yZ8dqwAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAMLqaDUaAcaZkRUn6bjhC/2k1Pv9jMTj/Xy0z/1QpMP8cP1H/D0NX/w84 + Sv8PN0n/EDhK/xRAVf8hXnf/KXmR/yBkeP8hdZX/Nr70/zOu2v8lgab/GmOF/xdZe/8hWXb/MGiG/zyV + wf9CxPb/MKjc/xZQaP8RPU//E0NW/xJBVP8jf6f/RNv//1/2//xq/f/8afz//Wj5//xo+v/8afz/+2Xz + +fkqbID+DC8//xA7TP8SQFP/Dz1O/x1AUf8+S1b/N0xZ/zJfdv9UbYH/emx1/5CLmf+fpLT/hHeB/2hj + av8wm4dMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP4l3QVZhXLFmQkf7bDU//24z + O/9RMz3/FEJW/xNHW/8TQlT/ETxO/xA6S/8POUr/DTJC/w0yQ/8WVHD/IXym/xhaev8KKDj/Bhgi/wQQ + F/8KERX/GiEm/x8nK/8gOET/JnKX/xtkhP8SQFP/EkBU/xJCVf8SQFP/IHOY/z3R/f9V7v/8af3//Gz9 + //5q/P/9avr//Gr5//xq/P/4WNbl+x1NXv8ONkb/EkBT/xFAUv8TPU7/JzxI/y1CT/80UmT/eXeB/8bA + yP/a6fr/srrQ/3xrdf9waW3/OaeNSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAA0q48COZuDSEh+cH9XW1XYOkZO9A5AV/8QQ1v/EEBV/xI/Uv8QOkz/ET5R/xNDVv8aXHj/Inqi/xJD + Wf8DDBH/AQYI/wEGCP8IDhH/GB8j/yAoLf8dIyf/Ex8l/xA4Sf8QOkv/E0NW/xJBVP8TQ1b/EkFT/yBy + lv84zP//Qdn//1Pp//5q/f/9b////W39//5r+v/9a/r/+Wb0//spZnz/CjBD/w05Tv8OPlP/Dj1R/ytN + Yf8sQE7/b3B3/+bh4v//////+P///5ybq/94Z2//eGRs/0GfilEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADechjQpeHOnI1lh8h5MW/UURVj/FENV/xVK + YP8ZWXP/JIWv/xVMZv8EDhT/AQcK/wEJDP8HDxL/FR0i/x8oLf8fJyz/Fx8k/wsfKP8KKjf/EDxN/xNF + WP8URlr/Ej5Q/xE9Tv8da47/LaLU/zW47v85yPz/SNv8/mX1//xw/v/9cP///Wj5//03k6r/FEFT/yBL + VvIkUVvzJVNd8hpLWvMiR1j/RVVm/87N0f///////////+Xj5/+FdoH/fGVw/29ma/45mYJFAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADe0 + liAypY0rMot4hypnaM0USmL/Inqg/yODr/8KJzT/AAYJ/wAGCv8EDA//DRUZ/xcgJf8cJCn/GiEl/xAh + Kf8JJC//DjNB/xJCVv8TQ1b/DzVE/wkjLf8JIi3/Cyg1/xE2SP8hX3z/L5LB/zK89P8+zvv/Yu///Gn5 + //06o7n/KWJguzGMeVY0r5UfNa6RJDawkyAxqY8lMYh3glNlaeaKY27/p4uS/6iNlP+IZ2//dVVe/3xa + Zv9UfHPGLbGSBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmY2jREEdg/yuVvf83rd7/HEpj/wsXH/8JEBb/CxAT/xAV + GP8VHCD/GSAj/xgqM/8OLTr/DS88/xJBU/8SQVP/DTA9/wQQFf8CCg3/AwoN/wsQE/8QFRj/GSQp/y1c + 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 + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAN4l3ZTJHUf8sPEf/KD9K/y9GVv92g5H/6O/2/+jj6/9zcYH/R8PS+1X+//pD6P/+Ioqy/yNa + ZfY4rpImAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAANKaNSjleYuQvQVH/M05f/09tgv+AnLL/qLnT/62uwv+Me4j/YEVO/yxx + h/9E6v/9LKXM/xtTavw1jHpuAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANZ2ENYqbnfnNztX/ztXa/8jX4v/N2e3/1dvz/6yn + u/92ZG7/clJZ/1tIUf8bT2X/I4iw/xlaef8vgXeQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAESKeXuhf4f/+PLz//jy + 9P/Esrj/loCN/415h/97Y2z/clRc/3VOVv9FRE//EEVa/xJOaf8qaGnONKCFEgAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AABWcml7bj9I/4RbZf+CW2T/bD9I/21ASf9vRU3/ckpT/3RLU/9vSFD/KDlI/wxDXP8samzRPYh0HQAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAARoFxbmxIUP9wPUj/bkBJ/3JETf9yRE3/ckRN/3JHTv91R1D/aEVO/yNJ + VfgocG+nPaOKHgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADO0lhhcX13meDxJ/3VETv90RU7/dEVO/3NE + Tv92Q07/b0tT/01vZsQ2nog+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOqWMSVhk + YNdsSk/9cUVO/3FGTv9vSE//X1lZ8kOKeXo1u5wJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAA2waETO6CIOD+HdZNAjHmdRIp4QkWKeCMAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAA//////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////x/////////AAH///////gAAD///// + /4AAAD/////+AAAAH/////wAAAAH////+AAAAAP////wAAAAAf///+AAAAAA////wAAAAAB///+AAAAA + AD///gAAAAAAH//8AAAAAAAfwAAAAAAAAA/AAAAAAAAAD8AAAAAAAAAP4AAAAAAAAAfgAAAAAAAAB/AA + AAAAAAAH+AAAAAAAAA/+AAAAAAAAD//AAAAAAAAP//AAAAAAAA///gAAAAPgD///AAAAB/gf//8AAAAP + /D///gAAAB/////4AAAAH////4AAAAAf////AAAAAB////8AAAAAH////wAAAAAf////gAAAAB////+A + AAAAH////8AAAAA/////8ADwAD//////g/AAP///////8AB////////gAH///////+AA////////wAH/ + //////+AAf///////4AD////////gAf///////+AD////////4A/////////wP/////////z//////// + //////////////////////////////////////////////////8= + + + \ No newline at end of file diff --git a/Growl/Growl/_source/Installation/ProtocolHandler.cs b/Growl/Growl/_source/Installation/ProtocolHandler.cs index b27f476..ab4e569 100644 --- a/Growl/Growl/_source/Installation/ProtocolHandler.cs +++ b/Growl/Growl/_source/Installation/ProtocolHandler.cs @@ -16,14 +16,16 @@ public ProtocolHandler(bool appIsAlreadyRunning) this.appIsAlreadyRunning = appIsAlreadyRunning; } - public int Process(string uri, ref List queuedNotifications) + public int Process(string uri, ref List queuedNotifications, ref int signalValue) { - // general format: growl://action*data1&data2&data3...etc - // example: growl://display*http://www.somesite.org/display.xml + // general format: growl:action*data1&data2&data3...etc + // example: growl:display*http://www.somesite.org/display.xml + // 09.22.2009 - changed protocol scheme from growl:// to just growl: because of a bug in Google Chrome: http://code.google.com/p/chromium/issues/detail?id=160 + // the old syntax (with //) is still supported as well int result = 0; - Regex regex = new Regex(@"growl://(?[^\*]*)\*(?[\s\S]*)"); + Regex regex = new Regex(@"growl:(//)?(?[^\*]*)\*(?[\s\S]*)"); Match match = regex.Match(uri); if (match.Success) { @@ -32,15 +34,21 @@ public int Process(string uri, ref List queuedNotification switch (action) { case "display": - InstallDisplay form = new InstallDisplay(); - bool newDisplayLoaded = form.LaunchInstaller(data, this.appIsAlreadyRunning, ref queuedNotifications); + InstallDisplay id = new InstallDisplay(); + bool newDisplayLoaded = id.LaunchInstaller(data, this.appIsAlreadyRunning, ref queuedNotifications); if (newDisplayLoaded) result = ApplicationMain.SIGNAL_RELOAD_DISPLAYS; + id.Close(); + id = null; break; case "extension": // this isnt a real use case yet break; case "language": - // this isnt a real use case yet + InstallLanguage il = new InstallLanguage(); + bool languageInstalled = il.LaunchInstaller(data, this.appIsAlreadyRunning, ref queuedNotifications, ref signalValue); + if (languageInstalled) result = ApplicationMain.SIGNAL_UPDATE_LANGUAGE; + il.Close(); + il = null; break; } } diff --git a/Growl/Growl/_source/Keyboard.cs b/Growl/Growl/_source/Keyboard.cs index ec0b4c9..37dff65 100644 --- a/Growl/Growl/_source/Keyboard.cs +++ b/Growl/Growl/_source/Keyboard.cs @@ -1,3 +1,4 @@ +/* NO LONGER USED - REPLACED WITH HotKeyManager using System; using System.Diagnostics; using System.Windows.Forms; @@ -99,3 +100,4 @@ public Keys KeyData } } } +*/ \ No newline at end of file diff --git a/Growl/Growl/_source/Program.cs b/Growl/Growl/_source/Program.cs index 9c454fb..63021bf 100644 --- a/Growl/Growl/_source/Program.cs +++ b/Growl/Growl/_source/Program.cs @@ -345,7 +345,7 @@ internal void ExitApp() Application.Exit(); } - internal void AlreadyRunning(int signalFlag) + internal void AlreadyRunning(int signalFlag, int signalValue) { if(this.controller != null) this.controller.SendSystemNotification(Properties.Resources.SystemNotification_Running_Title, Properties.Resources.SystemNotification_Running_Text, null); @@ -355,6 +355,18 @@ internal void AlreadyRunning(int signalFlag) DisplayStyleManager.Load(); if(this.mainForm != null) this.mainForm.BindDisplayList(); break; + case ApplicationMain.SIGNAL_UPDATE_LANGUAGE : + // read each subfolder in the app folder and find the one with the matching hash + System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(Application.StartupPath); + foreach (System.IO.DirectoryInfo directory in di.GetDirectories()) + { + if (directory.Name.GetHashCode() == signalValue) + { + Properties.Settings.Default.CultureCode = directory.Name; + break; + } + } + break; } } @@ -428,7 +440,7 @@ void controller_ApplicationRegistered(RegisteredApplication ra) if (this.mainForm.IsHandleCreated && this.mainForm.InvokeRequired) { Controller.ApplicationRegisteredDelegate del = new Controller.ApplicationRegisteredDelegate(this.mainForm.OnApplicationRegistered); - this.mainForm.BeginInvoke(del, new object[] { ra }); + this.mainForm.Invoke(del, new object[] { ra }); } else { @@ -444,7 +456,7 @@ void controller_NotificationReceived(Growl.DisplayStyle.Notification n) if (this.mainForm.IsHandleCreated && this.mainForm.InvokeRequired) { Controller.NotificationReceivedDelegate del = new Controller.NotificationReceivedDelegate(this.mainForm.OnNotificationReceived); - this.mainForm.BeginInvoke(del, new object[] { n }); + this.mainForm.Invoke(del, new object[] { n }); } else { @@ -460,7 +472,7 @@ void controller_NotificationPast(PastNotification pn) if (this.mainForm.IsHandleCreated && this.mainForm.InvokeRequired) { Controller.NotificationPastDelegate del = new Controller.NotificationPastDelegate(this.mainForm.OnNotificationPast); - this.mainForm.BeginInvoke(del, new object[] { pn }); + this.mainForm.Invoke(del, new object[] { pn }); } else { diff --git a/Growl/Growl/_source/SingleInstanceApplication.cs b/Growl/Growl/_source/SingleInstanceApplication.cs index fbb2063..59027f2 100644 --- a/Growl/Growl/_source/SingleInstanceApplication.cs +++ b/Growl/Growl/_source/SingleInstanceApplication.cs @@ -9,7 +9,7 @@ namespace Growl { public class SingleInstanceApplication : IMessageFilter, IDisposable { - public delegate void AnotherInstanceStartedEventHandler(int signalFlag); + public delegate void AnotherInstanceStartedEventHandler(int signalFlag, int signalValue); public event AnotherInstanceStartedEventHandler AnotherInstanceStarted; public static readonly int WM_SIGNALFIRSTINSTANCE = RegisterWindowMessage("WM_SIGNALFIRSTINSTANCE"); @@ -81,16 +81,16 @@ private void RunInternal(ApplicationContext applicationContext, Form mainForm) } } - public void SignalFirstInstance(int signalFlag) + public void SignalFirstInstance(int signalFlag, int signalValue) { - PostMessage(HWND_BROADCAST, WM_SIGNALFIRSTINSTANCE, (IntPtr) signalFlag, IntPtr.Zero); + PostMessage(HWND_BROADCAST, WM_SIGNALFIRSTINSTANCE, (IntPtr) signalFlag, (IntPtr) signalValue); } - protected void OnAnotherInstanceStarted(int signalFlag) + protected void OnAnotherInstanceStarted(int signalFlag, int signalValue) { if (AnotherInstanceStarted != null) { - this.AnotherInstanceStarted(signalFlag); + this.AnotherInstanceStarted(signalFlag, signalValue); } } @@ -103,7 +103,7 @@ public bool PreFilterMessage(ref Message m) { filter = false; //Console.WriteLine(m.ToString()); - this.OnAnotherInstanceStarted((int) m.WParam); + this.OnAnotherInstanceStarted((int) m.WParam, (int) m.LParam); this.filterTimer.Start(); } return false; diff --git a/Growl/Growl/_source/Subscription.cs b/Growl/Growl/_source/Subscription.cs index 5a11268..564ec86 100644 --- a/Growl/Growl/_source/Subscription.cs +++ b/Growl/Growl/_source/Subscription.cs @@ -112,7 +112,7 @@ private void Subscribe() EnsureTimer(); StopRetryTimer(); - if (this.subscriberID == null) this.subscriberID = Growl.Daemon.Subscriber.GenerateID(); + if (this.subscriberID == null) this.subscriberID = Utility.MachineID; this.AdditionalOfflineDisplayInfo = "connecting..."; if (this.sc != null) this.sc = null; Growl.Daemon.Subscriber subscriber = new Growl.Daemon.Subscriber(this.subscriberID, Environment.MachineName, Growl.Connector.GrowlConnector.TCP_PORT); diff --git a/Growl/Growl/_source/SystemBalloonIntercepter.cs b/Growl/Growl/_source/SystemBalloonIntercepter.cs index 2093b3a..82e7bee 100644 --- a/Growl/Growl/_source/SystemBalloonIntercepter.cs +++ b/Growl/Growl/_source/SystemBalloonIntercepter.cs @@ -79,6 +79,8 @@ public override void ProcessWindowMessage(ref Message m) if(!String.IsNullOrEmpty(ti.nid.szInfo)) OnSystemBalloonIntercepted(ti.nid.szInfoTitle, ti.nid.szInfo, null); + + m.Result = new IntPtr(1); } } else if (m.Msg == MSG_REPLACED) diff --git a/Growl/Growl/_source/Utility.cs b/Growl/Growl/_source/Utility.cs index c490b69..90d4058 100644 --- a/Growl/Growl/_source/Utility.cs +++ b/Growl/Growl/_source/Utility.cs @@ -8,6 +8,9 @@ namespace Growl { + /// + /// Provides access to commonly used properties and methods + /// public static class Utility { private static string userSettingsFolder; @@ -52,6 +55,10 @@ static Utility() Growl.CoreLibrary.PathUtility.EnsureDirectoryExists(userSettingsFolder); } + /// + /// Gets the full path to folder where all user settings are saved. + /// + /// Full folder path public static string UserSettingFolder { get @@ -60,6 +67,10 @@ public static string UserSettingFolder } } + /// + /// Gets the full path to folder where all user settings were saved in earlier beta versions. + /// + /// Full folder path public static string UserSettingFolderBeta { get @@ -68,6 +79,10 @@ public static string UserSettingFolderBeta } } + /// + /// Gets the file version info. + /// + /// The file version info. public static System.Diagnostics.FileVersionInfo FileVersionInfo { [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)] @@ -77,6 +92,11 @@ public static System.Diagnostics.FileVersionInfo FileVersionInfo } } + /// + /// Gets the full path to the folder where a displays user settings are saved. + /// + /// The display name. + /// Full folder path public static string GetDisplayUserSettingsFolder(string displayName) { string folder = Growl.CoreLibrary.PathUtility.Combine(UserSettingFolder, String.Format(@"Displays\{0}\", displayName)); @@ -84,12 +104,40 @@ public static string GetDisplayUserSettingsFolder(string displayName) return folder; } + /// + /// Handles properly formatting strings, especially those from resource strings. + /// + /// The resource string. + /// Properly formatted string + /// The main use for this method is to convert literal \n characters to newlines (since newlines are a pain to deal with in the resource xml files) public static string GetResourceString(string resourceString) { resourceString = resourceString.Replace("\\n", "\n"); return resourceString; } + /// + /// Gets an ID that can be used to uniquely identify this machine. + /// + /// The machine ID. + public static string MachineID + { + get + { + string machineID = Properties.Settings.Default.MachineID; + if (String.IsNullOrEmpty(machineID)) + { + machineID = System.Guid.NewGuid().ToString(); + Properties.Settings.Default.MachineID = machineID; + } + return machineID; + } + } + + /// + /// Gets or sets a value indicating whether the app is running in debug mode + /// + /// true if in debug mode; otherwise, false. public static bool DebugMode { get @@ -102,6 +150,10 @@ public static bool DebugMode } } + /// + /// Writes debug info to a log file + /// + /// The information to log public static void WriteDebugInfo(string info) { bool ok = DebugMode; diff --git a/Growl/Growl/app.config b/Growl/Growl/app.config index 4dfb3ab..1291d9b 100644 --- a/Growl/Growl/app.config +++ b/Growl/Growl/app.config @@ -91,6 +91,9 @@ False + + + diff --git a/Growl/Growl/release_notes.txt b/Growl/Growl/release_notes.txt index 1a82804..0564a9b 100644 --- a/Growl/Growl/release_notes.txt +++ b/Growl/Growl/release_notes.txt @@ -1,3 +1,32 @@ +RC2 changes +------------------------------ +- added 'Origin' column to History Detail view +- removed built-in displays from showing up in the Alt-Tab list +- fixed a bug that didnt allow loading dependent libraries from external displays +- fixed a bug that didnt handle some types of .ico files as valid images +- fixed the 'object is currently in use somewhere else' exception (again) +- fixed a bug that did not honor the 'Never consider me idle' setting if the computer had been locked previously +- fixed a bug that caused a crash when lots of subscribers came online +- fixed a bug that failed to forward notifications that originated over UDP +- fixed a bug that caused keyboard shortcuts to not work +- updated click-to-install protocol handler to workaround bug in Google Chrome browser (http://code.google.com/p/chromium/issues/detail?id=160) +- return more descriptive error message for 'MALFORMED REQUEST' errors +- moved call to IDisplay.Load to after SettingsPanel has been configured + +RC1/Beta 21 changes +------------------------------ +- replaced entire Bonjour implementation - hopefully solves the dnssd.dll crashes +- replaced global keyboard hook code with RegisterHotKey (no functional change, just better - thanks Jaykul) +- now automatically create the default proxy.config file on install +- fixed the 'object is currently in use somewhere else' exception +- fixed a bug that caused 'click-to-install' definition files to be considered invalid if not ASCII encoded +- fixed a bug that sometimes causes 'click-to-install' downloads to hang +- fixed messed up rendering of text in dialogs during 'click-to-install' process +- fixed a bug that caused a crash if a saved History item was corrupted +- fixed a bug that caused password changes to be lost if GfW was not shut down properly +- updated growlnotify to send filesystem-based images as binary data (url-based images are still sent as urls) +- fixed a bug in growlnotify if an empty /cu: parameter was passed + Beta 20 changes ------------------------------ - improved History tab: added detail view and filtering capability diff --git a/Growl/Growl/update.manifest b/Growl/Growl/update.manifest index 0b8ade7..8a8d54f 100644 --- a/Growl/Growl/update.manifest +++ b/Growl/Growl/update.manifest @@ -1,7 +1,7 @@ - 2.0.0.21 + 2.0.0.22 True http://www.growlforwindows.com/gfw/updates/gfw3.manifest - http://www.growlforwindows.com/gfw/d.ashx?f=Growl_v2.0rc1.msi + http://www.growlforwindows.com/gfw/d.ashx?f=Growl_v2.0rc2.msi \ No newline at end of file diff --git a/Growl/Test App/Form1.cs b/Growl/Test App/Form1.cs index ca14c69..34b7b80 100644 --- a/Growl/Test App/Form1.cs +++ b/Growl/Test App/Form1.cs @@ -34,10 +34,11 @@ public Form1() this.app = new Growl.Connector.Application("SurfWriter"); //app.Icon = "http://atomicbride.com/Apple.gif"; //app.Icon = "http://www.thetroyers.com/images/Apple_Logo.jpg"; - app.Icon = @"c:\apple.png"; + //app.Icon = @"c:\apple.png"; + app.Icon = Properties.Resources.Apple; app.CustomTextAttributes.Add("Creator", "Apple Software"); app.CustomTextAttributes.Add("Application-ID", "08d6c05a21512a79a1dfeb9d2a8f262f"); - app.CustomBinaryAttributes.Add("Sound", "http://fake.net/app.wav"); + //app.CustomBinaryAttributes.Add("Sound", "http://fake.net/app.wav"); Growl.CoreLibrary.Detector detector = new Detector(); @@ -78,16 +79,49 @@ void growl_NotificationCallback(Response response, CallbackData callbackContext) private void button1_Click(object sender, EventArgs e) { + /* + System.IO.FileStream fs1 = System.IO.File.Open(@"C:\Documents and Settings\brian\Desktop\f1.ico", System.IO.FileMode.Open); + System.Drawing.Image i1 = System.Drawing.Bitmap.FromStream(fs1); + + System.IO.FileStream fs2 = System.IO.File.Open(@"C:\Documents and Settings\brian\Desktop\f2.ico", System.IO.FileMode.Open); + System.Drawing.Image i2 = System.Drawing.Bitmap.FromStream(fs2); + + System.IO.FileStream fs3 = System.IO.File.Open(@"C:\Documents and Settings\brian\Desktop\f3.ico", System.IO.FileMode.Open); + //System.Drawing.Image i3 = System.Drawing.Bitmap.FromStream(fs3); + Icon icon = new Icon(fs3); + Image i3 = icon.ToBitmap(); + + System.Drawing.Image i4 = System.Drawing.Bitmap.FromFile(@"C:\Documents and Settings\brian\Desktop\f3.ico"); + + System.Net.WebClient wc = new System.Net.WebClient(); + using (wc) + { + byte[] bytes = wc.DownloadData("http://haxe.org/favicon.ico"); + System.IO.MemoryStream ms = new System.IO.MemoryStream(bytes, false); + using (ms) + { + ms.Position = 0; + System.Drawing.Image tempImage = System.Drawing.Bitmap.FromStream(ms, false, false); + // dont close stream yet, first create a copy + using (tempImage) + { + Image image = new Bitmap(tempImage); + Console.WriteLine(image); + } + } + } + */ + NotificationType nt1 = new NotificationType("Download Complete"); //nt1.Icon = new BinaryData(new byte[] { 65, 66, 67, 68 }); nt1.Icon = "http://www.hamradio.pl/images/thumb/e/e5/Icon_48x48_star_01.png/48px-Icon_48x48_star_01.png"; nt1.Enabled = false; nt1.CustomTextAttributes.Add("Language", "English"); nt1.CustomTextAttributes.Add("Timezone", "PST"); - nt1.CustomBinaryAttributes.Add("Sound", "http://fake.net/nt.wav"); + //nt1.CustomBinaryAttributes.Add("Sound", "http://fake.net/nt.wav"); NotificationType nt2 = new NotificationType("Document Published", "Document successfully published", null, true); nt2.Icon = "http://coaching.typepad.com/EspressoPundit/feed-icon-legacy_blue_38.png"; - nt2.CustomBinaryAttributes.Add("Sound", "http://fake.net/sound.wav"); + //nt2.CustomBinaryAttributes.Add("Sound", "http://fake.net/sound.wav"); nt2.CustomBinaryAttributes.Add("Sound-Alt", new BinaryData(new byte[] { 70, 71, 72, 73 })); NotificationType[] types = new NotificationType[] { nt1, nt2 }; @@ -119,7 +153,7 @@ private void button2_Click(object sender, EventArgs e) notification.Sticky = false; notification.Priority = Priority.Emergency; //notification.Icon = "http://atomicbride.com/Apple.gif"; - //app.Icon = @"c:\apple.png"; + notification.Icon = "http://haxe.org/favicon.ico"; notification.CustomTextAttributes.Add("Filename", @"c:\file.txt"); notification.CustomTextAttributes.Add("Timestamp", "8:57pm"); notification.CustomBinaryAttributes.Add("File", new BinaryData(new byte[] { 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78 })); diff --git a/Growl/Test App/Properties/Resources.Designer.cs b/Growl/Test App/Properties/Resources.Designer.cs index 14346ba..a5119ae 100644 --- a/Growl/Test App/Properties/Resources.Designer.cs +++ b/Growl/Test App/Properties/Resources.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:2.0.50727.1433 +// Runtime Version:2.0.50727.3082 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -59,5 +59,12 @@ internal Resources() { resourceCulture = value; } } + + internal static System.Drawing.Bitmap Apple { + get { + object obj = ResourceManager.GetObject("Apple", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } } } diff --git a/Growl/Test App/Properties/Resources.resx b/Growl/Test App/Properties/Resources.resx index ffecec8..b06894f 100644 --- a/Growl/Test App/Properties/Resources.resx +++ b/Growl/Test App/Properties/Resources.resx @@ -46,7 +46,7 @@ mimetype: application/x-microsoft.net.object.binary.base64 value : The object must be serialized with - : System.Serialization.Formatters.Binary.BinaryFormatter + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter : and then encoded with base64 encoding. mimetype: application/x-microsoft.net.object.soap.base64 @@ -60,6 +60,7 @@ : and then encoded with base64 encoding. --> + @@ -68,9 +69,10 @@ - + + @@ -85,9 +87,10 @@ - + + @@ -114,4 +117,8 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\Apple.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/Growl/Test App/Resources/Apple.png b/Growl/Test App/Resources/Apple.png new file mode 100644 index 0000000..ddb08f9 Binary files /dev/null and b/Growl/Test App/Resources/Apple.png differ diff --git a/Growl/Test App/Test App.csproj b/Growl/Test App/Test App.csproj index 292f693..67d644d 100644 --- a/Growl/Test App/Test App.csproj +++ b/Growl/Test App/Test App.csproj @@ -79,6 +79,9 @@ Growl.CoreLibrary + + +