diff --git a/src/Greenshot.Base/Controls/GreenshotForm.cs b/src/Greenshot.Base/Controls/GreenshotForm.cs
index eff79e975..42b2719ce 100644
--- a/src/Greenshot.Base/Controls/GreenshotForm.cs
+++ b/src/Greenshot.Base/Controls/GreenshotForm.cs
@@ -350,7 +350,7 @@ namespace Greenshot.Base.Controls
{
if (!Language.TryGetString(languageKey, out langString))
{
- LOG.WarnFormat("Unknown language key '{0}' configured for control '{1}', this might be okay.", languageKey, applyTo.Name);
+ LOG.DebugFormat("Unknown language key '{0}' configured for control '{1}', this might be okay.", languageKey, applyTo.Name);
return;
}
diff --git a/src/Greenshot.Base/Core/Language.cs b/src/Greenshot.Base/Core/Language.cs
index 8037393ad..4627a10fc 100644
--- a/src/Greenshot.Base/Core/Language.cs
+++ b/src/Greenshot.Base/Core/Language.cs
@@ -470,7 +470,7 @@ namespace Greenshot.Base.Core
languageFile
};
LanguageFiles.Add(languageFile.Ietf, currentFiles);
- Log.InfoFormat("Added language definition {0} from: {1}", languageFile.Description, languageFile.Filepath);
+ Log.DebugFormat("Added language definition {0} from: {1}", languageFile.Description, languageFile.Filepath);
}
}
}
diff --git a/src/Greenshot.Base/Interfaces/Drawing/Adorners/IAdorner.cs b/src/Greenshot.Base/Interfaces/Drawing/Adorners/IAdorner.cs
index 4dfa4811d..c55044928 100644
--- a/src/Greenshot.Base/Interfaces/Drawing/Adorners/IAdorner.cs
+++ b/src/Greenshot.Base/Interfaces/Drawing/Adorners/IAdorner.cs
@@ -108,5 +108,10 @@ namespace Greenshot.Base.Interfaces.Drawing.Adorners
/// The color of the fill of the adorner
///
Color FillColor { get; set; }
+
+ ///
+ /// This is to TAG the adorner so we know the type
+ ///
+ string Tag { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Greenshot.Base/Interfaces/Drawing/IDrawableContainer.cs b/src/Greenshot.Base/Interfaces/Drawing/IDrawableContainer.cs
index 3d420bfa3..2363b7ac9 100644
--- a/src/Greenshot.Base/Interfaces/Drawing/IDrawableContainer.cs
+++ b/src/Greenshot.Base/Interfaces/Drawing/IDrawableContainer.cs
@@ -24,6 +24,7 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
+using System.Windows.Forms;
using Greenshot.Base.Interfaces.Drawing.Adorners;
namespace Greenshot.Base.Interfaces.Drawing
@@ -97,5 +98,13 @@ namespace Greenshot.Base.Interfaces.Drawing
///
/// uint
void AdjustToDpi(uint dpi);
+
+ ///
+ /// Enable a way for elements to add a context menu entry
+ ///
+ /// ContextMenuStrip
+ /// ISurface
+ /// MouseEventArgs
+ void AddContextMenuItems(ContextMenuStrip menu, ISurface surface, MouseEventArgs mouseEventArgs);
}
}
\ No newline at end of file
diff --git a/src/Greenshot.Base/Interfaces/ISurface.cs b/src/Greenshot.Base/Interfaces/ISurface.cs
index 396a5702f..4ec000ed9 100644
--- a/src/Greenshot.Base/Interfaces/ISurface.cs
+++ b/src/Greenshot.Base/Interfaces/ISurface.cs
@@ -101,13 +101,49 @@ namespace Greenshot.Base.Interfaces
long SaveElementsToStream(Stream stream);
void LoadElementsFromStream(Stream stream);
+ ///
+ /// Provides the selected elements
+ ///
+ IDrawableContainerList SelectedElements { get; }
+
+ ///
+ /// Is there an element selected on the surface?
+ ///
bool HasSelectedElements { get; }
+
+ ///
+ /// Remove all selected elements
+ ///
void RemoveSelectedElements();
+
+ ///
+ /// Cut the selected elements to the clipboard
+ ///
void CutSelectedElements();
+
+ ///
+ /// Copy the selected elements to the clipboard
+ ///
void CopySelectedElements();
+
+ ///
+ /// Paste the elements from the clipboard
+ ///
void PasteElementFromClipboard();
+
+ ///
+ /// Duplicate the selected elements
+ ///
void DuplicateSelectedElements();
+
+ ///
+ /// Deselected the specified element
+ ///
void DeselectElement(IDrawableContainer container, bool generateEvents = true);
+
+ ///
+ /// Deselected all elements
+ ///
void DeselectAllElements();
///
diff --git a/src/Greenshot.Base/UnmanagedHelpers/Enums/RegionResult.cs b/src/Greenshot.Base/UnmanagedHelpers/Enums/RegionResult.cs
index 013f70ef3..f9c0e5a1f 100644
--- a/src/Greenshot.Base/UnmanagedHelpers/Enums/RegionResult.cs
+++ b/src/Greenshot.Base/UnmanagedHelpers/Enums/RegionResult.cs
@@ -28,5 +28,7 @@ namespace Greenshot.Base.UnmanagedHelpers.Enums
{
REGION_ERROR = 0,
REGION_NULLREGION = 1,
+ SIMPLEREGION = 2,
+ COMPLEXREGION = 3
}
}
\ No newline at end of file
diff --git a/src/Greenshot.Editor/Drawing/Adorners/AbstractAdorner.cs b/src/Greenshot.Editor/Drawing/Adorners/AbstractAdorner.cs
index dde10bb84..0890a87d9 100644
--- a/src/Greenshot.Editor/Drawing/Adorners/AbstractAdorner.cs
+++ b/src/Greenshot.Editor/Drawing/Adorners/AbstractAdorner.cs
@@ -176,5 +176,10 @@ namespace Greenshot.Editor.Drawing.Adorners
public virtual void Transform(Matrix matrix)
{
}
+
+ ///
+ /// This is to TAG the adorner so we know the type
+ ///
+ public string Tag { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Greenshot.Editor/Drawing/Adorners/TargetAdorner.cs b/src/Greenshot.Editor/Drawing/Adorners/TargetAdorner.cs
index f39f535e6..c59fc43ef 100644
--- a/src/Greenshot.Editor/Drawing/Adorners/TargetAdorner.cs
+++ b/src/Greenshot.Editor/Drawing/Adorners/TargetAdorner.cs
@@ -27,7 +27,7 @@ using Greenshot.Base.Interfaces.Drawing;
namespace Greenshot.Editor.Drawing.Adorners
{
///
- /// This implements the special "gripper" for the Speech-Bubble tail
+ /// This implements the special target "gripper", e.g. used for the Speech-Bubble tail
///
public sealed class TargetAdorner : AbstractAdorner
{
@@ -41,8 +41,8 @@ namespace Greenshot.Editor.Drawing.Adorners
///
/// Handle the mouse down
///
- ///
- ///
+ /// object
+ /// MouseEventArgs
public override void MouseDown(object sender, MouseEventArgs mouseEventArgs)
{
EditStatus = EditStatus.MOVING;
@@ -51,8 +51,8 @@ namespace Greenshot.Editor.Drawing.Adorners
///
/// Handle the mouse move
///
- ///
- ///
+ /// object
+ /// MouseEventArgs
public override void MouseMove(object sender, MouseEventArgs mouseEventArgs)
{
if (EditStatus != EditStatus.MOVING)
diff --git a/src/Greenshot.Editor/Drawing/ArrowContainer.cs b/src/Greenshot.Editor/Drawing/ArrowContainer.cs
index eb1e10e2f..9907ad106 100644
--- a/src/Greenshot.Editor/Drawing/ArrowContainer.cs
+++ b/src/Greenshot.Editor/Drawing/ArrowContainer.cs
@@ -66,44 +66,40 @@ namespace Greenshot.Editor.Drawing
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
- if (lineThickness > 0)
+ if (lineThickness <= 0) return;
+
+ graphics.SmoothingMode = SmoothingMode.HighQuality;
+ graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
+ graphics.CompositingQuality = CompositingQuality.HighQuality;
+ graphics.PixelOffsetMode = PixelOffsetMode.None;
+ Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
+ ArrowHeadCombination heads = (ArrowHeadCombination) GetFieldValue(FieldType.ARROWHEADS);
+ if (shadow)
{
- graphics.SmoothingMode = SmoothingMode.HighQuality;
- graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
- graphics.CompositingQuality = CompositingQuality.HighQuality;
- graphics.PixelOffsetMode = PixelOffsetMode.None;
- Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
- ArrowHeadCombination heads = (ArrowHeadCombination) GetFieldValue(FieldType.ARROWHEADS);
- if (lineThickness > 0)
+ //draw shadow first
+ int basealpha = 100;
+ int alpha = basealpha;
+ int steps = 5;
+ int currentStep = 1;
+ while (currentStep <= steps)
{
- if (shadow)
- {
- //draw shadow first
- int basealpha = 100;
- int alpha = basealpha;
- int steps = 5;
- int currentStep = 1;
- while (currentStep <= steps)
- {
- using Pen shadowCapPen = new Pen(Color.FromArgb(alpha, 100, 100, 100), lineThickness);
- SetArrowHeads(heads, shadowCapPen);
+ using Pen shadowCapPen = new Pen(Color.FromArgb(alpha, 100, 100, 100), lineThickness);
+ SetArrowHeads(heads, shadowCapPen);
- graphics.DrawLine(shadowCapPen,
- Left + currentStep,
- Top + currentStep,
- Left + currentStep + Width,
- Top + currentStep + Height);
+ graphics.DrawLine(shadowCapPen,
+ Left + currentStep,
+ Top + currentStep,
+ Left + currentStep + Width,
+ Top + currentStep + Height);
- currentStep++;
- alpha -= basealpha / steps;
- }
- }
-
- using Pen pen = new Pen(lineColor, lineThickness);
- SetArrowHeads(heads, pen);
- graphics.DrawLine(pen, Left, Top, Left + Width, Top + Height);
+ currentStep++;
+ alpha -= basealpha / steps;
}
}
+
+ using Pen pen = new Pen(lineColor, lineThickness);
+ SetArrowHeads(heads, pen);
+ graphics.DrawLine(pen, Left, Top, Left + Width, Top + Height);
}
private void SetArrowHeads(ArrowHeadCombination heads, Pen pen)
diff --git a/src/Greenshot.Editor/Drawing/DrawableContainer.cs b/src/Greenshot.Editor/Drawing/DrawableContainer.cs
index 38eab8b3f..f8a14052b 100644
--- a/src/Greenshot.Editor/Drawing/DrawableContainer.cs
+++ b/src/Greenshot.Editor/Drawing/DrawableContainer.cs
@@ -26,6 +26,7 @@ using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Runtime.Serialization;
+using System.Windows.Forms;
using Greenshot.Base.IniFile;
using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing;
@@ -448,6 +449,12 @@ namespace Greenshot.Editor.Drawing
}
}
+ ///
+ public virtual void AddContextMenuItems(ContextMenuStrip menu, ISurface surface, MouseEventArgs mouseEventArgs)
+ {
+ // Empty as we do not want to add something to the context menu for every element
+ }
+
public virtual bool Contains(int x, int y)
{
return Bounds.Contains(x, y);
diff --git a/src/Greenshot.Editor/Drawing/DrawableContainerList.cs b/src/Greenshot.Editor/Drawing/DrawableContainerList.cs
index 9ab825e4a..4da98fa37 100644
--- a/src/Greenshot.Editor/Drawing/DrawableContainerList.cs
+++ b/src/Greenshot.Editor/Drawing/DrawableContainerList.cs
@@ -589,9 +589,10 @@ namespace Greenshot.Editor.Drawing
///
/// Add items to a context menu for the selected item
///
- ///
- ///
- public virtual void AddContextMenuItems(ContextMenuStrip menu, ISurface surface)
+ /// ContextMenuStrip
+ /// ISurface
+ /// MouseEventArgs
+ public virtual void AddContextMenuItems(ContextMenuStrip menu, ISurface surface, MouseEventArgs mouseEventArgs)
{
bool push = surface.Elements.CanPushDown(this);
bool pull = surface.Elements.CanPullUp(this);
@@ -678,15 +679,7 @@ namespace Greenshot.Editor.Drawing
menu.Items.Add(item);
// Reset
- bool canReset = false;
- foreach (var drawableContainer in this)
- {
- var container = (DrawableContainer) drawableContainer;
- if (container.HasDefaultSize)
- {
- canReset = true;
- }
- }
+ bool canReset = this.Cast().Any(container => container.HasDefaultSize);
if (canReset)
{
@@ -713,48 +706,40 @@ namespace Greenshot.Editor.Drawing
};
menu.Items.Add(item);
}
+
+ // "ask" the containers to add to the context menu
+ foreach (var surfaceElement in surface.Elements)
+ {
+ surfaceElement.AddContextMenuItems(menu, surface, mouseEventArgs);
+ }
}
- public virtual void ShowContextMenu(MouseEventArgs e, ISurface iSurface)
+ public virtual void ShowContextMenu(MouseEventArgs mouseEventArgs, ISurface iSurface)
{
if (iSurface is not Surface surface)
{
return;
}
- bool hasMenu = false;
- foreach (var drawableContainer in this)
+ bool hasMenu = this.Cast().Any(container => container.HasContextMenu);
+
+ if (!hasMenu) return;
+
+ ContextMenuStrip menu = new ContextMenuStrip();
+ AddContextMenuItems(menu, surface, mouseEventArgs);
+ if (menu.Items.Count <= 0) return;
+ menu.Show(surface, surface.ToSurfaceCoordinates(mouseEventArgs.Location));
+ while (true)
{
- var container = (DrawableContainer) drawableContainer;
- if (!container.HasContextMenu)
+ if (menu.Visible)
{
- continue;
+ Application.DoEvents();
+ Thread.Sleep(100);
}
-
- hasMenu = true;
- break;
- }
-
- if (hasMenu)
- {
- ContextMenuStrip menu = new ContextMenuStrip();
- AddContextMenuItems(menu, surface);
- if (menu.Items.Count > 0)
+ else
{
- menu.Show(surface, surface.ToSurfaceCoordinates(e.Location));
- while (true)
- {
- if (menu.Visible)
- {
- Application.DoEvents();
- Thread.Sleep(100);
- }
- else
- {
- menu.Dispose();
- break;
- }
- }
+ menu.Dispose();
+ break;
}
}
}
@@ -763,18 +748,16 @@ namespace Greenshot.Editor.Drawing
protected virtual void Dispose(bool disposing)
{
- if (!_disposedValue)
+ if (_disposedValue) return;
+ if (disposing)
{
- if (disposing)
+ foreach (var drawableContainer in this)
{
- foreach (var drawableContainer in this)
- {
- drawableContainer.Dispose();
- }
+ drawableContainer.Dispose();
}
-
- _disposedValue = true;
}
+
+ _disposedValue = true;
}
// This code added to correctly implement the disposable pattern.
diff --git a/src/Greenshot.Editor/Drawing/Surface.cs b/src/Greenshot.Editor/Drawing/Surface.cs
index be40c7d1c..8eb2a872e 100644
--- a/src/Greenshot.Editor/Drawing/Surface.cs
+++ b/src/Greenshot.Editor/Drawing/Surface.cs
@@ -2036,23 +2036,27 @@ namespace Greenshot.Editor.Drawing
///
/// Returns if this surface has selected elements
///
- ///
- public bool HasSelectedElements => (selectedElements != null && selectedElements.Count > 0);
+ /// bool
+ public bool HasSelectedElements => selectedElements is { Count: > 0 };
+
+ ///
+ /// Provides the selected elements
+ ///
+ public IDrawableContainerList SelectedElements => selectedElements;
///
/// Remove all the selected elements
///
public void RemoveSelectedElements()
{
- if (HasSelectedElements)
+ if (!HasSelectedElements) return;
+
+ // As RemoveElement will remove the element from the selectedElements list we need to copy the element to another list.
+ RemoveElements(selectedElements);
+ if (_movingElementChanged != null)
{
- // 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();
- _movingElementChanged(this, eventArgs);
- }
+ SurfaceElementEventArgs eventArgs = new SurfaceElementEventArgs();
+ _movingElementChanged(this, eventArgs);
}
}