Enhanced ability to crop an image vertically and horizontally. #249 (#388)

Co-authored-by: Robin Krom <robin@getgreenshot.org>
This commit is contained in:
Christian Schulz 2022-03-22 11:57:01 +01:00 committed by GitHub
parent 4a66a4dbe2
commit 56c26ac038
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
64 changed files with 865 additions and 310 deletions

View file

@ -190,12 +190,14 @@ namespace Greenshot.Base.Core
/// <summary> /// <summary>
/// Private helper method for the FindAutoCropRectangle /// Private helper method for the FindAutoCropRectangle
/// </summary> /// </summary>
/// <param name="fastBitmap"></param> /// <param name="fastBitmap">IFastBitmap</param>
/// <param name="colorPoint"></param> /// <param name="colorPoint">Point</param>
/// <param name="cropDifference"></param> /// <param name="cropDifference">int</param>
/// <param name="area">Rectangle with optional area to scan in</param>
/// <returns>Rectangle</returns> /// <returns>Rectangle</returns>
private static Rectangle FindAutoCropRectangle(IFastBitmap fastBitmap, Point colorPoint, int cropDifference) private static Rectangle FindAutoCropRectangle(IFastBitmap fastBitmap, Point colorPoint, int cropDifference, Rectangle? area = null)
{ {
area ??= new Rectangle(0, 0, fastBitmap.Width, fastBitmap.Height);
Rectangle cropRectangle = Rectangle.Empty; Rectangle cropRectangle = Rectangle.Empty;
Color referenceColor = fastBitmap.GetColorAt(colorPoint.X, colorPoint.Y); Color referenceColor = fastBitmap.GetColorAt(colorPoint.X, colorPoint.Y);
Point min = new Point(int.MaxValue, int.MaxValue); Point min = new Point(int.MaxValue, int.MaxValue);
@ -203,9 +205,9 @@ namespace Greenshot.Base.Core
if (cropDifference > 0) if (cropDifference > 0)
{ {
for (int y = 0; y < fastBitmap.Height; y++) for (int y = area.Value.Top; y < area.Value.Bottom; y++)
{ {
for (int x = 0; x < fastBitmap.Width; x++) for (int x = area.Value.Left; x < area.Value.Right; x++)
{ {
Color currentColor = fastBitmap.GetColorAt(x, y); Color currentColor = fastBitmap.GetColorAt(x, y);
int diffR = Math.Abs(currentColor.R - referenceColor.R); int diffR = Math.Abs(currentColor.R - referenceColor.R);
@ -225,9 +227,9 @@ namespace Greenshot.Base.Core
} }
else else
{ {
for (int y = 0; y < fastBitmap.Height; y++) for (int y = area.Value.Top; y < area.Value.Bottom; y++)
{ {
for (int x = 0; x < fastBitmap.Width; x++) for (int x = area.Value.Left; x < area.Value.Right; x++)
{ {
Color currentColor = fastBitmap.GetColorAt(x, y); Color currentColor = fastBitmap.GetColorAt(x, y);
if (!referenceColor.Equals(currentColor)) if (!referenceColor.Equals(currentColor))
@ -243,7 +245,7 @@ namespace Greenshot.Base.Core
} }
} }
if (!(Point.Empty.Equals(min) && max.Equals(new Point(fastBitmap.Width - 1, fastBitmap.Height - 1)))) if (!(Point.Empty.Equals(min) && max.Equals(new Point(area.Value.Width - 1, area.Value.Height - 1))))
{ {
if (!(min.X == int.MaxValue || min.Y == int.MaxValue || max.X == int.MinValue || min.X == int.MinValue)) if (!(min.X == int.MaxValue || min.Y == int.MaxValue || max.X == int.MinValue || min.X == int.MinValue))
{ {
@ -257,18 +259,20 @@ namespace Greenshot.Base.Core
/// <summary> /// <summary>
/// Get a rectangle for the image which crops the image of all colors equal to that on 0,0 /// Get a rectangle for the image which crops the image of all colors equal to that on 0,0
/// </summary> /// </summary>
/// <param name="image"></param> /// <param name="image">Image</param>
/// <param name="cropDifference"></param> /// <param name="cropDifference">int</param>
/// <param name="area">Rectangle with optional area</param>
/// <returns>Rectangle</returns> /// <returns>Rectangle</returns>
public static Rectangle FindAutoCropRectangle(Image image, int cropDifference) public static Rectangle FindAutoCropRectangle(Image image, int cropDifference, Rectangle? area = null)
{ {
area ??= new Rectangle(0, 0, image.Width, image.Height);
Rectangle cropRectangle = Rectangle.Empty; Rectangle cropRectangle = Rectangle.Empty;
var checkPoints = new List<Point> var checkPoints = new List<Point>
{ {
new Point(0, 0), new Point(area.Value.Left, area.Value.Top),
new Point(0, image.Height - 1), new Point(area.Value.Left, area.Value.Bottom - 1),
new Point(image.Width - 1, 0), new Point(area.Value.Right - 1, area.Value.Top),
new Point(image.Width - 1, image.Height - 1) new Point(area.Value.Right - 1, area.Value.Bottom - 1)
}; };
// Top Left // Top Left
// Bottom Left // Bottom Left
@ -279,7 +283,7 @@ namespace Greenshot.Base.Core
// find biggest area // find biggest area
foreach (Point checkPoint in checkPoints) foreach (Point checkPoint in checkPoints)
{ {
var currentRectangle = FindAutoCropRectangle(fastBitmap, checkPoint, cropDifference); var currentRectangle = FindAutoCropRectangle(fastBitmap, checkPoint, cropDifference, area);
if (currentRectangle.Width * currentRectangle.Height > cropRectangle.Width * cropRectangle.Height) if (currentRectangle.Width * currentRectangle.Height > cropRectangle.Width * cropRectangle.Height)
{ {
cropRectangle = currentRectangle; cropRectangle = currentRectangle;
@ -295,7 +299,7 @@ namespace Greenshot.Base.Core
/// </summary> /// </summary>
/// <param name="sourceImage">Bitmap</param> /// <param name="sourceImage">Bitmap</param>
/// <param name="effect">IEffect</param> /// <param name="effect">IEffect</param>
/// <param name="matrix"></param> /// <param name="matrix">Matrix</param>
/// <returns>Bitmap</returns> /// <returns>Bitmap</returns>
public static Image ApplyEffect(Image sourceImage, IEffect effect, Matrix matrix) public static Image ApplyEffect(Image sourceImage, IEffect effect, Matrix matrix)
{ {

View file

@ -78,6 +78,11 @@ namespace Greenshot.Base.Interfaces.Drawing
bool InitContent(); bool InitContent();
/// <summary>
/// Defines if the drawable container participates in undo / redo
/// </summary>
bool IsUndoable { get; }
void MakeBoundsChangeUndoable(bool allowMerge); void MakeBoundsChangeUndoable(bool allowMerge);
EditStatus DefaultEditMode { get; } EditStatus DefaultEditMode { get; }

View file

@ -21,6 +21,9 @@
namespace Greenshot.Base.Interfaces.Drawing namespace Greenshot.Base.Interfaces.Drawing
{ {
/// <summary>
/// The IFieldAggregator defines the connections between fields and containers
/// </summary>
public interface IFieldAggregator public interface IFieldAggregator
{ {
void UnbindElement(IDrawableContainer dc); void UnbindElement(IDrawableContainer dc);

View file

@ -201,8 +201,16 @@ namespace Greenshot.Base.Interfaces
/// <param name="rc">A rectangle in the coordinate space of the surface.</param> /// <param name="rc">A rectangle in the coordinate space of the surface.</param>
Rectangle ToImageCoordinates(Rectangle rc); Rectangle ToImageCoordinates(Rectangle rc);
/// <summary>
/// Make it possible to undo the specified IMemento
/// </summary>
/// <param name="memento">IMemento</param>
/// <param name="allowMerge">bool to specify if the action can be merged, e.g. we do not want an undo for every part of a resize</param>
void MakeUndoable(IMemento memento, bool allowMerge); void MakeUndoable(IMemento memento, bool allowMerge);
/// <summary>
/// The IFieldAggregator
/// </summary>
IFieldAggregator FieldAggregator { get; } IFieldAggregator FieldAggregator { get; }
/// <summary> /// <summary>

View file

@ -33,6 +33,7 @@ namespace Greenshot.Editor.Configuration
contextmenu_capturefullscreen_right, contextmenu_capturefullscreen_right,
contextmenu_capturefullscreen_bottom, contextmenu_capturefullscreen_bottom,
contextmenu_captureie, contextmenu_captureie,
editor_autocrop_not_possible,
editor_clipboardfailed, editor_clipboardfailed,
editor_close_on_save, editor_close_on_save,
editor_close_on_save_title, editor_close_on_save_title,

View file

@ -19,10 +19,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
using System.Drawing; using System.Drawing;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Drawing; using Greenshot.Base.Interfaces.Drawing;
using Greenshot.Editor.Drawing.Adorners;
using Greenshot.Editor.Drawing.Fields; using Greenshot.Editor.Drawing.Fields;
using Greenshot.Editor.Helpers; using Greenshot.Editor.Helpers;
@ -33,6 +35,29 @@ namespace Greenshot.Editor.Drawing
/// </summary> /// </summary>
public class CropContainer : DrawableContainer public class CropContainer : DrawableContainer
{ {
/// <summary>
/// Available Crop modes
/// </summary>
public enum CropModes
{
/// <summary>
/// crop all outside the selection rectangle
/// </summary>
Default,
/// <summary>
/// like default, but initially creates the selection rectangle
/// </summary>
AutoCrop,
/// <summary>
/// crop all inside the selection, anchors the selection to the top and bottom edges
/// </summary>
Vertical,
/// <summary>
/// crop all inside the selection, anchors the selection to the left and right edges
/// </summary>
Horizontal
}
public CropContainer(ISurface parent) : base(parent) public CropContainer(ISurface parent) : base(parent)
{ {
Init(); Init();
@ -45,13 +70,66 @@ namespace Greenshot.Editor.Drawing
} }
private void Init() private void Init()
{
switch (GetFieldValue(FieldType.CROPMODE))
{
case CropModes.Horizontal:
{
InitHorizontalCropOutStyle();
break;
}
case CropModes.Vertical:
{
InitVerticalCropOutStyle();
break;
}
default:
{ {
CreateDefaultAdorners(); CreateDefaultAdorners();
break;
}
}
}
private void InitHorizontalCropOutStyle()
{
const int defaultHeight = 25;
if (_parent?.Image is { } image)
{
Size = new Size(image.Width, defaultHeight);
}
CreateTopBottomAdorners();
}
private void InitVerticalCropOutStyle()
{
const int defaultWidth = 25;
if (_parent?.Image is { } image)
{
Size = new Size(defaultWidth, image.Height);
}
CreateLeftRightAdorners();
}
private void CreateTopBottomAdorners()
{
Adorners.Add(new ResizeAdorner(this, Positions.TopCenter));
Adorners.Add(new ResizeAdorner(this, Positions.BottomCenter));
}
private void CreateLeftRightAdorners()
{
Adorners.Add(new ResizeAdorner(this, Positions.MiddleLeft));
Adorners.Add(new ResizeAdorner(this, Positions.MiddleRight));
} }
protected override void InitializeFields() protected override void InitializeFields()
{ {
AddField(GetType(), FieldType.FLAGS, FieldFlag.CONFIRMABLE); AddField(GetType(), FieldType.FLAGS, FieldFlag.CONFIRMABLE);
AddField(GetType(), FieldType.CROPMODE, CropModes.Default);
} }
public override void Invalidate() public override void Invalidate()
@ -83,6 +161,7 @@ namespace Greenshot.Editor.Drawing
return; return;
} }
using Brush cropBrush = new SolidBrush(Color.FromArgb(100, 150, 150, 100)); using Brush cropBrush = new SolidBrush(Color.FromArgb(100, 150, 150, 100));
Rectangle cropRectangle = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height); Rectangle cropRectangle = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height);
Rectangle selectionRect = new Rectangle(cropRectangle.Left - 1, cropRectangle.Top - 1, cropRectangle.Width + 1, cropRectangle.Height + 1); Rectangle selectionRect = new Rectangle(cropRectangle.Left - 1, cropRectangle.Top - 1, cropRectangle.Width + 1, cropRectangle.Height + 1);
@ -90,20 +169,104 @@ namespace Greenshot.Editor.Drawing
DrawSelectionBorder(g, selectionRect); DrawSelectionBorder(g, selectionRect);
switch (GetFieldValue(FieldType.CROPMODE))
{
case CropModes.Horizontal:
case CropModes.Vertical:
{
//draw inside
g.FillRectangle(cropBrush, cropRectangle);
break;
}
default:
{
//draw outside
// top // top
g.FillRectangle(cropBrush, new Rectangle(0, 0, imageSize.Width, cropRectangle.Top)); g.FillRectangle(cropBrush, new Rectangle(0, 0, imageSize.Width, cropRectangle.Top));
// left // left
g.FillRectangle(cropBrush, new Rectangle(0, cropRectangle.Top, cropRectangle.Left, cropRectangle.Height)); g.FillRectangle(cropBrush, new Rectangle(0, cropRectangle.Top, cropRectangle.Left, cropRectangle.Height));
// right // right
g.FillRectangle(cropBrush, g.FillRectangle(cropBrush, new Rectangle(cropRectangle.Left + cropRectangle.Width, cropRectangle.Top, imageSize.Width - (cropRectangle.Left + cropRectangle.Width), cropRectangle.Height));
new Rectangle(cropRectangle.Left + cropRectangle.Width, cropRectangle.Top, imageSize.Width - (cropRectangle.Left + cropRectangle.Width), cropRectangle.Height));
// bottom // bottom
g.FillRectangle(cropBrush, new Rectangle(0, cropRectangle.Top + cropRectangle.Height, imageSize.Width, imageSize.Height - (cropRectangle.Top + cropRectangle.Height))); g.FillRectangle(cropBrush, new Rectangle(0, cropRectangle.Top + cropRectangle.Height, imageSize.Width, imageSize.Height - (cropRectangle.Top + cropRectangle.Height)));
break;
}
}
} }
/// <summary> /// <summary>
/// No context menu for the CropContainer /// No context menu for the CropContainer
/// </summary> /// </summary>
public override bool HasContextMenu => false; public override bool HasContextMenu => false;
public override bool HandleMouseDown(int x, int y)
{
return GetFieldValue(FieldType.CROPMODE) switch
{
//force horizontal crop to left edge
CropModes.Horizontal => base.HandleMouseDown(0, y),
//force vertical crop to top edge
CropModes.Vertical => base.HandleMouseDown(x, 0),
_ => base.HandleMouseDown(x, y),
};
}
public override bool HandleMouseMove(int x, int y)
{
Invalidate();
switch (GetFieldValue(FieldType.CROPMODE))
{
case CropModes.Horizontal:
{
//stick on left and right
//allow only horizontal changes
if (_parent?.Image is { } image)
{
_boundsAfterResize.X = 0;
_boundsAfterResize.Y = _boundsBeforeResize.Top;
_boundsAfterResize.Width = image.Width;
_boundsAfterResize.Height = y - _boundsAfterResize.Top;
}
break;
}
case CropModes.Vertical:
{
//stick on top and bottom
//allow only vertical changes
if (_parent?.Image is { } image)
{
_boundsAfterResize.X = _boundsBeforeResize.Left;
_boundsAfterResize.Y = 0;
_boundsAfterResize.Width = x - _boundsAfterResize.Left;
_boundsAfterResize.Height = image.Height;
}
break;
}
default:
{
// reset "workbench" rectangle to current bounds
_boundsAfterResize.X = _boundsBeforeResize.Left;
_boundsAfterResize.Y = _boundsBeforeResize.Top;
_boundsAfterResize.Width = x - _boundsAfterResize.Left;
_boundsAfterResize.Height = y - _boundsAfterResize.Top;
break;
}
}
ScaleHelper.Scale(_boundsBeforeResize, x, y, ref _boundsAfterResize, GetAngleRoundProcessor());
// apply scaled bounds to this DrawableContainer
ApplyBounds(_boundsAfterResize);
Invalidate();
return true;
}
/// <inheritdoc cref="IDrawableContainer"/>
/// Make sure this container is not undoable
public override bool IsUndoable => false;
} }
} }

View file

@ -472,13 +472,20 @@ namespace Greenshot.Editor.Drawing
g.DrawRectangle(pen, rect); g.DrawRectangle(pen, rect);
} }
/// <inheritdoc cref="IDrawableContainer"/>
public virtual bool IsUndoable => true;
/// <summary> /// <summary>
/// Make a following bounds change on this drawablecontainer undoable! /// Make a following bounds change on this drawablecontainer undoable!
/// </summary> /// </summary>
/// <param name="allowMerge">true means allow the moves to be merged</param> /// <param name="allowMerge">true means allow the moves to be merged</param>
public void MakeBoundsChangeUndoable(bool allowMerge) public virtual void MakeBoundsChangeUndoable(bool allowMerge)
{ {
_parent.MakeUndoable(new DrawableContainerBoundsChangeMemento(this), allowMerge); if (!IsUndoable)
{
return;
}
_parent?.MakeUndoable(new DrawableContainerBoundsChangeMemento(this), allowMerge);
} }
public void MoveBy(int dx, int dy) public void MoveBy(int dx, int dy)
@ -552,12 +559,11 @@ namespace Greenshot.Editor.Drawing
protected void OnPropertyChanged(string propertyName) protected void OnPropertyChanged(string propertyName)
{ {
if (_propertyChanged != null) if (_propertyChanged == null) return;
{
_propertyChanged(this, new PropertyChangedEventArgs(propertyName)); _propertyChanged(this, new PropertyChangedEventArgs(propertyName));
Invalidate(); Invalidate();
} }
}
/// <summary> /// <summary>
/// This method will be called before a field is changes. /// This method will be called before a field is changes.
@ -566,8 +572,11 @@ namespace Greenshot.Editor.Drawing
/// <param name="fieldToBeChanged">The field to be changed</param> /// <param name="fieldToBeChanged">The field to be changed</param>
/// <param name="newValue">The new value</param> /// <param name="newValue">The new value</param>
public virtual void BeforeFieldChange(IField fieldToBeChanged, object newValue) public virtual void BeforeFieldChange(IField fieldToBeChanged, object newValue)
{
if (IsUndoable)
{ {
_parent?.MakeUndoable(new ChangeFieldHolderMemento(this, fieldToBeChanged), true); _parent?.MakeUndoable(new ChangeFieldHolderMemento(this, fieldToBeChanged), true);
}
Invalidate(); Invalidate();
} }

View file

@ -24,6 +24,7 @@ using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using System.Linq;
using System.Threading; using System.Threading;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Base.Core; using Greenshot.Base.Core;
@ -50,6 +51,11 @@ namespace Greenshot.Editor.Drawing
{ {
} }
public DrawableContainerList(IEnumerable<IDrawableContainer> elements)
{
AddRange(elements);
}
public DrawableContainerList(Guid parentId) public DrawableContainerList(Guid parentId)
{ {
ParentID = parentId; ParentID = parentId;
@ -130,17 +136,21 @@ namespace Greenshot.Editor.Drawing
} }
/// <summary> /// <summary>
/// Make a following bounds change on this containerlist undoable! /// Make a following bounds change on this DrawableContainerList undoable!
/// </summary> /// </summary>
/// <param name="allowMerge">true means allow the moves to be merged</param> /// <param name="allowMerge">true means allow the moves to be merged</param>
public void MakeBoundsChangeUndoable(bool allowMerge) public void MakeBoundsChangeUndoable(bool allowMerge)
{ {
if (Count > 0 && Parent != null) if (Count <= 0 || Parent == null) return;
// Take all containers to make undoable
var containersToClone = this.Where(c => c.IsUndoable).ToList();
if (!containersToClone.Any())
{ {
var clone = new DrawableContainerList(); return;
clone.AddRange(this);
Parent.MakeUndoable(new DrawableContainerBoundsChangeMemento(clone), allowMerge);
} }
var clone = new DrawableContainerList();
clone.AddRange(containersToClone);
Parent.MakeUndoable(new DrawableContainerBoundsChangeMemento(clone), allowMerge);
} }
/// <summary> /// <summary>
@ -291,8 +301,7 @@ namespace Greenshot.Editor.Drawing
{ {
return Rectangle.Empty; return Rectangle.Empty;
} }
else
{
var result = this[0].DrawingBounds; var result = this[0].DrawingBounds;
for (int i = 1; i < Count; i++) for (int i = 1; i < Count; i++)
{ {
@ -302,14 +311,13 @@ namespace Greenshot.Editor.Drawing
return result; return result;
} }
} }
}
/// <summary> /// <summary>
/// Triggers all elements in the list ot be redrawn. /// Triggers all elements in the list ot be redrawn.
/// </summary> /// </summary>
/// <param name="g">the to the bitmap related Graphics object</param> /// <param name="g">the to the bitmap related Graphics object</param>
/// <param name="bitmap">Bitmap to draw</param> /// <param name="bitmap">Bitmap to draw</param>
/// <param name="renderMode">the rendermode in which the element is to be drawn</param> /// <param name="renderMode">the RenderMode in which the element is to be drawn</param>
/// <param name="clipRectangle"></param> /// <param name="clipRectangle"></param>
public void Draw(Graphics g, Bitmap bitmap, RenderMode renderMode, Rectangle clipRectangle) public void Draw(Graphics g, Bitmap bitmap, RenderMode renderMode, Rectangle clipRectangle)
{ {
@ -574,9 +582,7 @@ namespace Greenshot.Editor.Drawing
return; return;
} }
var dc = this[index1]; (this[index1], this[index2]) = (this[index2], this[index1]);
this[index1] = this[index2];
this[index2] = dc;
Parent.Modified = true; Parent.Modified = true;
} }

View file

@ -31,31 +31,33 @@ namespace Greenshot.Editor.Drawing.Fields
[Serializable] [Serializable]
public class FieldType : IFieldType public class FieldType : IFieldType
{ {
public static readonly IFieldType ARROWHEADS = new FieldType("ARROWHEADS"); public static readonly IFieldType ARROWHEADS = new FieldType(nameof(ARROWHEADS));
public static readonly IFieldType BLUR_RADIUS = new FieldType("BLUR_RADIUS"); public static readonly IFieldType BLUR_RADIUS = new FieldType(nameof(BLUR_RADIUS));
public static readonly IFieldType BRIGHTNESS = new FieldType("BRIGHTNESS"); public static readonly IFieldType BRIGHTNESS = new FieldType(nameof(BRIGHTNESS));
public static readonly IFieldType FILL_COLOR = new FieldType("FILL_COLOR"); public static readonly IFieldType FILL_COLOR = new FieldType(nameof(FILL_COLOR));
public static readonly IFieldType FONT_BOLD = new FieldType("FONT_BOLD"); public static readonly IFieldType FONT_BOLD = new FieldType(nameof(FONT_BOLD));
public static readonly IFieldType FONT_FAMILY = new FieldType("FONT_FAMILY"); public static readonly IFieldType FONT_FAMILY = new FieldType(nameof(FONT_FAMILY));
public static readonly IFieldType FONT_ITALIC = new FieldType("FONT_ITALIC"); public static readonly IFieldType FONT_ITALIC = new FieldType(nameof(FONT_ITALIC));
public static readonly IFieldType FONT_SIZE = new FieldType("FONT_SIZE"); public static readonly IFieldType FONT_SIZE = new FieldType(nameof(FONT_SIZE));
public static readonly IFieldType TEXT_HORIZONTAL_ALIGNMENT = new FieldType("TEXT_HORIZONTAL_ALIGNMENT"); public static readonly IFieldType TEXT_HORIZONTAL_ALIGNMENT = new FieldType(nameof(TEXT_HORIZONTAL_ALIGNMENT));
public static readonly IFieldType TEXT_VERTICAL_ALIGNMENT = new FieldType("TEXT_VERTICAL_ALIGNMENT"); public static readonly IFieldType TEXT_VERTICAL_ALIGNMENT = new FieldType(nameof(TEXT_VERTICAL_ALIGNMENT));
public static readonly IFieldType HIGHLIGHT_COLOR = new FieldType("HIGHLIGHT_COLOR"); public static readonly IFieldType HIGHLIGHT_COLOR = new FieldType(nameof(HIGHLIGHT_COLOR));
public static readonly IFieldType LINE_COLOR = new FieldType("LINE_COLOR"); public static readonly IFieldType LINE_COLOR = new FieldType(nameof(LINE_COLOR));
public static readonly IFieldType LINE_THICKNESS = new FieldType("LINE_THICKNESS"); public static readonly IFieldType LINE_THICKNESS = new FieldType(nameof(LINE_THICKNESS));
public static readonly IFieldType MAGNIFICATION_FACTOR = new FieldType("MAGNIFICATION_FACTOR"); public static readonly IFieldType MAGNIFICATION_FACTOR = new FieldType(nameof(MAGNIFICATION_FACTOR));
public static readonly IFieldType PIXEL_SIZE = new FieldType("PIXEL_SIZE"); public static readonly IFieldType PIXEL_SIZE = new FieldType(nameof(PIXEL_SIZE));
public static readonly IFieldType PREVIEW_QUALITY = new FieldType("PREVIEW_QUALITY"); public static readonly IFieldType PREVIEW_QUALITY = new FieldType(nameof(PREVIEW_QUALITY));
public static readonly IFieldType SHADOW = new FieldType("SHADOW"); public static readonly IFieldType SHADOW = new FieldType(nameof(SHADOW));
public static readonly IFieldType PREPARED_FILTER_OBFUSCATE = new FieldType("PREPARED_FILTER_OBFUSCATE"); public static readonly IFieldType PREPARED_FILTER_OBFUSCATE = new FieldType(nameof(PREPARED_FILTER_OBFUSCATE));
public static readonly IFieldType PREPARED_FILTER_HIGHLIGHT = new FieldType("PREPARED_FILTER_HIGHLIGHT"); public static readonly IFieldType PREPARED_FILTER_HIGHLIGHT = new FieldType(nameof(PREPARED_FILTER_HIGHLIGHT));
public static readonly IFieldType FLAGS = new FieldType("FLAGS"); public static readonly IFieldType FLAGS = new FieldType(nameof(FLAGS));
public static readonly IFieldType CROPMODE = new FieldType(nameof(CROPMODE));
public static IFieldType[] Values = public static IFieldType[] Values =
{ {
ARROWHEADS, BLUR_RADIUS, BRIGHTNESS, FILL_COLOR, FONT_BOLD, FONT_FAMILY, FONT_ITALIC, FONT_SIZE, TEXT_HORIZONTAL_ALIGNMENT, TEXT_VERTICAL_ALIGNMENT, HIGHLIGHT_COLOR, ARROWHEADS, BLUR_RADIUS, BRIGHTNESS, FILL_COLOR, FONT_BOLD, FONT_FAMILY, FONT_ITALIC, FONT_SIZE, TEXT_HORIZONTAL_ALIGNMENT, TEXT_VERTICAL_ALIGNMENT, HIGHLIGHT_COLOR,
LINE_COLOR, LINE_THICKNESS, MAGNIFICATION_FACTOR, PIXEL_SIZE, PREVIEW_QUALITY, SHADOW, PREPARED_FILTER_OBFUSCATE, PREPARED_FILTER_HIGHLIGHT, FLAGS LINE_COLOR, LINE_THICKNESS, MAGNIFICATION_FACTOR, PIXEL_SIZE, PREVIEW_QUALITY, SHADOW, PREPARED_FILTER_OBFUSCATE, PREPARED_FILTER_HIGHLIGHT, FLAGS, CROPMODE
}; };
public string Name { get; set; } public string Name { get; set; }

View file

@ -26,6 +26,7 @@ using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.IO; using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Base.Controls; using Greenshot.Base.Controls;
@ -710,7 +711,7 @@ namespace Greenshot.Editor.Drawing
BinaryFormatter binaryRead = new BinaryFormatter(); BinaryFormatter binaryRead = new BinaryFormatter();
IDrawableContainerList loadedElements = (IDrawableContainerList) binaryRead.Deserialize(streamRead); IDrawableContainerList loadedElements = (IDrawableContainerList) binaryRead.Deserialize(streamRead);
loadedElements.Parent = this; loadedElements.Parent = this;
// Make sure the steplabels are sorted accoring to their number // Make sure the steplabels are sorted according to their number
_stepLabels.Sort((p1, p2) => p1.Number.CompareTo(p2.Number)); _stepLabels.Sort((p1, p2) => p1.Number.CompareTo(p2.Number));
DeselectAllElements(); DeselectAllElements();
AddElements(loadedElements); AddElements(loadedElements);
@ -972,16 +973,17 @@ namespace Greenshot.Editor.Drawing
/// <summary> /// <summary>
/// Auto crop the image /// Auto crop the image
/// </summary> /// </summary>
/// <param name="cropArea">Rectangle with optional area to find a crop region</param>
/// <returns>true if cropped</returns> /// <returns>true if cropped</returns>
public bool AutoCrop() public bool AutoCrop(Rectangle? cropArea = null)
{ {
Rectangle cropRectangle; Rectangle cropRectangle;
using (Image tmpImage = GetImageForExport()) using (Image tmpImage = GetImageForExport())
{ {
cropRectangle = ImageHelper.FindAutoCropRectangle(tmpImage, conf.AutoCropDifference); cropRectangle = ImageHelper.FindAutoCropRectangle(tmpImage, conf.AutoCropDifference, cropArea);
} }
if (!IsCropPossible(ref cropRectangle)) if (!IsCropPossible(ref cropRectangle, CropContainer.CropModes.AutoCrop))
{ {
return false; return false;
} }
@ -1060,11 +1062,13 @@ namespace Greenshot.Editor.Drawing
/// <summary> /// <summary>
/// check if a crop is possible /// check if a crop is possible
/// </summary> /// </summary>
/// <param name="cropRectangle"></param> /// <param name="cropRectangle">Rectangle adapted to the dimensions of the image</param>
/// <param name="cropMode">CropModes</param>
/// <returns>true if this is possible</returns> /// <returns>true if this is possible</returns>
public bool IsCropPossible(ref Rectangle cropRectangle) public bool IsCropPossible(ref Rectangle cropRectangle, CropContainer.CropModes cropMode)
{ {
cropRectangle = GuiRectangle.GetGuiRectangle(cropRectangle.Left, cropRectangle.Top, cropRectangle.Width, cropRectangle.Height); cropRectangle = GuiRectangle.GetGuiRectangle(cropRectangle.Left, cropRectangle.Top, cropRectangle.Width, cropRectangle.Height);
//Fitting the rectangle to the dimensions of the image
if (cropRectangle.Left < 0) if (cropRectangle.Left < 0)
{ {
cropRectangle = new Rectangle(0, cropRectangle.Top, cropRectangle.Width + cropRectangle.Left, cropRectangle.Height); cropRectangle = new Rectangle(0, cropRectangle.Top, cropRectangle.Width + cropRectangle.Left, cropRectangle.Height);
@ -1085,6 +1089,21 @@ namespace Greenshot.Editor.Drawing
cropRectangle = new Rectangle(cropRectangle.Left, cropRectangle.Top, cropRectangle.Width, Image.Height - cropRectangle.Top); cropRectangle = new Rectangle(cropRectangle.Left, cropRectangle.Top, cropRectangle.Width, Image.Height - cropRectangle.Top);
} }
// special condition for vertical
if(cropMode == CropContainer.CropModes.Vertical && cropRectangle.Width == Image.Width)
{
//crop out the hole image is not allowed
return false;
}
// special condition for vertical
if (cropMode == CropContainer.CropModes.Horizontal && cropRectangle.Height == Image.Height)
{
//crop out the hole image is not allowed
return false;
}
//condition for all other crop modes
if (cropRectangle.Height > 0 && cropRectangle.Width > 0) if (cropRectangle.Height > 0 && cropRectangle.Width > 0)
{ {
return true; return true;
@ -1101,8 +1120,8 @@ namespace Greenshot.Editor.Drawing
/// <param name="message">Message itself</param> /// <param name="message">Message itself</param>
public void SendMessageEvent(object source, SurfaceMessageTyp messageType, string message) public void SendMessageEvent(object source, SurfaceMessageTyp messageType, string message)
{ {
if (_surfaceMessage != null) if (_surfaceMessage == null) return;
{
var eventArgs = new SurfaceMessageEventArgs var eventArgs = new SurfaceMessageEventArgs
{ {
Message = message, Message = message,
@ -1111,85 +1130,80 @@ namespace Greenshot.Editor.Drawing
}; };
_surfaceMessage(source, eventArgs); _surfaceMessage(source, eventArgs);
} }
}
/// <summary> /// <summary>
/// Use to update UI when pressing a key to change the foreground color /// Use to update UI when pressing a key to change the foreground color
/// </summary> /// </summary>
/// <param name="source">Who send</param> /// <param name="source">Who send</param>
/// <param name="color">new color</param> /// <param name="color">new color</param>
public void UpdateForegroundColorEvent(object source, Color color) private void UpdateForegroundColorEvent(object source, Color color)
{
if (_foregroundColorChanged != null)
{ {
if (_foregroundColorChanged == null) return;
var eventArgs = new SurfaceForegroundColorEventArgs var eventArgs = new SurfaceForegroundColorEventArgs
{ {
Color = color, Color = color,
}; };
_foregroundColorChanged(source, eventArgs); _foregroundColorChanged(source, eventArgs);
} }
}
/// <summary> /// <summary>
/// Use to update UI when pressing a key to change the background color /// Use to update UI when pressing a key to change the background color
/// </summary> /// </summary>
/// <param name="source">Who send</param> /// <param name="source">Who send</param>
/// <param name="color">new color</param> /// <param name="color">new color</param>
public void UpdateBackgroundColorEvent(object source, Color color) private void UpdateBackgroundColorEvent(object source, Color color)
{
if (_lineThicknessChanged != null)
{ {
if (_lineThicknessChanged == null) return;
var eventArgs = new SurfaceBackgroundColorEventArgs var eventArgs = new SurfaceBackgroundColorEventArgs
{ {
Color = color, Color = color,
}; };
_backgroundColorChanged(source, eventArgs); _backgroundColorChanged(source, eventArgs);
} }
}
/// <summary> /// <summary>
/// Use to update UI when pressing a key to change the line thickness /// Use to update UI when pressing a key to change the line thickness
/// </summary> /// </summary>
/// <param name="source">Who send</param> /// <param name="source">Who send</param>
/// <param name="thickness">new thickness</param> /// <param name="thickness">new thickness</param>
public void UpdateLineThicknessEvent(object source, int thickness) private void UpdateLineThicknessEvent(object source, int thickness)
{
if (_lineThicknessChanged != null)
{ {
if (_lineThicknessChanged == null) return;
var eventArgs = new SurfaceLineThicknessEventArgs var eventArgs = new SurfaceLineThicknessEventArgs
{ {
Thickness = thickness, Thickness = thickness,
}; };
_lineThicknessChanged(source, eventArgs); _lineThicknessChanged(source, eventArgs);
} }
}
/// <summary> /// <summary>
/// Use to update UI when pressing the key to show/hide the shadow /// Use to update UI when pressing the key to show/hide the shadow
/// </summary> /// </summary>
/// <param name="source">Who send</param> /// <param name="source">Who send</param>
/// <param name="hasShadow">has shadow</param> /// <param name="hasShadow">has shadow</param>
public void UpdateShadowEvent(object source, bool hasShadow) private void UpdateShadowEvent(object source, bool hasShadow)
{
if (_shadowChanged != null)
{ {
if (_shadowChanged == null) return;
var eventArgs = new SurfaceShadowEventArgs var eventArgs = new SurfaceShadowEventArgs
{ {
HasShadow = hasShadow, HasShadow = hasShadow,
}; };
_shadowChanged(source, eventArgs); _shadowChanged(source, eventArgs);
} }
}
/// <summary> /// <summary>
/// Crop the surface /// Crop the surface
/// </summary> /// </summary>
/// <param name="cropRectangle"></param> /// <param name="cropRectangle">rectangle that remains</param>
/// <returns></returns> /// <returns>bool</returns>
public bool ApplyCrop(Rectangle cropRectangle) public bool ApplyCrop(Rectangle cropRectangle)
{ {
if (IsCropPossible(ref cropRectangle)) if (!IsCropPossible(ref cropRectangle, CropContainer.CropModes.Default)) return false;
{
Rectangle imageRectangle = new Rectangle(Point.Empty, Image.Size); Rectangle imageRectangle = new Rectangle(Point.Empty, Image.Size);
Bitmap tmpImage; Bitmap tmpImage;
// Make sure we have information, this this fails // Make sure we have information, this this fails
@ -1206,7 +1220,7 @@ namespace Greenshot.Editor.Drawing
throw; throw;
} }
Matrix matrix = new Matrix(); var matrix = new Matrix();
matrix.Translate(-cropRectangle.Left, -cropRectangle.Top, MatrixOrder.Append); matrix.Translate(-cropRectangle.Left, -cropRectangle.Top, MatrixOrder.Append);
// Make undoable // Make undoable
MakeUndoable(new SurfaceBackgroundChangeMemento(this, matrix), false); MakeUndoable(new SurfaceBackgroundChangeMemento(this, matrix), false);
@ -1223,7 +1237,120 @@ namespace Greenshot.Editor.Drawing
return true; return true;
} }
return false; /// <summary>
/// Crop out the surface
/// Splits the image in 3 parts(top, middle, bottom). Crop out the middle and joins top and bottom.
/// </summary>
/// <param name="cropRectangle">rectangle of the middle part</param>
/// <returns>bool</returns>
private bool ApplyHorizontalCrop(Rectangle cropRectangle)
{
if (!IsCropPossible(ref cropRectangle, CropContainer.CropModes.Horizontal)) return false;
var imageRectangle = new Rectangle(Point.Empty, Image.Size);
var topRectangle = new Rectangle(0, 0, Image.Size.Width, cropRectangle.Top);
var bottomRectangle = new Rectangle(0, cropRectangle.Top + cropRectangle.Height, Image.Size.Width, Image.Size.Height - cropRectangle.Top - cropRectangle.Height);
Bitmap newImage;
try
{
newImage = new Bitmap(Image.Size.Width, Image.Size.Height - cropRectangle.Height);
using var graphics = Graphics.FromImage(newImage);
var insertPositionTop = 0;
if (topRectangle.Height > 0)
{
graphics.DrawImage(Image, new Rectangle(0, insertPositionTop, topRectangle.Width, topRectangle.Height), topRectangle, GraphicsUnit.Pixel);
insertPositionTop += topRectangle.Height;
}
if (bottomRectangle.Height > 0)
{
graphics.DrawImage(Image, new Rectangle(0, insertPositionTop, bottomRectangle.Width, bottomRectangle.Height), bottomRectangle, GraphicsUnit.Pixel);
}
}
catch (Exception ex)
{
ex.Data.Add("CropRectangle", cropRectangle);
ex.Data.Add("Width", Image.Width);
ex.Data.Add("Height", Image.Height);
ex.Data.Add("Pixelformat", Image.PixelFormat);
throw;
}
var matrix = new Matrix();
matrix.Translate(0, -(cropRectangle.Top + cropRectangle.Height), MatrixOrder.Append);
// Make undoable
MakeUndoable(new SurfaceBackgroundChangeMemento(this, matrix), false);
// Do not dispose otherwise we can't undo the image!
SetImage(newImage, false);
_elements.Transform(matrix);
if (_surfaceSizeChanged != null && !imageRectangle.Equals(new Rectangle(Point.Empty, newImage.Size)))
{
_surfaceSizeChanged(this, null);
}
Invalidate();
return true;
}
/// <summary>
/// Crop out the surface
/// Splits the image in 3 parts(left, middle, right). Crop out the middle and joins top and bottom.
/// </summary>
/// <param name="cropRectangle">rectangle of the middle part</param>
/// <returns>bool</returns>
private bool ApplyVerticalCrop(Rectangle cropRectangle)
{
if (!IsCropPossible(ref cropRectangle, CropContainer.CropModes.Vertical)) return false;
var imageRectangle = new Rectangle(Point.Empty, Image.Size);
var leftRectangle = new Rectangle(0, 0, cropRectangle.Left, Image.Size.Height);
var rightRectangle = new Rectangle(cropRectangle.Left + cropRectangle.Width, 0, Image.Size.Width - cropRectangle.Width - cropRectangle.Left, Image.Size.Height);
Bitmap newImage;
try
{
newImage = new Bitmap(Image.Size.Width - cropRectangle.Width, Image.Size.Height);
using var graphics = Graphics.FromImage(newImage);
var insertPositionLeft = 0;
if (leftRectangle.Width > 0)
{
graphics.DrawImage(Image, new Rectangle(insertPositionLeft, 0, leftRectangle.Width, leftRectangle.Height), leftRectangle , GraphicsUnit.Pixel);
insertPositionLeft += leftRectangle.Width;
}
if (rightRectangle.Width > 0)
{
graphics.DrawImage(Image, new Rectangle(insertPositionLeft, 0, rightRectangle.Width, rightRectangle.Height), rightRectangle, GraphicsUnit.Pixel);
}
}
catch (Exception ex)
{
ex.Data.Add("CropRectangle", cropRectangle);
ex.Data.Add("Width", Image.Width);
ex.Data.Add("Height", Image.Height);
ex.Data.Add("Pixelformat", Image.PixelFormat);
throw;
}
var matrix = new Matrix();
matrix.Translate(-cropRectangle.Left - cropRectangle.Width, 0, MatrixOrder.Append);
// Make undoable
MakeUndoable(new SurfaceBackgroundChangeMemento(this, matrix), false);
// Do not dispose otherwise we can't undo the image!
SetImage(newImage, false);
_elements.Transform(matrix);
if (_surfaceSizeChanged != null && !imageRectangle.Equals(new Rectangle(Point.Empty, newImage.Size)))
{
_surfaceSizeChanged(this, null);
}
Invalidate();
return true;
} }
/// <summary> /// <summary>
@ -1255,8 +1382,8 @@ namespace Greenshot.Editor.Drawing
{ {
foreach (IAdorner adorner in drawableContainer.Adorners) foreach (IAdorner adorner in drawableContainer.Adorners)
{ {
if (adorner.IsActive || adorner.HitTest(mouseEventArgs.Location)) if (!adorner.IsActive && !adorner.HitTest(mouseEventArgs.Location)) continue;
{
if (adorner.Cursor != null) if (adorner.Cursor != null)
{ {
Cursor = adorner.Cursor; Cursor = adorner.Cursor;
@ -1265,7 +1392,6 @@ namespace Greenshot.Editor.Drawing
return adorner; return adorner;
} }
} }
}
return null; return null;
} }
@ -1494,8 +1620,8 @@ namespace Greenshot.Editor.Drawing
Cursor = DrawingMode != DrawingModes.None ? Cursors.Cross : Cursors.Default; Cursor = DrawingMode != DrawingModes.None ? Cursors.Cross : Cursors.Default;
if (_mouseDown) if (!_mouseDown) return;
{
if (_mouseDownElement != null) if (_mouseDownElement != null)
{ {
// an element is currently dragged // an element is currently dragged
@ -1537,7 +1663,6 @@ namespace Greenshot.Editor.Drawing
_modified = true; _modified = true;
} }
} }
}
/// <summary> /// <summary>
/// This event handler is called when the surface is double clicked. /// This event handler is called when the surface is double clicked.
@ -1795,7 +1920,7 @@ namespace Greenshot.Editor.Drawing
element.Invalidate(); element.Invalidate();
} }
if (makeUndoable) if (makeUndoable && element.IsUndoable)
{ {
MakeUndoable(new AddElementMemento(this, element), false); MakeUndoable(new AddElementMemento(this, element), false);
} }
@ -1811,11 +1936,17 @@ namespace Greenshot.Editor.Drawing
public void RemoveElements(IDrawableContainerList elementsToRemove, bool makeUndoable = true) public void RemoveElements(IDrawableContainerList elementsToRemove, bool makeUndoable = true)
{ {
// fix potential issues with iterating a changing list // fix potential issues with iterating a changing list
DrawableContainerList cloned = new DrawableContainerList(); DrawableContainerList cloned = new DrawableContainerList(elementsToRemove);
cloned.AddRange(elementsToRemove);
if (makeUndoable) if (makeUndoable)
{ {
MakeUndoable(new DeleteElementsMemento(this, cloned), false); // Take all containers to make undoable
var undoableContainers = elementsToRemove.Where(c => c.IsUndoable).ToList();
if (undoableContainers.Any())
{
var undoableContainerList = new DrawableContainerList(undoableContainers);
MakeUndoable(new DeleteElementsMemento(this, undoableContainerList), false);
}
} }
SuspendLayout(); SuspendLayout();
@ -1863,7 +1994,7 @@ namespace Greenshot.Editor.Drawing
Invalidate(); Invalidate();
} }
if (makeUndoable) if (makeUndoable && elementToRemove is { IsUndoable: true })
{ {
MakeUndoable(new DeleteElementMemento(this, elementToRemove), false); MakeUndoable(new DeleteElementMemento(this, elementToRemove), false);
} }
@ -1879,11 +2010,16 @@ namespace Greenshot.Editor.Drawing
public void AddElements(IDrawableContainerList elementsToAdd, bool makeUndoable = true) public void AddElements(IDrawableContainerList elementsToAdd, bool makeUndoable = true)
{ {
// fix potential issues with iterating a changing list // fix potential issues with iterating a changing list
DrawableContainerList cloned = new DrawableContainerList(); DrawableContainerList cloned = new DrawableContainerList(elementsToAdd);
cloned.AddRange(elementsToAdd);
if (makeUndoable) if (makeUndoable)
{ {
MakeUndoable(new AddElementsMemento(this, cloned), false); // Take all containers to make undoable
var undoableContainers = elementsToAdd.Where(c => c.IsUndoable).ToList();
if (undoableContainers.Any())
{
var undoableContainerList = new DrawableContainerList(undoableContainers);
MakeUndoable(new AddElementsMemento(this, undoableContainerList), false);
}
} }
SuspendLayout(); SuspendLayout();
@ -1925,50 +2061,106 @@ namespace Greenshot.Editor.Drawing
/// </summary> /// </summary>
public void CutSelectedElements() public void CutSelectedElements()
{ {
if (HasSelectedElements) if (!HasSelectedElements) return;
{
ClipboardHelper.SetClipboardData(typeof(IDrawableContainerList), selectedElements); ClipboardHelper.SetClipboardData(typeof(IDrawableContainerList), selectedElements);
RemoveSelectedElements(); RemoveSelectedElements();
} }
}
/// <summary> /// <summary>
/// Copy the selected elements to the clipboard /// Copy the selected elements to the clipboard
/// </summary> /// </summary>
public void CopySelectedElements() public void CopySelectedElements()
{ {
if (HasSelectedElements) if (!HasSelectedElements) return;
{
ClipboardHelper.SetClipboardData(typeof(IDrawableContainerList), selectedElements); ClipboardHelper.SetClipboardData(typeof(IDrawableContainerList), selectedElements);
} }
/// <summary>
/// This method is called to confirm/cancel.
/// Called when pressing enter or using the "check" in the editor.
/// redirects to the specialized confirm/cancel method
/// </summary>
/// <param name="confirm">bool</param>
public void Confirm(bool confirm)
{
if (DrawingMode == DrawingModes.Crop)
{
ConfirmCrop(confirm);
}
else
{
ConfirmSelectedConfirmableElements(confirm);
}
} }
/// <summary> /// <summary>
/// This method is called to confirm/cancel "confirmable" elements, like the crop-container. /// This method is called to confirm/cancel "confirmable" elements
/// Called when pressing enter or using the "check" in the editor. /// Called when pressing enter or using the "check" in the editor.
/// <br/>
/// For crop-container there is a dedicated method <see cref="ConfirmCrop(bool)"/>.
/// </summary> /// </summary>
/// <param name="confirm"></param> /// <param name="confirm">bool</param>
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) // create new collection so that we can iterate safely (selectedElements might change due with confirm/cancel)
List<IDrawableContainer> selectedDCs = new List<IDrawableContainer>(selectedElements); List<IDrawableContainer> selectedDCs = new List<IDrawableContainer>(selectedElements);
foreach (IDrawableContainer dc in selectedDCs) foreach (IDrawableContainer dc in selectedDCs)
{ {
if (dc.Equals(_cropContainer)) throw new NotImplementedException($"No confirm/cancel defined for Container type {dc.GetType()}");
}
// maybe the undo button has to be enabled
if (_movingElementChanged != null)
{
_movingElementChanged(this, new SurfaceElementEventArgs());
}
}
/// <summary>
/// This method is called to confirm/cancel the crop-container.
/// Called when pressing enter or using the "check" in the editor.
/// </summary>
/// <param name="confirm">bool</param>
public void ConfirmCrop(bool confirm)
{
if (_cropContainer is not CropContainer e) return;
if (confirm && selectedElements.Count > 0)
{ {
DrawingMode = DrawingModes.None;
// No undo memento for the cropcontainer itself, only for the effect // No undo memento for the cropcontainer itself, only for the effect
RemoveElement(_cropContainer, false); RemoveElement(_cropContainer, false);
if (confirm)
_ = e.GetFieldValue(FieldType.CROPMODE) switch
{ {
ApplyCrop(_cropContainer.Bounds); CropContainer.CropModes.Horizontal => ApplyHorizontalCrop(_cropContainer.Bounds),
} CropContainer.CropModes.Vertical => ApplyVerticalCrop(_cropContainer.Bounds),
_ => ApplyCrop(_cropContainer.Bounds)
};
_cropContainer.Dispose(); _cropContainer.Dispose();
_cropContainer = null; _cropContainer = null;
break; }
else
{
RemoveCropContainer();
}
DrawingMode = DrawingModes.None;
// maybe the undo button has to be enabled
if (_movingElementChanged != null)
{
_movingElementChanged(this, new SurfaceElementEventArgs());
} }
} }
public void RemoveCropContainer()
{
if (_cropContainer == null) return;
RemoveElement(_cropContainer, false);
_cropContainer.Dispose();
_cropContainer = null;
} }
/// <summary> /// <summary>
@ -2144,13 +2336,13 @@ namespace Greenshot.Editor.Drawing
/// <summary> /// <summary>
/// Get the rectangle bounding all selected elements (in surface coordinates space), /// Get the rectangle bounding all selected elements (in surface coordinates space),
/// or empty rectangle if nothing is selcted. /// or empty rectangle if nothing is selected.
/// </summary> /// </summary>
public Rectangle GetSelectionRectangle() public Rectangle GetSelectionRectangle()
=> ToSurfaceCoordinates(selectedElements.DrawingBounds); => ToSurfaceCoordinates(selectedElements.DrawingBounds);
/// <summary> /// <summary>
/// Duplicate all the selecteded elements /// Duplicate all the selected elements
/// </summary> /// </summary>
public void DuplicateSelectedElements() public void DuplicateSelectedElements()
{ {
@ -2289,7 +2481,7 @@ namespace Greenshot.Editor.Drawing
/// <returns>false if no keys were processed</returns> /// <returns>false if no keys were processed</returns>
public bool ProcessCmdKey(Keys k) public bool ProcessCmdKey(Keys k)
{ {
if (selectedElements.Count <= 0) return false; if (selectedElements.Count <= 0 && k != Keys.Escape) return false;
bool shiftModifier = (ModifierKeys & Keys.Shift) == Keys.Shift; bool shiftModifier = (ModifierKeys & Keys.Shift) == Keys.Shift;
int px = shiftModifier ? 10 : 1; int px = shiftModifier ? 10 : 1;
@ -2325,10 +2517,10 @@ namespace Greenshot.Editor.Drawing
PushElementsToBottom(); PushElementsToBottom();
break; break;
case Keys.Enter: case Keys.Enter:
ConfirmSelectedConfirmableElements(true); Confirm(true);
break; break;
case Keys.Escape: case Keys.Escape:
ConfirmSelectedConfirmableElements(false); Confirm(false);
break; break;
case Keys.D0 | Keys.Control: case Keys.D0 | Keys.Control:
case Keys.D0 | Keys.Shift | Keys.Control: case Keys.D0 | Keys.Shift | Keys.Control:
@ -2487,7 +2679,7 @@ namespace Greenshot.Editor.Drawing
return _elements.CanPushDown(selectedElements); return _elements.CanPushDown(selectedElements);
} }
public void Element_FieldChanged(object sender, FieldChangedEventArgs e) private void Element_FieldChanged(object sender, FieldChangedEventArgs e)
{ {
selectedElements.HandleFieldChangedEvent(sender, e); selectedElements.HandleFieldChangedEvent(sender, e);
} }
@ -2545,8 +2737,7 @@ namespace Greenshot.Editor.Drawing
{ {
return rc; return rc;
} }
else
{
Point[] points = Point[] points =
{ {
rc.Location, rc.Location + rc.Size rc.Location, rc.Location + rc.Size
@ -2560,5 +2751,4 @@ namespace Greenshot.Editor.Drawing
); );
} }
} }
}
} }

View file

@ -74,7 +74,7 @@ namespace Greenshot.Editor.Drawing
{ {
if ((text != null || newText == null) && string.Equals(text, newText)) return; if ((text != null || newText == null) && string.Equals(text, newText)) return;
if (makeUndoable && allowUndoable) if (makeUndoable && allowUndoable && IsUndoable)
{ {
makeUndoable = false; makeUndoable = false;
_parent.MakeUndoable(new TextChangeMemento(this), false); _parent.MakeUndoable(new TextChangeMemento(this), false);

View file

@ -98,8 +98,6 @@ namespace Greenshot.Editor.Forms {
this.toolStripSeparator12 = new System.Windows.Forms.ToolStripSeparator(); this.toolStripSeparator12 = new System.Windows.Forms.ToolStripSeparator();
this.preferencesToolStripMenuItem = new GreenshotToolStripMenuItem(); this.preferencesToolStripMenuItem = new GreenshotToolStripMenuItem();
this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator();
this.autoCropToolStripMenuItem = new GreenshotToolStripMenuItem();
this.toolStripSeparator17 = new System.Windows.Forms.ToolStripSeparator();
this.insert_window_toolstripmenuitem = new GreenshotToolStripMenuItem(); this.insert_window_toolstripmenuitem = new GreenshotToolStripMenuItem();
this.objectToolStripMenuItem = new GreenshotToolStripMenuItem(); this.objectToolStripMenuItem = new GreenshotToolStripMenuItem();
this.addRectangleToolStripMenuItem = new GreenshotToolStripMenuItem(); this.addRectangleToolStripMenuItem = new GreenshotToolStripMenuItem();
@ -144,8 +142,13 @@ namespace Greenshot.Editor.Forms {
this.btnHelp = new GreenshotToolStripButton(); this.btnHelp = new GreenshotToolStripButton();
this.propertiesToolStrip = new ToolStripEx(); this.propertiesToolStrip = new ToolStripEx();
this.obfuscateModeButton = new BindableToolStripDropDownButton(); this.obfuscateModeButton = new BindableToolStripDropDownButton();
this.cropModeButton = new BindableToolStripDropDownButton();
this.pixelizeToolStripMenuItem = new GreenshotToolStripMenuItem(); this.pixelizeToolStripMenuItem = new GreenshotToolStripMenuItem();
this.blurToolStripMenuItem = new GreenshotToolStripMenuItem(); this.blurToolStripMenuItem = new GreenshotToolStripMenuItem();
this.defaultCropModeToolStripMenuItem = new GreenshotToolStripMenuItem();
this.verticalCropModeToolStripMenuItem = new GreenshotToolStripMenuItem();
this.horizontalCropModeToolStripMenuItem = new GreenshotToolStripMenuItem();
this.autoCropModeToolStripMenuItem = new GreenshotToolStripMenuItem();
this.highlightModeButton = new BindableToolStripDropDownButton(); this.highlightModeButton = new BindableToolStripDropDownButton();
this.textHighlightMenuItem = new GreenshotToolStripMenuItem(); this.textHighlightMenuItem = new GreenshotToolStripMenuItem();
this.areaHighlightMenuItem = new GreenshotToolStripMenuItem(); this.areaHighlightMenuItem = new GreenshotToolStripMenuItem();
@ -593,8 +596,6 @@ namespace Greenshot.Editor.Forms {
this.toolStripSeparator12, this.toolStripSeparator12,
this.preferencesToolStripMenuItem, this.preferencesToolStripMenuItem,
this.toolStripSeparator5, this.toolStripSeparator5,
this.autoCropToolStripMenuItem,
this.toolStripSeparator17,
this.insert_window_toolstripmenuitem}); this.insert_window_toolstripmenuitem});
this.editToolStripMenuItem.LanguageKey = "editor_edit"; this.editToolStripMenuItem.LanguageKey = "editor_edit";
this.editToolStripMenuItem.Name = "editToolStripMenuItem"; this.editToolStripMenuItem.Name = "editToolStripMenuItem";
@ -678,16 +679,6 @@ namespace Greenshot.Editor.Forms {
// //
this.toolStripSeparator5.Name = "toolStripSeparator5"; this.toolStripSeparator5.Name = "toolStripSeparator5";
// //
// autoCropToolStripMenuItem
//
this.autoCropToolStripMenuItem.LanguageKey = "editor_autocrop";
this.autoCropToolStripMenuItem.Name = "autoCropToolStripMenuItem";
this.autoCropToolStripMenuItem.Click += new System.EventHandler(this.AutoCropToolStripMenuItemClick);
//
// toolStripSeparator17
//
this.toolStripSeparator17.Name = "toolStripSeparator17";
//
// insert_window_toolstripmenuitem // insert_window_toolstripmenuitem
// //
this.insert_window_toolstripmenuitem.LanguageKey = "editor_insertwindow"; this.insert_window_toolstripmenuitem.LanguageKey = "editor_insertwindow";
@ -1082,6 +1073,7 @@ namespace Greenshot.Editor.Forms {
this.toolStripSeparator10, this.toolStripSeparator10,
this.btnConfirm, this.btnConfirm,
this.btnCancel, this.btnCancel,
this.cropModeButton,
this.counterLabel, this.counterLabel,
this.counterUpDown}); this.counterUpDown});
// //
@ -1098,6 +1090,7 @@ namespace Greenshot.Editor.Forms {
this.obfuscateModeButton.SelectedTag = FilterContainer.PreparedFilter.BLUR; this.obfuscateModeButton.SelectedTag = FilterContainer.PreparedFilter.BLUR;
this.obfuscateModeButton.Tag = FilterContainer.PreparedFilter.BLUR; this.obfuscateModeButton.Tag = FilterContainer.PreparedFilter.BLUR;
// //
this.obfuscateModeButton.DropDownItemClicked += FilterPresetDropDownItemClicked;
// pixelizeToolStripMenuItem // pixelizeToolStripMenuItem
// //
this.pixelizeToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("pixelizeToolStripMenuItem.Image"))); this.pixelizeToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("pixelizeToolStripMenuItem.Image")));
@ -1111,6 +1104,55 @@ namespace Greenshot.Editor.Forms {
this.blurToolStripMenuItem.LanguageKey = "editor_obfuscate_blur"; this.blurToolStripMenuItem.LanguageKey = "editor_obfuscate_blur";
this.blurToolStripMenuItem.Name = "blurToolStripMenuItem"; this.blurToolStripMenuItem.Name = "blurToolStripMenuItem";
this.blurToolStripMenuItem.Tag = FilterContainer.PreparedFilter.BLUR; this.blurToolStripMenuItem.Tag = FilterContainer.PreparedFilter.BLUR;
//
// cropModeButton
//
this.cropModeButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.cropModeButton.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.defaultCropModeToolStripMenuItem,
this.verticalCropModeToolStripMenuItem,
this.horizontalCropModeToolStripMenuItem,
this.autoCropModeToolStripMenuItem});
this.cropModeButton.Image = ((System.Drawing.Image)(resources.GetObject("btnCrop.Image")));
this.cropModeButton.ImageTransparentColor = System.Drawing.Color.Magenta;
this.cropModeButton.LanguageKey = "editor_crop_mode";
this.cropModeButton.Name = "cropModeButton";
this.cropModeButton.SelectedTag = CropContainer.CropModes.Default;
this.cropModeButton.Tag = CropContainer.CropModes.Default;
this.cropModeButton.DropDownItemClicked += CropStyleDropDownItemClicked;
//
// defaultCropStyleToolStripMenuItem
//
this.defaultCropModeToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("btnCrop.Image")));
this.defaultCropModeToolStripMenuItem.LanguageKey = "editor_cropmode_default";
this.defaultCropModeToolStripMenuItem.Name = "defaultCropModeToolStripMenuItem";
this.defaultCropModeToolStripMenuItem.Tag = CropContainer.CropModes.Default;
//
// verticalCropStyleToolStripMenuItem
//
this.verticalCropModeToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("CropVertical.Image")));
this.verticalCropModeToolStripMenuItem.LanguageKey = "editor_cropmode_vertical";
this.verticalCropModeToolStripMenuItem.Name = "verticalCropModeToolStripMenuItem";
this.verticalCropModeToolStripMenuItem.Tag = CropContainer.CropModes.Vertical;
//
// horizontalCropStyleToolStripMenuItem
//
this.horizontalCropModeToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("CropHorizontal.Image")));
this.horizontalCropModeToolStripMenuItem.LanguageKey = "editor_cropmode_horizontal";
this.horizontalCropModeToolStripMenuItem.Name = "horizontalCropModeToolStripMenuItem";
this.horizontalCropModeToolStripMenuItem.Tag = CropContainer.CropModes.Horizontal;
//
// autoCropModeToolStripMenuItem
//
this.autoCropModeToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("AutoCrop.Image")));
this.autoCropModeToolStripMenuItem.LanguageKey = "editor_cropmode_auto";
this.autoCropModeToolStripMenuItem.Name = "autoCropModeToolStripMenuItem";
this.autoCropModeToolStripMenuItem.Tag = CropContainer.CropModes.AutoCrop;
// //
// highlightModeButton // highlightModeButton
// //
@ -1126,6 +1168,7 @@ namespace Greenshot.Editor.Forms {
this.highlightModeButton.Name = "highlightModeButton"; this.highlightModeButton.Name = "highlightModeButton";
this.highlightModeButton.SelectedTag = FilterContainer.PreparedFilter.TEXT_HIGHTLIGHT; this.highlightModeButton.SelectedTag = FilterContainer.PreparedFilter.TEXT_HIGHTLIGHT;
this.highlightModeButton.Tag = FilterContainer.PreparedFilter.TEXT_HIGHTLIGHT; this.highlightModeButton.Tag = FilterContainer.PreparedFilter.TEXT_HIGHTLIGHT;
this.highlightModeButton.DropDownItemClicked += FilterPresetDropDownItemClicked;
// //
// textHighlightMenuItem // textHighlightMenuItem
// //
@ -1233,6 +1276,7 @@ namespace Greenshot.Editor.Forms {
this.fontFamilyComboBox.Padding = new System.Windows.Forms.Padding(2,0,0,2); this.fontFamilyComboBox.Padding = new System.Windows.Forms.Padding(2,0,0,2);
this.fontFamilyComboBox.GotFocus += new System.EventHandler(this.ToolBarFocusableElementGotFocus); this.fontFamilyComboBox.GotFocus += new System.EventHandler(this.ToolBarFocusableElementGotFocus);
this.fontFamilyComboBox.LostFocus += new System.EventHandler(this.ToolBarFocusableElementLostFocus); this.fontFamilyComboBox.LostFocus += new System.EventHandler(this.ToolBarFocusableElementLostFocus);
this.fontFamilyComboBox.PropertyChanged += FontPropertyChanged;
// //
// fontSizeLabel // fontSizeLabel
// //
@ -1873,6 +1917,11 @@ namespace Greenshot.Editor.Forms {
private BindableToolStripButton btnConfirm; private BindableToolStripButton btnConfirm;
private GreenshotToolStripMenuItem selectAllToolStripMenuItem; private GreenshotToolStripMenuItem selectAllToolStripMenuItem;
private BindableToolStripDropDownButton highlightModeButton; private BindableToolStripDropDownButton highlightModeButton;
private BindableToolStripDropDownButton cropModeButton;
private GreenshotToolStripMenuItem defaultCropModeToolStripMenuItem;
private GreenshotToolStripMenuItem verticalCropModeToolStripMenuItem;
private GreenshotToolStripMenuItem horizontalCropModeToolStripMenuItem;
private GreenshotToolStripMenuItem autoCropModeToolStripMenuItem;
private GreenshotToolStripMenuItem pixelizeToolStripMenuItem; private GreenshotToolStripMenuItem pixelizeToolStripMenuItem;
private GreenshotToolStripMenuItem blurToolStripMenuItem; private GreenshotToolStripMenuItem blurToolStripMenuItem;
private BindableToolStripDropDownButton obfuscateModeButton; private BindableToolStripDropDownButton obfuscateModeButton;

View file

@ -25,6 +25,7 @@ using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.IO; using System.IO;
using System.Linq;
using System.Threading; using System.Threading;
using System.Windows.Forms; using System.Windows.Forms;
using Greenshot.Base; using Greenshot.Base;
@ -181,6 +182,9 @@ namespace Greenshot.Editor.Forms
UpdateUi(); UpdateUi();
// Workaround: for the MouseWheel event which doesn't get to the panel
MouseWheel += PanelMouseWheel;
// Use best fit, for those capture modes where we can get huge images // Use best fit, for those capture modes where we can get huge images
bool useBestFit = _surface.CaptureDetails.CaptureMode switch bool useBestFit = _surface.CaptureDetails.CaptureMode switch
{ {
@ -280,11 +284,6 @@ namespace Greenshot.Editor.Forms
// a smaller size than the initial panel size (as set by the forms designer) // a smaller size than the initial panel size (as set by the forms designer)
panel1.Height = 10; panel1.Height = 10;
fontFamilyComboBox.PropertyChanged += FontPropertyChanged;
obfuscateModeButton.DropDownItemClicked += FilterPresetDropDownItemClicked;
highlightModeButton.DropDownItemClicked += FilterPresetDropDownItemClicked;
_toolbarButtons = new[] _toolbarButtons = new[]
{ {
btnCursor, btnRect, btnEllipse, btnText, btnLine, btnArrow, btnFreehand, btnHighlight, btnObfuscate, btnCrop, btnStepLabel, btnSpeechBubble btnCursor, btnRect, btnEllipse, btnText, btnLine, btnArrow, btnFreehand, btnHighlight, btnObfuscate, btnCrop, btnStepLabel, btnSpeechBubble
@ -293,9 +292,6 @@ namespace Greenshot.Editor.Forms
pluginToolStripMenuItem.Visible = pluginToolStripMenuItem.DropDownItems.Count > 0; pluginToolStripMenuItem.Visible = pluginToolStripMenuItem.DropDownItems.Count > 0;
// Workaround: for the MouseWheel event which doesn't get to the panel
MouseWheel += PanelMouseWheel;
// Make sure the value is set correctly when starting // Make sure the value is set correctly when starting
if (Surface != null) if (Surface != null)
{ {
@ -727,7 +723,10 @@ namespace Greenshot.Editor.Forms
private void BtnCropClick(object sender, EventArgs e) private void BtnCropClick(object sender, EventArgs e)
{ {
if (_surface.DrawingMode == DrawingModes.Crop) return;
_surface.DrawingMode = DrawingModes.Crop; _surface.DrawingMode = DrawingModes.Crop;
InitCropMode((CropContainer.CropModes)_surface.FieldAggregator.GetField(FieldType.CROPMODE).Value);
RefreshFieldControls(); RefreshFieldControls();
} }
@ -1292,6 +1291,7 @@ namespace Greenshot.Editor.Forms
new BidirectionalBinding(previewQualityUpDown, "Value", _surface.FieldAggregator.GetField(FieldType.PREVIEW_QUALITY), "Value", new BidirectionalBinding(previewQualityUpDown, "Value", _surface.FieldAggregator.GetField(FieldType.PREVIEW_QUALITY), "Value",
DecimalDoublePercentageConverter.GetInstance(), NotNullValidator.GetInstance()); DecimalDoublePercentageConverter.GetInstance(), NotNullValidator.GetInstance());
new BidirectionalBinding(obfuscateModeButton, "SelectedTag", _surface.FieldAggregator.GetField(FieldType.PREPARED_FILTER_OBFUSCATE), "Value"); new BidirectionalBinding(obfuscateModeButton, "SelectedTag", _surface.FieldAggregator.GetField(FieldType.PREPARED_FILTER_OBFUSCATE), "Value");
new BidirectionalBinding(cropModeButton, "SelectedTag", _surface.FieldAggregator.GetField(FieldType.CROPMODE), "Value");
new BidirectionalBinding(highlightModeButton, "SelectedTag", _surface.FieldAggregator.GetField(FieldType.PREPARED_FILTER_HIGHLIGHT), "Value"); new BidirectionalBinding(highlightModeButton, "SelectedTag", _surface.FieldAggregator.GetField(FieldType.PREPARED_FILTER_HIGHLIGHT), "Value");
new BidirectionalBinding(counterUpDown, "Value", _surface, "CounterStart", DecimalIntConverter.GetInstance(), NotNullValidator.GetInstance()); new BidirectionalBinding(counterUpDown, "Value", _surface, "CounterStart", DecimalIntConverter.GetInstance(), NotNullValidator.GetInstance());
} }
@ -1321,12 +1321,13 @@ namespace Greenshot.Editor.Forms
textHorizontalAlignmentButton.Visible = props.HasFieldValue(FieldType.TEXT_HORIZONTAL_ALIGNMENT); textHorizontalAlignmentButton.Visible = props.HasFieldValue(FieldType.TEXT_HORIZONTAL_ALIGNMENT);
textVerticalAlignmentButton.Visible = props.HasFieldValue(FieldType.TEXT_VERTICAL_ALIGNMENT); textVerticalAlignmentButton.Visible = props.HasFieldValue(FieldType.TEXT_VERTICAL_ALIGNMENT);
shadowButton.Visible = props.HasFieldValue(FieldType.SHADOW); shadowButton.Visible = props.HasFieldValue(FieldType.SHADOW);
counterLabel.Visible = counterUpDown.Visible = props.HasFieldValue(FieldType.FLAGS) counterLabel.Visible = counterUpDown.Visible = props.HasFieldValue(FieldType.FLAGS) && ((FieldFlag)props.GetFieldValue(FieldType.FLAGS)).HasFlag(FieldFlag.COUNTER);
&& ((FieldFlag) props.GetFieldValue(FieldType.FLAGS) & FieldFlag.COUNTER) == FieldFlag.COUNTER;
btnConfirm.Visible = btnCancel.Visible = props.HasFieldValue(FieldType.FLAGS) btnConfirm.Visible = btnCancel.Visible = props.HasFieldValue(FieldType.FLAGS) && ((FieldFlag) props.GetFieldValue(FieldType.FLAGS)).HasFlag(FieldFlag.CONFIRMABLE);
&& ((FieldFlag) props.GetFieldValue(FieldType.FLAGS) & FieldFlag.CONFIRMABLE) == FieldFlag.CONFIRMABLE; btnConfirm.Enabled = _surface.HasSelectedElements;
obfuscateModeButton.Visible = props.HasFieldValue(FieldType.PREPARED_FILTER_OBFUSCATE); obfuscateModeButton.Visible = props.HasFieldValue(FieldType.PREPARED_FILTER_OBFUSCATE);
cropModeButton.Visible = props.HasFieldValue(FieldType.CROPMODE);
highlightModeButton.Visible = props.HasFieldValue(FieldType.PREPARED_FILTER_HIGHLIGHT); highlightModeButton.Visible = props.HasFieldValue(FieldType.PREPARED_FILTER_HIGHLIGHT);
} }
else else
@ -1582,6 +1583,39 @@ namespace Greenshot.Editor.Forms
Invalidate(true); Invalidate(true);
} }
protected void CropStyleDropDownItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
InitCropMode((CropContainer.CropModes)e.ClickedItem.Tag);
RefreshFieldControls();
Invalidate(true);
}
private void InitCropMode(CropContainer.CropModes mode)
{
var cropArea = _surface.Elements.FirstOrDefault(c => c is CropContainer)?.Bounds;
_surface.DrawingMode = DrawingModes.None;
_surface.RemoveCropContainer();
if (mode == CropContainer.CropModes.AutoCrop)
{
if (!_surface.AutoCrop(cropArea))
{
//not AutoCrop possible automatic switch to default crop mode
_surface.DrawingMode = DrawingModes.Crop;
_surface.FieldAggregator.GetField(FieldType.CROPMODE).Value = CropContainer.CropModes.Default;
this.cropModeButton.SelectedTag = CropContainer.CropModes.Default;
this.statusLabel.Text = Language.GetString(LangKey.editor_autocrop_not_possible);
}
}
else
{
_surface.DrawingMode = DrawingModes.Crop;
}
RefreshEditorControls();
}
private void SelectAllToolStripMenuItemClick(object sender, EventArgs e) private void SelectAllToolStripMenuItemClick(object sender, EventArgs e)
{ {
_surface.SelectAllElements(); _surface.SelectAllElements();
@ -1590,14 +1624,14 @@ namespace Greenshot.Editor.Forms
private void BtnConfirmClick(object sender, EventArgs e) private void BtnConfirmClick(object sender, EventArgs e)
{ {
_surface.ConfirmSelectedConfirmableElements(true); _surface.Confirm(true);
RefreshFieldControls(); RefreshEditorControls();
} }
private void BtnCancelClick(object sender, EventArgs e) private void BtnCancelClick(object sender, EventArgs e)
{ {
_surface.ConfirmSelectedConfirmableElements(false); _surface.Confirm(false);
RefreshFieldControls(); RefreshEditorControls();
} }
private void Insert_window_toolstripmenuitemMouseEnter(object sender, EventArgs e) private void Insert_window_toolstripmenuitemMouseEnter(object sender, EventArgs e)
@ -1643,14 +1677,6 @@ namespace Greenshot.Editor.Forms
} }
} }
private void AutoCropToolStripMenuItemClick(object sender, EventArgs e)
{
if (_surface.AutoCrop())
{
RefreshFieldControls();
}
}
private void AddBorderToolStripMenuItemClick(object sender, EventArgs e) private void AddBorderToolStripMenuItemClick(object sender, EventArgs e)
{ {
_surface.ApplyBitmapEffect(new BorderEffect()); _surface.ApplyBitmapEffect(new BorderEffect());
@ -1681,7 +1707,7 @@ namespace Greenshot.Editor.Forms
cropRectangle = ImageHelper.FindAutoCropRectangle(tmpImage, coreConfiguration.AutoCropDifference); cropRectangle = ImageHelper.FindAutoCropRectangle(tmpImage, coreConfiguration.AutoCropDifference);
} }
if (_surface.IsCropPossible(ref cropRectangle)) if (_surface.IsCropPossible(ref cropRectangle, CropContainer.CropModes.AutoCrop))
{ {
_surface.ApplyCrop(cropRectangle); _surface.ApplyCrop(cropRectangle);
UpdateUndoRedoSurfaceDependencies(); UpdateUndoRedoSurfaceDependencies();

View file

@ -1107,4 +1107,13 @@
<metadata name="zoomMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <metadata name="zoomMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>782, 17</value> <value>782, 17</value>
</metadata> </metadata>
<data name="AutoCrop.Image" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\AutoCrop.Image.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="CropHorizontal.Image" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\CropHorizontal.Image.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="CropVertical.Image" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\CropVertical.Image.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root> </root>

View file

@ -44,7 +44,7 @@ namespace Greenshot.Editor.Memento
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
protected virtual void Dispose(bool disposing) private void Dispose(bool disposing)
{ {
//if (disposing) { } //if (disposing) { }
_drawableContainer = null; _drawableContainer = null;

View file

@ -43,7 +43,7 @@ namespace Greenshot.Editor.Memento
Dispose(true); Dispose(true);
} }
protected virtual void Dispose(bool disposing) private void Dispose(bool disposing)
{ {
if (disposing) if (disposing)
{ {

View file

@ -44,7 +44,7 @@ namespace Greenshot.Editor.Memento
Dispose(true); Dispose(true);
} }
protected virtual void Dispose(bool disposing) private void Dispose(bool disposing)
{ {
if (disposing) if (disposing)
{ {

View file

@ -45,7 +45,7 @@ namespace Greenshot.Editor.Memento
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
protected virtual void Dispose(bool disposing) private void Dispose(bool disposing)
{ {
if (!disposing) return; if (!disposing) return;

View file

@ -43,7 +43,7 @@ namespace Greenshot.Editor.Memento
Dispose(true); Dispose(true);
} }
protected virtual void Dispose(bool disposing) private void Dispose(bool disposing)
{ {
if (disposing) if (disposing)
{ {

View file

@ -34,30 +34,30 @@ namespace Greenshot.Editor.Memento
{ {
private readonly List<Point> _points = new(); private readonly List<Point> _points = new();
private readonly List<Size> _sizes = new(); private readonly List<Size> _sizes = new();
private IDrawableContainerList _listOfdrawableContainer; private IDrawableContainerList _listOfDrawableContainer;
private void StoreBounds() private void StoreBounds()
{ {
foreach (IDrawableContainer drawableContainer in _listOfdrawableContainer) foreach (IDrawableContainer drawableContainer in _listOfDrawableContainer)
{ {
_points.Add(drawableContainer.Location); _points.Add(drawableContainer.Location);
_sizes.Add(drawableContainer.Size); _sizes.Add(drawableContainer.Size);
} }
} }
public DrawableContainerBoundsChangeMemento(IDrawableContainerList listOfdrawableContainer) public DrawableContainerBoundsChangeMemento(IDrawableContainerList listOfDrawableContainer)
{ {
_listOfdrawableContainer = listOfdrawableContainer; _listOfDrawableContainer = listOfDrawableContainer;
StoreBounds(); StoreBounds();
} }
public DrawableContainerBoundsChangeMemento(IDrawableContainer drawableContainer) public DrawableContainerBoundsChangeMemento(IDrawableContainer drawableContainer)
{ {
_listOfdrawableContainer = new DrawableContainerList _listOfDrawableContainer = new DrawableContainerList
{ {
drawableContainer drawableContainer
}; };
_listOfdrawableContainer.Parent = drawableContainer.Parent; _listOfDrawableContainer.Parent = drawableContainer.Parent;
StoreBounds(); StoreBounds();
} }
@ -66,21 +66,21 @@ namespace Greenshot.Editor.Memento
Dispose(true); Dispose(true);
} }
protected virtual void Dispose(bool disposing) private void Dispose(bool disposing)
{ {
if (disposing) if (disposing)
{ {
_listOfdrawableContainer?.Dispose(); _listOfDrawableContainer?.Dispose();
} }
_listOfdrawableContainer = null; _listOfDrawableContainer = null;
} }
public bool Merge(IMemento otherMemento) public bool Merge(IMemento otherMemento)
{ {
if (otherMemento is not DrawableContainerBoundsChangeMemento other) return false; if (otherMemento is not DrawableContainerBoundsChangeMemento other) return false;
if (ObjectExtensions.CompareLists(_listOfdrawableContainer, other._listOfdrawableContainer)) if (ObjectExtensions.CompareLists(_listOfDrawableContainer, other._listOfDrawableContainer))
{ {
// Lists are equal, as we have the state already we can ignore the new memento // Lists are equal, as we have the state already we can ignore the new memento
return true; return true;
@ -91,10 +91,10 @@ namespace Greenshot.Editor.Memento
public IMemento Restore() public IMemento Restore()
{ {
var oldState = new DrawableContainerBoundsChangeMemento(_listOfdrawableContainer); var oldState = new DrawableContainerBoundsChangeMemento(_listOfDrawableContainer);
for (int index = 0; index < _listOfdrawableContainer.Count; index++) for (int index = 0; index < _listOfDrawableContainer.Count; index++)
{ {
IDrawableContainer drawableContainer = _listOfdrawableContainer[index]; IDrawableContainer drawableContainer = _listOfDrawableContainer[index];
// Before // Before
drawableContainer.Invalidate(); drawableContainer.Invalidate();
drawableContainer.Left = _points[index].X; drawableContainer.Left = _points[index].X;

View file

@ -52,7 +52,7 @@ namespace Greenshot.Editor.Memento
Dispose(true); Dispose(true);
} }
protected virtual void Dispose(bool disposing) private void Dispose(bool disposing)
{ {
if (!disposing) return; if (!disposing) return;

View file

@ -43,7 +43,7 @@ namespace Greenshot.Editor.Memento
Dispose(true); Dispose(true);
} }
protected virtual void Dispose(bool disposing) private void Dispose(bool disposing)
{ {
if (disposing) if (disposing)
{ {

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View file

@ -62,6 +62,7 @@
<resource name="editor_copypathtoclipboard">انسخ المسار الي الذاكرة</resource> <resource name="editor_copypathtoclipboard">انسخ المسار الي الذاكرة</resource>
<resource name="editor_copytoclipboard">نسخ</resource> <resource name="editor_copytoclipboard">نسخ</resource>
<resource name="editor_crop">قص (C)</resource> <resource name="editor_crop">قص (C)</resource>
<resource name="editor_cropmode_default">قص</resource>
<resource name="editor_cursortool">اداة التحديد (ESC)</resource> <resource name="editor_cursortool">اداة التحديد (ESC)</resource>
<resource name="editor_cuttoclipboard">قص</resource> <resource name="editor_cuttoclipboard">قص</resource>
<resource name="editor_deleteelement">احذف</resource> <resource name="editor_deleteelement">احذف</resource>

View file

@ -92,6 +92,8 @@ Abans de crear un nou informe d'error, us agrairem que comproveu que l'error no
<resource name="editor_copypathtoclipboard">Copia el camí al porta-retalls</resource> <resource name="editor_copypathtoclipboard">Copia el camí al porta-retalls</resource>
<resource name="editor_copytoclipboard">Copia</resource> <resource name="editor_copytoclipboard">Copia</resource>
<resource name="editor_crop">Retalla(C)</resource> <resource name="editor_crop">Retalla(C)</resource>
<resource name="editor_cropmode_default">Retalla</resource>
<resource name="editor_cropmode_auto">Autorretalla</resource>
<resource name="editor_cursortool">Eina de selecció (ESC)</resource> <resource name="editor_cursortool">Eina de selecció (ESC)</resource>
<resource name="editor_cuttoclipboard">Retalla</resource> <resource name="editor_cuttoclipboard">Retalla</resource>
<resource name="editor_deleteelement">Esborra</resource> <resource name="editor_deleteelement">Esborra</resource>

View file

@ -93,6 +93,8 @@ Také bychom velmi ocenili, kdybyste zkontrolovali, zda tato chyba již není ev
<resource name="editor_copypathtoclipboard">Kopírovat cestu do schránky</resource> <resource name="editor_copypathtoclipboard">Kopírovat cestu do schránky</resource>
<resource name="editor_copytoclipboard">Kopírovat</resource> <resource name="editor_copytoclipboard">Kopírovat</resource>
<resource name="editor_crop">Oříznout (C)</resource> <resource name="editor_crop">Oříznout (C)</resource>
<resource name="editor_cropmode_default">Oříznout</resource>
<resource name="editor_cropmode_auto">Automatické oříznutí</resource>
<resource name="editor_cursortool">Výběr objektů (ESC)</resource> <resource name="editor_cursortool">Výběr objektů (ESC)</resource>
<resource name="editor_cuttoclipboard">Vystřihnout</resource> <resource name="editor_cuttoclipboard">Vystřihnout</resource>
<resource name="editor_deleteelement">Odstranit</resource> <resource name="editor_deleteelement">Odstranit</resource>

View file

@ -469,6 +469,9 @@ tidspunktet, fx 11_58_32 (plus filendelsen angivet i indstillingerne).
<resource name="editor_crop"> <resource name="editor_crop">
Beskær (C) Beskær (C)
</resource> </resource>
<resource name="editor_cropmode_default">
Beskær
</resource>
<resource name="contextmenu_captureclipboard"> <resource name="contextmenu_captureclipboard">
Åbn billede fra udklipsholder Åbn billede fra udklipsholder
</resource> </resource>

View file

@ -77,6 +77,7 @@ schnell zu finden. Vielen Dank :)</resource>
<resource name="editor_arrowheads_none">Keine</resource> <resource name="editor_arrowheads_none">Keine</resource>
<resource name="editor_arrowheads_start">Anfangspunkt</resource> <resource name="editor_arrowheads_start">Anfangspunkt</resource>
<resource name="editor_autocrop">Automatisch zuschneiden</resource> <resource name="editor_autocrop">Automatisch zuschneiden</resource>
<resource name="editor_autocrop_not_possible">Automatisches Zuschneiden nicht möglich</resource>
<resource name="editor_backcolor">Hintergrundfarbe (0-9)</resource> <resource name="editor_backcolor">Hintergrundfarbe (0-9)</resource>
<resource name="editor_blur_radius">Weichzeichner-Radius</resource> <resource name="editor_blur_radius">Weichzeichner-Radius</resource>
<resource name="editor_bold">Fett</resource> <resource name="editor_bold">Fett</resource>
@ -92,6 +93,11 @@ schnell zu finden. Vielen Dank :)</resource>
<resource name="editor_copypathtoclipboard">Pfad in Zwischenablage kopieren</resource> <resource name="editor_copypathtoclipboard">Pfad in Zwischenablage kopieren</resource>
<resource name="editor_copytoclipboard">Kopieren</resource> <resource name="editor_copytoclipboard">Kopieren</resource>
<resource name="editor_crop">Zuschneiden (C)</resource> <resource name="editor_crop">Zuschneiden (C)</resource>
<resource name="editor_crop_mode">Zuschneiden - Modus</resource>
<resource name="editor_cropmode_default">Zuschneiden</resource>
<resource name="editor_cropmode_vertical">Vertikal ausschneiden</resource>
<resource name="editor_cropmode_horizontal">Horizontal ausschneiden</resource>
<resource name="editor_cropmode_auto">Automatisch zuschneiden</resource>
<resource name="editor_cursortool">Auswahlwerkzeug (Esc)</resource> <resource name="editor_cursortool">Auswahlwerkzeug (Esc)</resource>
<resource name="editor_cuttoclipboard">Ausschneiden</resource> <resource name="editor_cuttoclipboard">Ausschneiden</resource>
<resource name="editor_deleteelement">Gewähltes Element löschen</resource> <resource name="editor_deleteelement">Gewähltes Element löschen</resource>

View file

@ -88,6 +88,8 @@ Dangschee, wassd scho :)</resource>
<resource name="editor_copypathtoclipboard">Bfad in däi Zwischnblach nei</resource> <resource name="editor_copypathtoclipboard">Bfad in däi Zwischnblach nei</resource>
<resource name="editor_copytoclipboard">Kobiern</resource> <resource name="editor_copytoclipboard">Kobiern</resource>
<resource name="editor_crop">Zamschneidn (C)</resource> <resource name="editor_crop">Zamschneidn (C)</resource>
<resource name="editor_cropmode_default">Zamschneidn</resource>
<resource name="editor_cropmode_auto">Audomadisch zamschneidn</resource>
<resource name="editor_cursortool">Angriffln (ESC)</resource> <resource name="editor_cursortool">Angriffln (ESC)</resource>
<resource name="editor_cuttoclipboard">Ausschneidn</resource> <resource name="editor_cuttoclipboard">Ausschneidn</resource>
<resource name="editor_deleteelement">Wech mid dem Ding!</resource> <resource name="editor_deleteelement">Wech mid dem Ding!</resource>

View file

@ -93,6 +93,8 @@
<resource name="editor_copypathtoclipboard">Αντιγραφή της θέσης του αρχείου στο πρόχειρο</resource> <resource name="editor_copypathtoclipboard">Αντιγραφή της θέσης του αρχείου στο πρόχειρο</resource>
<resource name="editor_copytoclipboard">Αντιγραφή</resource> <resource name="editor_copytoclipboard">Αντιγραφή</resource>
<resource name="editor_crop">Περικοπή (C)</resource> <resource name="editor_crop">Περικοπή (C)</resource>
<resource name="editor_cropmode_default">Περικοπή</resource>
<resource name="editor_cropmode_auto">Αυτόματη Περικοπή</resource>
<resource name="editor_cursortool">Εργαλείο Επιλογής (ESC)</resource> <resource name="editor_cursortool">Εργαλείο Επιλογής (ESC)</resource>
<resource name="editor_cuttoclipboard">Αποκοπή</resource> <resource name="editor_cuttoclipboard">Αποκοπή</resource>
<resource name="editor_deleteelement">Διαγραφή</resource> <resource name="editor_deleteelement">Διαγραφή</resource>

View file

@ -78,6 +78,7 @@ Also, we would highly appreciate if you checked whether a tracker item already e
<resource name="editor_arrowheads_none">None</resource> <resource name="editor_arrowheads_none">None</resource>
<resource name="editor_arrowheads_start">Start point</resource> <resource name="editor_arrowheads_start">Start point</resource>
<resource name="editor_autocrop">Auto crop</resource> <resource name="editor_autocrop">Auto crop</resource>
<resource name="editor_autocrop_not_possible">Auto crop not possible</resource>
<resource name="editor_backcolor">Fill color (0-9)</resource> <resource name="editor_backcolor">Fill color (0-9)</resource>
<resource name="editor_blur_radius">Blur radius</resource> <resource name="editor_blur_radius">Blur radius</resource>
<resource name="editor_bold">Bold</resource> <resource name="editor_bold">Bold</resource>
@ -93,6 +94,11 @@ Also, we would highly appreciate if you checked whether a tracker item already e
<resource name="editor_copypathtoclipboard">Copy path to clipboard</resource> <resource name="editor_copypathtoclipboard">Copy path to clipboard</resource>
<resource name="editor_copytoclipboard">Copy</resource> <resource name="editor_copytoclipboard">Copy</resource>
<resource name="editor_crop">Crop (C)</resource> <resource name="editor_crop">Crop (C)</resource>
<resource name="editor_crop_mode">Crop mode</resource>
<resource name="editor_cropmode_default">Crop</resource>
<resource name="editor_cropmode_vertical">Crop out vertically</resource>
<resource name="editor_cropmode_horizontal">Crop out horizontally</resource>
<resource name="editor_cropmode_auto">Auto crop</resource>
<resource name="editor_cursortool">Selection Tool (ESC)</resource> <resource name="editor_cursortool">Selection Tool (ESC)</resource>
<resource name="editor_cuttoclipboard">Cut</resource> <resource name="editor_cuttoclipboard">Cut</resource>
<resource name="editor_deleteelement">Delete</resource> <resource name="editor_deleteelement">Delete</resource>

View file

@ -80,6 +80,8 @@ Antes de crear un nuevo informe de error, te agradeceríamos que comprobaras que
<resource name="editor_copypathtoclipboard">Copiar ruta al portapapeles</resource> <resource name="editor_copypathtoclipboard">Copiar ruta al portapapeles</resource>
<resource name="editor_copytoclipboard">Copiar</resource> <resource name="editor_copytoclipboard">Copiar</resource>
<resource name="editor_crop">Recortar(C)</resource> <resource name="editor_crop">Recortar(C)</resource>
<resource name="editor_cropmode_default">Recortar</resource>
<resource name="editor_cropmode_auto">Autorrecortar</resource>
<resource name="editor_cursortool">Herramienta de selección (ESC)</resource> <resource name="editor_cursortool">Herramienta de selección (ESC)</resource>
<resource name="editor_cuttoclipboard">Cortar</resource> <resource name="editor_cuttoclipboard">Cortar</resource>
<resource name="editor_deleteelement">Borrar</resource> <resource name="editor_deleteelement">Borrar</resource>

View file

@ -92,6 +92,8 @@ Me oleksime väga tänulik, kui te enne kontrolliksite, ega sellest veast pole j
<resource name="editor_copypathtoclipboard">Kopeerige asukoht lõikelauale</resource> <resource name="editor_copypathtoclipboard">Kopeerige asukoht lõikelauale</resource>
<resource name="editor_copytoclipboard">Kopeeri</resource> <resource name="editor_copytoclipboard">Kopeeri</resource>
<resource name="editor_crop">Lõika (C)</resource> <resource name="editor_crop">Lõika (C)</resource>
<resource name="editor_cropmode_default">Lõika</resource>
<resource name="editor_cropmode_auto">Automaatne lõikus</resource>
<resource name="editor_cursortool">Valiku tööriist (ESC)</resource> <resource name="editor_cursortool">Valiku tööriist (ESC)</resource>
<resource name="editor_cuttoclipboard">Lõika</resource> <resource name="editor_cuttoclipboard">Lõika</resource>
<resource name="editor_deleteelement">Kustuta</resource> <resource name="editor_deleteelement">Kustuta</resource>

View file

@ -67,6 +67,7 @@ Could not save Greenshot's configuration file. Please check access permissions f
<resource name="editor_copytoclipboard">رونویس</resource> <resource name="editor_copytoclipboard">رونویس</resource>
<resource name="editor_crop">چیدن <resource name="editor_crop">چیدن
(C دکمه)</resource> (C دکمه)</resource>
<resource name="editor_cropmode_default">چیدن</resource>
<resource name="editor_cursortool">انتخابگر <resource name="editor_cursortool">انتخابگر
(ESC دکمه)</resource> (ESC دکمه)</resource>
<resource name="editor_cuttoclipboard">برش</resource> <resource name="editor_cuttoclipboard">برش</resource>

View file

@ -62,6 +62,7 @@ Olisi myös hyvä jos voisit tarkistaa onko virhe jo raportoitu aikaisemmin (voi
<resource name="editor_copypathtoclipboard">Kopioi tiedostopolku leikepöydälle</resource> <resource name="editor_copypathtoclipboard">Kopioi tiedostopolku leikepöydälle</resource>
<resource name="editor_copytoclipboard">Kopioi</resource> <resource name="editor_copytoclipboard">Kopioi</resource>
<resource name="editor_crop">Rajaa (C)</resource> <resource name="editor_crop">Rajaa (C)</resource>
<resource name="editor_cropmode_default">Rajaa</resource>
<resource name="editor_cursortool">Valintatyökalu (ESC)</resource> <resource name="editor_cursortool">Valintatyökalu (ESC)</resource>
<resource name="editor_cuttoclipboard">Leikkaa</resource> <resource name="editor_cuttoclipboard">Leikkaa</resource>
<resource name="editor_deleteelement">Poista</resource> <resource name="editor_deleteelement">Poista</resource>

View file

@ -93,6 +93,8 @@ De plus, nous apprécierions beaucoup que vous preniez la peine de vérifier si
<resource name="editor_copytoclipboard">Copier</resource> <resource name="editor_copytoclipboard">Copier</resource>
<resource name="editor_counter">Ajouter un compteur</resource> <resource name="editor_counter">Ajouter un compteur</resource>
<resource name="editor_crop">Recadrer (C)</resource> <resource name="editor_crop">Recadrer (C)</resource>
<resource name="editor_cropmode_default">Recadrer</resource>
<resource name="editor_cropmode_auto">Cadrage automatique</resource>
<resource name="editor_cursortool">Outil de sélection (ESC)</resource> <resource name="editor_cursortool">Outil de sélection (ESC)</resource>
<resource name="editor_cuttoclipboard">Couper</resource> <resource name="editor_cuttoclipboard">Couper</resource>
<resource name="editor_deleteelement">Supprimer</resource> <resource name="editor_deleteelement">Supprimer</resource>

View file

@ -78,6 +78,8 @@ De plus, nous apprécierions beaucoup que vous preniez la peine de vérifier si
<resource name="editor_copypathtoclipboard">Copier le chemin vers le presse-papier</resource> <resource name="editor_copypathtoclipboard">Copier le chemin vers le presse-papier</resource>
<resource name="editor_copytoclipboard">Copier</resource> <resource name="editor_copytoclipboard">Copier</resource>
<resource name="editor_crop">Rogner (C)</resource> <resource name="editor_crop">Rogner (C)</resource>
<resource name="editor_cropmode_default">Rogner</resource>
<resource name="editor_cropmode_auto">Rognage automatique</resource>
<resource name="editor_cursortool">Outil de sélection (ESC)</resource> <resource name="editor_cursortool">Outil de sélection (ESC)</resource>
<resource name="editor_cuttoclipboard">Couper</resource> <resource name="editor_cuttoclipboard">Couper</resource>
<resource name="editor_deleteelement">Supprimer</resource> <resource name="editor_deleteelement">Supprimer</resource>

View file

@ -63,6 +63,7 @@ Details about the GNU General Public License:</resource>
<resource name="editor_copypathtoclipboard">העתק נתיב אל הלוח</resource> <resource name="editor_copypathtoclipboard">העתק נתיב אל הלוח</resource>
<resource name="editor_copytoclipboard">העתקה</resource> <resource name="editor_copytoclipboard">העתקה</resource>
<resource name="editor_crop">חתוך (C)</resource> <resource name="editor_crop">חתוך (C)</resource>
<resource name="editor_cropmode_default">חתוך</resource>
<resource name="editor_cursortool">כלי בחירה (ESC)</resource> <resource name="editor_cursortool">כלי בחירה (ESC)</resource>
<resource name="editor_cuttoclipboard">חיתוך</resource> <resource name="editor_cuttoclipboard">חיתוך</resource>
<resource name="editor_deleteelement">מחיקה</resource> <resource name="editor_deleteelement">מחיקה</resource>

View file

@ -63,6 +63,7 @@ Kérjük adjon összefoglaló leírást és csatoljon minden olyan információt
<resource name="editor_copypathtoclipboard">Másolja a vágólapra</resource> <resource name="editor_copypathtoclipboard">Másolja a vágólapra</resource>
<resource name="editor_copytoclipboard">Másolás</resource> <resource name="editor_copytoclipboard">Másolás</resource>
<resource name="editor_crop">Vágás eszköz (C)</resource> <resource name="editor_crop">Vágás eszköz (C)</resource>
<resource name="editor_cropmode_default">Vágás eszköz</resource>
<resource name="editor_cursortool">Kiválasztó eszköz (ESC)</resource> <resource name="editor_cursortool">Kiválasztó eszköz (ESC)</resource>
<resource name="editor_cuttoclipboard">Kivágás</resource> <resource name="editor_cuttoclipboard">Kivágás</resource>
<resource name="editor_deleteelement">Törlés</resource> <resource name="editor_deleteelement">Törlés</resource>

View file

@ -93,6 +93,8 @@ Juga, kami sangat terbantu apabila anda mengecek laporan lain yang sama dengan k
<resource name="editor_copytoclipboard">Kopi</resource> <resource name="editor_copytoclipboard">Kopi</resource>
<resource name="editor_counter">Buat penomor</resource> <resource name="editor_counter">Buat penomor</resource>
<resource name="editor_crop">Potong (C)</resource> <resource name="editor_crop">Potong (C)</resource>
<resource name="editor_cropmode_default">Potong</resource>
<resource name="editor_cropmode_auto">Auto potong</resource>
<resource name="editor_cursortool">Alat seleksi (ESC)</resource> <resource name="editor_cursortool">Alat seleksi (ESC)</resource>
<resource name="editor_cuttoclipboard">Gunting</resource> <resource name="editor_cuttoclipboard">Gunting</resource>
<resource name="editor_deleteelement">Hapus</resource> <resource name="editor_deleteelement">Hapus</resource>

View file

@ -98,6 +98,8 @@ Controlla i permessi di accesso per '{0}'.</resource>
<resource name="editor_copypathtoclipboard">Copia percorso negli appunti</resource> <resource name="editor_copypathtoclipboard">Copia percorso negli appunti</resource>
<resource name="editor_copytoclipboard">Copia</resource> <resource name="editor_copytoclipboard">Copia</resource>
<resource name="editor_crop">Ritaglia (C)</resource> <resource name="editor_crop">Ritaglia (C)</resource>
<resource name="editor_cropmode_default">Ritaglia</resource>
<resource name="editor_cropmode_auto">Ritaglia Automaticamente</resource>
<resource name="editor_cursortool">Strumento di selezione (ESC)</resource> <resource name="editor_cursortool">Strumento di selezione (ESC)</resource>
<resource name="editor_cuttoclipboard">Taglia</resource> <resource name="editor_cuttoclipboard">Taglia</resource>
<resource name="editor_deleteelement">Elimina</resource> <resource name="editor_deleteelement">Elimina</resource>

View file

@ -92,6 +92,8 @@ Greenshot には一切の保障がありません。GNU General Public License
<resource name="editor_copytoclipboard">コピー</resource> <resource name="editor_copytoclipboard">コピー</resource>
<resource name="editor_counter">カウンターを挿入する (I)</resource> <resource name="editor_counter">カウンターを挿入する (I)</resource>
<resource name="editor_crop">切り抜き (C)</resource> <resource name="editor_crop">切り抜き (C)</resource>
<resource name="editor_cropmode_default">切り抜き</resource>
<resource name="editor_cropmode_auto">自動切り抜き</resource>
<resource name="editor_cursortool">選択ツール (ESC)</resource> <resource name="editor_cursortool">選択ツール (ESC)</resource>
<resource name="editor_cuttoclipboard">切り取り</resource> <resource name="editor_cuttoclipboard">切り取り</resource>
<resource name="editor_deleteelement">削除</resource> <resource name="editor_deleteelement">削除</resource>

View file

@ -93,6 +93,8 @@ Rnu ɣur-s, nḥemmel aṭas ma yella tesneqdeḍ aneqqis igebren ugur-agi. (Tze
<resource name="editor_copytoclipboard">Nɣel</resource> <resource name="editor_copytoclipboard">Nɣel</resource>
<resource name="editor_counter">Rnu Amesmiḍan</resource> <resource name="editor_counter">Rnu Amesmiḍan</resource>
<resource name="editor_crop">Seggem (C)</resource> <resource name="editor_crop">Seggem (C)</resource>
<resource name="editor_cropmode_default">Seggem</resource>
<resource name="editor_cropmode_auto">Aseggem awurman</resource>
<resource name="editor_cursortool">Afecku n ufran (ESC)</resource> <resource name="editor_cursortool">Afecku n ufran (ESC)</resource>
<resource name="editor_cuttoclipboard">Gzem</resource> <resource name="editor_cuttoclipboard">Gzem</resource>
<resource name="editor_deleteelement">Kkes</resource> <resource name="editor_deleteelement">Kkes</resource>

View file

@ -92,6 +92,8 @@ Also, we would highly appreciate if you checked whether a tracker item already e
<resource name="editor_copypathtoclipboard">경로를 클립보드로 복사</resource> <resource name="editor_copypathtoclipboard">경로를 클립보드로 복사</resource>
<resource name="editor_copytoclipboard">복사</resource> <resource name="editor_copytoclipboard">복사</resource>
<resource name="editor_crop">잘라내기 (C)</resource> <resource name="editor_crop">잘라내기 (C)</resource>
<resource name="editor_cropmode_default">잘라내기</resource>
<resource name="editor_cropmode_auto">자동 잘라내기</resource>
<resource name="editor_cursortool">선택도구 (ESC)</resource> <resource name="editor_cursortool">선택도구 (ESC)</resource>
<resource name="editor_cuttoclipboard">잘라내기</resource> <resource name="editor_cuttoclipboard">잘라내기</resource>
<resource name="editor_deleteelement">삭제</resource> <resource name="editor_deleteelement">삭제</resource>

View file

@ -61,6 +61,7 @@ Dėkojame už pagalbą :)</resource>
<resource name="editor_copypathtoclipboard">Kopijuoti pilną failo vardą</resource> <resource name="editor_copypathtoclipboard">Kopijuoti pilną failo vardą</resource>
<resource name="editor_copytoclipboard">Коpijuoti</resource> <resource name="editor_copytoclipboard">Коpijuoti</resource>
<resource name="editor_crop">Iškirpti (C)</resource> <resource name="editor_crop">Iškirpti (C)</resource>
<resource name="editor_cropmode_default">Iškirpti</resource>
<resource name="editor_cursortool">Objektų pasirinkimas (ESC)</resource> <resource name="editor_cursortool">Objektų pasirinkimas (ESC)</resource>
<resource name="editor_cuttoclipboard">Apkirpti</resource> <resource name="editor_cuttoclipboard">Apkirpti</resource>
<resource name="editor_deleteelement">Naikinti</resource> <resource name="editor_deleteelement">Naikinti</resource>

View file

@ -92,6 +92,8 @@ Mēs būtu Tev pateicīgi, ja Tu vispirms pārbaudītu, vai kāds cits jau nav z
<resource name="editor_copypathtoclipboard">Ievietot ceļu starpliktuvē</resource> <resource name="editor_copypathtoclipboard">Ievietot ceļu starpliktuvē</resource>
<resource name="editor_copytoclipboard">Kopēt</resource> <resource name="editor_copytoclipboard">Kopēt</resource>
<resource name="editor_crop">Apcirst (C)</resource> <resource name="editor_crop">Apcirst (C)</resource>
<resource name="editor_cropmode_default">Apcirst</resource>
<resource name="editor_cropmode_auto">Automātiski apcirst</resource>
<resource name="editor_cursortool">Atlases rīks (ESC)</resource> <resource name="editor_cursortool">Atlases rīks (ESC)</resource>
<resource name="editor_cuttoclipboard">Izgriezt</resource> <resource name="editor_cuttoclipboard">Izgriezt</resource>
<resource name="editor_deleteelement">Izdzēst</resource> <resource name="editor_deleteelement">Izdzēst</resource>

View file

@ -93,6 +93,8 @@ Controleer ook even of dit probleem mogelijk al gemeld is! Gebruik de zoekfuncti
<resource name="editor_copypathtoclipboard">Locatie naar klembord kopiëren</resource> <resource name="editor_copypathtoclipboard">Locatie naar klembord kopiëren</resource>
<resource name="editor_copytoclipboard">Kopiëren</resource> <resource name="editor_copytoclipboard">Kopiëren</resource>
<resource name="editor_crop">Bijsnijden (C)</resource> <resource name="editor_crop">Bijsnijden (C)</resource>
<resource name="editor_cropmode_default">Bijsnijden</resource>
<resource name="editor_cropmode_auto">Automatisch bijsnijden</resource>
<resource name="editor_cursortool">Selectiegereedschap (ESC)</resource> <resource name="editor_cursortool">Selectiegereedschap (ESC)</resource>
<resource name="editor_cuttoclipboard">Knippen</resource> <resource name="editor_cuttoclipboard">Knippen</resource>
<resource name="editor_deleteelement">Verwijderen</resource> <resource name="editor_deleteelement">Verwijderen</resource>

View file

@ -80,6 +80,8 @@ Me sett òg pris på om du ved hjelp av søkefunksjonen på sida kan sjekke om d
<resource name="editor_copypathtoclipboard">Kopier filstigen til utklyppstavla</resource> <resource name="editor_copypathtoclipboard">Kopier filstigen til utklyppstavla</resource>
<resource name="editor_copytoclipboard">Kopier</resource> <resource name="editor_copytoclipboard">Kopier</resource>
<resource name="editor_crop">Skjer bildet [C]</resource> <resource name="editor_crop">Skjer bildet [C]</resource>
<resource name="editor_cropmode_default">Skjer bildet</resource>
<resource name="editor_cropmode_auto">Auto-skjer</resource>
<resource name="editor_cursortool">Peikarverktøy [Esc]</resource> <resource name="editor_cursortool">Peikarverktøy [Esc]</resource>
<resource name="editor_cuttoclipboard">Klypp ut</resource> <resource name="editor_cuttoclipboard">Klypp ut</resource>
<resource name="editor_deleteelement">Slett</resource> <resource name="editor_deleteelement">Slett</resource>

View file

@ -93,6 +93,8 @@ Będziemy wdzięczni, jeśli najpierw sprawdzisz, czy takie zdarzenie nie zosta
<resource name="editor_copypathtoclipboard">Kopiuj ścieżkę do schowka</resource> <resource name="editor_copypathtoclipboard">Kopiuj ścieżkę do schowka</resource>
<resource name="editor_copytoclipboard">Kopiuj</resource> <resource name="editor_copytoclipboard">Kopiuj</resource>
<resource name="editor_crop">Przytnij (C)</resource> <resource name="editor_crop">Przytnij (C)</resource>
<resource name="editor_cropmode_default">Przytnij (C)</resource>
<resource name="editor_cropmode_auto">Przytnij automatycznie</resource>
<resource name="editor_cursortool">Narzędzie wyboru (ESC)</resource> <resource name="editor_cursortool">Narzędzie wyboru (ESC)</resource>
<resource name="editor_cuttoclipboard">Wytnij</resource> <resource name="editor_cuttoclipboard">Wytnij</resource>
<resource name="editor_deleteelement">Usuń</resource> <resource name="editor_deleteelement">Usuń</resource>

View file

@ -89,6 +89,7 @@
<resource name="editor_copypathtoclipboard">Copiar o caminho da pasta atual do arquivo para a Área de transferência</resource> <resource name="editor_copypathtoclipboard">Copiar o caminho da pasta atual do arquivo para a Área de transferência</resource>
<resource name="editor_copytoclipboard">Copiar</resource> <resource name="editor_copytoclipboard">Copiar</resource>
<resource name="editor_crop">Cortar (C)</resource> <resource name="editor_crop">Cortar (C)</resource>
<resource name="editor_cropmode_default">Cortar</resource>
<resource name="editor_cursortool">Ferramenta de Seleção (ESC)</resource> <resource name="editor_cursortool">Ferramenta de Seleção (ESC)</resource>
<resource name="editor_cuttoclipboard">Cortar</resource> <resource name="editor_cuttoclipboard">Cortar</resource>
<resource name="editor_deleteelement">Apagar</resource> <resource name="editor_deleteelement">Apagar</resource>

View file

@ -92,6 +92,8 @@ Também apreciaremos muito se puder verificar se não existe já um relatório d
<resource name="editor_copypathtoclipboard">Copiar atalho para a Área de transferência</resource> <resource name="editor_copypathtoclipboard">Copiar atalho para a Área de transferência</resource>
<resource name="editor_copytoclipboard">Copiar</resource> <resource name="editor_copytoclipboard">Copiar</resource>
<resource name="editor_crop">Recortar (C)</resource> <resource name="editor_crop">Recortar (C)</resource>
<resource name="editor_cropmode_default">Recortar</resource>
<resource name="editor_cropmode_auto">Recortar auto</resource>
<resource name="editor_cursortool">Ferramenta de Selecção (ESC)</resource> <resource name="editor_cursortool">Ferramenta de Selecção (ESC)</resource>
<resource name="editor_cuttoclipboard">Cortar</resource> <resource name="editor_cuttoclipboard">Cortar</resource>
<resource name="editor_deleteelement">Eliminar</resource> <resource name="editor_deleteelement">Eliminar</resource>

View file

@ -471,6 +471,9 @@ timpul curent, ex. 11_58_32 (plus extensia fișierului definită în setări)
<resource name="editor_crop"> <resource name="editor_crop">
Taie (C) Taie (C)
</resource> </resource>
<resource name="editor_cropmode_default">
Taie
</resource>
<resource name="contextmenu_captureclipboard"> <resource name="contextmenu_captureclipboard">
Deschide imaginea din clipboard Deschide imaginea din clipboard
</resource> </resource>

View file

@ -93,6 +93,8 @@ Greenshot поставляется БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.
<resource name="editor_copypathtoclipboard">Копировать путь в буфер обмена</resource> <resource name="editor_copypathtoclipboard">Копировать путь в буфер обмена</resource>
<resource name="editor_copytoclipboard">Копировать</resource> <resource name="editor_copytoclipboard">Копировать</resource>
<resource name="editor_crop">Обрезка (C)</resource> <resource name="editor_crop">Обрезка (C)</resource>
<resource name="editor_cropmode_default">Обрезка</resource>
<resource name="editor_cropmode_auto">Автообрезка</resource>
<resource name="editor_cursortool">Инструмент «Выделение» (ESC)</resource> <resource name="editor_cursortool">Инструмент «Выделение» (ESC)</resource>
<resource name="editor_cuttoclipboard">Вырезать</resource> <resource name="editor_cuttoclipboard">Вырезать</resource>
<resource name="editor_deleteelement">Удалить</resource> <resource name="editor_deleteelement">Удалить</resource>

View file

@ -80,6 +80,8 @@ Tiež by sme velmi ocenili, keby ste najskôr skontrolovali, či už neexistuje
<resource name="editor_copypathtoclipboard">Kopírovať cestu do schránky</resource> <resource name="editor_copypathtoclipboard">Kopírovať cestu do schránky</resource>
<resource name="editor_copytoclipboard">Kopírovať</resource> <resource name="editor_copytoclipboard">Kopírovať</resource>
<resource name="editor_crop">Orezať (C)</resource> <resource name="editor_crop">Orezať (C)</resource>
<resource name="editor_cropmode_default">Orezať</resource>
<resource name="editor_cropmode_auto">Automatické orezanie</resource>
<resource name="editor_cursortool">Nástroj pre výber (ESC)</resource> <resource name="editor_cursortool">Nástroj pre výber (ESC)</resource>
<resource name="editor_cuttoclipboard">Vystrihnúť</resource> <resource name="editor_cuttoclipboard">Vystrihnúť</resource>
<resource name="editor_deleteelement">Zmazať</resource> <resource name="editor_deleteelement">Zmazať</resource>

View file

@ -78,6 +78,8 @@ Pred objavo preverite tudi ali je napaka že prijavlja s strani kakšnega drugeg
<resource name="editor_copypathtoclipboard">Kopiraj pot na odložišče</resource> <resource name="editor_copypathtoclipboard">Kopiraj pot na odložišče</resource>
<resource name="editor_copytoclipboard">Kopiraj</resource> <resource name="editor_copytoclipboard">Kopiraj</resource>
<resource name="editor_crop">Obreži (C)</resource> <resource name="editor_crop">Obreži (C)</resource>
<resource name="editor_cropmode_default">Obreži</resource>
<resource name="editor_cropmode_auto">Samodejno obreži</resource>
<resource name="editor_cursortool">Orodje za izbor (ESC)</resource> <resource name="editor_cursortool">Orodje za izbor (ESC)</resource>
<resource name="editor_cuttoclipboard">Kopiraj</resource> <resource name="editor_cuttoclipboard">Kopiraj</resource>
<resource name="editor_deleteelement">Briši</resource> <resource name="editor_deleteelement">Briši</resource>

View file

@ -78,6 +78,8 @@
<resource name="editor_copypathtoclipboard">Умножи путању</resource> <resource name="editor_copypathtoclipboard">Умножи путању</resource>
<resource name="editor_copytoclipboard">Умножи</resource> <resource name="editor_copytoclipboard">Умножи</resource>
<resource name="editor_crop">Опсеци (C)</resource> <resource name="editor_crop">Опсеци (C)</resource>
<resource name="editor_cropmode_default">Опсеци</resource>
<resource name="editor_cropmode_auto">Аутоматско опсецање</resource>
<resource name="editor_cursortool">Алатка за одабир (ESC)</resource> <resource name="editor_cursortool">Алатка за одабир (ESC)</resource>
<resource name="editor_cuttoclipboard">Исеци</resource> <resource name="editor_cuttoclipboard">Исеци</resource>
<resource name="editor_deleteelement">Обриши</resource> <resource name="editor_deleteelement">Обриши</resource>

View file

@ -93,6 +93,8 @@ Innan du skickar uppskattar vi verkligen om du kontrollerar om felet redan blivi
<resource name="editor_copypathtoclipboard">Kopiera sökväg till urklipp</resource> <resource name="editor_copypathtoclipboard">Kopiera sökväg till urklipp</resource>
<resource name="editor_copytoclipboard">Kopiera</resource> <resource name="editor_copytoclipboard">Kopiera</resource>
<resource name="editor_crop">Beskär (C)</resource> <resource name="editor_crop">Beskär (C)</resource>
<resource name="editor_cropmode_default">Beskär</resource>
<resource name="editor_cropmode_auto">Autobeskärning</resource>
<resource name="editor_cursortool">Markeringsverktyg (ESC)</resource> <resource name="editor_cursortool">Markeringsverktyg (ESC)</resource>
<resource name="editor_cuttoclipboard">Klipp ut</resource> <resource name="editor_cuttoclipboard">Klipp ut</resource>
<resource name="editor_deleteelement">Radera</resource> <resource name="editor_deleteelement">Radera</resource>

View file

@ -78,6 +78,8 @@ Ayrıca bu hata için bir izleyici kaydının açılmış olup olmadığını da
<resource name="editor_copypathtoclipboard">Yolu panoya kopyala</resource> <resource name="editor_copypathtoclipboard">Yolu panoya kopyala</resource>
<resource name="editor_copytoclipboard">Kopyala</resource> <resource name="editor_copytoclipboard">Kopyala</resource>
<resource name="editor_crop">Kırp (C)</resource> <resource name="editor_crop">Kırp (C)</resource>
<resource name="editor_cropmode_default">Kırp</resource>
<resource name="editor_cropmode_auto">Otomatik kırpma</resource>
<resource name="editor_cursortool">Seçim Aracı (ESC)</resource> <resource name="editor_cursortool">Seçim Aracı (ESC)</resource>
<resource name="editor_cuttoclipboard">Kes</resource> <resource name="editor_cuttoclipboard">Kes</resource>
<resource name="editor_deleteelement">Sil</resource> <resource name="editor_deleteelement">Sil</resource>

View file

@ -92,6 +92,8 @@ Greenshot постачається АБСОЛЮТНО БЕЗ ГАРАНТІЇ.
<resource name="editor_copypathtoclipboard">Копіювати шлях у буфер обміну</resource> <resource name="editor_copypathtoclipboard">Копіювати шлях у буфер обміну</resource>
<resource name="editor_copytoclipboard">Копіювати</resource> <resource name="editor_copytoclipboard">Копіювати</resource>
<resource name="editor_crop">Обрізати (С)</resource> <resource name="editor_crop">Обрізати (С)</resource>
<resource name="editor_cropmode_default">Обрізати</resource>
<resource name="editor_cropmode_auto">Автоматичне обрізання</resource>
<resource name="editor_cursortool">Інструмент вибору (Esc)</resource> <resource name="editor_cursortool">Інструмент вибору (Esc)</resource>
<resource name="editor_cuttoclipboard">Вирізати</resource> <resource name="editor_cuttoclipboard">Вирізати</resource>
<resource name="editor_deleteelement">Видалити</resource> <resource name="editor_deleteelement">Видалити</resource>

View file

@ -58,6 +58,7 @@
<resource name="editor_copypathtoclipboard">Chép đuờng dẫn tới clipboard.</resource> <resource name="editor_copypathtoclipboard">Chép đuờng dẫn tới clipboard.</resource>
<resource name="editor_copytoclipboard">Chép</resource> <resource name="editor_copytoclipboard">Chép</resource>
<resource name="editor_crop">Cắt (C)</resource> <resource name="editor_crop">Cắt (C)</resource>
<resource name="editor_cropmode_default">Cắt</resource>
<resource name="editor_cursortool">Công cụ chọn (ESC)</resource> <resource name="editor_cursortool">Công cụ chọn (ESC)</resource>
<resource name="editor_cuttoclipboard">Cắt</resource> <resource name="editor_cuttoclipboard">Cắt</resource>
<resource name="editor_deleteelement">Xóa</resource> <resource name="editor_deleteelement">Xóa</resource>

View file

@ -84,6 +84,8 @@
<resource name="editor_copypathtoclipboard">复制路径到剪贴板</resource> <resource name="editor_copypathtoclipboard">复制路径到剪贴板</resource>
<resource name="editor_copytoclipboard">复制</resource> <resource name="editor_copytoclipboard">复制</resource>
<resource name="editor_crop">裁剪 (C)</resource> <resource name="editor_crop">裁剪 (C)</resource>
<resource name="editor_cropmode_default">裁剪</resource>
<resource name="editor_cropmode_auto">自动裁剪</resource>
<resource name="editor_cursortool">选择工具 (ESC)</resource> <resource name="editor_cursortool">选择工具 (ESC)</resource>
<resource name="editor_cuttoclipboard">剪切</resource> <resource name="editor_cuttoclipboard">剪切</resource>
<resource name="editor_deleteelement">刪除物件</resource> <resource name="editor_deleteelement">刪除物件</resource>

View file

@ -93,6 +93,8 @@ Greenshot 不對這個程式做任何擔保。這個程式是自由軟體,您
<resource name="editor_copypathtoclipboard">複製路徑到剪貼簿</resource> <resource name="editor_copypathtoclipboard">複製路徑到剪貼簿</resource>
<resource name="editor_copytoclipboard">複製</resource> <resource name="editor_copytoclipboard">複製</resource>
<resource name="editor_crop">裁剪 (C)</resource> <resource name="editor_crop">裁剪 (C)</resource>
<resource name="editor_cropmode_default">裁剪</resource>
<resource name="editor_cropmode_auto">自動裁剪</resource>
<resource name="editor_cursortool">選取工具 (ESC)</resource> <resource name="editor_cursortool">選取工具 (ESC)</resource>
<resource name="editor_cuttoclipboard">剪下</resource> <resource name="editor_cuttoclipboard">剪下</resource>
<resource name="editor_deleteelement">刪除</resource> <resource name="editor_deleteelement">刪除</resource>