mirror of
https://github.com/greenshot/greenshot
synced 2025-08-19 21:13:23 -07:00
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:
parent
9d5e3e33be
commit
4f64dfe676
7 changed files with 192 additions and 158 deletions
1
Greenshot/Forms/ImageEditorForm.Designer.cs
generated
1
Greenshot/Forms/ImageEditorForm.Designer.cs
generated
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -426,7 +426,5 @@ namespace Greenshot.IniFile {
|
|||
// All other types
|
||||
return valueObject.ToString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue