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
This commit is contained in:
RKrom 2012-06-13 22:17:53 +00:00
commit 4f64dfe676
7 changed files with 192 additions and 158 deletions

View file

@ -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;

View file

@ -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};
@ -152,6 +163,14 @@ namespace Greenshot {
// Workaround: for the MouseWheel event which doesn't get to the panel
this.MouseWheel += new MouseEventHandler( PanelMouseWheel);
ApplyLanguage();
}
/// <summary>
/// Get all the destinations and display them in the file menu and the buttons
/// </summary>
void AddDestinations() {
this.Invoke((MethodInvoker)delegate {
// Create export buttons
foreach(IDestination destination in DestinationHelper.GetAllDestinations()) {
if (destination.Priority <= 2) {
@ -170,11 +189,10 @@ namespace Greenshot {
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();
});
}
void AddDestinationButton(IDestination toolstripDestination) {
@ -292,15 +310,8 @@ namespace Greenshot {
private void ReloadConfiguration(object source, FileSystemEventArgs e) {
this.Invoke((MethodInvoker) delegate {
// Even update language when needed
updateUI();
});
}
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 {

View file

@ -342,7 +342,6 @@ namespace Greenshot {
}
coreConfiguration.ClipboardFormats = clipboardFormats;
coreConfiguration.WindowCaptureMode = GetSelected<WindowCaptureMode>(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();

View file

@ -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;
if (toolStrip != null) {
foreach (ToolStripItem item in toolStrip.Items) {
ApplyLanguage(item);
}
@ -250,17 +250,16 @@ 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;
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) {
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);
@ -269,6 +268,19 @@ namespace GreenshotPlugin.Controls {
}
}
}
/// <summary>
/// Helper method to cache the fieldinfo values, so we don't need to reflect all the time!
/// </summary>
/// <param name="typeToGetFieldsFor"></param>
/// <returns></returns>
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;
}
/// <summary>
@ -342,50 +354,54 @@ 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;
}
/// <summary>
/// Fill all GreenshotControls with the values from the configuration
/// </summary>
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 (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)) {
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)) {
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;
string hotkeyValue = (string)section.Values[configBindable.PropertyName].Value;
if (hotkeyControl != null) {
string hotkeyValue = (string)iniValue.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);
}
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;
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();
iniDirty = true;
} else if (typeof(TextBox).IsAssignableFrom(field.FieldType)) {
continue;
}
TextBox textBox = controlObject as TextBox;
section.Values[configBindable.PropertyName].UseValueOrDefault(textBox.Text);
if (textBox != null) {
iniValue.UseValueOrDefault(textBox.Text);
iniDirty = true;
} else if (typeof(GreenshotComboBox).IsAssignableFrom(field.FieldType)) {
continue;
}
GreenshotComboBox comboxBox = controlObject as GreenshotComboBox;
section.Values[configBindable.PropertyName].Value = comboxBox.GetSelectedEnum();
if (comboxBox != null) {
iniValue.Value = comboxBox.GetSelectedEnum();
iniDirty = true;
continue;
}
HotkeyControl hotkeyControl = controlObject as HotkeyControl;
if (hotkeyControl != null) {
iniValue.Value = hotkeyControl.ToString();
iniDirty = true;
continue;
}
}
}

View file

@ -272,10 +272,9 @@ namespace Greenshot.IniFile {
/// <param name="sectionName"></param>
/// <returns></returns>
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;
}
/// <summary>
@ -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<string, string> PropertiesForSection(IniSection section) {
Type iniSectionType = section.GetType();
string sectionName = getSectionName(iniSectionType);
string sectionName = section.IniSectionAttribute.Name;
// Get the properties for the section
Dictionary<string, string> 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);

View file

@ -33,6 +33,16 @@ namespace Greenshot.IniFile {
[NonSerialized]
private IDictionary<string, IniValue> values = new Dictionary<string, IniValue>();
[NonSerialized]
private IniSectionAttribute iniSectionAttribute = null;
public IniSectionAttribute IniSectionAttribute {
get {
if (iniSectionAttribute == null) {
iniSectionAttribute = GetIniSectionAttribute(this.GetType());
}
return iniSectionAttribute;
}
}
/// <summary>
/// Get the dictionary with all the IniValues
@ -86,6 +96,21 @@ namespace Greenshot.IniFile {
public virtual void AfterSave() {
}
/// <summary>
/// Helper method to get the IniSectionAttribute of a type
/// </summary>
/// <param name="iniSectionType"></param>
/// <returns></returns>
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;
}
/// <summary>
/// Fill the section with the supplied properties
/// </summary>
@ -129,24 +154,16 @@ namespace Greenshot.IniFile {
/// <param name="writer"></param>
/// <param name="onlyProperties"></param>
public void Write(TextWriter writer, bool onlyProperties) {
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) {
if (IniSectionAttribute == null) {
throw new ArgumentException("Section didn't implement the IniSectionAttribute");
}
BeforeSave();
try {
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);

View file

@ -426,7 +426,5 @@ namespace Greenshot.IniFile {
// All other types
return valueObject.ToString();
}
}
}