From f7c0dd744b2fdfc35332a56c5c60e3c4b7ccd0c6 Mon Sep 17 00:00:00 2001 From: RKrom Date: Thu, 28 Mar 2013 09:56:55 +0000 Subject: [PATCH] Fix for #1481, checking paste location git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@2538 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4 --- Greenshot/Drawing/DrawableContainerList.cs | 14 +++- Greenshot/Drawing/Surface.cs | 78 ++++++++++++++++++++-- GreenshotPlugin/Interfaces/Generic.cs | 8 +++ 3 files changed, 94 insertions(+), 6 deletions(-) diff --git a/Greenshot/Drawing/DrawableContainerList.cs b/Greenshot/Drawing/DrawableContainerList.cs index 32739ab84..d6420a7fc 100644 --- a/Greenshot/Drawing/DrawableContainerList.cs +++ b/Greenshot/Drawing/DrawableContainerList.cs @@ -40,8 +40,17 @@ namespace Greenshot.Drawing { private static CoreConfiguration conf = IniConfig.GetIniSection(); private static System.ComponentModel.ComponentResourceManager editorFormResources = new System.ComponentModel.ComponentResourceManager(typeof(ImageEditorForm)); + public Guid ParentID { + get; + private set; + } + public DrawableContainerList() { } + + public DrawableContainerList(Guid parentID) { + ParentID = parentID; + } public EditStatus Status { get { @@ -87,12 +96,13 @@ namespace Greenshot.Drawing { /// public ISurface Parent { get { - if(Count > 0) { + if (Count > 0) { return this[Count-1].Parent; } return null; } - set { + set { + ParentID = value.ID; foreach(DrawableContainer dc in this) { dc.Parent = value; } diff --git a/Greenshot/Drawing/Surface.cs b/Greenshot/Drawing/Surface.cs index 7dc958475..08caad5ff 100644 --- a/Greenshot/Drawing/Surface.cs +++ b/Greenshot/Drawing/Surface.cs @@ -49,6 +49,21 @@ namespace Greenshot.Drawing { public static int Count = 0; private static CoreConfiguration conf = IniConfig.GetIniSection(); + // Property to identify the Surface ID + private Guid uniqueID = Guid.NewGuid(); + + /// + /// The GUID of the surface + /// + public Guid ID { + get { + return uniqueID; + } + set { + uniqueID = value; + } + } + /// /// Event handlers (do not serialize!) /// @@ -159,7 +174,7 @@ namespace Greenshot.Drawing { /// all selected elements, do not serialize /// [NonSerialized] - private DrawableContainerList selectedElements = new DrawableContainerList(); + private DrawableContainerList selectedElements; /// /// the element we are drawing with, do not serialize @@ -198,7 +213,7 @@ namespace Greenshot.Drawing { /// /// all elements on the surface, needed with serialization /// - private DrawableContainerList elements = new DrawableContainerList(); + private DrawableContainerList elements; /// /// all elements on the surface, needed with serialization @@ -366,6 +381,8 @@ namespace Greenshot.Drawing { /// public Surface() : base(){ Count++; + elements = new DrawableContainerList(uniqueID); + selectedElements = new DrawableContainerList(uniqueID); LOG.Debug("Creating surface!"); this.MouseDown += new MouseEventHandler(SurfaceMouseDown); this.MouseUp += new MouseEventHandler(SurfaceMouseUp); @@ -961,7 +978,7 @@ namespace Greenshot.Drawing { // Single element IDrawableContainer rightClickedContainer = elements.ClickableElementAt(mouseStart.X, mouseStart.Y); if (rightClickedContainer != null) { - selectedList = new DrawableContainerList(); + selectedList = new DrawableContainerList(ID); selectedList.Add(rightClickedContainer); } } @@ -1373,8 +1390,61 @@ namespace Greenshot.Drawing { if (formats.Contains(typeof(DrawableContainerList).FullName)) { DrawableContainerList dcs = (DrawableContainerList)ClipboardHelper.GetFromDataObject(clipboard, typeof(DrawableContainerList)); if (dcs != null) { + // Make element(s) only move 10,10 if the surface is the same + Point moveOffset; + bool isSameSurface = (dcs.ParentID == this.uniqueID); dcs.Parent = this; - dcs.MoveBy(10,10); + if (isSameSurface) { + moveOffset = new Point(10, 10); + } else { + moveOffset = Point.Empty; + } + // Here a fix for bug #1475, first calculate the bounds of the complete DrawableContainerList + Rectangle drawableContainerListBounds = Rectangle.Empty; + foreach (IDrawableContainer element in dcs) { + if (drawableContainerListBounds == Rectangle.Empty) { + drawableContainerListBounds = element.DrawingBounds; + } 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) { + Point containersLocation = drawableContainerListBounds.Location; + containersLocation.Offset(moveOffset); + if (!Bounds.Contains(containersLocation)) { + // Easy fix for same surface + if (isSameSurface) { + moveOffset = new Point(-10, -10); + } 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 { + Rectangle moveContainerListBounds = drawableContainerListBounds; + moveContainerListBounds.Offset(moveOffset); + // check if the element is inside + if (!Bounds.Contains(moveContainerListBounds)) { + // Easy fix for same surface + if (isSameSurface) { + moveOffset = new Point(-10, -10); + } else { + // For different surface, which is most likely smaller + int offsetX = 0; + int offsetY = 0; + if (drawableContainerListBounds.Right > Bounds.Right) { + offsetX = Bounds.Right - drawableContainerListBounds.Right; + } + if (drawableContainerListBounds.Bottom > Bounds.Bottom) { + offsetY = Bounds.Bottom - drawableContainerListBounds.Bottom; + } + moveOffset = new Point(offsetX, offsetY); + } + } + } + dcs.MoveBy(moveOffset.X, moveOffset.Y); AddElements(dcs); FieldAggregator.BindElements(dcs); DeselectAllElements(); diff --git a/GreenshotPlugin/Interfaces/Generic.cs b/GreenshotPlugin/Interfaces/Generic.cs index 6e1e9d577..9cf9fb032 100644 --- a/GreenshotPlugin/Interfaces/Generic.cs +++ b/GreenshotPlugin/Interfaces/Generic.cs @@ -86,6 +86,14 @@ namespace Greenshot.Plugin { event SurfaceDrawingModeEventHandler DrawingModeChanged; event SurfaceElementEventHandler MovingElementChanged; + /// + /// Unique ID of the Surface + /// + Guid ID { + get; + set; + } + /// /// Get/Set the image to the Surface /// get will give the image as is currently visible