diff --git a/Greenshot/releases/additional_files/readme.txt b/Greenshot/releases/additional_files/readme.txt index ea98222ed..18522fa4f 100644 --- a/Greenshot/releases/additional_files/readme.txt +++ b/Greenshot/releases/additional_files/readme.txt @@ -3,6 +3,12 @@ Greenshot: A screenshot tool optimized for productivity. Save a screenshot or a CHANGE LOG: +1.0.1 build 1984 (intermediate state) + +Bugs resolved: +* Rewrote the "please wait" window to allow the user to cancel the operation, this was needed due to problems with Imgur uploads +* Fixed a memory leak when using ESC on the destination picker + 1.0.1 build 1980 Release Candidate 1 We changed the version to 1.0 after 5 year the version should no longer have a "beta" feeling! diff --git a/GreenshotImgurPlugin/ImgurPlugin.cs b/GreenshotImgurPlugin/ImgurPlugin.cs index d947e02c3..a541936dc 100644 --- a/GreenshotImgurPlugin/ImgurPlugin.cs +++ b/GreenshotImgurPlugin/ImgurPlugin.cs @@ -129,19 +129,32 @@ namespace GreenshotImgurPlugin { Shutdown(); } + /// + /// Upload the capture to imgur + /// + /// + /// + /// out string for the url + /// true if the upload succeeded public bool Upload(ICaptureDetails captureDetails, Image image, out string uploadURL) { OutputSettings outputSettings = new OutputSettings(config.UploadFormat, config.UploadJpegQuality, config.UploadReduceColors); using (MemoryStream stream = new MemoryStream()) { - BackgroundForm backgroundForm = BackgroundForm.ShowAndWait(Attributes.Name, Language.GetString("imgur", LangKey.communication_wait)); - host.SaveToStream(image, stream, outputSettings); try { string filename = Path.GetFileName(host.GetFilename(config.UploadFormat, captureDetails)); - ImgurInfo imgurInfo = ImgurUtils.UploadToImgur(stream.GetBuffer(), (int)stream.Length, captureDetails.Title, filename); - LOG.InfoFormat("Storing imgur upload for hash {0} and delete hash {1}", imgurInfo.Hash, imgurInfo.DeleteHash); - config.ImgurUploadHistory.Add(imgurInfo.Hash, imgurInfo.DeleteHash); - config.runtimeImgurHistory.Add(imgurInfo.Hash, imgurInfo); - CheckHistory(); + ImgurInfo imgurInfo = null; + + // Run upload in the background + new PleaseWaitForm().ShowAndWait(Attributes.Name, Language.GetString("imgur", LangKey.communication_wait), Language.GetString("CANCEL"), + delegate() { + imgurInfo = ImgurUtils.UploadToImgur(stream.GetBuffer(), (int)stream.Length, captureDetails.Title, filename); + LOG.InfoFormat("Storing imgur upload for hash {0} and delete hash {1}", imgurInfo.Hash, imgurInfo.DeleteHash); + config.ImgurUploadHistory.Add(imgurInfo.Hash, imgurInfo.DeleteHash); + config.runtimeImgurHistory.Add(imgurInfo.Hash, imgurInfo); + CheckHistory(); + } + ); + imgurInfo.Image = ImageHelper.CreateThumbnail(image, 90, 90); IniConfig.Save(); uploadURL = imgurInfo.Page; @@ -156,9 +169,8 @@ namespace GreenshotImgurPlugin { } return true; } catch (Exception e) { + LOG.Error(e); MessageBox.Show(Language.GetString("imgur", LangKey.upload_failure) + " " + e.Message); - } finally { - backgroundForm.CloseDialog(); } } uploadURL = null; diff --git a/GreenshotImgurPlugin/ImgurUtils.cs b/GreenshotImgurPlugin/ImgurUtils.cs index 1c3c96b12..91997fb3c 100644 --- a/GreenshotImgurPlugin/ImgurUtils.cs +++ b/GreenshotImgurPlugin/ImgurUtils.cs @@ -69,6 +69,20 @@ namespace GreenshotImgurPlugin { config.ImgurUploadHistory.Remove(hash); saveNeeded = true; } + } catch (WebException wE) { + bool redirected = false; + if (wE.Status == WebExceptionStatus.ProtocolError) { + HttpWebResponse response = ((HttpWebResponse)wE.Response); + // Image no longer available + if (response.StatusCode == HttpStatusCode.Redirect) { + LOG.InfoFormat("ImgUr image for hash {0} is no longer available", hash); + config.ImgurUploadHistory.Remove(hash); + redirected = true; + } + } + if (!redirected) { + LOG.Error("Problem loading ImgUr history for hash " + hash, wE); + } } catch (Exception e) { LOG.Error("Problem loading ImgUr history for hash " + hash, e); } @@ -152,16 +166,17 @@ namespace GreenshotImgurPlugin { } LOG.Info(responseString); ImgurInfo imgurInfo = ImgurInfo.ParseResponse(responseString); + LOG.Debug("Upload to imgur was finished"); return imgurInfo; } public static void RetrieveImgurThumbnail(ImgurInfo imgurInfo) { - if (imgurInfo.SmallSquare == null) { - LOG.Warn("Imgur URL was null, not retrieving thumbnail."); - return; - } - LOG.InfoFormat("Retrieving Imgur image for {0} with url {1}", imgurInfo.Hash, imgurInfo); - HttpWebRequest webRequest = (HttpWebRequest)NetworkHelper.CreateWebRequest(imgurInfo.SmallSquare); + if (imgurInfo.SmallSquare == null) { + LOG.Warn("Imgur URL was null, not retrieving thumbnail."); + return; + } + LOG.InfoFormat("Retrieving Imgur image for {0} with url {1}", imgurInfo.Hash, imgurInfo.SmallSquare); + HttpWebRequest webRequest = (HttpWebRequest)NetworkHelper.CreateWebRequest(imgurInfo.SmallSquare); webRequest.Method = "GET"; webRequest.ServicePoint.Expect100Continue = false; diff --git a/GreenshotPlugin/Controls/PleaseWaitForm.Designer.cs b/GreenshotPlugin/Controls/PleaseWaitForm.Designer.cs new file mode 100644 index 000000000..2f913a926 --- /dev/null +++ b/GreenshotPlugin/Controls/PleaseWaitForm.Designer.cs @@ -0,0 +1,102 @@ +/* + * Greenshot - a free and open source screenshot tool + * Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom + * + * For more information see: http://getgreenshot.org/ + * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +namespace GreenshotPlugin.Controls { + partial class PleaseWaitForm { + /// + /// Designer variable used to keep track of non-visual components. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Disposes resources used by the form. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) { + if (disposing) { + if (components != null) { + components.Dispose(); + } + } + base.Dispose(disposing); + } + + /// + /// This method is required for Windows Forms designer support. + /// Do not change the method contents inside the source code editor. The Forms designer might + /// not be able to load this method if it was changed manually. + /// + private void InitializeComponent() { + this.label_pleasewait = new System.Windows.Forms.Label(); + this.cancelButton = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // label_pleasewait + // + this.label_pleasewait.AutoSize = true; + this.label_pleasewait.Dock = System.Windows.Forms.DockStyle.Fill; + this.label_pleasewait.Location = new System.Drawing.Point(0, 0); + this.label_pleasewait.Name = "label_pleasewait"; + this.label_pleasewait.Padding = new System.Windows.Forms.Padding(10); + this.label_pleasewait.Size = new System.Drawing.Size(90, 33); + this.label_pleasewait.TabIndex = 0; + this.label_pleasewait.Text = "Please wait..."; + this.label_pleasewait.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + this.label_pleasewait.UseWaitCursor = true; + // + // cancelButton + // + this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.cancelButton.Location = new System.Drawing.Point(38, 41); + this.cancelButton.Name = "cancelButton"; + this.cancelButton.Size = new System.Drawing.Size(94, 23); + this.cancelButton.TabIndex = 1; + this.cancelButton.Text = "Cancel"; + this.cancelButton.UseVisualStyleBackColor = true; + this.cancelButton.UseWaitCursor = true; + this.cancelButton.Click += new System.EventHandler(this.CancelButtonClick); + // + // PleaseWaitForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.AutoSize = true; + this.CancelButton = this.cancelButton; + this.ClientSize = new System.Drawing.Size(169, 76); + this.Controls.Add(this.cancelButton); + this.Controls.Add(this.label_pleasewait); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "PleaseWaitForm"; + this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "Greenshot"; + this.TopMost = true; + this.UseWaitCursor = true; + this.ResumeLayout(false); + this.PerformLayout(); + } + private System.Windows.Forms.Button cancelButton; + private System.Windows.Forms.Label label_pleasewait; + } +} diff --git a/GreenshotPlugin/Controls/PleaseWaitForm.cs b/GreenshotPlugin/Controls/PleaseWaitForm.cs new file mode 100644 index 000000000..049b52238 --- /dev/null +++ b/GreenshotPlugin/Controls/PleaseWaitForm.cs @@ -0,0 +1,102 @@ +/* + * Greenshot - a free and open source screenshot tool + * Copyright (C) 2007-2012 Thomas Braun, Jens Klingen, Robin Krom + * + * For more information see: http://getgreenshot.org/ + * The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/greenshot/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +using System; +using System.Drawing; +using System.Windows.Forms; +using System.Threading; + +namespace GreenshotPlugin.Controls { + /// + /// Description of PleaseWaitForm. + /// + public partial class PleaseWaitForm : Form { + private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(PleaseWaitForm)); + private Thread waitFor = null; + private string title; + public PleaseWaitForm() { + // + // The InitializeComponent() call is required for Windows Forms designer support. + // + InitializeComponent(); + this.Icon = GreenshotPlugin.Core.GreenshotResources.getGreenshotIcon(); + } + + /// + /// Prevent the close button showing + /// + private const int CP_NOCLOSE_BUTTON = 0x200; + protected override CreateParams CreateParams { + get { + CreateParams createParams = base.CreateParams; + createParams.ClassStyle = createParams.ClassStyle | CP_NOCLOSE_BUTTON ; + return createParams; + } + } + + public void ShowAndWait(string title, string text, string cancelText, ThreadStart waitDelegate) { + this.title = title; + this.Text = title; + this.label_pleasewait.Text = text; + this.cancelButton.Text = cancelText; + + Show(); + + Exception threadException = null; + try { + // Wrap the passed delegate in a try/catch which saves the exception + waitFor = new Thread(new ThreadStart( + delegate { + try { + waitDelegate.Invoke(); + } catch (Exception ex) { + threadException = ex; + } + }) + ); + waitFor.Name = title; + waitFor.IsBackground = true; + waitFor.SetApartmentState(ApartmentState.STA); + waitFor.Start(); + + // Wait until finished + while (!waitFor.Join(TimeSpan.FromMilliseconds(100))) { + Application.DoEvents(); + } + LOG.DebugFormat("Finished {0}", title); + } catch (Exception ex) { + LOG.Error(ex); + throw ex; + } finally { + Close(); + } + // Check if an exception occured, if so throw it + if (threadException != null) { + throw threadException; + } + } + + void CancelButtonClick(object sender, EventArgs e) { + LOG.DebugFormat("Cancel clicked on {0}", title); + cancelButton.Enabled = false; + waitFor.Abort(); + } + } +} diff --git a/GreenshotPlugin/GreenshotPlugin.csproj b/GreenshotPlugin/GreenshotPlugin.csproj index 6df9722a5..927b0c15b 100644 --- a/GreenshotPlugin/GreenshotPlugin.csproj +++ b/GreenshotPlugin/GreenshotPlugin.csproj @@ -226,6 +226,10 @@ Component + + + PleaseWaitForm.cs + Form