diff --git a/Greenshot/Configuration/EditorConfiguration.cs b/Greenshot/Configuration/EditorConfiguration.cs
index 3d3240273..52039eac2 100644
--- a/Greenshot/Configuration/EditorConfiguration.cs
+++ b/Greenshot/Configuration/EditorConfiguration.cs
@@ -26,6 +26,7 @@ using Greenshot.Drawing.Fields;
using GreenshotPlugin.UnmanagedHelpers;
using Greenshot.IniFile;
using Greenshot.Core;
+using GreenshotPlugin.Interfaces.Drawing;
namespace Greenshot.Configuration {
///
@@ -75,7 +76,8 @@ namespace Greenshot.Configuration {
/// FieldType of the field to construct
///
/// a new Field of the given fieldType, with the scope of it's value being restricted to the Type scope
- public Field CreateField(Type requestingType, FieldType fieldType, object preferredDefaultValue) {
+ public IField CreateField(Type requestingType, IFieldType fieldType, object preferredDefaultValue)
+ {
string requestingTypeName = requestingType.Name;
string requestedField = requestingTypeName + "." + fieldType.Name;
object fieldValue = preferredDefaultValue;
@@ -101,8 +103,9 @@ namespace Greenshot.Configuration {
returnField.Value = fieldValue;
return returnField;
}
-
- public void UpdateLastFieldValue(Field field) {
+
+ public void UpdateLastFieldValue(IField field)
+ {
string requestedField = field.Scope + "." + field.FieldType.Name;
// Check if the configuration exists
if (LastUsedFieldValues == null) {
@@ -110,9 +113,9 @@ namespace Greenshot.Configuration {
}
// check if settings for the requesting type exist, if not create!
if (LastUsedFieldValues.ContainsKey(requestedField)) {
- LastUsedFieldValues[requestedField] = field.myValue;
+ LastUsedFieldValues[requestedField] = field.Value;
} else {
- LastUsedFieldValues.Add(requestedField, field.myValue);
+ LastUsedFieldValues.Add(requestedField, field.Value);
}
}
diff --git a/Greenshot/Drawing/CropContainer.cs b/Greenshot/Drawing/CropContainer.cs
index e1bf7a78a..96b03d3b5 100644
--- a/Greenshot/Drawing/CropContainer.cs
+++ b/Greenshot/Drawing/CropContainer.cs
@@ -24,6 +24,7 @@ using System.Runtime.Serialization;
using Greenshot.Drawing.Fields;
using Greenshot.Helpers;
using Greenshot.Plugin.Drawing;
+using GreenshotPlugin.Interfaces.Drawing;
namespace Greenshot.Drawing {
///
@@ -45,10 +46,14 @@ namespace Greenshot.Drawing {
CreateDefaultAdorners();
}
protected override void InitializeFields() {
- AddField(GetType(), FieldType.FLAGS, FieldType.Flag.CONFIRMABLE);
+ AddField(GetType(), FieldType.FLAGS, FieldFlag.CONFIRMABLE);
}
public override void Invalidate() {
+ if (_parent == null)
+ {
+ return;
+ }
_parent.Invalidate();
}
diff --git a/Greenshot/Drawing/DrawableContainer.cs b/Greenshot/Drawing/DrawableContainer.cs
index f65480b2b..1c42a066d 100644
--- a/Greenshot/Drawing/DrawableContainer.cs
+++ b/Greenshot/Drawing/DrawableContainer.cs
@@ -29,6 +29,7 @@ using Greenshot.Memento;
using Greenshot.Plugin;
using Greenshot.Plugin.Drawing;
using Greenshot.Plugin.Drawing.Adorners;
+using GreenshotPlugin.Interfaces.Drawing;
using log4net;
using System;
using System.Collections.Generic;
@@ -104,7 +105,7 @@ namespace Greenshot.Drawing
remove{ _propertyChanged -= value; }
}
- public List Filters {
+ public IList Filters {
get {
List ret = new List();
foreach(IFieldHolder c in Children) {
@@ -124,10 +125,10 @@ namespace Greenshot.Drawing
}
[NonSerialized]
- private TargetAdorner _targetGripper;
- public TargetAdorner TargetGripper {
+ private TargetAdorner _targetAdorner;
+ public TargetAdorner TargetAdorner {
get {
- return _targetGripper;
+ return _targetAdorner;
}
}
@@ -305,7 +306,10 @@ namespace Greenshot.Drawing
}
public void AlignToParent(HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment) {
-
+ if (_parent == null)
+ {
+ return;
+ }
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
if (horizontalAlignment == HorizontalAlignment.Left) {
Left = lineThickness/2;
@@ -335,9 +339,9 @@ namespace Greenshot.Drawing
///
/// Initialize a target gripper
///
- protected void InitTargetGripper(Color gripperColor, Point location) {
- _targetGripper = new TargetAdorner(this, location);
- Adorners.Add(_targetGripper);
+ protected void InitAdorner(Color gripperColor, Point location) {
+ _targetAdorner = new TargetAdorner(this, location);
+ Adorners.Add(_targetAdorner);
}
///
@@ -478,6 +482,19 @@ namespace Greenshot.Drawing
}
protected virtual void SwitchParent(Surface newParent) {
+ if (newParent == Parent)
+ {
+ return;
+ }
+ if (_parent != null)
+ {
+ // Remove FieldAggregator
+ FieldAggregator fieldAggregator = _parent.FieldAggregator;
+ if (fieldAggregator != null)
+ {
+ fieldAggregator.UnbindElement(this);
+ }
+ }
_parent = newParent;
foreach(IFilter filter in Filters) {
@@ -485,24 +502,6 @@ namespace Greenshot.Drawing
}
}
- // drawablecontainers are regarded equal if they are of the same type and their bounds are equal. this should be sufficient.
- public override bool Equals(object obj) {
- bool ret = false;
- if (obj != null && GetType() == obj.GetType()) {
- DrawableContainer other = obj as DrawableContainer;
- if (other != null && left==other.left && top==other.top && width==other.width && height==other.height) {
- ret = true;
- }
- }
- return ret;
- }
-
- public override int GetHashCode() {
- // TODO: This actually doesn't make sense...
- // Place the container in a list, and you can't find it :)
- return left.GetHashCode() ^ top.GetHashCode() ^ width.GetHashCode() ^ height.GetHashCode() ^ GetFields().GetHashCode();
- }
-
protected void OnPropertyChanged(string propertyName) {
if (_propertyChanged != null) {
_propertyChanged(this, new PropertyChangedEventArgs(propertyName));
@@ -516,7 +515,7 @@ namespace Greenshot.Drawing
///
/// The field to be changed
/// The new value
- public virtual void BeforeFieldChange(Field fieldToBeChanged, object newValue) {
+ public virtual void BeforeFieldChange(IField fieldToBeChanged, object newValue) {
_parent.MakeUndoable(new ChangeFieldHolderMemento(this, fieldToBeChanged), true);
Invalidate();
}
@@ -531,7 +530,6 @@ namespace Greenshot.Drawing
if (e.Field.FieldType == FieldType.SHADOW) {
accountForShadowChange = true;
}
- Invalidate();
}
///
diff --git a/Greenshot/Drawing/DrawableContainerList.cs b/Greenshot/Drawing/DrawableContainerList.cs
index 692295966..597db8f3e 100644
--- a/Greenshot/Drawing/DrawableContainerList.cs
+++ b/Greenshot/Drawing/DrawableContainerList.cs
@@ -25,6 +25,7 @@ using Greenshot.Memento;
using Greenshot.Plugin;
using Greenshot.Plugin.Drawing;
using GreenshotPlugin.Core;
+using GreenshotPlugin.Interfaces.Drawing;
using System;
using System.Collections.Generic;
using System.ComponentModel;
@@ -38,7 +39,8 @@ namespace Greenshot.Drawing {
/// Dispatches most of a DrawableContainer's public properties and methods to a list of DrawableContainers.
///
[Serializable]
- public class DrawableContainerList : List {
+ public class DrawableContainerList : List, IDrawableContainerList
+ {
private static readonly ComponentResourceManager editorFormResources = new ComponentResourceManager(typeof(ImageEditorForm));
public Guid ParentID {
@@ -116,14 +118,11 @@ namespace Greenshot.Drawing {
///
/// true means allow the moves to be merged
public void MakeBoundsChangeUndoable(bool allowMerge) {
- List movingList = new List();
- Surface surface = null;
- foreach(DrawableContainer dc in this) {
- movingList.Add(dc);
- surface = dc._parent;
- }
- if (movingList.Count > 0 && surface != null) {
- surface.MakeUndoable(new DrawableContainerBoundsChangeMemento(movingList), allowMerge);
+ if (Count > 0 && Parent != null)
+ {
+ var clone = new DrawableContainerList();
+ clone.AddRange(this);
+ Parent.MakeUndoable(new DrawableContainerBoundsChangeMemento(clone), allowMerge);
}
}
@@ -246,9 +245,19 @@ namespace Greenshot.Drawing {
/// the rendermode in which the element is to be drawn
///
public void Draw(Graphics g, Bitmap bitmap, RenderMode renderMode, Rectangle clipRectangle) {
- foreach(var drawableContainer in this) {
- var dc = (DrawableContainer) drawableContainer;
- if (dc.DrawingBounds.IntersectsWith(clipRectangle)) {
+ if (Parent == null)
+ {
+ return;
+ }
+ foreach (var drawableContainer in this)
+ {
+ var dc = (DrawableContainer)drawableContainer;
+ if (dc.Parent == null)
+ {
+ continue;
+ }
+ if (dc.DrawingBounds.IntersectsWith(clipRectangle))
+ {
dc.DrawContent(g, bitmap, renderMode, clipRectangle);
}
}
@@ -270,9 +279,16 @@ namespace Greenshot.Drawing {
/// Invalidate the bounds of all the DC's in this list
///
public void Invalidate() {
- foreach(var dc in this) {
- dc.Invalidate();
+ if (Parent == null)
+ {
+ return;
}
+ Rectangle region = Rectangle.Empty;
+ foreach (var dc in this)
+ {
+ region = Rectangle.Union(region, dc.DrawingBounds);
+ }
+ Parent.Invalidate(region);
}
///
/// Indicates whether the given list of elements can be pulled up,
@@ -280,7 +296,7 @@ namespace Greenshot.Drawing {
///
/// list of elements to pull up
/// true if the elements could be pulled up
- public bool CanPullUp(DrawableContainerList elements) {
+ public bool CanPullUp(IDrawableContainerList elements) {
if (elements.Count == 0 || elements.Count == Count) {
return false;
}
@@ -296,7 +312,7 @@ namespace Greenshot.Drawing {
/// Pulls one or several elements up one level in hierarchy (z-index).
///
/// list of elements to pull up
- public void PullElementsUp(DrawableContainerList elements) {
+ public void PullElementsUp(IDrawableContainerList elements) {
for(int i=Count-1; i>=0; i--) {
var dc = this[i];
if (!elements.Contains(dc)) {
@@ -312,7 +328,7 @@ namespace Greenshot.Drawing {
/// Pulls one or several elements up to the topmost level(s) in hierarchy (z-index).
///
/// of elements to pull to top
- public void PullElementsToTop(DrawableContainerList elements) {
+ public void PullElementsToTop(IDrawableContainerList elements) {
var dcs = ToArray();
for(int i=0; i
/// list of elements to push down
/// true if the elements could be pushed down
- public bool CanPushDown(DrawableContainerList elements) {
+ public bool CanPushDown(IDrawableContainerList elements) {
if (elements.Count == 0 || elements.Count == Count) {
return false;
}
@@ -347,7 +363,7 @@ namespace Greenshot.Drawing {
/// Pushes one or several elements down one level in hierarchy (z-index).
///
/// list of elements to push down
- public void PushElementsDown(DrawableContainerList elements) {
+ public void PushElementsDown(IDrawableContainerList elements) {
for(int i=0; i
/// of elements to push to bottom
- public void PushElementsToBottom(DrawableContainerList elements) {
+ public void PushElementsToBottom(IDrawableContainerList elements) {
var dcs = ToArray();
for(int i=dcs.Length-1; i>=0; i--) {
var dc = dcs[i];
@@ -397,7 +413,7 @@ namespace Greenshot.Drawing {
///
///
///
- public virtual void AddContextMenuItems(ContextMenuStrip menu, Surface surface) {
+ public virtual void AddContextMenuItems(ContextMenuStrip menu, ISurface surface) {
bool push = surface.Elements.CanPushDown(this);
bool pull = surface.Elements.CanPullUp(this);
@@ -437,7 +453,7 @@ namespace Greenshot.Drawing {
// Duplicate
item = new ToolStripMenuItem(Language.GetString(LangKey.editor_duplicate));
item.Click += delegate {
- DrawableContainerList dcs = this.Clone();
+ IDrawableContainerList dcs = this.Clone();
dcs.Parent = surface;
dcs.MoveBy(10, 10);
surface.AddElements(dcs);
@@ -448,48 +464,36 @@ namespace Greenshot.Drawing {
// Copy
item = new ToolStripMenuItem(Language.GetString(LangKey.editor_copytoclipboard));
- item.Image = (Image)editorFormResources.GetObject("copyToolStripMenuItem.Image");
+ item.Image = ((Image)(editorFormResources.GetObject("copyToolStripMenuItem.Image")));
item.Click += delegate {
- ClipboardHelper.SetClipboardData(typeof(DrawableContainerList), this);
+ ClipboardHelper.SetClipboardData(typeof(IDrawableContainerList), this);
};
menu.Items.Add(item);
// Cut
item = new ToolStripMenuItem(Language.GetString(LangKey.editor_cuttoclipboard));
- item.Image = (Image)editorFormResources.GetObject("btnCut.Image");
+ item.Image = ((Image)(editorFormResources.GetObject("btnCut.Image")));
item.Click += delegate {
- ClipboardHelper.SetClipboardData(typeof(DrawableContainerList), this);
- List containersToDelete = new List();
- foreach (var drawableContainer in this) {
- var container = (DrawableContainer) drawableContainer;
- containersToDelete.Add(container);
- }
- foreach (var container in containersToDelete) {
- surface.RemoveElement(container, true);
- }
+ ClipboardHelper.SetClipboardData(typeof(IDrawableContainerList), this);
+ surface.RemoveElements(this, true);
};
menu.Items.Add(item);
// Delete
item = new ToolStripMenuItem(Language.GetString(LangKey.editor_deleteelement));
- item.Image = (Image)editorFormResources.GetObject("removeObjectToolStripMenuItem.Image");
+ item.Image = ((Image)(editorFormResources.GetObject("removeObjectToolStripMenuItem.Image")));
item.Click += delegate {
- List containersToDelete = new List();
- foreach(var drawableContainer in this) {
- var container = (DrawableContainer) drawableContainer;
- containersToDelete.Add(container);
- }
- foreach (DrawableContainer container in containersToDelete) {
- surface.RemoveElement(container, true);
- }
+ surface.RemoveElements(this, true);
};
menu.Items.Add(item);
// Reset
bool canReset = false;
- foreach (var drawableContainer in this) {
- var container = (DrawableContainer) drawableContainer;
- if (container.HasDefaultSize) {
+ foreach (var drawableContainer in this)
+ {
+ var container = (DrawableContainer)drawableContainer;
+ if (container.HasDefaultSize)
+ {
canReset = true;
}
}
@@ -497,24 +501,29 @@ namespace Greenshot.Drawing {
item = new ToolStripMenuItem(Language.GetString(LangKey.editor_resetsize));
//item.Image = ((System.Drawing.Image)(editorFormResources.GetObject("removeObjectToolStripMenuItem.Image")));
item.Click += delegate {
+ MakeBoundsChangeUndoable(false);
foreach (var drawableContainer in this) {
var container = (DrawableContainer) drawableContainer;
if (!container.HasDefaultSize) {
continue;
}
Size defaultSize = container.DefaultSize;
- container.Invalidate();
container.MakeBoundsChangeUndoable(false);
container.Width = defaultSize.Width;
container.Height = defaultSize.Height;
- container.Invalidate();
}
+ surface.Invalidate();
};
menu.Items.Add(item);
}
}
- public virtual void ShowContextMenu(MouseEventArgs e, Surface surface) {
+ public virtual void ShowContextMenu(MouseEventArgs e, ISurface surface)
+ {
+ if (!(surface is Surface))
+ {
+ return;
+ }
bool hasMenu = false;
foreach (var drawableContainer in this) {
var container = (DrawableContainer) drawableContainer;
@@ -528,7 +537,8 @@ namespace Greenshot.Drawing {
ContextMenuStrip menu = new ContextMenuStrip();
AddContextMenuItems(menu, surface);
if (menu.Items.Count > 0) {
- menu.Show(surface, e.Location);
+ // TODO: cast should be somehow avoided
+ menu.Show((Surface)surface, e.Location);
while (true) {
if (menu.Visible) {
Application.DoEvents();
@@ -541,5 +551,32 @@ namespace Greenshot.Drawing {
}
}
}
+
+ #region IDisposable Support
+ private bool _disposedValue = false; // To detect redundant calls
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ if (disposing)
+ {
+ foreach (var drawableContainer in this)
+ {
+ drawableContainer.Dispose();
+ }
+ }
+
+ _disposedValue = true;
+ }
+ }
+
+ // This code added to correctly implement the disposable pattern.
+ public void Dispose()
+ {
+ // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
+ Dispose(true);
+ }
+ #endregion
}
}
diff --git a/Greenshot/Drawing/Fields/AbstractFieldHolder.cs b/Greenshot/Drawing/Fields/AbstractFieldHolder.cs
index 1c4a98037..203f590c3 100644
--- a/Greenshot/Drawing/Fields/AbstractFieldHolder.cs
+++ b/Greenshot/Drawing/Fields/AbstractFieldHolder.cs
@@ -3,7 +3,7 @@
* Copyright (C) 2007-2015 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/
+ * The Greenshot project is hosted on GitHub https://github.com/greenshot/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
@@ -26,39 +26,48 @@ using System.Runtime.Serialization;
using Greenshot.Configuration;
using Greenshot.IniFile;
using log4net;
+using GreenshotPlugin.Interfaces.Drawing;
-namespace Greenshot.Drawing.Fields {
+namespace Greenshot.Drawing.Fields
+{
///
/// Basic IFieldHolder implementation, providing access to a set of fields
///
[Serializable]
- public abstract class AbstractFieldHolder : IFieldHolder {
+ public abstract class AbstractFieldHolder : IFieldHolder
+ {
private static readonly ILog LOG = LogManager.GetLogger(typeof(AbstractFieldHolder));
- private static readonly EditorConfiguration editorConfiguration = IniConfig.GetIniSection();
+ private static EditorConfiguration editorConfiguration = IniConfig.GetIniSection();
///
/// called when a field's value has changed
///
[NonSerialized]
private FieldChangedEventHandler fieldChanged;
- public event FieldChangedEventHandler FieldChanged {
+ public event FieldChangedEventHandler FieldChanged
+ {
add { fieldChanged += value; }
- remove{ fieldChanged -= value; }
+ remove { fieldChanged -= value; }
}
-
+
// we keep two Collections of our fields, dictionary for quick access, list for serialization
// this allows us to use default serialization
[NonSerialized]
- private Dictionary fieldsByType = new Dictionary();
- private readonly List fields = new List();
+ private IDictionary fieldsByType = new Dictionary();
+ private IList fields = new List();
+
+ public AbstractFieldHolder() { }
[OnDeserialized]
- private void OnFieldHolderDeserialized(StreamingContext context) {
- fieldsByType = new Dictionary();
+ private void OnDeserialized(StreamingContext context)
+ {
+ fieldsByType = new Dictionary();
// listen to changing properties
- foreach(Field field in fields) {
+ foreach (Field field in fields)
+ {
field.PropertyChanged += delegate {
- if (fieldChanged != null) {
+ if (fieldChanged != null)
+ {
fieldChanged(this, new FieldChangedEventArgs(field));
}
};
@@ -66,97 +75,124 @@ namespace Greenshot.Drawing.Fields {
}
}
- public void AddField(Type requestingType, FieldType fieldType, object fieldValue) {
+ public void AddField(Type requestingType, IFieldType fieldType, object fieldValue)
+ {
AddField(editorConfiguration.CreateField(requestingType, fieldType, fieldValue));
}
- public virtual void AddField(Field field) {
- if (fieldsByType != null && fieldsByType.ContainsKey(field.FieldType)) {
- if (LOG.IsDebugEnabled) {
+ public virtual void AddField(IField field)
+ {
+ if (fieldsByType != null && fieldsByType.ContainsKey(field.FieldType))
+ {
+ if (LOG.IsDebugEnabled)
+ {
LOG.DebugFormat("A field with of type '{0}' already exists in this {1}, will overwrite.", field.FieldType, GetType());
}
- }
-
+ }
+
fields.Add(field);
fieldsByType[field.FieldType] = field;
- field.PropertyChanged += delegate { if(fieldChanged != null) fieldChanged(this, new FieldChangedEventArgs(field)); };
+ field.PropertyChanged += delegate { if (fieldChanged != null) fieldChanged(this, new FieldChangedEventArgs(field)); };
}
-
- public void RemoveField(Field field) {
+
+ public void RemoveField(IField field)
+ {
fields.Remove(field);
fieldsByType.Remove(field.FieldType);
field.PropertyChanged -= delegate {
- if (fieldChanged != null) {
+ if (fieldChanged != null)
+ {
fieldChanged(this, new FieldChangedEventArgs(field));
}
};
}
-
- public List GetFields() {
+
+ public IList GetFields()
+ {
return fields;
}
-
- public Field GetField(FieldType fieldType) {
- try {
+
+ public IField GetField(IFieldType fieldType)
+ {
+ try
+ {
return fieldsByType[fieldType];
- } catch(KeyNotFoundException e) {
+ }
+ catch (KeyNotFoundException e)
+ {
throw new ArgumentException("Field '" + fieldType + "' does not exist in " + GetType(), e);
}
}
-
- public object GetFieldValue(FieldType fieldType) {
+
+ public object GetFieldValue(IFieldType fieldType)
+ {
return GetField(fieldType).Value;
}
-
+
#region convenience methods to save us some casts outside
- public string GetFieldValueAsString(FieldType fieldType) {
+ public string GetFieldValueAsString(IFieldType fieldType)
+ {
return Convert.ToString(GetFieldValue(fieldType));
}
-
- public int GetFieldValueAsInt(FieldType fieldType) {
+
+ public int GetFieldValueAsInt(IFieldType fieldType)
+ {
return Convert.ToInt32(GetFieldValue(fieldType));
}
-
- public decimal GetFieldValueAsDecimal(FieldType fieldType) {
+
+ public decimal GetFieldValueAsDecimal(IFieldType fieldType)
+ {
return Convert.ToDecimal(GetFieldValue(fieldType));
}
-
- public double GetFieldValueAsDouble(FieldType fieldType) {
+
+ public double GetFieldValueAsDouble(IFieldType fieldType)
+ {
return Convert.ToDouble(GetFieldValue(fieldType));
}
-
- public float GetFieldValueAsFloat(FieldType fieldType) {
+
+ public float GetFieldValueAsFloat(IFieldType fieldType)
+ {
return Convert.ToSingle(GetFieldValue(fieldType));
}
-
- public bool GetFieldValueAsBool(FieldType fieldType) {
+
+ public bool GetFieldValueAsBool(IFieldType fieldType)
+ {
return Convert.ToBoolean(GetFieldValue(fieldType));
}
-
- public Color GetFieldValueAsColor(FieldType fieldType) {
+
+ public Color GetFieldValueAsColor(IFieldType fieldType)
+ {
return (Color)GetFieldValue(fieldType);
}
#endregion
-
- public bool HasField(FieldType fieldType) {
+
+ public bool HasField(IFieldType fieldType)
+ {
return fieldsByType.ContainsKey(fieldType);
}
-
- public bool HasFieldValue(FieldType fieldType) {
+
+ public bool HasFieldValue(IFieldType fieldType)
+ {
return HasField(fieldType) && fieldsByType[fieldType].HasValue;
}
-
- public void SetFieldValue(FieldType fieldType, object value) {
- try {
+
+ public void SetFieldValue(IFieldType fieldType, object value)
+ {
+ try
+ {
fieldsByType[fieldType].Value = value;
- } catch(KeyNotFoundException e) {
- throw new ArgumentException("Field '"+fieldType+"' does not exist in " + GetType(), e);
+ }
+ catch (KeyNotFoundException e)
+ {
+ throw new ArgumentException("Field '" + fieldType + "' does not exist in " + GetType(), e);
}
}
-
- protected void OnFieldChanged(object sender, FieldChangedEventArgs e){
- if (fieldChanged != null) {
+
+ protected void OnFieldChanged(object sender, FieldChangedEventArgs e)
+ {
+ if (fieldChanged != null)
+ {
fieldChanged(sender, e);
}
}
diff --git a/Greenshot/Drawing/Fields/AbstractFieldHolderWithChildren.cs b/Greenshot/Drawing/Fields/AbstractFieldHolderWithChildren.cs
index a81308d0e..ae610a5fa 100644
--- a/Greenshot/Drawing/Fields/AbstractFieldHolderWithChildren.cs
+++ b/Greenshot/Drawing/Fields/AbstractFieldHolderWithChildren.cs
@@ -3,7 +3,7 @@
* Copyright (C) 2007-2015 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/
+ * The Greenshot project is hosted on GitHub https://github.com/greenshot/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
@@ -18,86 +18,110 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
+
+using GreenshotPlugin.Interfaces.Drawing;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
-namespace Greenshot.Drawing.Fields {
+namespace Greenshot.Drawing.Fields
+{
///
/// Basic IFieldHolderWithChildren implementation. Similar to IFieldHolder,
/// but has a List of children.
/// Field values are passed to and from children as well.
///
- [Serializable()]
- public abstract class AbstractFieldHolderWithChildren : AbstractFieldHolder {
- readonly FieldChangedEventHandler fieldChangedEventHandler;
-
+ [Serializable()]
+ public abstract class AbstractFieldHolderWithChildren : AbstractFieldHolder
+ {
+
+ FieldChangedEventHandler fieldChangedEventHandler;
+
[NonSerialized]
private EventHandler childrenChanged;
- public event EventHandler ChildrenChanged {
+ public event EventHandler ChildrenChanged
+ {
add { childrenChanged += value; }
remove { childrenChanged -= value; }
}
-
+
public List Children = new List();
-
- public AbstractFieldHolderWithChildren() {
+
+ public AbstractFieldHolderWithChildren()
+ {
fieldChangedEventHandler = OnFieldChanged;
}
-
- [OnDeserialized]
- private void OnFieldHolderWithChildrenDeserialized(StreamingContext context) {
+
+ [OnDeserialized()]
+ private void OnDeserialized(StreamingContext context)
+ {
// listen to changing properties
- foreach(IFieldHolder fieldHolder in Children) {
+ foreach (IFieldHolder fieldHolder in Children)
+ {
fieldHolder.FieldChanged += fieldChangedEventHandler;
}
- if(childrenChanged != null) childrenChanged(this, EventArgs.Empty);
+ if (childrenChanged != null) childrenChanged(this, EventArgs.Empty);
}
-
- public void AddChild(IFieldHolder fieldHolder) {
+
+ public void AddChild(IFieldHolder fieldHolder)
+ {
Children.Add(fieldHolder);
fieldHolder.FieldChanged += fieldChangedEventHandler;
- if(childrenChanged != null) childrenChanged(this, EventArgs.Empty);
+ if (childrenChanged != null) childrenChanged(this, EventArgs.Empty);
}
-
- public void RemoveChild(IFieldHolder fieldHolder) {
+
+ public void RemoveChild(IFieldHolder fieldHolder)
+ {
Children.Remove(fieldHolder);
fieldHolder.FieldChanged -= fieldChangedEventHandler;
- if(childrenChanged != null) childrenChanged(this, EventArgs.Empty);
+ if (childrenChanged != null) childrenChanged(this, EventArgs.Empty);
}
-
- public new List GetFields() {
- List ret = new List();
+
+ public new IList GetFields()
+ {
+ List ret = new List();
ret.AddRange(base.GetFields());
- foreach(IFieldHolder fh in Children) {
+ foreach (IFieldHolder fh in Children)
+ {
ret.AddRange(fh.GetFields());
}
return ret;
}
-
- public new Field GetField(FieldType fieldType) {
- Field ret = null;
- if(base.HasField(fieldType)) {
+
+ public new IField GetField(IFieldType fieldType)
+ {
+ IField ret = null;
+ if (base.HasField(fieldType))
+ {
ret = base.GetField(fieldType);
- } else {
- foreach(IFieldHolder fh in Children) {
- if(fh.HasField(fieldType)) {
+ }
+ else
+ {
+ foreach (IFieldHolder fh in Children)
+ {
+ if (fh.HasField(fieldType))
+ {
ret = fh.GetField(fieldType);
break;
}
}
}
- if(ret == null) {
- throw new ArgumentException("Field '"+fieldType+"' does not exist in " + GetType());
+ if (ret == null)
+ {
+ throw new ArgumentException("Field '" + fieldType + "' does not exist in " + GetType());
}
return ret;
}
-
- public new bool HasField(FieldType fieldType) {
+
+ public new bool HasField(IFieldType fieldType)
+ {
bool ret = base.HasField(fieldType);
- if(!ret) {
- foreach(IFieldHolder fh in Children) {
- if(fh.HasField(fieldType)) {
+ if (!ret)
+ {
+ foreach (IFieldHolder fh in Children)
+ {
+ if (fh.HasField(fieldType))
+ {
ret = true;
break;
}
@@ -105,16 +129,18 @@ namespace Greenshot.Drawing.Fields {
}
return ret;
}
-
- public new bool HasFieldValue(FieldType fieldType) {
- Field f = GetField(fieldType);
+
+ public new bool HasFieldValue(IFieldType fieldType)
+ {
+ IField f = GetField(fieldType);
return f != null && f.HasValue;
}
-
- public new void SetFieldValue(FieldType fieldType, object value) {
- Field f = GetField(fieldType);
- if(f != null) f.Value = value;
+
+ public new void SetFieldValue(IFieldType fieldType, object value)
+ {
+ IField f = GetField(fieldType);
+ if (f != null) f.Value = value;
}
-
+
}
}
diff --git a/Greenshot/Drawing/Fields/Field.cs b/Greenshot/Drawing/Fields/Field.cs
index 28246a6cc..cee59f0c6 100644
--- a/Greenshot/Drawing/Fields/Field.cs
+++ b/Greenshot/Drawing/Fields/Field.cs
@@ -3,7 +3,7 @@
* Copyright (C) 2007-2015 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/
+ * The Greenshot project is hosted on GitHub https://github.com/greenshot/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
@@ -18,36 +18,53 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
+
+using GreenshotPlugin.Interfaces.Drawing;
using System;
using System.ComponentModel;
-namespace Greenshot.Drawing.Fields {
+namespace Greenshot.Drawing.Fields
+{
///
/// Represents a single field of a drawable element, i.e.
/// line thickness of a rectangle.
///
[Serializable]
- public class Field : INotifyPropertyChanged {
- [field:NonSerialized]
+ public class Field : IField
+ {
+ [field: NonSerialized]
public event PropertyChangedEventHandler PropertyChanged;
-
- public object myValue;
- public object Value {
- get {
- return myValue;
+
+ private object _myValue;
+ public object Value
+ {
+ get
+ {
+ return _myValue;
}
- set {
- if (!Equals(myValue,value)) {
- myValue = value;
- if (PropertyChanged!=null) {
+ set
+ {
+ if (!Equals(_myValue, value))
+ {
+ _myValue = value;
+ if (PropertyChanged != null)
+ {
PropertyChanged(this, new PropertyChangedEventArgs("Value"));
}
}
}
}
- public FieldType FieldType;
- public string Scope;
-
+ public IFieldType FieldType
+ {
+ get;
+ set;
+ }
+ public string Scope
+ {
+ get;
+ set;
+ }
+
///
/// Constructs a new Field instance, usually you should be using FieldFactory
/// to create Fields.
@@ -59,70 +76,64 @@ namespace Greenshot.Drawing.Fields {
/// When scope is set to a Type (e.g. typeof(RectangleContainer)), its value
/// should not be reused for FieldHolders of another Type (e.g. typeof(EllipseContainer))
///
- public Field(FieldType fieldType, Type scope) {
+ public Field(IFieldType fieldType, Type scope)
+ {
FieldType = fieldType;
Scope = scope.Name;
}
- public Field(FieldType fieldType, string scope) {
+ public Field(IFieldType fieldType, string scope)
+ {
FieldType = fieldType;
Scope = scope;
}
- public Field(FieldType fieldType) {
+ public Field(IFieldType fieldType)
+ {
FieldType = fieldType;
}
///
/// Returns true if this field holds a value other than null.
///
- public bool HasValue {
- get{ return Value != null; }
+ public bool HasValue
+ {
+ get { return Value != null; }
}
-
+
///
/// Creates a flat clone of this Field. The fields value itself is not cloned.
///
///
- public Field Clone() {
+ public Field Clone()
+ {
Field ret = new Field(FieldType, Scope);
ret.Value = Value;
return ret;
}
-
- public override int GetHashCode() {
+
+ public override int GetHashCode()
+ {
int hashCode = 0;
- unchecked {
+ unchecked
+ {
hashCode += 1000000009 * FieldType.GetHashCode();
if (Scope != null)
hashCode += 1000000021 * Scope.GetHashCode();
}
return hashCode;
}
-
- public override bool Equals(object obj) {
+
+ public override bool Equals(object obj)
+ {
Field other = obj as Field;
- if (other == null) {
+ if (other == null)
+ {
return false;
}
return FieldType == other.FieldType && Equals(Scope, other.Scope);
}
-
- public override string ToString() {
- return string.Format("[Field FieldType={1} Value={0} Scope={2}]", myValue, FieldType, Scope);
- }
- }
-
-
- ///
- /// EventHandler to be used when a field value changes
- ///
- public delegate void FieldChangedEventHandler(object sender, FieldChangedEventArgs e);
-
- ///
- /// EventArgs to be used with FieldChangedEventHandler
- ///
- public class FieldChangedEventArgs : EventArgs {
- public readonly Field Field;
- public FieldChangedEventArgs(Field field) {
- Field = field;
+
+ public override string ToString()
+ {
+ return string.Format("[Field FieldType={1} Value={0} Scope={2}]", _myValue, FieldType, Scope);
}
}
}
diff --git a/Greenshot/Drawing/Fields/FieldAggregator.cs b/Greenshot/Drawing/Fields/FieldAggregator.cs
index 476233f73..7c2e7558f 100644
--- a/Greenshot/Drawing/Fields/FieldAggregator.cs
+++ b/Greenshot/Drawing/Fields/FieldAggregator.cs
@@ -3,7 +3,7 @@
* Copyright (C) 2007-2015 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/
+ * The Greenshot project is hosted on GitHub https://github.com/greenshot/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
@@ -19,14 +19,18 @@
* along with this program. If not, see .
*/
+using Greenshot.Configuration;
+using Greenshot.IniFile;
+using Greenshot.Plugin;
+using Greenshot.Plugin.Drawing;
+using GreenshotPlugin.Interfaces;
+using GreenshotPlugin.Interfaces.Drawing;
+using log4net;
using System.Collections.Generic;
using System.ComponentModel;
-using Greenshot.Configuration;
-using Greenshot.IniFile;
-using Greenshot.Plugin.Drawing;
-
-namespace Greenshot.Drawing.Fields {
+namespace Greenshot.Drawing.Fields
+{
///
/// Represents the current set of properties for the editor.
/// When one of EditorProperties' properties is updated, the change will be promoted
@@ -38,35 +42,47 @@ namespace Greenshot.Drawing.Fields {
/// Properties that do not apply for ALL selected elements are null (or 0 respectively)
/// If the property values of the selected elements differ, the value of the last bound element wins.
///
- public class FieldAggregator : AbstractFieldHolder {
-
- private readonly List boundContainers;
- private bool internalUpdateRunning;
+ public class FieldAggregator : AbstractFieldHolder
+ {
- private static readonly EditorConfiguration editorConfiguration = IniConfig.GetIniSection();
+ private IDrawableContainerList boundContainers;
+ private bool internalUpdateRunning = false;
- public FieldAggregator() {
- foreach(FieldType fieldType in FieldType.Values) {
+ enum Status { IDLE, BINDING, UPDATING };
+
+ private static readonly ILog LOG = LogManager.GetLogger(typeof(FieldAggregator));
+ private static EditorConfiguration editorConfiguration = IniConfig.GetIniSection();
+
+ public FieldAggregator(ISurface parent)
+ {
+ foreach (FieldType fieldType in FieldType.Values)
+ {
Field field = new Field(fieldType, GetType());
AddField(field);
}
- boundContainers = new List();
+ boundContainers = new DrawableContainerList();
+ boundContainers.Parent = parent;
}
-
- public override void AddField(Field field) {
+
+ public override void AddField(IField field)
+ {
base.AddField(field);
field.PropertyChanged += OwnPropertyChanged;
}
-
- public void BindElements(DrawableContainerList dcs) {
- foreach(DrawableContainer dc in dcs) {
+
+ public void BindElements(IDrawableContainerList dcs)
+ {
+ foreach (DrawableContainer dc in dcs)
+ {
BindElement(dc);
}
}
- public void BindElement(IDrawableContainer dc) {
+ public void BindElement(IDrawableContainer dc)
+ {
DrawableContainer container = dc as DrawableContainer;
- if (container != null && !boundContainers.Contains(container)) {
+ if (container != null && !boundContainers.Contains(container))
+ {
boundContainers.Add(container);
container.ChildrenChanged += delegate {
UpdateFromBoundElements();
@@ -74,101 +90,126 @@ namespace Greenshot.Drawing.Fields {
UpdateFromBoundElements();
}
}
-
- public void BindAndUpdateElement(IDrawableContainer dc) {
+
+ public void BindAndUpdateElement(IDrawableContainer dc)
+ {
UpdateElement(dc);
BindElement(dc);
}
-
- public void UpdateElement(IDrawableContainer dc) {
+
+ public void UpdateElement(IDrawableContainer dc)
+ {
DrawableContainer container = dc as DrawableContainer;
- if (container == null) {
+ if (container == null)
+ {
return;
}
internalUpdateRunning = true;
- foreach(Field field in GetFields()) {
- if (container.HasField(field.FieldType) && field.HasValue) {
+ foreach (Field field in GetFields())
+ {
+ if (container.HasField(field.FieldType) && field.HasValue)
+ {
//if(LOG.IsDebugEnabled) LOG.Debug(" "+field+ ": "+field.Value);
container.SetFieldValue(field.FieldType, field.Value);
}
}
internalUpdateRunning = false;
}
-
- public void UnbindElement(IDrawableContainer dc) {
- if (boundContainers.Contains(dc)) {
+
+ public void UnbindElement(IDrawableContainer dc)
+ {
+ if (boundContainers.Contains(dc))
+ {
boundContainers.Remove(dc);
UpdateFromBoundElements();
}
}
-
- public void Clear() {
+
+ public void Clear()
+ {
ClearFields();
- boundContainers.Clear();
+ boundContainers.Clear();
UpdateFromBoundElements();
}
-
+
///
/// sets all field values to null, however does not remove fields
///
- private void ClearFields() {
+ private void ClearFields()
+ {
internalUpdateRunning = true;
- foreach(Field field in GetFields()) {
+ foreach (Field field in GetFields())
+ {
field.Value = null;
}
internalUpdateRunning = false;
}
-
+
///
/// Updates this instance using the respective fields from the bound elements.
/// Fields that do not apply to every bound element are set to null, or 0 respectively.
/// All other fields will be set to the field value of the least bound element.
///
- private void UpdateFromBoundElements() {
+ private void UpdateFromBoundElements()
+ {
ClearFields();
internalUpdateRunning = true;
- foreach(Field field in FindCommonFields()) {
+ foreach (Field field in FindCommonFields())
+ {
SetFieldValue(field.FieldType, field.Value);
}
internalUpdateRunning = false;
}
-
- private List FindCommonFields() {
- List returnFields = null;
- if (boundContainers.Count > 0) {
+
+ private IList FindCommonFields()
+ {
+ IList returnFields = null;
+ if (boundContainers.Count > 0)
+ {
// take all fields from the least selected container...
DrawableContainer leastSelectedContainer = boundContainers[boundContainers.Count - 1] as DrawableContainer;
- if (leastSelectedContainer != null) {
+ if (leastSelectedContainer != null)
+ {
returnFields = leastSelectedContainer.GetFields();
- for (int i = 0; i < boundContainers.Count - 1; i++) {
+ for (int i = 0; i < boundContainers.Count - 1; i++)
+ {
DrawableContainer dc = boundContainers[i] as DrawableContainer;
- if (dc != null) {
- List fieldsToRemove = new List();
- foreach (Field f in returnFields) {
+ if (dc != null)
+ {
+ IList fieldsToRemove = new List();
+ foreach (IField field in returnFields)
+ {
// ... throw out those that do not apply to one of the other containers
- if (!dc.HasField(f.FieldType)) {
- fieldsToRemove.Add(f);
+ if (!dc.HasField(field.FieldType))
+ {
+ fieldsToRemove.Add(field);
}
}
- foreach (Field f in fieldsToRemove) {
- returnFields.Remove(f);
+ foreach (IField field in fieldsToRemove)
+ {
+ returnFields.Remove(field);
}
}
}
}
}
- if (returnFields == null) {
- returnFields = new List();
+ if (returnFields == null)
+ {
+ returnFields = new List();
}
return returnFields;
}
-
- public void OwnPropertyChanged(object sender, PropertyChangedEventArgs ea) {
- Field field = (Field) sender;
- if (!internalUpdateRunning && field.Value != null) {
- foreach(DrawableContainer drawableContainer in boundContainers) {
- if (drawableContainer.HasField(field.FieldType)) {
- Field drawableContainerField = drawableContainer.GetField(field.FieldType);
+
+ public void OwnPropertyChanged(object sender, PropertyChangedEventArgs ea)
+ {
+ IField field = (IField)sender;
+ if (!internalUpdateRunning && field.Value != null)
+ {
+ foreach (DrawableContainer drawableContainer in boundContainers)
+ {
+ if (drawableContainer.HasField(field.FieldType))
+ {
+ IField drawableContainerField = drawableContainer.GetField(field.FieldType);
// Notify before change, so we can e.g. invalidate the area
drawableContainer.BeforeFieldChange(drawableContainerField, field.Value);
@@ -180,5 +221,5 @@ namespace Greenshot.Drawing.Fields {
}
}
- }
+ }
}
diff --git a/Greenshot/Drawing/Fields/FieldType.cs b/Greenshot/Drawing/Fields/FieldType.cs
index 4469f86cf..3090e3e51 100644
--- a/Greenshot/Drawing/Fields/FieldType.cs
+++ b/Greenshot/Drawing/Fields/FieldType.cs
@@ -3,7 +3,7 @@
* Copyright (C) 2007-2015 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/
+ * The Greenshot project is hosted on GitHub https://github.com/greenshot/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
@@ -18,38 +18,41 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
+using GreenshotPlugin.Interfaces.Drawing;
using System;
-namespace Greenshot.Drawing.Fields {
+namespace Greenshot.Drawing.Fields
+{
///
/// Defines all FieldTypes + their default value.
/// (The additional value is why this is not an enum)
///
[Serializable]
- public class FieldType {
-
- public static readonly FieldType ARROWHEADS = new FieldType("ARROWHEADS");
- public static readonly FieldType BLUR_RADIUS = new FieldType("BLUR_RADIUS");
- public static readonly FieldType BRIGHTNESS = new FieldType("BRIGHTNESS");
- public static readonly FieldType FILL_COLOR = new FieldType("FILL_COLOR");
- public static readonly FieldType FONT_BOLD = new FieldType("FONT_BOLD");
- public static readonly FieldType FONT_FAMILY = new FieldType("FONT_FAMILY");
- public static readonly FieldType FONT_ITALIC = new FieldType("FONT_ITALIC");
- public static readonly FieldType FONT_SIZE = new FieldType("FONT_SIZE");
- public static readonly FieldType TEXT_HORIZONTAL_ALIGNMENT = new FieldType("TEXT_HORIZONTAL_ALIGNMENT");
- public static readonly FieldType TEXT_VERTICAL_ALIGNMENT = new FieldType("TEXT_VERTICAL_ALIGNMENT");
- public static readonly FieldType HIGHLIGHT_COLOR = new FieldType("HIGHLIGHT_COLOR");
- public static readonly FieldType LINE_COLOR = new FieldType("LINE_COLOR");
- public static readonly FieldType LINE_THICKNESS = new FieldType("LINE_THICKNESS");
- public static readonly FieldType MAGNIFICATION_FACTOR = new FieldType("MAGNIFICATION_FACTOR");
- public static readonly FieldType PIXEL_SIZE = new FieldType("PIXEL_SIZE");
- public static readonly FieldType PREVIEW_QUALITY = new FieldType("PREVIEW_QUALITY");
- public static readonly FieldType SHADOW = new FieldType("SHADOW");
- public static readonly FieldType PREPARED_FILTER_OBFUSCATE = new FieldType("PREPARED_FILTER_OBFUSCATE");
- public static readonly FieldType PREPARED_FILTER_HIGHLIGHT = new FieldType("PREPARED_FILTER_HIGHLIGHT");
- public static readonly FieldType FLAGS = new FieldType("FLAGS");
-
- public static FieldType[] Values = new FieldType[]{
+ public class FieldType : IFieldType
+ {
+
+ public static readonly IFieldType ARROWHEADS = new FieldType("ARROWHEADS");
+ public static readonly IFieldType BLUR_RADIUS = new FieldType("BLUR_RADIUS");
+ public static readonly IFieldType BRIGHTNESS = new FieldType("BRIGHTNESS");
+ public static readonly IFieldType FILL_COLOR = new FieldType("FILL_COLOR");
+ public static readonly IFieldType FONT_BOLD = new FieldType("FONT_BOLD");
+ public static readonly IFieldType FONT_FAMILY = new FieldType("FONT_FAMILY");
+ public static readonly IFieldType FONT_ITALIC = new FieldType("FONT_ITALIC");
+ public static readonly IFieldType FONT_SIZE = new FieldType("FONT_SIZE");
+ public static readonly IFieldType TEXT_HORIZONTAL_ALIGNMENT = new FieldType("TEXT_HORIZONTAL_ALIGNMENT");
+ public static readonly IFieldType TEXT_VERTICAL_ALIGNMENT = new FieldType("TEXT_VERTICAL_ALIGNMENT");
+ public static readonly IFieldType HIGHLIGHT_COLOR = new FieldType("HIGHLIGHT_COLOR");
+ public static readonly IFieldType LINE_COLOR = new FieldType("LINE_COLOR");
+ public static readonly IFieldType LINE_THICKNESS = new FieldType("LINE_THICKNESS");
+ public static readonly IFieldType MAGNIFICATION_FACTOR = new FieldType("MAGNIFICATION_FACTOR");
+ public static readonly IFieldType PIXEL_SIZE = new FieldType("PIXEL_SIZE");
+ public static readonly IFieldType PREVIEW_QUALITY = new FieldType("PREVIEW_QUALITY");
+ public static readonly IFieldType SHADOW = new FieldType("SHADOW");
+ public static readonly IFieldType PREPARED_FILTER_OBFUSCATE = new FieldType("PREPARED_FILTER_OBFUSCATE");
+ public static readonly IFieldType PREPARED_FILTER_HIGHLIGHT = new FieldType("PREPARED_FILTER_HIGHLIGHT");
+ public static readonly IFieldType FLAGS = new FieldType("FLAGS");
+
+ public static IFieldType[] Values = new IFieldType[]{
ARROWHEADS,
BLUR_RADIUS,
BRIGHTNESS,
@@ -66,53 +69,55 @@ namespace Greenshot.Drawing.Fields {
MAGNIFICATION_FACTOR,
PIXEL_SIZE,
PREVIEW_QUALITY,
- SHADOW,
+ SHADOW,
PREPARED_FILTER_OBFUSCATE,
- PREPARED_FILTER_HIGHLIGHT,
+ PREPARED_FILTER_HIGHLIGHT,
FLAGS
};
-
- [Flags]
- public enum Flag {
- NONE = 0,
- CONFIRMABLE = 1
+
+ public string Name
+ {
+ get;
+ set;
}
-
-
- public string Name;
- private FieldType(string name) {
+
+ private FieldType(string name)
+ {
Name = name;
}
- public override string ToString() {
+ public override string ToString()
+ {
return Name;
}
public override int GetHashCode()
{
int hashCode = 0;
- unchecked {
+ unchecked
+ {
if (Name != null)
hashCode += 1000000009 * Name.GetHashCode();
}
return hashCode;
}
-
+
public override bool Equals(object obj)
{
FieldType other = obj as FieldType;
if (other == null)
+ {
return false;
- return Equals(Name,other.Name);
+ }
+ return Equals(Name, other.Name);
}
-
- public static bool operator ==(FieldType a, FieldType b) {
- return Equals(a,b);
+
+ public static bool operator ==(FieldType a, FieldType b)
+ {
+ return Equals(a, b);
}
-
- public static bool operator !=(FieldType a, FieldType b) {
- return !Equals(a,b);
+
+ public static bool operator !=(FieldType a, FieldType b)
+ {
+ return !Equals(a, b);
}
-
}
-
-
}
diff --git a/Greenshot/Drawing/Filters/IFilter.cs b/Greenshot/Drawing/Filters/IFilter.cs
index 5840e9650..f2ff0640c 100644
--- a/Greenshot/Drawing/Filters/IFilter.cs
+++ b/Greenshot/Drawing/Filters/IFilter.cs
@@ -21,11 +21,11 @@
using System.ComponentModel;
using System.Drawing;
-
-using Greenshot.Drawing.Fields;
using Greenshot.Plugin.Drawing;
+using GreenshotPlugin.Interfaces.Drawing;
-namespace Greenshot.Drawing.Filters {
+namespace Greenshot.Drawing.Filters
+{
public interface IFilter : INotifyPropertyChanged, IFieldHolder {
DrawableContainer Parent {get; set; }
void Apply(Graphics graphics, Bitmap bmp, Rectangle rect, RenderMode renderMode);
diff --git a/Greenshot/Drawing/HighlightContainer.cs b/Greenshot/Drawing/HighlightContainer.cs
index 5b8b783e2..fc871e4fe 100644
--- a/Greenshot/Drawing/HighlightContainer.cs
+++ b/Greenshot/Drawing/HighlightContainer.cs
@@ -23,6 +23,7 @@ using System.Runtime.Serialization;
using Greenshot.Drawing.Fields;
using Greenshot.Drawing.Filters;
+using GreenshotPlugin.Interfaces.Drawing;
namespace Greenshot.Drawing {
///
diff --git a/Greenshot/Drawing/ImageContainer.cs b/Greenshot/Drawing/ImageContainer.cs
index ca1742195..0b286fcea 100644
--- a/Greenshot/Drawing/ImageContainer.cs
+++ b/Greenshot/Drawing/ImageContainer.cs
@@ -28,6 +28,7 @@ using System.Drawing.Drawing2D;
using Greenshot.Core;
using log4net;
using System.Runtime.Serialization;
+using GreenshotPlugin.Interfaces.Drawing;
namespace Greenshot.Drawing {
///
diff --git a/Greenshot/Drawing/ObfuscateContainer.cs b/Greenshot/Drawing/ObfuscateContainer.cs
index 032291527..1805f86d2 100644
--- a/Greenshot/Drawing/ObfuscateContainer.cs
+++ b/Greenshot/Drawing/ObfuscateContainer.cs
@@ -22,6 +22,7 @@ using System;
using System.Runtime.Serialization;
using Greenshot.Drawing.Fields;
using Greenshot.Drawing.Filters;
+using GreenshotPlugin.Interfaces.Drawing;
namespace Greenshot.Drawing {
///
diff --git a/Greenshot/Drawing/SpeechbubbleContainer.cs b/Greenshot/Drawing/SpeechbubbleContainer.cs
index e86c52be5..e3e74e113 100644
--- a/Greenshot/Drawing/SpeechbubbleContainer.cs
+++ b/Greenshot/Drawing/SpeechbubbleContainer.cs
@@ -48,8 +48,8 @@ namespace Greenshot.Drawing
///
[OnSerializing]
private void SetValuesOnSerializing(StreamingContext context) {
- if (TargetGripper != null) {
- _storedTargetGripperLocation = TargetGripper.Location;
+ if (TargetAdorner != null) {
+ _storedTargetGripperLocation = TargetAdorner.Location;
}
}
@@ -59,7 +59,7 @@ namespace Greenshot.Drawing
///
protected override void OnDeserialized(StreamingContext context)
{
- InitTargetGripper(Color.Green, _storedTargetGripperLocation);
+ InitAdorner(Color.Green, _storedTargetGripperLocation);
}
#endregion
@@ -88,9 +88,9 @@ namespace Greenshot.Drawing
///
/// true if the surface doesn't need to handle the event
public override bool HandleMouseDown(int mouseX, int mouseY) {
- if (TargetGripper == null) {
+ if (TargetAdorner == null) {
_initialGripperPoint = new Point(mouseX, mouseY);
- InitTargetGripper(Color.Green, new Point(mouseX, mouseY));
+ InitAdorner(Color.Green, new Point(mouseX, mouseY));
}
return base.HandleMouseDown(mouseX, mouseY);
}
@@ -114,9 +114,9 @@ namespace Greenshot.Drawing
Point newGripperLocation = _initialGripperPoint;
newGripperLocation.Offset(xOffset, yOffset);
- if (TargetGripper.Location != newGripperLocation) {
+ if (TargetAdorner.Location != newGripperLocation) {
Invalidate();
- TargetGripper.Location = newGripperLocation;
+ TargetAdorner.Location = newGripperLocation;
Invalidate();
}
return returnValue;
@@ -178,7 +178,7 @@ namespace Greenshot.Drawing
private GraphicsPath CreateTail() {
Rectangle rect = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height);
- int tailLength = GeometryHelper.Distance2D(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2), TargetGripper.Location.X, TargetGripper.Location.Y);
+ int tailLength = GeometryHelper.Distance2D(rect.Left + (rect.Width / 2), rect.Top + (rect.Height / 2), TargetAdorner.Location.X, TargetAdorner.Location.Y);
int tailWidth = (Math.Abs(rect.Width) + Math.Abs(rect.Height)) / 20;
// This should fix a problem with the tail being to wide
@@ -190,7 +190,7 @@ namespace Greenshot.Drawing
tail.AddLine(tailWidth, 0, 0, -tailLength);
tail.CloseFigure();
- int tailAngle = 90 + (int)GeometryHelper.Angle2D(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2, TargetGripper.Location.X, TargetGripper.Location.Y);
+ int tailAngle = 90 + (int)GeometryHelper.Angle2D(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2, TargetAdorner.Location.X, TargetAdorner.Location.Y);
using (Matrix tailMatrix = new Matrix()) {
tailMatrix.Translate(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2);
@@ -207,7 +207,7 @@ namespace Greenshot.Drawing
///
///
public override void Draw(Graphics graphics, RenderMode renderMode) {
- if (TargetGripper == null) {
+ if (TargetAdorner == null) {
return;
}
graphics.SmoothingMode = SmoothingMode.HighQuality;
diff --git a/Greenshot/Drawing/StepLabelContainer.cs b/Greenshot/Drawing/StepLabelContainer.cs
index 636fd4540..45dce668e 100644
--- a/Greenshot/Drawing/StepLabelContainer.cs
+++ b/Greenshot/Drawing/StepLabelContainer.cs
@@ -94,6 +94,10 @@ namespace Greenshot.Drawing {
///
///
protected override void SwitchParent(Surface newParent) {
+ if (newParent == Parent)
+ {
+ return;
+ }
if (Parent != null) {
((Surface)Parent).RemoveStepLabel(this);
}
diff --git a/Greenshot/Drawing/Surface.cs b/Greenshot/Drawing/Surface.cs
index 13dec90c0..8b56d16f3 100644
--- a/Greenshot/Drawing/Surface.cs
+++ b/Greenshot/Drawing/Surface.cs
@@ -3,7 +3,7 @@
* Copyright (C) 2007-2015 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/
+ * The Greenshot project is hosted on GitHub https://github.com/greenshot/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
@@ -30,10 +30,10 @@ using Greenshot.Plugin.Drawing;
using Greenshot.Plugin.Drawing.Adorners;
using GreenshotPlugin.Controls;
using GreenshotPlugin.Core;
+using GreenshotPlugin.Interfaces.Drawing;
using log4net;
using System;
using System.Collections.Generic;
-using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
@@ -43,14 +43,14 @@ using System.Windows.Forms;
namespace Greenshot.Drawing
{
-
///
/// Description of Surface.
///
- public class Surface : Control, ISurface {
- private static readonly ILog LOG = LogManager.GetLogger(typeof(Surface));
- public static int Count;
- private static readonly CoreConfiguration conf = IniConfig.GetIniSection();
+ public class Surface : Control, ISurface
+ {
+ private static ILog LOG = LogManager.GetLogger(typeof(Surface));
+ public static int Count = 0;
+ private static CoreConfiguration conf = IniConfig.GetIniSection();
// Property to identify the Surface ID
private Guid _uniqueId = Guid.NewGuid();
@@ -58,11 +58,14 @@ namespace Greenshot.Drawing
///
/// The GUID of the surface
///
- public Guid ID {
- get {
+ public Guid ID
+ {
+ get
+ {
return _uniqueId;
}
- set {
+ set
+ {
_uniqueId = value;
}
}
@@ -72,41 +75,53 @@ namespace Greenshot.Drawing
///
[NonSerialized]
private SurfaceElementEventHandler _movingElementChanged;
- public event SurfaceElementEventHandler MovingElementChanged {
- add {
+ public event SurfaceElementEventHandler MovingElementChanged
+ {
+ add
+ {
_movingElementChanged += value;
}
- remove {
+ remove
+ {
_movingElementChanged -= value;
}
}
[NonSerialized]
private SurfaceDrawingModeEventHandler _drawingModeChanged;
- public event SurfaceDrawingModeEventHandler DrawingModeChanged {
- add {
+ public event SurfaceDrawingModeEventHandler DrawingModeChanged
+ {
+ add
+ {
_drawingModeChanged += value;
}
- remove {
+ remove
+ {
_drawingModeChanged -= value;
}
}
[NonSerialized]
private SurfaceSizeChangeEventHandler _surfaceSizeChanged;
- public event SurfaceSizeChangeEventHandler SurfaceSizeChanged {
- add {
+ public event SurfaceSizeChangeEventHandler SurfaceSizeChanged
+ {
+ add
+ {
_surfaceSizeChanged += value;
}
- remove {
+ remove
+ {
_surfaceSizeChanged -= value;
}
}
[NonSerialized]
private SurfaceMessageEventHandler _surfaceMessage;
- public event SurfaceMessageEventHandler SurfaceMessage {
- add {
+ public event SurfaceMessageEventHandler SurfaceMessage
+ {
+ add
+ {
_surfaceMessage += value;
}
- remove {
+ remove
+ {
_surfaceMessage -= value;
}
}
@@ -171,7 +186,7 @@ namespace Greenshot.Drawing
/// all selected elements, do not serialize
///
[NonSerialized]
- private readonly DrawableContainerList selectedElements;
+ private readonly IDrawableContainerList selectedElements;
///
/// the element we are drawing with, do not serialize
@@ -212,10 +227,15 @@ namespace Greenshot.Drawing
///
private readonly List _stepLabels = new List();
- public void AddStepLabel(StepLabelContainer stepLabel) {
- _stepLabels.Add(stepLabel);
+ public void AddStepLabel(StepLabelContainer stepLabel)
+ {
+ if (!_stepLabels.Contains(stepLabel))
+ {
+ _stepLabels.Add(stepLabel);
+ }
}
- public void RemoveStepLabel(StepLabelContainer stepLabel) {
+ public void RemoveStepLabel(StepLabelContainer stepLabel)
+ {
_stepLabels.Remove(stepLabel);
}
@@ -224,13 +244,17 @@ namespace Greenshot.Drawing
///
/// can be null, if not the counting stops here
/// number of steplabels before the supplied container
- public int CountStepLabels(IDrawableContainer stopAtContainer) {
+ public int CountStepLabels(IDrawableContainer stopAtContainer)
+ {
int number = 1;
- foreach (var possibleThis in _stepLabels) {
- if (possibleThis.Equals(stopAtContainer)) {
+ foreach (var possibleThis in _stepLabels)
+ {
+ if (possibleThis.Equals(stopAtContainer))
+ {
break;
}
- if (IsOnSurface(possibleThis)) {
+ if (IsOnSurface(possibleThis))
+ {
number++;
}
}
@@ -240,12 +264,12 @@ namespace Greenshot.Drawing
///
/// all elements on the surface, needed with serialization
///
- private readonly DrawableContainerList _elements;
+ private readonly IDrawableContainerList _elements;
///
/// all elements on the surface, needed with serialization
///
- private FieldAggregator _fieldAggregator = new FieldAggregator();
+ private FieldAggregator _fieldAggregator;
///
/// the cursor container, needed with serialization as we need a direct acces to it.
@@ -269,11 +293,14 @@ namespace Greenshot.Drawing
/// The image is the actual captured image, needed with serialization
///
private Image _image;
- public Image Image {
- get {
+ public Image Image
+ {
+ get
+ {
return _image;
}
- set {
+ set
+ {
_image = value;
Size = _image.Size;
}
@@ -283,11 +310,14 @@ namespace Greenshot.Drawing
/// The field aggregator is that which is used to have access to all the fields inside the currently selected elements.
/// e.g. used to decided if and which line thickness is shown when multiple elements are selected.
///
- public FieldAggregator FieldAggregator {
- get {
+ public FieldAggregator FieldAggregator
+ {
+ get
+ {
return _fieldAggregator;
}
- set {
+ set
+ {
_fieldAggregator = value;
}
}
@@ -295,8 +325,10 @@ namespace Greenshot.Drawing
///
/// The cursor container has it's own accessor so we can find and remove this (when needed)
///
- public IDrawableContainer CursorContainer {
- get {
+ public IDrawableContainer CursorContainer
+ {
+ get
+ {
return _cursorContainer;
}
}
@@ -304,8 +336,10 @@ namespace Greenshot.Drawing
///
/// A simple getter to ask if this surface has a cursor
///
- public bool HasCursor {
- get {
+ public bool HasCursor
+ {
+ get
+ {
return _cursorContainer != null;
}
}
@@ -313,7 +347,8 @@ namespace Greenshot.Drawing
///
/// A simple helper method to remove the cursor from the surface
///
- public void RemoveCursor() {
+ public void RemoveCursor()
+ {
RemoveElement(_cursorContainer, true);
_cursorContainer = null;
}
@@ -321,11 +356,14 @@ namespace Greenshot.Drawing
///
/// The brush which is used to draw the transparent background
///
- public Brush TransparencyBackgroundBrush {
- get {
+ public Brush TransparencyBackgroundBrush
+ {
+ get
+ {
return _transparencyBackgroundBrush;
}
- set {
+ set
+ {
_transparencyBackgroundBrush = value;
}
}
@@ -333,11 +371,14 @@ namespace Greenshot.Drawing
///
/// Are the keys on this surface locked?
///
- public bool KeysLocked {
- get {
+ public bool KeysLocked
+ {
+ get
+ {
return _keysLocked;
}
- set {
+ set
+ {
_keysLocked = value;
}
}
@@ -345,11 +386,14 @@ namespace Greenshot.Drawing
///
/// Is this surface modified? This is only true if the surface has not been exported.
///
- public bool Modified {
- get {
+ public bool Modified
+ {
+ get
+ {
return _modified;
}
- set {
+ set
+ {
_modified = value;
}
}
@@ -357,11 +401,14 @@ namespace Greenshot.Drawing
///
/// The DrawingMode property specifies the mode for drawing, more or less the element type.
///
- public DrawingModes DrawingMode {
- get {return _drawingMode;}
- set {
+ public DrawingModes DrawingMode
+ {
+ get { return _drawingMode; }
+ set
+ {
_drawingMode = value;
- if (_drawingModeChanged != null) {
+ if (_drawingModeChanged != null)
+ {
SurfaceDrawingModeEventArgs eventArgs = new SurfaceDrawingModeEventArgs();
eventArgs.DrawingMode = _drawingMode;
_drawingModeChanged.Invoke(this, eventArgs);
@@ -374,11 +421,14 @@ namespace Greenshot.Drawing
///
/// Property for accessing the last save "full" path
///
- public string LastSaveFullPath {
- get {
+ public string LastSaveFullPath
+ {
+ get
+ {
return _lastSaveFullPath;
}
- set {
+ set
+ {
_lastSaveFullPath = value;
}
}
@@ -386,7 +436,8 @@ namespace Greenshot.Drawing
///
/// Property for accessing the URL to which the surface was recently uploaded
///
- public string UploadURL {
+ public string UploadURL
+ {
get;
set;
}
@@ -394,11 +445,14 @@ namespace Greenshot.Drawing
///
/// Property for accessing the capture details
///
- public ICaptureDetails CaptureDetails {
- get {
+ public ICaptureDetails CaptureDetails
+ {
+ get
+ {
return _captureDetails;
}
- set {
+ set
+ {
_captureDetails = value;
}
}
@@ -406,7 +460,9 @@ namespace Greenshot.Drawing
///
/// Base Surface constructor
///
- public Surface() : base(){
+ public Surface() : base()
+ {
+ _fieldAggregator = new FieldAggregator(this);
Count++;
_elements = new DrawableContainerList(_uniqueId);
selectedElements = new DrawableContainerList(_uniqueId);
@@ -429,15 +485,17 @@ namespace Greenshot.Drawing
DoubleBuffered = true;
SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.ContainerControl | ControlStyles.OptimizedDoubleBuffer | ControlStyles.SupportsTransparentBackColor, true);
}
-
+
///
/// Private method, the current image is disposed the new one will stay.
///
/// The new image
/// true if the old image needs to be disposed, when using undo this should not be true!!
- private void SetImage(Image newImage, bool dispose) {
+ private void SetImage(Image newImage, bool dispose)
+ {
// Dispose
- if (_image != null && dispose) {
+ if (_image != null && dispose)
+ {
_image.Dispose();
}
@@ -452,7 +510,8 @@ namespace Greenshot.Drawing
/// Surface constructor with an image
///
///
- public Surface(Image newImage) : this() {
+ public Surface(Image newImage) : this()
+ {
LOG.DebugFormat("Got image with dimensions {0} and format {1}", newImage.Size, newImage.PixelFormat);
SetImage(newImage, true);
}
@@ -461,13 +520,16 @@ namespace Greenshot.Drawing
/// Surface contructor with a capture
///
///
- public Surface(ICapture capture) : this(capture.Image) {
+ public Surface(ICapture capture) : this(capture.Image)
+ {
// check if cursor is captured, and visible
- if (capture.Cursor != null && capture.CursorVisible) {
+ if (capture.Cursor != null && capture.CursorVisible)
+ {
Rectangle cursorRect = new Rectangle(capture.CursorLocation, capture.Cursor.Size);
Rectangle captureRect = new Rectangle(Point.Empty, capture.Image.Size);
// check if cursor is on the capture, otherwise we leave it out.
- if (cursorRect.IntersectsWith(captureRect)) {
+ if (cursorRect.IntersectsWith(captureRect))
+ {
_cursorContainer = AddIconContainer(capture.Cursor, capture.CursorLocation.X, capture.CursorLocation.Y);
SelectElement(_cursorContainer);
}
@@ -478,34 +540,43 @@ namespace Greenshot.Drawing
_captureDetails = capture.CaptureDetails;
}
- protected override void Dispose(bool disposing) {
- if (disposing) {
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
Count--;
LOG.Debug("Disposing surface!");
- if (_buffer != null) {
+ if (_buffer != null)
+ {
_buffer.Dispose();
_buffer = null;
}
- if (_transparencyBackgroundBrush != null) {
+ if (_transparencyBackgroundBrush != null)
+ {
_transparencyBackgroundBrush.Dispose();
_transparencyBackgroundBrush = null;
}
// Cleanup undo/redo stacks
- while (_undoStack != null && _undoStack.Count > 0) {
+ while (_undoStack != null && _undoStack.Count > 0)
+ {
_undoStack.Pop().Dispose();
}
- while (_redoStack != null && _redoStack.Count > 0) {
+ while (_redoStack != null && _redoStack.Count > 0)
+ {
_redoStack.Pop().Dispose();
}
- foreach (IDrawableContainer container in _elements) {
+ foreach (IDrawableContainer container in _elements)
+ {
container.Dispose();
}
- if (_undrawnElement != null) {
+ if (_undrawnElement != null)
+ {
_undrawnElement.Dispose();
_undrawnElement = null;
}
- if (_cropContainer != null) {
+ if (_cropContainer != null)
+ {
_cropContainer.Dispose();
_cropContainer = null;
}
@@ -516,32 +587,38 @@ namespace Greenshot.Drawing
///
/// Undo the last action
///
- public void Undo() {
- if (_undoStack.Count > 0) {
+ public void Undo()
+ {
+ if (_undoStack.Count > 0)
+ {
_inUndoRedo = true;
IMemento top = _undoStack.Pop();
_redoStack.Push(top.Restore());
_inUndoRedo = false;
}
- }
+ }
///
/// Undo an undo (=redo)
///
- public void Redo() {
- if (_redoStack.Count > 0) {
+ public void Redo()
+ {
+ if (_redoStack.Count > 0)
+ {
_inUndoRedo = true;
IMemento top = _redoStack.Pop();
_undoStack.Push(top.Restore());
_inUndoRedo = false;
}
}
-
+
///
/// Returns if the surface can do a undo
///
- public bool CanUndo {
- get {
+ public bool CanUndo
+ {
+ get
+ {
return _undoStack.Count > 0;
}
}
@@ -549,8 +626,10 @@ namespace Greenshot.Drawing
///
/// Returns if the surface can do a redo
///
- public bool CanRedo {
- get {
+ public bool CanRedo
+ {
+ get
+ {
return _redoStack.Count > 0;
}
}
@@ -558,11 +637,10 @@ namespace Greenshot.Drawing
///
/// Get the language key for the undo action
///
- public LangKey UndoActionLanguageKey {
- get {
- if (CanUndo) {
- return _undoStack.Peek().ActionLanguageKey;
- }
+ public LangKey UndoActionLanguageKey
+ {
+ get
+ {
return LangKey.none;
}
}
@@ -570,11 +648,10 @@ namespace Greenshot.Drawing
///
/// Get the language key for redo action
///
- public LangKey RedoActionLanguageKey {
- get {
- if (CanRedo) {
- return _redoStack.Peek().ActionLanguageKey;
- }
+ public LangKey RedoActionLanguageKey
+ {
+ get
+ {
return LangKey.none;
}
}
@@ -584,19 +661,25 @@ namespace Greenshot.Drawing
///
/// The memento implementing the undo
/// Allow changes to be merged
- public void MakeUndoable(IMemento memento, bool allowMerge) {
- if (_inUndoRedo) {
+ public void MakeUndoable(IMemento memento, bool allowMerge)
+ {
+ if (_inUndoRedo)
+ {
throw new InvalidOperationException("Invoking do within an undo/redo action.");
}
- if (memento != null) {
+ if (memento != null)
+ {
bool allowPush = true;
- if (_undoStack.Count > 0 && allowMerge) {
+ if (_undoStack.Count > 0 && allowMerge)
+ {
// Check if merge is possible
allowPush = !_undoStack.Peek().Merge(memento);
}
- if (allowPush) {
+ if (allowPush)
+ {
// Clear the redo-stack and dispose
- while(_redoStack.Count > 0) {
+ while (_redoStack.Count > 0)
+ {
_redoStack.Pop().Dispose();
}
_undoStack.Push(memento);
@@ -610,14 +693,18 @@ namespace Greenshot.Drawing
///
///
///
- public long SaveElementsToStream(Stream streamWrite) {
+ public long SaveElementsToStream(Stream streamWrite)
+ {
long bytesWritten = 0;
- try {
+ try
+ {
long lengtBefore = streamWrite.Length;
BinaryFormatter binaryWrite = new BinaryFormatter();
binaryWrite.Serialize(streamWrite, _elements);
bytesWritten = streamWrite.Length - lengtBefore;
- } catch (Exception e) {
+ }
+ catch (Exception e)
+ {
LOG.Error("Error serializing elements to stream.", e);
}
return bytesWritten;
@@ -627,20 +714,24 @@ namespace Greenshot.Drawing
/// This loads elements from a stream, among others this is used to load a surface.
///
///
- public void LoadElementsFromStream(Stream streamRead) {
- try {
+ public void LoadElementsFromStream(Stream streamRead)
+ {
+ try
+ {
BinaryFormatter binaryRead = new BinaryFormatter();
- DrawableContainerList loadedElements = (DrawableContainerList) binaryRead.Deserialize(streamRead);
+ IDrawableContainerList loadedElements = (IDrawableContainerList)binaryRead.Deserialize(streamRead);
loadedElements.Parent = this;
// Make sure the steplabels are sorted accoring to their number
- _stepLabels.Sort(delegate(StepLabelContainer p1, StepLabelContainer p2) {
+ _stepLabels.Sort(delegate (StepLabelContainer p1, StepLabelContainer p2) {
return p1.Number.CompareTo(p2.Number);
});
DeselectAllElements();
AddElements(loadedElements);
SelectElements(loadedElements);
FieldAggregator.BindElements(loadedElements);
- } catch (Exception e) {
+ }
+ catch (Exception e)
+ {
LOG.Error("Error serializing elements from stream.", e);
}
}
@@ -650,11 +741,14 @@ namespace Greenshot.Drawing
/// But here an element is created which is not yet draw, thus "undrawnElement".
/// The element is than used while drawing on the surface.
///
- private void CreateUndrawnElement() {
- if(_undrawnElement != null) {
+ private void CreateUndrawnElement()
+ {
+ if (_undrawnElement != null)
+ {
FieldAggregator.UnbindElement(_undrawnElement);
}
- switch (DrawingMode) {
+ switch (DrawingMode)
+ {
case DrawingModes.Rect:
_undrawnElement = new RectangleContainer(this);
break;
@@ -696,13 +790,15 @@ namespace Greenshot.Drawing
_undrawnElement = null;
break;
}
- if (_undrawnElement != null) {
+ if (_undrawnElement != null)
+ {
FieldAggregator.BindElement(_undrawnElement);
}
}
#region Plugin interface implementations
- public IImageContainer AddImageContainer(Image image, int x, int y) {
+ public IImageContainer AddImageContainer(Image image, int x, int y)
+ {
ImageContainer bitmapContainer = new ImageContainer(this);
bitmapContainer.Image = image;
bitmapContainer.Left = x;
@@ -711,7 +807,8 @@ namespace Greenshot.Drawing
return bitmapContainer;
}
- public IImageContainer AddImageContainer(string filename, int x, int y) {
+ public IImageContainer AddImageContainer(string filename, int x, int y)
+ {
ImageContainer bitmapContainer = new ImageContainer(this);
bitmapContainer.Load(filename);
bitmapContainer.Left = x;
@@ -719,7 +816,8 @@ namespace Greenshot.Drawing
AddElement(bitmapContainer);
return bitmapContainer;
}
- public IIconContainer AddIconContainer(Icon icon, int x, int y) {
+ public IIconContainer AddIconContainer(Icon icon, int x, int y)
+ {
IconContainer iconContainer = new IconContainer(this);
iconContainer.Icon = icon;
iconContainer.Left = x;
@@ -727,7 +825,8 @@ namespace Greenshot.Drawing
AddElement(iconContainer);
return iconContainer;
}
- public IIconContainer AddIconContainer(string filename, int x, int y) {
+ public IIconContainer AddIconContainer(string filename, int x, int y)
+ {
IconContainer iconContainer = new IconContainer(this);
iconContainer.Load(filename);
iconContainer.Left = x;
@@ -735,7 +834,8 @@ namespace Greenshot.Drawing
AddElement(iconContainer);
return iconContainer;
}
- public ICursorContainer AddCursorContainer(Cursor cursor, int x, int y) {
+ public ICursorContainer AddCursorContainer(Cursor cursor, int x, int y)
+ {
CursorContainer cursorContainer = new CursorContainer(this);
cursorContainer.Cursor = cursor;
cursorContainer.Left = x;
@@ -743,7 +843,8 @@ namespace Greenshot.Drawing
AddElement(cursorContainer);
return cursorContainer;
}
- public ICursorContainer AddCursorContainer(string filename, int x, int y) {
+ public ICursorContainer AddCursorContainer(string filename, int x, int y)
+ {
CursorContainer cursorContainer = new CursorContainer(this);
cursorContainer.Load(filename);
cursorContainer.Left = x;
@@ -752,7 +853,8 @@ namespace Greenshot.Drawing
return cursorContainer;
}
- public ITextContainer AddTextContainer(string text, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment, FontFamily family, float size, bool italic, bool bold, bool shadow, int borderSize, Color color, Color fillColor) {
+ public ITextContainer AddTextContainer(string text, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment, FontFamily family, float size, bool italic, bool bold, bool shadow, int borderSize, Color color, Color fillColor)
+ {
TextContainer textContainer = new TextContainer(this);
textContainer.Text = text;
textContainer.SetFieldValue(FieldType.FONT_FAMILY, family.Name);
@@ -776,19 +878,28 @@ namespace Greenshot.Drawing
#region DragDrop
- private void OnDragEnter(object sender, DragEventArgs e) {
- if(LOG.IsDebugEnabled) {
+ private void OnDragEnter(object sender, DragEventArgs e)
+ {
+ if (LOG.IsDebugEnabled)
+ {
LOG.Debug("DragEnter got following formats: ");
- foreach(string format in ClipboardHelper.GetFormats(e.Data)) {
+ foreach (string format in ClipboardHelper.GetFormats(e.Data))
+ {
LOG.Debug(format);
}
}
- if ((e.AllowedEffect & DragDropEffects.Copy) != DragDropEffects.Copy) {
- e.Effect=DragDropEffects.None;
- } else {
- if (ClipboardHelper.ContainsImage(e.Data) || ClipboardHelper.ContainsFormat(e.Data, "DragImageBits")) {
+ if ((e.AllowedEffect & DragDropEffects.Copy) != DragDropEffects.Copy)
+ {
+ e.Effect = DragDropEffects.None;
+ }
+ else
+ {
+ if (ClipboardHelper.ContainsImage(e.Data) || ClipboardHelper.ContainsFormat(e.Data, "DragImageBits"))
+ {
e.Effect = DragDropEffects.Copy;
- } else {
+ }
+ else
+ {
e.Effect = DragDropEffects.None;
}
}
@@ -799,14 +910,19 @@ namespace Greenshot.Drawing
///
///
///
- private void OnDragDrop(object sender, DragEventArgs e) {
+ private void OnDragDrop(object sender, DragEventArgs e)
+ {
Point mouse = PointToClient(new Point(e.X, e.Y));
- if (e.Data.GetDataPresent("Text")) {
+ if (e.Data.GetDataPresent("Text"))
+ {
string possibleUrl = ClipboardHelper.GetText(e.Data);
// Test if it's an url and try to download the image so we have it in the original form
- if (possibleUrl != null && possibleUrl.StartsWith("http")) {
- using (Image image = NetworkHelper.DownloadImage(possibleUrl)) {
- if (image != null) {
+ if (possibleUrl != null && possibleUrl.StartsWith("http"))
+ {
+ using (Image image = NetworkHelper.DownloadImage(possibleUrl))
+ {
+ if (image != null)
+ {
AddImageContainer(image, mouse.X, mouse.Y);
return;
}
@@ -814,25 +930,29 @@ namespace Greenshot.Drawing
}
}
- foreach (Image image in ClipboardHelper.GetImages(e.Data)) {
+ foreach (Image image in ClipboardHelper.GetImages(e.Data))
+ {
AddImageContainer(image, mouse.X, mouse.Y);
mouse.Offset(10, 10);
image.Dispose();
}
}
-
+
#endregion
///
/// Auto crop the image
///
/// true if cropped
- public bool AutoCrop() {
+ public bool AutoCrop()
+ {
Rectangle cropRectangle;
- using (Image tmpImage = GetImageForExport()) {
+ using (Image tmpImage = GetImageForExport())
+ {
cropRectangle = ImageHelper.FindAutoCropRectangle(tmpImage, conf.AutoCropDifference);
}
- if (!IsCropPossible(ref cropRectangle)) {
+ if (!IsCropPossible(ref cropRectangle))
+ {
return false;
}
DeselectAllElements();
@@ -855,10 +975,12 @@ namespace Greenshot.Drawing
/// A simple clear
///
/// The color for the background
- public void Clear(Color newColor) {
+ public void Clear(Color newColor)
+ {
//create a blank bitmap the same size as original
Bitmap newBitmap = ImageHelper.CreateEmptyLike(Image, Color.Empty);
- if (newBitmap != null) {
+ if (newBitmap != null)
+ {
// Make undoable
MakeUndoable(new SurfaceBackgroundChangeMemento(this, null), false);
SetImage(newBitmap, false);
@@ -870,29 +992,37 @@ namespace Greenshot.Drawing
/// Apply a bitmap effect to the surface
///
///
- public void ApplyBitmapEffect(IEffect effect) {
+ public void ApplyBitmapEffect(IEffect effect)
+ {
BackgroundForm backgroundForm = new BackgroundForm("Effect", "Please wait");
backgroundForm.Show();
Application.DoEvents();
- try {
+ try
+ {
Rectangle imageRectangle = new Rectangle(Point.Empty, Image.Size);
Matrix matrix = new Matrix();
Image newImage = ImageHelper.ApplyEffect(Image, effect, matrix);
- if (newImage != null) {
+ if (newImage != null)
+ {
// Make sure the elements move according to the offset the effect made the bitmap move
_elements.Transform(matrix);
// Make undoable
MakeUndoable(new SurfaceBackgroundChangeMemento(this, matrix), false);
SetImage(newImage, false);
Invalidate();
- if (_surfaceSizeChanged != null && !imageRectangle.Equals(new Rectangle(Point.Empty, newImage.Size))) {
+ if (_surfaceSizeChanged != null && !imageRectangle.Equals(new Rectangle(Point.Empty, newImage.Size)))
+ {
_surfaceSizeChanged(this, null);
}
- } else {
+ }
+ else
+ {
// clean up matrix, as it hasn't been used in the undo stack.
matrix.Dispose();
}
- } finally {
+ }
+ finally
+ {
// Always close the background form
backgroundForm.CloseDialog();
}
@@ -903,34 +1033,42 @@ namespace Greenshot.Drawing
///
///
/// true if this is possible
- public bool IsCropPossible(ref Rectangle cropRectangle) {
+ public bool IsCropPossible(ref Rectangle cropRectangle)
+ {
cropRectangle = GuiRectangle.GetGuiRectangle(cropRectangle.Left, cropRectangle.Top, cropRectangle.Width, cropRectangle.Height);
- if (cropRectangle.Left < 0) {
+ if (cropRectangle.Left < 0)
+ {
cropRectangle = new Rectangle(0, cropRectangle.Top, cropRectangle.Width + cropRectangle.Left, cropRectangle.Height);
}
- if (cropRectangle.Top < 0) {
+ if (cropRectangle.Top < 0)
+ {
cropRectangle = new Rectangle(cropRectangle.Left, 0, cropRectangle.Width, cropRectangle.Height + cropRectangle.Top);
}
- if (cropRectangle.Left + cropRectangle.Width > Width) {
+ if (cropRectangle.Left + cropRectangle.Width > Width)
+ {
cropRectangle = new Rectangle(cropRectangle.Left, cropRectangle.Top, Width - cropRectangle.Left, cropRectangle.Height);
}
- if (cropRectangle.Top + cropRectangle.Height > Height) {
+ if (cropRectangle.Top + cropRectangle.Height > Height)
+ {
cropRectangle = new Rectangle(cropRectangle.Left, cropRectangle.Top, cropRectangle.Width, Height - cropRectangle.Top);
}
- if (cropRectangle.Height > 0 && cropRectangle.Width > 0) {
+ if (cropRectangle.Height > 0 && cropRectangle.Width > 0)
+ {
return true;
}
return false;
}
-
+
///
/// Use to send any registered SurfaceMessageEventHandler a message, e.g. used for the notification area
///
/// Who send
/// Type of message
/// Message itself
- public void SendMessageEvent(object source, SurfaceMessageTyp messageType, string message) {
- if (_surfaceMessage != null) {
+ public void SendMessageEvent(object source, SurfaceMessageTyp messageType, string message)
+ {
+ if (_surfaceMessage != null)
+ {
SurfaceMessageEventArgs eventArgs = new SurfaceMessageEventArgs();
eventArgs.Message = message;
eventArgs.MessageType = messageType;
@@ -944,14 +1082,19 @@ namespace Greenshot.Drawing
///
///
///
- public bool ApplyCrop(Rectangle cropRectangle) {
- if (IsCropPossible(ref cropRectangle)) {
+ public bool ApplyCrop(Rectangle cropRectangle)
+ {
+ if (IsCropPossible(ref cropRectangle))
+ {
Rectangle imageRectangle = new Rectangle(Point.Empty, Image.Size);
Bitmap tmpImage;
// Make sure we have information, this this fails
- try {
+ try
+ {
tmpImage = ImageHelper.CloneArea(Image, cropRectangle, PixelFormat.DontCare);
- } catch (Exception ex) {
+ }
+ catch (Exception ex)
+ {
ex.Data.Add("CropRectangle", cropRectangle);
ex.Data.Add("Width", Image.Width);
ex.Data.Add("Height", Image.Height);
@@ -967,7 +1110,8 @@ namespace Greenshot.Drawing
// Do not dispose otherwise we can't undo the image!
SetImage(tmpImage, false);
_elements.Transform(matrix);
- if (_surfaceSizeChanged != null && !imageRectangle.Equals(new Rectangle(Point.Empty, tmpImage.Size))) {
+ if (_surfaceSizeChanged != null && !imageRectangle.Equals(new Rectangle(Point.Empty, tmpImage.Size)))
+ {
_surfaceSizeChanged(this, null);
}
Invalidate();
@@ -982,17 +1126,19 @@ namespace Greenshot.Drawing
///
///
///
- public void UndoBackgroundChange(Image previous, Matrix matrix) {
+ public void UndoBackgroundChange(Image previous, Matrix matrix)
+ {
SetImage(previous, false);
- if (matrix != null) {
+ if (matrix != null)
+ {
_elements.Transform(matrix);
}
- if (_surfaceSizeChanged != null) {
+ if (_surfaceSizeChanged != null)
+ {
_surfaceSizeChanged(this, null);
}
Invalidate();
}
-
///
/// Check if an adorner was "hit", and change the cursor if so
///
@@ -1000,11 +1146,11 @@ namespace Greenshot.Drawing
/// IAdorner
private IAdorner FindActiveAdorner(MouseEventArgs mouseEventArgs)
{
- foreach(IDrawableContainer drawableContainer in selectedElements)
+ foreach (IDrawableContainer drawableContainer in selectedElements)
{
- foreach(IAdorner adorner in drawableContainer.Adorners)
+ foreach (IAdorner adorner in drawableContainer.Adorners)
{
-
+
if (adorner.IsActive || adorner.HitTest(mouseEventArgs.Location))
{
if (adorner.Cursor != null)
@@ -1023,7 +1169,8 @@ namespace Greenshot.Drawing
///
///
///
- void SurfaceMouseDown(object sender, MouseEventArgs e) {
+ void SurfaceMouseDown(object sender, MouseEventArgs e)
+ {
// Handle Adorners
var adorner = FindActiveAdorner(e);
@@ -1034,21 +1181,27 @@ namespace Greenshot.Drawing
}
_mouseStart = e.Location;
-
+
// check contextmenu
- if (e.Button == MouseButtons.Right) {
- DrawableContainerList selectedList = null;
- if (selectedElements != null && selectedElements.Count > 0) {
+ if (e.Button == MouseButtons.Right)
+ {
+ IDrawableContainerList selectedList = null;
+ if (selectedElements != null && selectedElements.Count > 0)
+ {
selectedList = selectedElements;
- } else {
+ }
+ else
+ {
// Single element
IDrawableContainer rightClickedContainer = _elements.ClickableElementAt(_mouseStart.X, _mouseStart.Y);
- if (rightClickedContainer != null) {
+ if (rightClickedContainer != null)
+ {
selectedList = new DrawableContainerList(ID);
selectedList.Add(rightClickedContainer);
}
}
- if (selectedList != null && selectedList.Count > 0) {
+ if (selectedList != null && selectedList.Count > 0)
+ {
selectedList.ShowContextMenu(e, this);
}
return;
@@ -1057,28 +1210,30 @@ namespace Greenshot.Drawing
_mouseDown = true;
_isSurfaceMoveMadeUndoable = false;
- if (_cropContainer != null && ((_undrawnElement == null) || (_undrawnElement != null && DrawingMode != DrawingModes.Crop))) {
+ if (_cropContainer != null && ((_undrawnElement == null) || (_undrawnElement != null && DrawingMode != DrawingModes.Crop)))
+ {
RemoveElement(_cropContainer, false);
_cropContainer = null;
_drawingElement = null;
}
- if (_drawingElement == null && DrawingMode != DrawingModes.None) {
- if (_undrawnElement == null) {
+ if (_drawingElement == null && DrawingMode != DrawingModes.None)
+ {
+ if (_undrawnElement == null)
+ {
DeselectAllElements();
- if (_undrawnElement == null) {
+ if (_undrawnElement == null)
+ {
CreateUndrawnElement();
}
}
_drawingElement = _undrawnElement;
// if a new element has been drawn, set location and register it
- if (_drawingElement != null) {
- if (_undrawnElement != null)
+ if (_drawingElement != null)
+ {
+ _drawingElement.Status = _undrawnElement.DefaultEditMode;
+ if (!_drawingElement.HandleMouseDown(_mouseStart.X, _mouseStart.Y))
{
- _drawingElement.Status = _undrawnElement.DefaultEditMode;
- }
- _drawingElement.PropertyChanged += ElementPropertyChanged;
- if (!_drawingElement.HandleMouseDown(_mouseStart.X, _mouseStart.Y)) {
_drawingElement.Left = _mouseStart.X;
_drawingElement.Top = _mouseStart.Y;
}
@@ -1086,13 +1241,16 @@ namespace Greenshot.Drawing
_drawingElement.Selected = true;
}
_undrawnElement = null;
- } else {
+ }
+ else
+ {
// check whether an existing element was clicked
// we save mouse down element separately from selectedElements (checked on mouse up),
// since it could be moved around before it is actually selected
_mouseDownElement = _elements.ClickableElementAt(_mouseStart.X, _mouseStart.Y);
- if (_mouseDownElement != null) {
+ if (_mouseDownElement != null)
+ {
_mouseDownElement.Status = EditStatus.MOVING;
}
}
@@ -1103,7 +1261,8 @@ namespace Greenshot.Drawing
///
///
///
- void SurfaceMouseUp(object sender, MouseEventArgs e) {
+ void SurfaceMouseUp(object sender, MouseEventArgs e)
+ {
// Handle Adorners
var adorner = FindActiveAdorner(e);
@@ -1116,48 +1275,66 @@ namespace Greenshot.Drawing
Point currentMouse = new Point(e.X, e.Y);
_elements.Status = EditStatus.IDLE;
- if (_mouseDownElement != null) {
+ if (_mouseDownElement != null)
+ {
_mouseDownElement.Status = EditStatus.IDLE;
}
_mouseDown = false;
_mouseDownElement = null;
- if (DrawingMode == DrawingModes.None) {
+ if (DrawingMode == DrawingModes.None)
+ {
// check whether an existing element was clicked
IDrawableContainer element = _elements.ClickableElementAt(currentMouse.X, currentMouse.Y);
bool shiftModifier = (ModifierKeys & Keys.Shift) == Keys.Shift;
- if (element != null) {
+ if (element != null)
+ {
element.Invalidate();
bool alreadySelected = selectedElements.Contains(element);
- if (shiftModifier) {
- if (alreadySelected) {
+ if (shiftModifier)
+ {
+ if (alreadySelected)
+ {
DeselectElement(element);
- } else {
+ }
+ else
+ {
SelectElement(element);
}
- } else {
- if (!alreadySelected) {
+ }
+ else
+ {
+ if (!alreadySelected)
+ {
DeselectAllElements();
SelectElement(element);
}
}
- } else if(!shiftModifier) {
+ }
+ else if (!shiftModifier)
+ {
DeselectAllElements();
}
}
-
- if (selectedElements.Count > 0) {
+
+ if (selectedElements.Count > 0)
+ {
selectedElements.Invalidate();
selectedElements.Selected = true;
}
- if (_drawingElement != null) {
- if (!_drawingElement.InitContent()) {
+ if (_drawingElement != null)
+ {
+ if (!_drawingElement.InitContent())
+ {
_elements.Remove(_drawingElement);
_drawingElement.Invalidate();
- } else {
+ }
+ else
+ {
_drawingElement.HandleMouseUp(currentMouse.X, currentMouse.Y);
_drawingElement.Invalidate();
- if (Math.Abs(_drawingElement.Width) < 5 && Math.Abs(_drawingElement.Height) < 5) {
+ if (Math.Abs(_drawingElement.Width) < 5 && Math.Abs(_drawingElement.Height) < 5)
+ {
_drawingElement.Width = 25;
_drawingElement.Height = 25;
}
@@ -1173,7 +1350,8 @@ namespace Greenshot.Drawing
///
///
///
- void SurfaceMouseMove(object sender, MouseEventArgs e) {
+ void SurfaceMouseMove(object sender, MouseEventArgs e)
+ {
// Handle Adorners
var adorner = FindActiveAdorner(e);
if (adorner != null)
@@ -1184,27 +1362,37 @@ namespace Greenshot.Drawing
Point currentMouse = e.Location;
- if (DrawingMode != DrawingModes.None) {
+ if (DrawingMode != DrawingModes.None)
+ {
Cursor = Cursors.Cross;
- } else {
+ }
+ else
+ {
Cursor = Cursors.Default;
}
- if (_mouseDown) {
- if (_mouseDownElement != null) { // an element is currently dragged
+ if (_mouseDown)
+ {
+ if (_mouseDownElement != null)
+ { // an element is currently dragged
_mouseDownElement.Invalidate();
selectedElements.Invalidate();
// Move the element
- if (_mouseDownElement.Selected) {
- if (!_isSurfaceMoveMadeUndoable) {
+ if (_mouseDownElement.Selected)
+ {
+ if (!_isSurfaceMoveMadeUndoable)
+ {
// Only allow one undoable per mouse-down/move/up "cycle"
_isSurfaceMoveMadeUndoable = true;
selectedElements.MakeBoundsChangeUndoable(false);
}
// dragged element has been selected before -> move all
selectedElements.MoveBy(currentMouse.X - _mouseStart.X, currentMouse.Y - _mouseStart.Y);
- } else {
- if (!_isSurfaceMoveMadeUndoable) {
+ }
+ else
+ {
+ if (!_isSurfaceMoveMadeUndoable)
+ {
// Only allow one undoable per mouse-down/move/up "cycle"
_isSurfaceMoveMadeUndoable = true;
_mouseDownElement.MakeBoundsChangeUndoable(false);
@@ -1215,19 +1403,22 @@ namespace Greenshot.Drawing
_mouseStart = currentMouse;
_mouseDownElement.Invalidate();
_modified = true;
- } else if (_drawingElement != null) {
+ }
+ else if (_drawingElement != null)
+ {
_drawingElement.HandleMouseMove(currentMouse.X, currentMouse.Y);
_modified = true;
}
}
}
-
+
///
/// This event handler is called when the surface is double clicked.
///
///
///
- void SurfaceDoubleClick(object sender, MouseEventArgs e) {
+ void SurfaceDoubleClick(object sender, MouseEventArgs e)
+ {
selectedElements.OnDoubleClick();
selectedElements.Invalidate();
}
@@ -1237,11 +1428,13 @@ namespace Greenshot.Drawing
///
///
///
- private Image GetImage(RenderMode renderMode) {
+ private Image GetImage(RenderMode renderMode)
+ {
// Generate a copy of the original image with a dpi equal to the default...
Bitmap clone = ImageHelper.Clone(_image, PixelFormat.DontCare);
// otherwise we would have a problem drawing the image to the surface... :(
- using (Graphics graphics = Graphics.FromImage(clone)) {
+ using (Graphics graphics = Graphics.FromImage(clone))
+ {
// Do not set the following, the containers need to decide themselves
//graphics.SmoothingMode = SmoothingMode.HighQuality;
//graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
@@ -1256,7 +1449,8 @@ namespace Greenshot.Drawing
/// This returns the image "result" of this surface, with all the elements rendered on it.
///
///
- public Image GetImageForExport() {
+ public Image GetImageForExport()
+ {
return GetImage(RenderMode.EXPORT);
}
@@ -1265,27 +1459,34 @@ namespace Greenshot.Drawing
///
///
/// PaintEventArgs
- void SurfacePaint(object sender, PaintEventArgs paintEventArgs) {
+ void SurfacePaint(object sender, PaintEventArgs paintEventArgs)
+ {
Graphics targetGraphics = paintEventArgs.Graphics;
Rectangle clipRectangle = paintEventArgs.ClipRectangle;
- if (Rectangle.Empty.Equals(clipRectangle)) {
+ if (Rectangle.Empty.Equals(clipRectangle))
+ {
LOG.Debug("Empty cliprectangle??");
return;
}
- if (_elements.HasIntersectingFilters(clipRectangle)) {
- if (_buffer != null) {
- if (_buffer.Width != Image.Width || _buffer.Height != Image.Height || _buffer.PixelFormat != Image.PixelFormat) {
+ if (_elements.HasIntersectingFilters(clipRectangle))
+ {
+ if (_buffer != null)
+ {
+ if (_buffer.Width != Image.Width || _buffer.Height != Image.Height || _buffer.PixelFormat != Image.PixelFormat)
+ {
_buffer.Dispose();
_buffer = null;
}
}
- if (_buffer == null) {
+ if (_buffer == null)
+ {
_buffer = ImageHelper.CreateEmpty(Image.Width, Image.Height, Image.PixelFormat, Color.Empty, Image.HorizontalResolution, Image.VerticalResolution);
LOG.DebugFormat("Created buffer with size: {0}x{1}", Image.Width, Image.Height);
}
// Elements might need the bitmap, so we copy the part we need
- using (Graphics graphics = Graphics.FromImage(_buffer)) {
+ using (Graphics graphics = Graphics.FromImage(_buffer))
+ {
// do not set the following, the containers need to decide this themselves!
//graphics.SmoothingMode = SmoothingMode.HighQuality;
//graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
@@ -1297,7 +1498,9 @@ namespace Greenshot.Drawing
_elements.Draw(graphics, _buffer, RenderMode.EDIT, clipRectangle);
}
targetGraphics.DrawImage(_buffer, clipRectangle, clipRectangle, GraphicsUnit.Pixel);
- } else {
+ }
+ else
+ {
DrawBackground(targetGraphics, clipRectangle);
targetGraphics.DrawImage(Image, clipRectangle, clipRectangle, GraphicsUnit.Pixel);
_elements.Draw(targetGraphics, null, RenderMode.EDIT, clipRectangle);
@@ -1308,35 +1511,32 @@ namespace Greenshot.Drawing
// Draw adorners last
foreach (var drawableContainer in selectedElements)
{
- foreach(var adorner in drawableContainer.Adorners)
+ foreach (var adorner in drawableContainer.Adorners)
{
adorner.Paint(paintEventArgs);
}
}
}
- private void DrawBackground(Graphics targetGraphics, Rectangle clipRectangle) {
+ private void DrawBackground(Graphics targetGraphics, Rectangle clipRectangle)
+ {
// check if we need to draw the checkerboard
- if (Image.IsAlphaPixelFormat(Image.PixelFormat) && _transparencyBackgroundBrush != null) {
+ if (Image.IsAlphaPixelFormat(Image.PixelFormat) && _transparencyBackgroundBrush != null)
+ {
targetGraphics.FillRectangle(_transparencyBackgroundBrush, clipRectangle);
- } else {
+ }
+ else
+ {
targetGraphics.Clear(BackColor);
}
}
-
+
///
/// Draw a checkboard when capturing with transparency
///
/// PaintEventArgs
- protected override void OnPaintBackground(PaintEventArgs e) {
- }
-
- ///
- /// Wrapper for makeUndoable flag which was introduced later, will call AddElement with makeundoable set to true
- ///
- /// the new element
- public void AddElement(IDrawableContainer element) {
- AddElement(element, true);
+ protected override void OnPaintBackground(PaintEventArgs e)
+ {
}
///
@@ -1344,39 +1544,88 @@ namespace Greenshot.Drawing
///
/// the new element
/// true if the adding should be undoable
- public void AddElement(IDrawableContainer element, bool makeUndoable) {
+ /// true if invalidate needs to be called
+ public void AddElement(IDrawableContainer element, bool makeUndoable = true, bool invalidate = true)
+ {
_elements.Add(element);
DrawableContainer container = element as DrawableContainer;
- if (container != null) {
+ if (container != null)
+ {
container.FieldChanged += element_FieldChanged;
}
- element.PropertyChanged += ElementPropertyChanged;
- if (element.Status == EditStatus.UNDRAWN) {
+ element.Parent = this;
+ if (element.Status == EditStatus.UNDRAWN)
+ {
element.Status = EditStatus.IDLE;
}
- element.Invalidate();
- if (makeUndoable) {
+ if (element.Selected)
+ {
+ // Use false, as the element is invalidated when invalidate == true anyway
+ SelectElement(element, false);
+ }
+ if (invalidate)
+ {
+ element.Invalidate();
+ }
+ if (makeUndoable)
+ {
MakeUndoable(new AddElementMemento(this, element), false);
}
_modified = true;
}
+ ///
+ /// Remove the list of elements
+ ///
+ /// IDrawableContainerList
+ /// flag specifying if the remove needs to be undoable
+ public void RemoveElements(IDrawableContainerList elementsToRemove, bool makeUndoable = true)
+ {
+ // fix potential issues with iterating a changing list
+ DrawableContainerList cloned = new DrawableContainerList();
+ cloned.AddRange(elementsToRemove);
+ if (makeUndoable)
+ {
+ MakeUndoable(new DeleteElementsMemento(this, cloned), false);
+ }
+ SuspendLayout();
+ foreach (var drawableContainer in cloned)
+ {
+ RemoveElement(drawableContainer, false, false, false);
+ }
+ ResumeLayout();
+ Invalidate();
+ if (_movingElementChanged != null)
+ {
+ SurfaceElementEventArgs eventArgs = new SurfaceElementEventArgs();
+ eventArgs.Elements = cloned;
+ _movingElementChanged(this, eventArgs);
+ }
+ }
+
///
/// Remove an element of the elements list
///
/// Element to remove
/// flag specifying if the remove needs to be undoable
- public void RemoveElement(IDrawableContainer elementToRemove, bool makeUndoable) {
- DeselectElement(elementToRemove);
+ /// flag specifying if an surface invalidate needs to be called
+ public void RemoveElement(IDrawableContainer elementToRemove, bool makeUndoable = true, bool invalidate = true, bool generateEvents = true)
+ {
+ DeselectElement(elementToRemove, generateEvents);
_elements.Remove(elementToRemove);
DrawableContainer element = elementToRemove as DrawableContainer;
- if (element != null) {
+ if (element != null)
+ {
element.FieldChanged -= element_FieldChanged;
}
- elementToRemove.PropertyChanged -= ElementPropertyChanged;
+ element.Parent = null;
// Do not dispose, the memento should!! element.Dispose();
- Invalidate();
- if (makeUndoable) {
+ if (invalidate)
+ {
+ Invalidate();
+ }
+ if (makeUndoable)
+ {
MakeUndoable(new DeleteElementMemento(this, elementToRemove), false);
}
_modified = true;
@@ -1385,43 +1634,52 @@ namespace Greenshot.Drawing
///
/// Add the supplied elements to the surface
///
- ///
- public void AddElements(DrawableContainerList elementsToAdd) {
- foreach(IDrawableContainer element in elementsToAdd) {
- AddElement(element, true);
+ /// DrawableContainerList
+ /// true if the adding should be undoable
+ /// true if invalidate needs to be called
+ public void AddElements(IDrawableContainerList elementsToAdd, bool makeUndoable = true)
+ {
+ // fix potential issues with iterating a changing list
+ DrawableContainerList cloned = new DrawableContainerList();
+ cloned.AddRange(elementsToAdd);
+ if (makeUndoable)
+ {
+ MakeUndoable(new AddElementsMemento(this, cloned), false);
}
+ SuspendLayout();
+ foreach (var element in cloned)
+ {
+ element.Selected = true;
+ AddElement(element, false, false);
+ }
+ ResumeLayout();
+ Invalidate();
}
///
/// Returns if this surface has selected elements
///
///
- public bool HasSelectedElements {
- get {
- return selectedElements != null && selectedElements.Count > 0;
+ public bool HasSelectedElements
+ {
+ get
+ {
+ return (selectedElements != null && selectedElements.Count > 0);
}
}
///
/// Remove all the selected elements
///
- public void RemoveSelectedElements() {
- if (HasSelectedElements) {
- // As RemoveElement will remove the element from the selectedElements list we need to copy the element
- // to another list.
- List elementsToRemove = new List();
- foreach (DrawableContainer element in selectedElements) {
- // Collect to remove later
- elementsToRemove.Add(element);
- }
- // Remove now
- foreach(DrawableContainer element in elementsToRemove) {
- RemoveElement(element, true);
- }
- selectedElements.Clear();
- if (_movingElementChanged != null) {
+ public void RemoveSelectedElements()
+ {
+ if (HasSelectedElements)
+ {
+ // As RemoveElement will remove the element from the selectedElements list we need to copy the element to another list.
+ RemoveElements(selectedElements);
+ if (_movingElementChanged != null)
+ {
SurfaceElementEventArgs eventArgs = new SurfaceElementEventArgs();
- eventArgs.Elements = selectedElements;
_movingElementChanged(this, eventArgs);
}
}
@@ -1430,9 +1688,11 @@ namespace Greenshot.Drawing
///
/// Cut the selected elements from the surface to the clipboard
///
- public void CutSelectedElements() {
- if (HasSelectedElements) {
- ClipboardHelper.SetClipboardData(typeof(DrawableContainerList), selectedElements);
+ public void CutSelectedElements()
+ {
+ if (HasSelectedElements)
+ {
+ ClipboardHelper.SetClipboardData(typeof(IDrawableContainerList), selectedElements);
RemoveSelectedElements();
}
}
@@ -1440,9 +1700,11 @@ namespace Greenshot.Drawing
///
/// Copy the selected elements to the clipboard
///
- public void CopySelectedElements() {
- if (HasSelectedElements) {
- ClipboardHelper.SetClipboardData(typeof(DrawableContainerList), selectedElements);
+ public void CopySelectedElements()
+ {
+ if (HasSelectedElements)
+ {
+ ClipboardHelper.SetClipboardData(typeof(IDrawableContainerList), selectedElements);
}
}
@@ -1451,24 +1713,23 @@ namespace Greenshot.Drawing
/// Called when pressing enter or using the "check" in the editor.
///
///
- public void ConfirmSelectedConfirmableElements(bool confirm){
+ public void ConfirmSelectedConfirmableElements(bool confirm)
+ {
// create new collection so that we can iterate safely (selectedElements might change due with confirm/cancel)
List selectedDCs = new List(selectedElements);
- if (_cropContainer == null)
+ foreach (IDrawableContainer dc in selectedDCs)
{
- return;
- }
- foreach (IDrawableContainer dc in selectedDCs){
- if (dc.Equals(_cropContainer)){
+ if (dc.Equals(_cropContainer))
+ {
DrawingMode = DrawingModes.None;
// No undo memento for the cropcontainer itself, only for the effect
RemoveElement(_cropContainer, false);
- if (confirm) {
+ if (confirm)
+ {
ApplyCrop(_cropContainer.Bounds);
}
_cropContainer.Dispose();
_cropContainer = null;
- break;
}
}
}
@@ -1476,78 +1737,106 @@ namespace Greenshot.Drawing
///
/// Paste all the elements that are on the clipboard
///
- public void PasteElementFromClipboard() {
+ public void PasteElementFromClipboard()
+ {
IDataObject clipboard = ClipboardHelper.GetDataObject();
List formats = ClipboardHelper.GetFormats(clipboard);
- if (formats == null || formats.Count == 0) {
+ if (formats == null || formats.Count == 0)
+ {
return;
}
- if (LOG.IsDebugEnabled) {
+ if (LOG.IsDebugEnabled)
+ {
LOG.Debug("List of clipboard formats available for pasting:");
- foreach(string format in formats) {
+ foreach (string format in formats)
+ {
LOG.Debug("\tgot format: " + format);
}
}
- if (formats.Contains(typeof(DrawableContainerList).FullName)) {
- DrawableContainerList dcs = (DrawableContainerList)ClipboardHelper.GetFromDataObject(clipboard, typeof(DrawableContainerList));
- if (dcs != null) {
+ if (formats.Contains(typeof(IDrawableContainerList).FullName))
+ {
+ IDrawableContainerList dcs = (IDrawableContainerList)ClipboardHelper.GetFromDataObject(clipboard, typeof(IDrawableContainerList));
+ if (dcs != null)
+ {
// Make element(s) only move 10,10 if the surface is the same
Point moveOffset;
- bool isSameSurface = dcs.ParentID == _uniqueId;
+ bool isSameSurface = (dcs.ParentID == _uniqueId);
dcs.Parent = this;
- if (isSameSurface) {
+ if (isSameSurface)
+ {
moveOffset = new Point(10, 10);
- } else {
+ }
+ else
+ {
moveOffset = Point.Empty;
}
- // Here a fix for bug #1475, first calculate the bounds of the complete DrawableContainerList
+ // Here a fix for bug #1475, first calculate the bounds of the complete IDrawableContainerList
Rectangle drawableContainerListBounds = Rectangle.Empty;
- foreach (IDrawableContainer element in dcs) {
- if (drawableContainerListBounds == Rectangle.Empty) {
+ foreach (IDrawableContainer element in dcs)
+ {
+ if (drawableContainerListBounds == Rectangle.Empty)
+ {
drawableContainerListBounds = element.DrawingBounds;
- } else {
+ }
+ else
+ {
drawableContainerListBounds = Rectangle.Union(drawableContainerListBounds, element.DrawingBounds);
}
}
// And find a location inside the target surface to paste to
bool containersCanFit = drawableContainerListBounds.Width < Bounds.Width && drawableContainerListBounds.Height < Bounds.Height;
- if (!containersCanFit) {
+ if (!containersCanFit)
+ {
Point containersLocation = drawableContainerListBounds.Location;
containersLocation.Offset(moveOffset);
- if (!Bounds.Contains(containersLocation)) {
+ if (!Bounds.Contains(containersLocation))
+ {
// Easy fix for same surface
- if (isSameSurface) {
+ if (isSameSurface)
+ {
moveOffset = new Point(-10, -10);
- } else {
+ }
+ else
+ {
// For different surface, which is most likely smaller, we move to "10,10"
moveOffset = new Point(-drawableContainerListBounds.Location.X + 10, -drawableContainerListBounds.Location.Y + 10);
}
}
- } else {
+ }
+ else
+ {
Rectangle moveContainerListBounds = drawableContainerListBounds;
moveContainerListBounds.Offset(moveOffset);
// check if the element is inside
- if (!Bounds.Contains(moveContainerListBounds)) {
+ if (!Bounds.Contains(moveContainerListBounds))
+ {
// Easy fix for same surface
- if (isSameSurface) {
+ if (isSameSurface)
+ {
moveOffset = new Point(-10, -10);
- } else {
+ }
+ else
+ {
// For different surface, which is most likely smaller
int offsetX = 0;
int offsetY = 0;
- if (drawableContainerListBounds.Right > Bounds.Right) {
+ if (drawableContainerListBounds.Right > Bounds.Right)
+ {
offsetX = Bounds.Right - drawableContainerListBounds.Right;
// Correction for the correction
- if (drawableContainerListBounds.Left + offsetX < 0) {
+ if (drawableContainerListBounds.Left + offsetX < 0)
+ {
offsetX += Math.Abs(drawableContainerListBounds.Left + offsetX);
}
}
- if (drawableContainerListBounds.Bottom > Bounds.Bottom) {
+ if (drawableContainerListBounds.Bottom > Bounds.Bottom)
+ {
offsetY = Bounds.Bottom - drawableContainerListBounds.Bottom;
// Correction for the correction
- if (drawableContainerListBounds.Top + offsetY < 0) {
+ if (drawableContainerListBounds.Top + offsetY < 0)
+ {
offsetY += Math.Abs(drawableContainerListBounds.Top + offsetY);
}
}
@@ -1561,11 +1850,15 @@ namespace Greenshot.Drawing
DeselectAllElements();
SelectElements(dcs);
}
- } else if (ClipboardHelper.ContainsImage(clipboard)) {
+ }
+ else if (ClipboardHelper.ContainsImage(clipboard))
+ {
int x = 10;
int y = 10;
- foreach (Image clipboardImage in ClipboardHelper.GetImages(clipboard)) {
- if (clipboardImage != null) {
+ foreach (Image clipboardImage in ClipboardHelper.GetImages(clipboard))
+ {
+ if (clipboardImage != null)
+ {
DeselectAllElements();
IImageContainer container = AddImageContainer(clipboardImage as Bitmap, x, y);
SelectElement(container);
@@ -1574,9 +1867,12 @@ namespace Greenshot.Drawing
y += 10;
}
}
- } else if (ClipboardHelper.ContainsText(clipboard)) {
+ }
+ else if (ClipboardHelper.ContainsText(clipboard))
+ {
string text = ClipboardHelper.GetText(clipboard);
- if (text != null) {
+ if (text != null)
+ {
DeselectAllElements();
ITextContainer textContainer = AddTextContainer(text, HorizontalAlignment.Center, VerticalAlignment.CENTER,
FontFamily.GenericSansSerif, 12f, false, false, false, 2, Color.Black, Color.Transparent);
@@ -1584,78 +1880,99 @@ namespace Greenshot.Drawing
}
}
}
-
+
///
/// Duplicate all the selecteded elements
///
- public void DuplicateSelectedElements() {
+ public void DuplicateSelectedElements()
+ {
LOG.DebugFormat("Duplicating {0} selected elements", selectedElements.Count);
- DrawableContainerList dcs = selectedElements.Clone();
+ IDrawableContainerList dcs = selectedElements.Clone();
dcs.Parent = this;
- dcs.MoveBy(10,10);
+ dcs.MoveBy(10, 10);
AddElements(dcs);
DeselectAllElements();
SelectElements(dcs);
}
-
+
///
/// Deselect the specified element
///
///
- public void DeselectElement(IDrawableContainer container) {
+ public void DeselectElement(IDrawableContainer container, bool generateEvents = true)
+ {
container.Selected = false;
selectedElements.Remove(container);
- container.Invalidate();
FieldAggregator.UnbindElement(container);
- if (_movingElementChanged != null) {
+ if (generateEvents && _movingElementChanged != null)
+ {
SurfaceElementEventArgs eventArgs = new SurfaceElementEventArgs();
eventArgs.Elements = selectedElements;
_movingElementChanged(this, eventArgs);
}
}
+ ///
+ /// Deselect the specified elements
+ ///
+ ///
+ public void DeselectElements(IDrawableContainerList elements)
+ {
+ if (elements.Count == 0)
+ {
+ return;
+ }
+ while (elements.Count > 0)
+ {
+ var element = elements[0];
+ DeselectElement(element, false);
+ }
+ if (_movingElementChanged != null)
+ {
+ SurfaceElementEventArgs eventArgs = new SurfaceElementEventArgs();
+ eventArgs.Elements = selectedElements;
+ _movingElementChanged(this, eventArgs);
+ }
+ Invalidate();
+ }
+
///
/// Deselect all the selected elements
///
- public void DeselectAllElements() {
- if (HasSelectedElements) {
- while(selectedElements.Count > 0) {
- IDrawableContainer element = selectedElements[0];
- element.Selected = false;
- selectedElements.Remove(element);
- element.Invalidate();
- FieldAggregator.UnbindElement(element);
- }
- if (_movingElementChanged != null) {
- SurfaceElementEventArgs eventArgs = new SurfaceElementEventArgs();
- eventArgs.Elements = selectedElements;
- _movingElementChanged(this, eventArgs);
- }
- }
+ public void DeselectAllElements()
+ {
+ DeselectElements(selectedElements);
}
///
/// Select the supplied element
///
///
- public void SelectElement(IDrawableContainer container) {
- if (!selectedElements.Contains(container)) {
+ public void SelectElement(IDrawableContainer container, bool invalidate = true, bool generateEvents = true)
+ {
+ if (!selectedElements.Contains(container))
+ {
selectedElements.Add(container);
container.Selected = true;
FieldAggregator.BindElement(container);
- if (_movingElementChanged != null) {
+ if (generateEvents && _movingElementChanged != null)
+ {
SurfaceElementEventArgs eventArgs = new SurfaceElementEventArgs();
eventArgs.Elements = selectedElements;
_movingElementChanged(this, eventArgs);
}
- container.Invalidate();
+ if (invalidate)
+ {
+ container.Invalidate();
+ }
}
}
///
/// Select all elements, this is called when Ctrl+A is pressed
///
- public void SelectAllElements() {
+ public void SelectAllElements()
+ {
SelectElements(_elements);
}
@@ -1663,10 +1980,21 @@ namespace Greenshot.Drawing
/// Select the supplied elements
///
///
- public void SelectElements(DrawableContainerList elements) {
- foreach(DrawableContainer element in elements) {
- SelectElement(element);
+ public void SelectElements(IDrawableContainerList elements)
+ {
+ SuspendLayout();
+ foreach (DrawableContainer element in elements)
+ {
+ SelectElement(element, false, false);
}
+ if (_movingElementChanged != null)
+ {
+ SurfaceElementEventArgs eventArgs = new SurfaceElementEventArgs();
+ eventArgs.Elements = selectedElements;
+ _movingElementChanged(this, eventArgs);
+ }
+ ResumeLayout();
+ Invalidate();
}
///
@@ -1674,13 +2002,16 @@ namespace Greenshot.Drawing
///
/// Keys
/// false if no keys were processed
- public bool ProcessCmdKey(Keys k) {
- if (selectedElements.Count > 0) {
+ public bool ProcessCmdKey(Keys k)
+ {
+ if (selectedElements.Count > 0)
+ {
bool shiftModifier = (ModifierKeys & Keys.Shift) == Keys.Shift;
int px = shiftModifier ? 10 : 1;
Point moveBy = Point.Empty;
-
- switch (k) {
+
+ switch (k)
+ {
case Keys.Left:
case Keys.Left | Keys.Shift:
moveBy = new Point(-px, 0);
@@ -1721,7 +2052,8 @@ namespace Greenshot.Drawing
default:
return false;
}
- if (!Point.Empty.Equals(moveBy)) {
+ if (!Point.Empty.Equals(moveBy))
+ {
selectedElements.MakeBoundsChangeUndoable(true);
selectedElements.MoveBy(moveBy.X, moveBy.Y);
}
@@ -1733,8 +2065,10 @@ namespace Greenshot.Drawing
///
/// Property for accessing the elements on the surface
///
- public DrawableContainerList Elements {
- get {
+ public IDrawableContainerList Elements
+ {
+ get
+ {
return _elements;
}
}
@@ -1742,60 +2076,64 @@ namespace Greenshot.Drawing
///
/// pulls selected elements up one level in hierarchy
///
- public void PullElementsUp() {
+ public void PullElementsUp()
+ {
_elements.PullElementsUp(selectedElements);
_elements.Invalidate();
}
-
+
///
/// pushes selected elements up to top in hierarchy
///
- public void PullElementsToTop() {
+ public void PullElementsToTop()
+ {
_elements.PullElementsToTop(selectedElements);
_elements.Invalidate();
}
-
+
///
/// pushes selected elements down one level in hierarchy
///
- public void PushElementsDown() {
+ public void PushElementsDown()
+ {
_elements.PushElementsDown(selectedElements);
_elements.Invalidate();
}
-
+
///
/// pushes selected elements down to bottom in hierarchy
///
- public void PushElementsToBottom() {
+ public void PushElementsToBottom()
+ {
_elements.PushElementsToBottom(selectedElements);
_elements.Invalidate();
}
-
+
///
/// indicates whether the selected elements could be pulled up in hierarchy
///
/// true if selected elements could be pulled up, false otherwise
- public bool CanPullSelectionUp() {
+ public bool CanPullSelectionUp()
+ {
return _elements.CanPullUp(selectedElements);
}
-
+
///
/// indicates whether the selected elements could be pushed down in hierarchy
///
/// true if selected elements could be pushed down, false otherwise
- public bool CanPushSelectionDown() {
+ public bool CanPushSelectionDown()
+ {
return _elements.CanPushDown(selectedElements);
}
-
- public void ElementPropertyChanged(object sender, PropertyChangedEventArgs e) {
- //Invalidate();
- }
-
- public void element_FieldChanged(object sender, FieldChangedEventArgs e) {
+
+ public void element_FieldChanged(object sender, FieldChangedEventArgs e)
+ {
selectedElements.HandleFieldChangedEvent(sender, e);
}
- public bool IsOnSurface(IDrawableContainer container) {
+ public bool IsOnSurface(IDrawableContainer container)
+ {
return _elements.Contains(container);
}
}
diff --git a/Greenshot/Drawing/TextContainer.cs b/Greenshot/Drawing/TextContainer.cs
index 1b369ea78..96792de69 100644
--- a/Greenshot/Drawing/TextContainer.cs
+++ b/Greenshot/Drawing/TextContainer.cs
@@ -23,6 +23,7 @@ using Greenshot.Drawing.Fields;
using Greenshot.Helpers;
using Greenshot.Memento;
using Greenshot.Plugin.Drawing;
+using GreenshotPlugin.Interfaces.Drawing;
using System;
using System.ComponentModel;
using System.Drawing;
diff --git a/Greenshot/Forms/ImageEditorForm.cs b/Greenshot/Forms/ImageEditorForm.cs
index e72052944..5f8252549 100644
--- a/Greenshot/Forms/ImageEditorForm.cs
+++ b/Greenshot/Forms/ImageEditorForm.cs
@@ -30,8 +30,10 @@ using Greenshot.Help;
using Greenshot.Helpers;
using Greenshot.IniFile;
using Greenshot.Plugin;
+using Greenshot.Plugin.Drawing;
using GreenshotPlugin.Controls;
using GreenshotPlugin.Core;
+using GreenshotPlugin.Interfaces.Drawing;
using GreenshotPlugin.UnmanagedHelpers;
using log4net;
using System;
@@ -56,7 +58,7 @@ namespace Greenshot {
private Surface _surface;
private GreenshotToolStripButton[] _toolbarButtons;
- private static readonly string[] SupportedClipboardFormats = {typeof(string).FullName, "Text", typeof(DrawableContainerList).FullName};
+ private static readonly string[] SupportedClipboardFormats = {typeof(string).FullName, "Text", typeof(IDrawableContainerList).FullName};
private bool _originalBoldCheckState;
private bool _originalItalicCheckState;
@@ -1045,8 +1047,8 @@ namespace Greenshot {
textVerticalAlignmentButton.Visible = props.HasFieldValue(FieldType.TEXT_VERTICAL_ALIGNMENT);
shadowButton.Visible = props.HasFieldValue(FieldType.SHADOW);
btnConfirm.Visible = btnCancel.Visible = props.HasFieldValue(FieldType.FLAGS)
- && ((FieldType.Flag)props.GetFieldValue(FieldType.FLAGS)&FieldType.Flag.CONFIRMABLE) == FieldType.Flag.CONFIRMABLE;
-
+ && ((FieldFlag)props.GetFieldValue(FieldType.FLAGS) & FieldFlag.CONFIRMABLE) == FieldFlag.CONFIRMABLE;
+
obfuscateModeButton.Visible = props.HasFieldValue(FieldType.PREPARED_FILTER_OBFUSCATE);
highlightModeButton.Visible = props.HasFieldValue(FieldType.PREPARED_FILTER_HIGHLIGHT);
} else {
@@ -1078,9 +1080,10 @@ namespace Greenshot {
FieldAggregator props = _surface.FieldAggregator;
// if a confirmable element is selected, we must disable most of the controls
// since we demand confirmation or cancel for confirmable element
- if (props.HasFieldValue(FieldType.FLAGS) && ((FieldType.Flag)props.GetFieldValue(FieldType.FLAGS) & FieldType.Flag.CONFIRMABLE) == FieldType.Flag.CONFIRMABLE) {
+ if (props.HasFieldValue(FieldType.FLAGS) && ((FieldFlag)props.GetFieldValue(FieldType.FLAGS) & FieldFlag.CONFIRMABLE) == FieldFlag.CONFIRMABLE)
+ {
// disable most controls
- if(!_controlsDisabledDueToConfirmable) {
+ if (!_controlsDisabledDueToConfirmable) {
ToolStripItemEndisabler.Disable(menuStrip1);
ToolStripItemEndisabler.Disable(destinationsToolStrip);
ToolStripItemEndisabler.Disable(toolsToolStrip);
diff --git a/Greenshot/Greenshot.csproj b/Greenshot/Greenshot.csproj
index 0fc6043a0..8e743d8b7 100644
--- a/Greenshot/Greenshot.csproj
+++ b/Greenshot/Greenshot.csproj
@@ -112,7 +112,6 @@
-
@@ -215,13 +214,14 @@
+
+
-
diff --git a/Greenshot/Memento/AddElementMemento.cs b/Greenshot/Memento/AddElementMemento.cs
index 98a70214e..c7f21dbde 100644
--- a/Greenshot/Memento/AddElementMemento.cs
+++ b/Greenshot/Memento/AddElementMemento.cs
@@ -47,12 +47,6 @@ namespace Greenshot.Memento {
_surface = null;
}
- public LangKey ActionLanguageKey {
- get {
- return LangKey.none;
- }
- }
-
public bool Merge(IMemento otherMemento) {
return false;
}
diff --git a/Greenshot/Memento/AddElementsMemento.cs b/Greenshot/Memento/AddElementsMemento.cs
new file mode 100644
index 000000000..ce566c3c2
--- /dev/null
+++ b/Greenshot/Memento/AddElementsMemento.cs
@@ -0,0 +1,77 @@
+/*
+ * Greenshot - a free and open source screenshot tool
+ * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
+ *
+ * For more information see: http://getgreenshot.org/
+ * The Greenshot project is hosted on GitHub https://github.com/greenshot/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 Greenshot.Drawing;
+using Greenshot.Plugin.Drawing;
+
+namespace Greenshot.Memento
+{
+ ///
+ /// The AddElementMemento makes it possible to undo adding an element
+ ///
+ public class AddElementsMemento : IMemento
+ {
+ private IDrawableContainerList _containerList;
+ private Surface _surface;
+
+ public AddElementsMemento(Surface surface, IDrawableContainerList containerList)
+ {
+ _surface = surface;
+ _containerList = containerList;
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ if (_containerList != null)
+ {
+ _containerList.Dispose();
+ }
+ }
+ _containerList = null;
+ _surface = null;
+ }
+
+ public bool Merge(IMemento otherMemento)
+ {
+ return false;
+ }
+
+ public IMemento Restore()
+ {
+ // Store the selected state, as it's overwritten by the RemoveElement
+ bool selected = _containerList.Selected;
+
+ var oldState = new DeleteElementsMemento(_surface, _containerList);
+
+ _surface.RemoveElements(_containerList, false);
+
+ // After, so everything is gone
+ _surface.Invalidate();
+ return oldState;
+ }
+ }
+}
diff --git a/Greenshot/Memento/ChangeFieldHolderMemento.cs b/Greenshot/Memento/ChangeFieldHolderMemento.cs
index 03a04ab5d..7314f097a 100644
--- a/Greenshot/Memento/ChangeFieldHolderMemento.cs
+++ b/Greenshot/Memento/ChangeFieldHolderMemento.cs
@@ -3,7 +3,7 @@
* Copyright (C) 2007-2015 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/
+ * The Greenshot project is hosted on GitHub https://github.com/greenshot/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
@@ -18,47 +18,54 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-using System;
-using Greenshot.Plugin.Drawing;
-using Greenshot.Drawing.Fields;
-using Greenshot.Configuration;
-namespace Greenshot.Memento {
+using Greenshot.Plugin.Drawing;
+using GreenshotPlugin.Interfaces.Drawing;
+
+namespace Greenshot.Memento
+{
///
/// The ChangeFieldHolderMemento makes it possible to undo-redo an IDrawableContainer move
///
- public class ChangeFieldHolderMemento : IMemento {
- private IDrawableContainer drawableContainer;
- private readonly Field fieldToBeChanged;
- private readonly object oldValue;
-
- public ChangeFieldHolderMemento(IDrawableContainer drawableContainer, Field fieldToBeChanged) {
- this.drawableContainer = drawableContainer;
- this.fieldToBeChanged = fieldToBeChanged;
- oldValue = fieldToBeChanged.Value;
+ public class ChangeFieldHolderMemento : IMemento
+ {
+ private IDrawableContainer _drawableContainer;
+ private IField _fieldToBeChanged;
+ private object _oldValue;
+
+ public ChangeFieldHolderMemento(IDrawableContainer drawableContainer, IField fieldToBeChanged)
+ {
+ _drawableContainer = drawableContainer;
+ _fieldToBeChanged = fieldToBeChanged;
+ _oldValue = fieldToBeChanged.Value;
}
- public void Dispose() {
+ public void Dispose()
+ {
Dispose(true);
- GC.SuppressFinalize(this);
}
- protected virtual void Dispose(bool disposing) {
- //if (disposing) { }
- drawableContainer = null;
- }
-
- public LangKey ActionLanguageKey {
- get {
- return LangKey.none;
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ if (_drawableContainer != null)
+ {
+ _drawableContainer.Dispose();
+ }
}
+ _drawableContainer = null;
}
- public bool Merge(IMemento otherMemento) {
+ public bool Merge(IMemento otherMemento)
+ {
ChangeFieldHolderMemento other = otherMemento as ChangeFieldHolderMemento;
- if (other != null) {
- if (other.drawableContainer.Equals(drawableContainer)) {
- if (other.fieldToBeChanged.Equals(fieldToBeChanged)) {
+ if (other != null)
+ {
+ if (other._drawableContainer.Equals(_drawableContainer))
+ {
+ if (other._fieldToBeChanged.Equals(_fieldToBeChanged))
+ {
// Match, do not store anything as the initial state is what we want.
return true;
}
@@ -67,13 +74,14 @@ namespace Greenshot.Memento {
return false;
}
- public IMemento Restore() {
+ public IMemento Restore()
+ {
// Before
- drawableContainer.Invalidate();
- ChangeFieldHolderMemento oldState = new ChangeFieldHolderMemento(drawableContainer, fieldToBeChanged);
- fieldToBeChanged.Value = oldValue;
+ _drawableContainer.Invalidate();
+ ChangeFieldHolderMemento oldState = new ChangeFieldHolderMemento(_drawableContainer, _fieldToBeChanged);
+ _fieldToBeChanged.Value = _oldValue;
// After
- drawableContainer.Invalidate();
+ _drawableContainer.Invalidate();
return oldState;
}
}
diff --git a/Greenshot/Memento/DeleteElementMemento.cs b/Greenshot/Memento/DeleteElementMemento.cs
index b715e26a8..dc1d012de 100644
--- a/Greenshot/Memento/DeleteElementMemento.cs
+++ b/Greenshot/Memento/DeleteElementMemento.cs
@@ -50,13 +50,6 @@ namespace Greenshot.Memento {
}
}
- public LangKey ActionLanguageKey {
- get {
- //return LangKey.editor_deleteelement;
- return LangKey.none;
- }
- }
-
public bool Merge(IMemento otherMemento) {
return false;
}
diff --git a/Greenshot/Memento/DeleteElementsMemento.cs b/Greenshot/Memento/DeleteElementsMemento.cs
new file mode 100644
index 000000000..d01bc3089
--- /dev/null
+++ b/Greenshot/Memento/DeleteElementsMemento.cs
@@ -0,0 +1,72 @@
+/*
+ * Greenshot - a free and open source screenshot tool
+ * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
+ *
+ * For more information see: http://getgreenshot.org/
+ * The Greenshot project is hosted on GitHub https://github.com/greenshot/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 Greenshot.Drawing;
+using Greenshot.Plugin.Drawing;
+
+namespace Greenshot.Memento
+{
+ ///
+ /// The DeleteElementMemento makes it possible to undo deleting an element
+ ///
+ public class DeleteElementsMemento : IMemento
+ {
+ private IDrawableContainerList _containerList;
+ private Surface _surface;
+
+ public DeleteElementsMemento(Surface surface, IDrawableContainerList containerList)
+ {
+ _surface = surface;
+ _containerList = containerList;
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ if (_containerList != null)
+ {
+ _containerList.Dispose();
+ }
+ }
+ _containerList = null;
+ _surface = null;
+ }
+
+ public bool Merge(IMemento otherMemento)
+ {
+ return false;
+ }
+
+ public IMemento Restore()
+ {
+ AddElementsMemento oldState = new AddElementsMemento(_surface, _containerList);
+ _surface.AddElements(_containerList, false);
+ // After
+ _surface.Invalidate();
+ return oldState;
+ }
+ }
+}
diff --git a/Greenshot/Memento/DrawableContainerBoundsChangeMemento.cs b/Greenshot/Memento/DrawableContainerBoundsChangeMemento.cs
index 940fbd4ee..123d260f0 100644
--- a/Greenshot/Memento/DrawableContainerBoundsChangeMemento.cs
+++ b/Greenshot/Memento/DrawableContainerBoundsChangeMemento.cs
@@ -3,7 +3,7 @@
* Copyright (C) 2007-2015 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/
+ * The Greenshot project is hosted on GitHub https://github.com/greenshot/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
@@ -18,61 +18,70 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-using System;
+using Greenshot.Drawing;
+using Greenshot.Plugin.Drawing;
+using GreenshotPlugin.Core;
using System.Collections.Generic;
using System.Drawing;
-using Greenshot.Configuration;
-using Greenshot.Plugin.Drawing;
-using GreenshotPlugin.Core;
-
-namespace Greenshot.Memento {
+namespace Greenshot.Memento
+{
///
/// The DrawableContainerBoundsChangeMemento makes it possible to undo-redo an IDrawableContainer resize & move
///
- public class DrawableContainerBoundsChangeMemento : IMemento {
- readonly List points = new List();
- readonly List sizes = new List();
- List listOfdrawableContainer;
-
- private void StoreBounds() {
- foreach(IDrawableContainer drawableContainer in listOfdrawableContainer) {
+ public class DrawableContainerBoundsChangeMemento : IMemento
+ {
+ List points = new List();
+ List sizes = new List();
+ IDrawableContainerList listOfdrawableContainer;
+
+ private void StoreBounds()
+ {
+ foreach (IDrawableContainer drawableContainer in listOfdrawableContainer)
+ {
points.Add(drawableContainer.Location);
sizes.Add(drawableContainer.Size);
}
}
- public DrawableContainerBoundsChangeMemento(List listOfdrawableContainer) {
+ public DrawableContainerBoundsChangeMemento(IDrawableContainerList listOfdrawableContainer)
+ {
this.listOfdrawableContainer = listOfdrawableContainer;
StoreBounds();
}
- public DrawableContainerBoundsChangeMemento(IDrawableContainer drawableContainer) {
- listOfdrawableContainer = new List();
+ public DrawableContainerBoundsChangeMemento(IDrawableContainer drawableContainer)
+ {
+ listOfdrawableContainer = new DrawableContainerList();
listOfdrawableContainer.Add(drawableContainer);
+ listOfdrawableContainer.Parent = drawableContainer.Parent;
StoreBounds();
}
- public void Dispose() {
+ public void Dispose()
+ {
Dispose(true);
- GC.SuppressFinalize(this);
}
- protected virtual void Dispose(bool disposing) {
- // if (disposing) { }
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ if (listOfdrawableContainer != null)
+ {
+ listOfdrawableContainer.Dispose();
+ }
+ }
listOfdrawableContainer = null;
}
- public LangKey ActionLanguageKey {
- get {
- return LangKey.none;
- }
- }
-
- public bool Merge(IMemento otherMemento) {
- DrawableContainerBoundsChangeMemento other = otherMemento as DrawableContainerBoundsChangeMemento;
- if (other != null) {
- if (Objects.CompareLists(listOfdrawableContainer, other.listOfdrawableContainer)) {
+ public bool Merge(IMemento otherMemento)
+ {
+ var other = otherMemento as DrawableContainerBoundsChangeMemento;
+ if (other != null)
+ {
+ if (Objects.CompareLists(listOfdrawableContainer, other.listOfdrawableContainer))
+ {
// Lists are equal, as we have the state already we can ignore the new memento
return true;
}
@@ -80,9 +89,11 @@ namespace Greenshot.Memento {
return false;
}
- public IMemento Restore() {
- DrawableContainerBoundsChangeMemento oldState = new DrawableContainerBoundsChangeMemento(listOfdrawableContainer);
- for(int index = 0; index < listOfdrawableContainer.Count; index++) {
+ public IMemento Restore()
+ {
+ var oldState = new DrawableContainerBoundsChangeMemento(listOfdrawableContainer);
+ for (int index = 0; index < listOfdrawableContainer.Count; index++)
+ {
IDrawableContainer drawableContainer = listOfdrawableContainer[index];
// Before
drawableContainer.Invalidate();
diff --git a/Greenshot/Memento/SurfaceBackgroundChangeMemento.cs b/Greenshot/Memento/SurfaceBackgroundChangeMemento.cs
index 9c8935abc..32f371261 100644
--- a/Greenshot/Memento/SurfaceBackgroundChangeMemento.cs
+++ b/Greenshot/Memento/SurfaceBackgroundChangeMemento.cs
@@ -44,7 +44,6 @@ namespace Greenshot.Memento {
public void Dispose() {
Dispose(true);
- GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing) {
@@ -64,13 +63,6 @@ namespace Greenshot.Memento {
public bool Merge(IMemento otherMemento) {
return false;
}
-
- public LangKey ActionLanguageKey {
- get {
- //return LangKey.editor_crop;
- return LangKey.none;
- }
- }
public IMemento Restore() {
SurfaceBackgroundChangeMemento oldState = new SurfaceBackgroundChangeMemento(_surface, _matrix);
diff --git a/Greenshot/Memento/TextChangeMemento.cs b/Greenshot/Memento/TextChangeMemento.cs
index 716b9e171..d7b9a8d54 100644
--- a/Greenshot/Memento/TextChangeMemento.cs
+++ b/Greenshot/Memento/TextChangeMemento.cs
@@ -37,7 +37,6 @@ namespace Greenshot.Memento {
public void Dispose() {
Dispose(true);
- GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing) {
@@ -46,12 +45,6 @@ namespace Greenshot.Memento {
}
}
- public LangKey ActionLanguageKey {
- get {
- return LangKey.none;
- }
- }
-
public bool Merge(IMemento otherMemento) {
TextChangeMemento other = otherMemento as TextChangeMemento;
if (other != null) {
diff --git a/GreenshotPlugin/Core/OperatingSystemExtensions.cs b/GreenshotPlugin/Core/OperatingSystemExtensions.cs
index 769547e03..ffe07bc6f 100644
--- a/GreenshotPlugin/Core/OperatingSystemExtensions.cs
+++ b/GreenshotPlugin/Core/OperatingSystemExtensions.cs
@@ -55,7 +55,7 @@ namespace GreenshotPlugin.Core
/// true if we are running on Windows 8 or later
public static bool IsWindows8OrLater(this OperatingSystem operatingSystem)
{
- return (operatingSystem.Version.Major == 6 && operatingSystem.Version.Minor >= 2) || operatingSystem.Version.Major >= 6;
+ return (operatingSystem.Version.Major == 6 && operatingSystem.Version.Minor >= 2) || operatingSystem.Version.Major > 6;
}
///
@@ -65,7 +65,7 @@ namespace GreenshotPlugin.Core
/// true if we are running on Windows 7 or later
public static bool IsWindows7OrLater(this OperatingSystem operatingSystem)
{
- return (operatingSystem.Version.Major == 6 && operatingSystem.Version.Minor >= 1) || operatingSystem.Version.Major >= 6;
+ return (operatingSystem.Version.Major == 6 && operatingSystem.Version.Minor >= 1) || operatingSystem.Version.Major > 6;
}
///
diff --git a/GreenshotPlugin/Core/WindowsHelper.cs b/GreenshotPlugin/Core/WindowsHelper.cs
index 855dd79be..1a829b4a5 100644
--- a/GreenshotPlugin/Core/WindowsHelper.cs
+++ b/GreenshotPlugin/Core/WindowsHelper.cs
@@ -1017,7 +1017,11 @@ namespace GreenshotPlugin.Core {
// and subtracting the border from the size (2 times, as we move right/down for the capture without resizing)
captureRectangle.Inflate(borderSize.Width, borderSize.Height);
} else {
- captureRectangle.Inflate(-1, -1);
+ // TODO: Also 8.x?
+ if (Environment.OSVersion.IsWindows10())
+ {
+ captureRectangle.Inflate(-1, -1);
+ }
if (autoMode) {
// check if the capture fits
diff --git a/GreenshotPlugin/GreenshotPlugin.csproj b/GreenshotPlugin/GreenshotPlugin.csproj
index 8bc85a253..86922e91e 100644
--- a/GreenshotPlugin/GreenshotPlugin.csproj
+++ b/GreenshotPlugin/GreenshotPlugin.csproj
@@ -68,6 +68,9 @@
+
+
+
diff --git a/GreenshotPlugin/Interfaces/Drawing/Container.cs b/GreenshotPlugin/Interfaces/Drawing/Container.cs
index afae80489..02e52cd65 100644
--- a/GreenshotPlugin/Interfaces/Drawing/Container.cs
+++ b/GreenshotPlugin/Interfaces/Drawing/Container.cs
@@ -3,7 +3,7 @@
* Copyright (C) 2007-2015 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/
+ * The Greenshot project is hosted on GitHub https://github.com/greenshot/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
@@ -25,65 +25,80 @@ using System.Drawing.Imaging;
using System.Windows.Forms;
using System.ComponentModel;
using System.Collections.Generic;
+using GreenshotPlugin.Interfaces.Drawing;
using Greenshot.Plugin.Drawing.Adorners;
-using System.Runtime.Serialization;
-namespace Greenshot.Plugin.Drawing {
- public enum RenderMode {EDIT, EXPORT};
- public enum EditStatus {UNDRAWN, DRAWING, MOVING, RESIZING, IDLE};
+namespace Greenshot.Plugin.Drawing
+{
+ public enum RenderMode { EDIT, EXPORT };
+ public enum EditStatus { UNDRAWN, DRAWING, MOVING, RESIZING, IDLE };
- public interface IDrawableContainer : INotifyPropertyChanged, IDisposable {
- ISurface Parent {
- get;
- }
- bool Selected {
+ public interface IDrawableContainer : INotifyPropertyChanged, IDisposable
+ {
+ ISurface Parent
+ {
get;
set;
}
-
- int Left {
+ bool Selected
+ {
get;
set;
}
-
- int Top {
+
+ int Left
+ {
get;
set;
}
-
- int Width {
+
+ int Top
+ {
get;
set;
}
-
- int Height {
+
+ int Width
+ {
get;
set;
}
-
- Point Location {
+
+ int Height
+ {
+ get;
+ set;
+ }
+
+ Point Location
+ {
get;
}
- Size Size {
- get;
- }
-
- Rectangle Bounds {
+ Size Size
+ {
get;
}
- Rectangle DrawingBounds {
+ Rectangle Bounds
+ {
+ get;
+ }
+
+ Rectangle DrawingBounds
+ {
get;
}
void ApplyBounds(RectangleF newBounds);
-
- bool hasFilters {
+
+ bool hasFilters
+ {
get;
}
- EditStatus Status {
+ EditStatus Status
+ {
get;
set;
}
@@ -97,7 +112,8 @@ namespace Greenshot.Plugin.Drawing {
bool HandleMouseMove(int x, int y);
bool InitContent();
void MakeBoundsChangeUndoable(bool allowMerge);
- EditStatus DefaultEditMode {
+ EditStatus DefaultEditMode
+ {
get;
}
@@ -107,38 +123,91 @@ namespace Greenshot.Plugin.Drawing {
IList Adorners { get; }
}
- public interface ITextContainer: IDrawableContainer {
- string Text {
+ public interface IDrawableContainerList : IList, IDisposable
+ {
+ Guid ParentID
+ {
+ get;
+ }
+
+ bool Selected
+ {
+ get;
+ set;
+ }
+
+ ISurface Parent
+ {
+ get;
+ set;
+ }
+ EditStatus Status
+ {
+ get;
+ set;
+ }
+ void MakeBoundsChangeUndoable(bool allowMerge);
+ void Transform(Matrix matrix);
+ void MoveBy(int dx, int dy);
+ bool ClickableAt(int x, int y);
+ IDrawableContainer ClickableElementAt(int x, int y);
+ void OnDoubleClick();
+ bool HasIntersectingFilters(Rectangle clipRectangle);
+ bool IntersectsWith(Rectangle clipRectangle);
+ void Draw(Graphics g, Bitmap bitmap, RenderMode renderMode, Rectangle clipRectangle);
+ void Invalidate();
+ void PullElementsToTop(IDrawableContainerList elements);
+ bool CanPushDown(IDrawableContainerList elements);
+ void PullElementsUp(IDrawableContainerList elements);
+ bool CanPullUp(IDrawableContainerList elements);
+ void PushElementsDown(IDrawableContainerList elements);
+ void PushElementsToBottom(IDrawableContainerList elements);
+ void ShowContextMenu(MouseEventArgs e, ISurface surface);
+ void HandleFieldChangedEvent(object sender, FieldChangedEventArgs e);
+ }
+
+ public interface ITextContainer : IDrawableContainer
+ {
+ string Text
+ {
get;
set;
}
void FitToText();
}
- public interface IImageContainer: IDrawableContainer {
- Image Image {
+ public interface IImageContainer : IDrawableContainer
+ {
+ Image Image
+ {
get;
set;
}
void Load(string filename);
}
- public interface ICursorContainer: IDrawableContainer {
- Cursor Cursor {
+ public interface ICursorContainer : IDrawableContainer
+ {
+ Cursor Cursor
+ {
get;
set;
}
void Load(string filename);
}
- public interface IIconContainer: IDrawableContainer {
- Icon Icon {
+ public interface IIconContainer : IDrawableContainer
+ {
+ Icon Icon
+ {
get;
set;
}
void Load(string filename);
}
- public interface IMetafileContainer: IDrawableContainer {
- Metafile Metafile {
+ public interface IMetafileContainer : IDrawableContainer
+ {
+ Metafile Metafile
+ {
get;
set;
}
diff --git a/GreenshotPlugin/Interfaces/Drawing/IField.cs b/GreenshotPlugin/Interfaces/Drawing/IField.cs
new file mode 100644
index 000000000..515c8b107
--- /dev/null
+++ b/GreenshotPlugin/Interfaces/Drawing/IField.cs
@@ -0,0 +1,84 @@
+/*
+ * Greenshot - a free and open source screenshot tool
+ * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
+ *
+ * For more information see: http://getgreenshot.org/
+ * The Greenshot project is hosted on GitHub https://github.com/greenshot/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.ComponentModel;
+
+namespace GreenshotPlugin.Interfaces.Drawing
+{
+ [Flags]
+ public enum FieldFlag
+ {
+ NONE = 0,
+ CONFIRMABLE = 1
+ }
+ public interface IFieldType
+ {
+ string Name
+ {
+ get;
+ set;
+ }
+ }
+
+ public interface IField : INotifyPropertyChanged
+ {
+ object Value
+ {
+ get;
+ set;
+ }
+ IFieldType FieldType
+ {
+ get;
+ set;
+ }
+ string Scope
+ {
+ get;
+ set;
+ }
+ bool HasValue
+ {
+ get;
+ }
+ }
+ ///
+ /// EventHandler to be used when a field value changes
+ ///
+ public delegate void FieldChangedEventHandler(object sender, FieldChangedEventArgs e);
+
+ ///
+ /// EventArgs to be used with FieldChangedEventHandler
+ ///
+ public class FieldChangedEventArgs : EventArgs
+ {
+ public IField Field
+ {
+ get;
+ private set;
+ }
+ public FieldChangedEventArgs(IField field)
+ {
+ Field = field;
+ }
+ }
+}
diff --git a/GreenshotPlugin/Interfaces/Drawing/IFieldholder.cs b/GreenshotPlugin/Interfaces/Drawing/IFieldholder.cs
new file mode 100644
index 000000000..5e6f9e15b
--- /dev/null
+++ b/GreenshotPlugin/Interfaces/Drawing/IFieldholder.cs
@@ -0,0 +1,56 @@
+/*
+ * Greenshot - a free and open source screenshot tool
+ * Copyright (C) 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
+ *
+ * For more information see: http://getgreenshot.org/
+ * The Greenshot project is hosted on GitHub https://github.com/greenshot/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.Collections.Generic;
+
+namespace GreenshotPlugin.Interfaces.Drawing
+{
+ ///
+ /// Any element holding Fields must provide access to it.
+ /// AbstractFieldHolder is the basic implementation.
+ /// If you need the fieldHolder to have child fieldHolders,
+ /// you should consider using IFieldHolderWithChildren.
+ ///
+ public interface IFieldHolder
+ {
+
+ event FieldChangedEventHandler FieldChanged;
+
+ void AddField(IField field);
+ void RemoveField(IField field);
+ IList GetFields();
+ IField GetField(IFieldType fieldType);
+ bool HasField(IFieldType fieldType);
+ void SetFieldValue(IFieldType fieldType, object value);
+ }
+
+ ///
+ /// Extended fieldHolder which has fieldHolder children.
+ /// Implementations should pass field values to and from
+ /// their children.
+ /// AbstractFieldHolderWithChildren is the basic implementation.
+ ///
+ public interface IFieldHolderWithChildren : IFieldHolder
+ {
+ void AddChild(IFieldHolder fieldHolder);
+ void RemoveChild(IFieldHolder fieldHolder);
+ }
+}
diff --git a/GreenshotPlugin/Interfaces/Drawing/IMemento.cs b/GreenshotPlugin/Interfaces/Drawing/IMemento.cs
new file mode 100644
index 000000000..1d5971c55
--- /dev/null
+++ b/GreenshotPlugin/Interfaces/Drawing/IMemento.cs
@@ -0,0 +1,43 @@
+/*
+ * Greenshot - a free and open source screenshot tool
+ * Copyright (C) 2007-2015 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;
+
+namespace Greenshot.Memento {
+ ///
+ /// Description of IMemento.
+ ///
+ public interface IMemento : IDisposable {
+ ///
+ /// Restores target to the state memorized by this memento.
+ ///
+ ///
+ /// A memento of the state before restoring
+ ///
+ IMemento Restore();
+
+ ///
+ /// Try to merge the current memento with another, preventing loads of items on the stack
+ ///
+ /// The memento to try to merge with
+ ///
+ bool Merge(IMemento other);
+ }
+}
diff --git a/GreenshotPlugin/Interfaces/Generic.cs b/GreenshotPlugin/Interfaces/Generic.cs
index 29a66597f..ca0ea04b7 100644
--- a/GreenshotPlugin/Interfaces/Generic.cs
+++ b/GreenshotPlugin/Interfaces/Generic.cs
@@ -3,7 +3,7 @@
* Copyright (C) 2007-2015 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/
+ * The Greenshot project is hosted on GitHub https://github.com/greenshot/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
@@ -18,63 +18,74 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
+using Greenshot.Core;
+using Greenshot.Memento;
+using Greenshot.Plugin.Drawing;
+using GreenshotPlugin.Interfaces.Drawing;
using System;
using System.Drawing;
+using System.IO;
using System.Windows.Forms;
-using Greenshot.Plugin.Drawing;
-using System.IO;
-using System.Collections.Generic;
-using Greenshot.Core;
-
-namespace Greenshot.Plugin {
+namespace Greenshot.Plugin
+{
///
/// Alignment Enums for possitioning
///
//public enum HorizontalAlignment {LEFT, CENTER, RIGHT};
- public enum VerticalAlignment {TOP, CENTER, BOTTOM};
+ public enum VerticalAlignment { TOP, CENTER, BOTTOM };
- public enum SurfaceMessageTyp {
+ public enum SurfaceMessageTyp
+ {
FileSaved,
Error,
Info,
UploadedUri
}
- public class SurfaceMessageEventArgs : EventArgs {
- public SurfaceMessageTyp MessageType {
+ public class SurfaceMessageEventArgs : EventArgs
+ {
+ public SurfaceMessageTyp MessageType
+ {
get;
set;
}
- public string Message {
+ public string Message
+ {
get;
set;
}
- public ISurface Surface {
+ public ISurface Surface
+ {
get;
set;
}
}
- public class SurfaceElementEventArgs : EventArgs {
- public IList Elements {
+ public class SurfaceElementEventArgs : EventArgs
+ {
+ public IDrawableContainerList Elements
+ {
get;
set;
}
}
- public class SurfaceDrawingModeEventArgs : EventArgs {
- public DrawingModes DrawingMode {
+ public class SurfaceDrawingModeEventArgs : EventArgs
+ {
+ public DrawingModes DrawingMode
+ {
get;
set;
}
}
-
+
public delegate void SurfaceSizeChangeEventHandler(object sender, EventArgs e);
public delegate void SurfaceMessageEventHandler(object sender, SurfaceMessageEventArgs e);
public delegate void SurfaceElementEventHandler(object sender, SurfaceElementEventArgs e);
public delegate void SurfaceDrawingModeEventHandler(object sender, SurfaceDrawingModeEventArgs e);
- public enum DrawingModes {
+ public enum DrawingModes
+ {
None,
Rect,
Ellipse,
@@ -93,7 +104,8 @@ namespace Greenshot.Plugin {
///
/// The interface to the Surface object, so Plugins can use it.
///
- public interface ISurface : IDisposable {
+ public interface ISurface : IDisposable
+ {
event SurfaceSizeChangeEventHandler SurfaceSizeChanged;
event SurfaceMessageEventHandler SurfaceMessage;
event SurfaceDrawingModeEventHandler DrawingModeChanged;
@@ -102,11 +114,17 @@ namespace Greenshot.Plugin {
///
/// Unique ID of the Surface
///
- Guid ID {
+ Guid ID
+ {
get;
set;
}
+ IDrawableContainerList Elements
+ {
+ get;
+ }
+
///
/// Get/Set the image to the Surface
/// get will give the image as is currently visible
@@ -116,18 +134,19 @@ namespace Greenshot.Plugin {
/// The setter will clone the passed bitmap and dispose it when the Surface is disposed
/// This means that the supplied image needs to be disposed by the calling code (if needed!)
///
- Image Image {
+ Image Image
+ {
get;
set;
}
-
+
///
/// Get the current Image from the Editor for Exporting (save/upload etc)
/// Don't forget to call image.Dispose() when finished!!!
///
/// Bitmap
Image GetImageForExport();
-
+
///
/// Add a TextContainer, at the given location, to the Surface.
/// The TextContainer will be "re"sized to the text size.
@@ -154,7 +173,8 @@ namespace Greenshot.Plugin {
long SaveElementsToStream(Stream stream);
void LoadElementsFromStream(Stream stream);
- bool HasSelectedElements {
+ bool HasSelectedElements
+ {
get;
}
void RemoveSelectedElements();
@@ -162,9 +182,32 @@ namespace Greenshot.Plugin {
void CopySelectedElements();
void PasteElementFromClipboard();
void DuplicateSelectedElements();
- void DeselectElement(IDrawableContainer container);
+ void DeselectElement(IDrawableContainer container, bool generateEvents = true);
void DeselectAllElements();
- void SelectElement(IDrawableContainer container);
+
+ ///
+ /// Add an element to the surface
+ ///
+ /// IDrawableContainerList
+ /// Should it be placed on the undo stack?
+ void AddElements(IDrawableContainerList elements, bool makeUndoable = true);
+ void RemoveElements(IDrawableContainerList elements, bool makeUndoable = true);
+ void SelectElements(IDrawableContainerList elements);
+
+ ///
+ /// Add an element to the surface
+ ///
+ /// IDrawableContainer
+ /// Should it be placed on the undo stack?
+ /// Should it be invalidated (draw)
+ void AddElement(IDrawableContainer element, bool makeUndoable = true, bool invalidate = true);
+
+ ///
+ /// Select the supplied container
+ ///
+ /// IDrawableContainer
+ /// false to skip invalidation
+ void SelectElement(IDrawableContainer container, bool invalidate = true, bool generateEvents = true);
///
/// Is the supplied container "on" the surface?
///
@@ -173,31 +216,46 @@ namespace Greenshot.Plugin {
bool IsOnSurface(IDrawableContainer container);
void Invalidate(Rectangle rectangleToInvalidate);
void Invalidate();
- bool Modified {
+ bool Modified
+ {
get;
set;
}
- string LastSaveFullPath {
+ string LastSaveFullPath
+ {
get;
set;
}
- string UploadURL {
+ string UploadURL
+ {
get;
set;
}
- void RemoveElement(IDrawableContainer elementToRemove, bool makeUndoable);
+ ///
+ /// Remove an element of the elements list
+ ///
+ /// Element to remove
+ /// flag specifying if the remove needs to be undoable
+ /// flag specifying if an surface invalidate needs to be called
+ /// flag specifying if the deselect needs to generate an event
+ void RemoveElement(IDrawableContainer elementToRemove, bool makeUndoable = true, bool invalidate = true, bool generateEvents = true);
+
void SendMessageEvent(object source, SurfaceMessageTyp messageType, string message);
void ApplyBitmapEffect(IEffect effect);
void RemoveCursor();
- bool HasCursor {
+ bool HasCursor
+ {
get;
}
- ICaptureDetails CaptureDetails {
+ ICaptureDetails CaptureDetails
+ {
get;
set;
}
int Width { get; }
int Height { get; }
+
+ void MakeUndoable(IMemento memento, bool allowMerge);
}
}
\ No newline at end of file