From 4f64dfe67654448264baa89fdd0383e99e1239b0 Mon Sep 17 00:00:00 2001 From: RKrom Date: Wed, 13 Jun 2012 22:17:53 +0000 Subject: [PATCH] Improving the responsiveness of the editor and optimizing some general code. git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@1922 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4 --- Greenshot/Forms/ImageEditorForm.Designer.cs | 1 - Greenshot/Forms/ImageEditorForm.cs | 111 +++++++------ Greenshot/Forms/SettingsForm.cs | 3 - GreenshotPlugin/Controls/GreenshotForm.cs | 167 +++++++++++--------- GreenshotPlugin/IniFile/IniConfig.cs | 23 +-- GreenshotPlugin/IniFile/IniSection.cs | 43 +++-- GreenshotPlugin/IniFile/IniValue.cs | 2 - 7 files changed, 192 insertions(+), 158 deletions(-) diff --git a/Greenshot/Forms/ImageEditorForm.Designer.cs b/Greenshot/Forms/ImageEditorForm.Designer.cs index f8f01894f..972f9e596 100644 --- a/Greenshot/Forms/ImageEditorForm.Designer.cs +++ b/Greenshot/Forms/ImageEditorForm.Designer.cs @@ -1608,7 +1608,6 @@ namespace Greenshot { this.propertiesToolStrip.PerformLayout(); this.fileSavedStatusContextMenu.ResumeLayout(false); this.ResumeLayout(false); - } private GreenshotPlugin.Controls.GreenshotToolStripMenuItem invertToolStripMenuItem; private GreenshotPlugin.Controls.GreenshotToolStripMenuItem grayscaleToolStripMenuItem; diff --git a/Greenshot/Forms/ImageEditorForm.cs b/Greenshot/Forms/ImageEditorForm.cs index 54fbdf142..176519305 100644 --- a/Greenshot/Forms/ImageEditorForm.cs +++ b/Greenshot/Forms/ImageEditorForm.cs @@ -88,11 +88,39 @@ namespace Greenshot { this.surface = iSurface as Surface; editorList.Add(this); - this.SuspendLayout(); + // Intial "saved" flag for asking if the image needs to be save + surface.Modified = !outputMade; + // // The InitializeComponent() call is required for Windows Forms designer support. // InitializeComponent(); + updateUI(); + + this.Load += delegate { + new Thread(delegate() {AddDestinations();}).Start(); + }; + + IniConfig.IniChanged += new FileSystemEventHandler(ReloadConfiguration); + + // Make sure the editor is placed on the same location as the last editor was on close + WindowDetails thisForm = new WindowDetails(this.Handle); + thisForm.SetWindowPlacement(editorConfiguration.GetEditorPlacement()); + + SurfaceSizeChanged(this.Surface); + + bindFieldControls(); + refreshEditorControls(); + // Workaround: As the cursor is (mostly) selected on the surface a funny artifact is visible, this fixes it. + hideToolstripItems(); + } + + + private void updateUI() { + if (surface != null && surface.CaptureDetails != null && surface.CaptureDetails.Title != null) { + this.Text = surface.CaptureDetails.Title + " - " + Language.GetString(LangKey.editor_title); + } + this.Icon = GreenshotPlugin.Core.GreenshotResources.getGreenshotIcon(); // Disable access to the settings, for feature #3521446 @@ -107,9 +135,6 @@ namespace Greenshot { // Make sure Double-buffer is enabled SetStyle(ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true); - // Intial "saved" flag for asking if the image needs to be save - surface.Modified = !outputMade; - // resizing the panel is futile, since it is docked. however, it seems // to fix the bug (?) with the vscrollbar not being able to shrink to // a smaller size than the initial panel size (as set by the forms designer) @@ -130,20 +155,6 @@ namespace Greenshot { panel1.Controls.Add(surface); - // Make sure the editor is placed on the same location as the last editor was on close - WindowDetails thisForm = new WindowDetails(this.Handle); - thisForm.SetWindowPlacement(editorConfiguration.GetEditorPlacement()); - - SurfaceSizeChanged(this.Surface); - - updateUI(); - IniConfig.IniChanged += new FileSystemEventHandler(ReloadConfiguration); - - bindFieldControls(); - refreshEditorControls(); - // Workaround: As the cursor is (mostly) selected on the surface a funny artifact is visible, this fixes it. - hideToolstripItems(); - toolbarButtons = new GreenshotPlugin.Controls.GreenshotToolStripButton[] { btnCursor, btnRect, btnEllipse, btnText, btnLine, btnArrow, btnFreehand, btnHighlight, btnObfuscate, btnCrop }; //toolbarDropDownButtons = new ToolStripDropDownButton[]{btnBlur, btnPixeliate, btnTextHighlighter, btnAreaHighlighter, btnMagnifier}; @@ -151,32 +162,39 @@ namespace Greenshot { // Workaround: for the MouseWheel event which doesn't get to the panel this.MouseWheel += new MouseEventHandler( PanelMouseWheel); - - // Create export buttons - foreach(IDestination destination in DestinationHelper.GetAllDestinations()) { - if (destination.Priority <= 2) { - continue; - } - if (!destination.isActive) { - continue; - } - if (destination.DisplayIcon == null) { - continue; - } - try { - AddDestinationButton(destination); - } catch (Exception addingException) { - LOG.WarnFormat("Problem adding destination {0}", destination.Designation); - LOG.Warn("Exception: ", addingException); - } - } - - // Create the file menu, normally this is done when opening but if we don't do it now the short-cut keys are missing. - // See Bugs #3526974 & #3527020 - FileMenuDropDownOpening(null, null); - this.ResumeLayout(); + + ApplyLanguage(); } + /// + /// Get all the destinations and display them in the file menu and the buttons + /// + void AddDestinations() { + this.Invoke((MethodInvoker)delegate { + // Create export buttons + foreach(IDestination destination in DestinationHelper.GetAllDestinations()) { + if (destination.Priority <= 2) { + continue; + } + if (!destination.isActive) { + continue; + } + if (destination.DisplayIcon == null) { + continue; + } + try { + AddDestinationButton(destination); + } catch (Exception addingException) { + LOG.WarnFormat("Problem adding destination {0}", destination.Designation); + LOG.Warn("Exception: ", addingException); + } + } + // Create the file menu, normally this is done when opening but if we don't do it now the short-cut keys are missing. + // See Bugs #3526974 & #3527020 + FileMenuDropDownOpening(null, null); + }); + } + void AddDestinationButton(IDestination toolstripDestination) { if (toolstripDestination.isDynamic) { ToolStripSplitButton destinationButton = new ToolStripSplitButton(); @@ -292,16 +310,9 @@ namespace Greenshot { private void ReloadConfiguration(object source, FileSystemEventArgs e) { this.Invoke((MethodInvoker) delegate { // Even update language when needed - updateUI(); + ApplyLanguage(); }); } - - private void updateUI() { - ApplyLanguage(); - if (surface != null && surface.CaptureDetails != null && surface.CaptureDetails.Title != null) { - this.Text = surface.CaptureDetails.Title + " - " + Language.GetString(LangKey.editor_title); - } - } public ISurface Surface { get {return surface;} diff --git a/Greenshot/Forms/SettingsForm.cs b/Greenshot/Forms/SettingsForm.cs index 003e310f1..689ce5be7 100644 --- a/Greenshot/Forms/SettingsForm.cs +++ b/Greenshot/Forms/SettingsForm.cs @@ -342,7 +342,6 @@ namespace Greenshot { } coreConfiguration.ClipboardFormats = clipboardFormats; - coreConfiguration.WindowCaptureMode = GetSelected(combobox_window_capture_mode); if (!FilenameHelper.FillVariables(coreConfiguration.OutputFilePath, false).Equals(textbox_storagelocation.Text)) { coreConfiguration.OutputFilePath = textbox_storagelocation.Text; @@ -366,8 +365,6 @@ namespace Greenshot { coreConfiguration.DWMBackgroundColor = colorButton_window_background.SelectedColor; coreConfiguration.UpdateCheckInterval = (int)numericUpDown_daysbetweencheck.Value; - IniConfig.Save(); - // Make sure the current language & settings are reflected in the Main-context menu MainForm.instance.UpdateUI(); diff --git a/GreenshotPlugin/Controls/GreenshotForm.cs b/GreenshotPlugin/Controls/GreenshotForm.cs index 16d9834d5..3a8e8a2dc 100644 --- a/GreenshotPlugin/Controls/GreenshotForm.cs +++ b/GreenshotPlugin/Controls/GreenshotForm.cs @@ -241,8 +241,8 @@ namespace GreenshotPlugin.Controls { IGreenshotLanguageBindable languageBindable = applyTo as IGreenshotLanguageBindable; if (languageBindable == null) { // check if it's a menu! - if (applyTo is ToolStrip) { - ToolStrip toolStrip = applyTo as ToolStrip; + ToolStrip toolStrip = applyTo as ToolStrip; + if (toolStrip != null) { foreach (ToolStripItem item in toolStrip.Items) { ApplyLanguage(item); } @@ -250,26 +250,38 @@ namespace GreenshotPlugin.Controls { return; } - string languageKey = languageBindable.LanguageKey; // Apply language text to the control - ApplyLanguage(applyTo, languageKey); + ApplyLanguage(applyTo, languageBindable.LanguageKey); + // Repopulate the combox boxes - if (typeof(IGreenshotConfigBindable).IsAssignableFrom(applyTo.GetType())) { - if (typeof(GreenshotComboBox).IsAssignableFrom(applyTo.GetType())) { - IGreenshotConfigBindable configBindable = applyTo as IGreenshotConfigBindable; - if (!string.IsNullOrEmpty(configBindable.SectionName) && !string.IsNullOrEmpty(configBindable.PropertyName)) { - IniSection section = IniConfig.GetIniSection(configBindable.SectionName); - if (section != null) { - GreenshotComboBox comboxBox = applyTo as GreenshotComboBox; - // Only update the language, so get the actual value and than repopulate - Enum currentValue = (Enum)comboxBox.GetSelectedEnum(); - comboxBox.Populate(section.Values[configBindable.PropertyName].ValueType); - comboxBox.SetValue(currentValue); - } + IGreenshotConfigBindable configBindable = applyTo as IGreenshotConfigBindable; + GreenshotComboBox comboxBox = applyTo as GreenshotComboBox; + if (configBindable != null && comboxBox != null) { + if (!string.IsNullOrEmpty(configBindable.SectionName) && !string.IsNullOrEmpty(configBindable.PropertyName)) { + IniSection section = IniConfig.GetIniSection(configBindable.SectionName); + if (section != null) { + // Only update the language, so get the actual value and than repopulate + Enum currentValue = (Enum)comboxBox.GetSelectedEnum(); + comboxBox.Populate(section.Values[configBindable.PropertyName].ValueType); + comboxBox.SetValue(currentValue); } } } } + + /// + /// Helper method to cache the fieldinfo values, so we don't need to reflect all the time! + /// + /// + /// + private static FieldInfo[] GetCachedFields(Type typeToGetFieldsFor) { + FieldInfo[] fields = null; + if (!reflectionCache.TryGetValue(typeToGetFieldsFor, out fields)) { + fields = typeToGetFieldsFor.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); + reflectionCache.Add(typeToGetFieldsFor, fields); + } + return fields; + } /// /// Apply all the language settings to the "Greenshot" Controls on this form @@ -341,51 +353,55 @@ namespace GreenshotPlugin.Controls { } } } - - private static FieldInfo[] GetCachedFields(Type typeToGetFieldsFor) { - FieldInfo[] fields = null; - if (!reflectionCache.TryGetValue(typeToGetFieldsFor, out fields)) { - fields = typeToGetFieldsFor.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); - reflectionCache.Add(typeToGetFieldsFor, fields); - } - return fields; - } /// /// Fill all GreenshotControls with the values from the configuration /// protected void FillFields() { foreach (FieldInfo field in GetCachedFields(this.GetType())) { - if (!field.FieldType.IsSubclassOf(typeof(Control))) { + Object controlObject = field.GetValue(this); + if (controlObject == null) { continue; } - Object controlObject = field.GetValue(this); - if (typeof(IGreenshotConfigBindable).IsAssignableFrom(field.FieldType)) { - IGreenshotConfigBindable configBindable = controlObject as IGreenshotConfigBindable; - if (!string.IsNullOrEmpty(configBindable.SectionName) && !string.IsNullOrEmpty(configBindable.PropertyName)) { - IniSection section = IniConfig.GetIniSection(configBindable.SectionName); - if (section != null) { - if (!section.Values.ContainsKey(configBindable.PropertyName)) { - LOG.WarnFormat("Wrong property '{0}' configured for field '{1}'",configBindable.PropertyName,field.Name); - continue; - } - if (typeof(CheckBox).IsAssignableFrom(field.FieldType)) { - CheckBox checkBox = controlObject as CheckBox; - checkBox.Checked = (bool)section.Values[configBindable.PropertyName].Value; - } else if (typeof(HotkeyControl).IsAssignableFrom(field.FieldType)) { - HotkeyControl hotkeyControl = controlObject as HotkeyControl; - string hotkeyValue = (string)section.Values[configBindable.PropertyName].Value; - if (!string.IsNullOrEmpty(hotkeyValue)) { - hotkeyControl.SetHotkey(hotkeyValue); - } - } else if (typeof(TextBox).IsAssignableFrom(field.FieldType)) { - TextBox textBox = controlObject as TextBox; - textBox.Text = section.Values[configBindable.PropertyName].ToString(); - } else if (typeof(GreenshotComboBox).IsAssignableFrom(field.FieldType)) { - GreenshotComboBox comboxBox = controlObject as GreenshotComboBox; - comboxBox.Populate(section.Values[configBindable.PropertyName].ValueType); - comboxBox.SetValue((Enum)section.Values[configBindable.PropertyName].Value); + IGreenshotConfigBindable configBindable = controlObject as IGreenshotConfigBindable; + if (configBindable == null) { + continue; + } + if (!string.IsNullOrEmpty(configBindable.SectionName) && !string.IsNullOrEmpty(configBindable.PropertyName)) { + IniSection section = IniConfig.GetIniSection(configBindable.SectionName); + if (section != null) { + IniValue iniValue = null; + if (!section.Values.TryGetValue(configBindable.PropertyName, out iniValue)) { + LOG.WarnFormat("Wrong property '{0}' configured for field '{1}'",configBindable.PropertyName,field.Name); + continue; + } + + CheckBox checkBox = controlObject as CheckBox; + if (checkBox != null) { + checkBox.Checked = (bool)iniValue.Value; + continue; + } + + TextBox textBox = controlObject as TextBox; + if (textBox != null) { + textBox.Text = iniValue.ToString(); + continue; + } + + GreenshotComboBox comboxBox = controlObject as GreenshotComboBox; + if (comboxBox != null) { + comboxBox.Populate(iniValue.ValueType); + comboxBox.SetValue((Enum)iniValue.Value); + continue; + } + + HotkeyControl hotkeyControl = controlObject as HotkeyControl; + if (hotkeyControl != null) { + string hotkeyValue = (string)iniValue.Value; + if (!string.IsNullOrEmpty(hotkeyValue)) { + hotkeyControl.SetHotkey(hotkeyValue); } + continue; } } } @@ -398,36 +414,45 @@ namespace GreenshotPlugin.Controls { protected void StoreFields() { bool iniDirty = false; foreach (FieldInfo field in GetCachedFields(this.GetType())) { - if (!field.FieldType.IsSubclassOf(typeof(Control))) { - continue; - } - if (!typeof(IGreenshotConfigBindable).IsAssignableFrom(field.FieldType)) { - continue; - } Object controlObject = field.GetValue(this); + if (controlObject == null) { + continue; + } IGreenshotConfigBindable configBindable = controlObject as IGreenshotConfigBindable; + if (configBindable == null) { + continue; + } if (!string.IsNullOrEmpty(configBindable.SectionName) && !string.IsNullOrEmpty(configBindable.PropertyName)) { IniSection section = IniConfig.GetIniSection(configBindable.SectionName); if (section != null) { - if (!section.Values.ContainsKey(configBindable.PropertyName)) { + IniValue iniValue = null; + if (!section.Values.TryGetValue(configBindable.PropertyName, out iniValue)) { continue; } - if (typeof(CheckBox).IsAssignableFrom(field.FieldType)) { - CheckBox checkBox = controlObject as CheckBox; - section.Values[configBindable.PropertyName].Value = checkBox.Checked; + CheckBox checkBox = controlObject as CheckBox; + if (checkBox != null) { + iniValue.Value = checkBox.Checked; iniDirty = true; - } else if (typeof(HotkeyControl).IsAssignableFrom(field.FieldType)) { - HotkeyControl hotkeyControl = controlObject as HotkeyControl; - section.Values[configBindable.PropertyName].Value = hotkeyControl.ToString(); + continue; + } + TextBox textBox = controlObject as TextBox; + if (textBox != null) { + iniValue.UseValueOrDefault(textBox.Text); iniDirty = true; - } else if (typeof(TextBox).IsAssignableFrom(field.FieldType)) { - TextBox textBox = controlObject as TextBox; - section.Values[configBindable.PropertyName].UseValueOrDefault(textBox.Text); + continue; + } + GreenshotComboBox comboxBox = controlObject as GreenshotComboBox; + if (comboxBox != null) { + iniValue.Value = comboxBox.GetSelectedEnum(); iniDirty = true; - } else if (typeof(GreenshotComboBox).IsAssignableFrom(field.FieldType)) { - GreenshotComboBox comboxBox = controlObject as GreenshotComboBox; - section.Values[configBindable.PropertyName].Value = comboxBox.GetSelectedEnum(); + continue; + } + HotkeyControl hotkeyControl = controlObject as HotkeyControl; + if (hotkeyControl != null) { + iniValue.Value = hotkeyControl.ToString(); + iniDirty = true; + continue; } } } diff --git a/GreenshotPlugin/IniFile/IniConfig.cs b/GreenshotPlugin/IniFile/IniConfig.cs index fc577af8a..65331c581 100644 --- a/GreenshotPlugin/IniFile/IniConfig.cs +++ b/GreenshotPlugin/IniFile/IniConfig.cs @@ -272,10 +272,9 @@ namespace Greenshot.IniFile { /// /// public static IniSection GetIniSection(string sectionName) { - if (sectionMap.ContainsKey(sectionName)) { - return sectionMap[sectionName]; - } - return null; + IniSection returnValue = null; + sectionMap.TryGetValue(sectionName, out returnValue); + return returnValue; } /// @@ -286,7 +285,7 @@ namespace Greenshot.IniFile { T section; Type iniSectionType = typeof(T); - string sectionName = getSectionName(iniSectionType); + string sectionName = IniSection.GetIniSectionAttribute(iniSectionType).Name; if (sectionMap.ContainsKey(sectionName)) { //LOG.Debug("Returning pre-mapped section " + sectionName); section = (T)sectionMap[sectionName]; @@ -307,7 +306,7 @@ namespace Greenshot.IniFile { public static Dictionary PropertiesForSection(IniSection section) { Type iniSectionType = section.GetType(); - string sectionName = getSectionName(iniSectionType); + string sectionName = section.IniSectionAttribute.Name; // Get the properties for the section Dictionary properties = null; if (sections.ContainsKey(sectionName)) { @@ -319,17 +318,6 @@ namespace Greenshot.IniFile { return properties; } - private static string getSectionName(Type iniSectionType) { - Attribute[] classAttributes = Attribute.GetCustomAttributes(iniSectionType); - foreach (Attribute attribute in classAttributes) { - if (attribute is IniSectionAttribute) { - IniSectionAttribute iniSectionAttribute = (IniSectionAttribute)attribute; - return iniSectionAttribute.Name; - } - } - return null; - } - public static void Save() { string iniLocation = CreateIniLocation(configName + INI_EXTENSION); try { @@ -340,7 +328,6 @@ namespace Greenshot.IniFile { } } - private static void SaveInternally(string iniLocation) { WatchConfigFile(false); diff --git a/GreenshotPlugin/IniFile/IniSection.cs b/GreenshotPlugin/IniFile/IniSection.cs index ca7684bd5..f7ae8fa23 100644 --- a/GreenshotPlugin/IniFile/IniSection.cs +++ b/GreenshotPlugin/IniFile/IniSection.cs @@ -33,6 +33,16 @@ namespace Greenshot.IniFile { [NonSerialized] private IDictionary values = new Dictionary(); + [NonSerialized] + private IniSectionAttribute iniSectionAttribute = null; + public IniSectionAttribute IniSectionAttribute { + get { + if (iniSectionAttribute == null) { + iniSectionAttribute = GetIniSectionAttribute(this.GetType()); + } + return iniSectionAttribute; + } + } /// /// Get the dictionary with all the IniValues @@ -86,6 +96,21 @@ namespace Greenshot.IniFile { public virtual void AfterSave() { } + /// + /// Helper method to get the IniSectionAttribute of a type + /// + /// + /// + public static IniSectionAttribute GetIniSectionAttribute(Type iniSectionType) { + Attribute[] classAttributes = Attribute.GetCustomAttributes(iniSectionType); + foreach (Attribute attribute in classAttributes) { + if (attribute is IniSectionAttribute) { + return (IniSectionAttribute)attribute; + } + } + return null; + } + /// /// Fill the section with the supplied properties /// @@ -129,24 +154,16 @@ namespace Greenshot.IniFile { /// /// public void Write(TextWriter writer, bool onlyProperties) { + if (IniSectionAttribute == null) { + throw new ArgumentException("Section didn't implement the IniSectionAttribute"); + } BeforeSave(); try { - Attribute[] classAttributes = Attribute.GetCustomAttributes(this.GetType()); - IniSectionAttribute iniSectionAttribute = null; - foreach (Attribute attribute in classAttributes) { - if (attribute is IniSectionAttribute) { - iniSectionAttribute = (IniSectionAttribute)attribute; - break; - } - } - if (iniSectionAttribute == null) { - throw new ArgumentException("Section didn't implement the IniSectionAttribute"); - } if (!onlyProperties) { - writer.WriteLine("; {0}", iniSectionAttribute.Description); + writer.WriteLine("; {0}", IniSectionAttribute.Description); } - writer.WriteLine("[{0}]", iniSectionAttribute.Name); + writer.WriteLine("[{0}]", IniSectionAttribute.Name); foreach (IniValue value in Values.Values) { value.Write(writer, onlyProperties); diff --git a/GreenshotPlugin/IniFile/IniValue.cs b/GreenshotPlugin/IniFile/IniValue.cs index 7f38c9a46..e2cbbf0e6 100644 --- a/GreenshotPlugin/IniFile/IniValue.cs +++ b/GreenshotPlugin/IniFile/IniValue.cs @@ -426,7 +426,5 @@ namespace Greenshot.IniFile { // All other types return valueObject.ToString(); } - - } } \ No newline at end of file