public void Paste(bool toNewLayer, int x = 0, int y = 0)
{
// Create a compound history item for recording several
// operations so that they can all be undone/redone together.
CompoundHistoryItem paste_action;
if (toNewLayer)
{
paste_action = new CompoundHistoryItem (Stock.Paste, Catalog.GetString ("Paste Into New Layer"));
}
else
{
paste_action = new CompoundHistoryItem (Stock.Paste, Catalog.GetString ("Paste"));
}
Gtk.Clipboard cb = Gtk.Clipboard.Get (Gdk.Atom.Intern ("CLIPBOARD", false));
// See if the current tool wants to handle the paste
// operation (e.g., the text tool could paste text)
if (!toNewLayer)
{
if (PintaCore.Tools.CurrentTool.TryHandlePaste (cb))
return;
}
PintaCore.Tools.Commit ();
// Don't dispose this, as we're going to give it to the history
Gdk.Pixbuf cbImage = null;
if (cb.WaitIsImageAvailable ()) {
cbImage = cb.WaitForImage ();
}
if (cbImage == null)
{
ShowClipboardEmptyDialog();
return;
}
Gdk.Size canvas_size = PintaCore.Workspace.ImageSize;
// If the image being pasted is larger than the canvas size, allow the user to optionally resize the canvas
if (cbImage.Width > canvas_size.Width || cbImage.Height > canvas_size.Height)
{
ResponseType response = ShowExpandCanvasDialog ();
if (response == ResponseType.Accept)
{
PintaCore.Workspace.ResizeCanvas (cbImage.Width, cbImage.Height,
Pinta.Core.Anchor.Center, paste_action);
PintaCore.Actions.View.UpdateCanvasScale ();
}
else if (response == ResponseType.Cancel || response == ResponseType.DeleteEvent)
{
return;
}
}
// If the pasted image would fall off bottom- or right-
// side of image, adjust paste position
x = Math.Max (0, Math.Min (x, canvas_size.Width - cbImage.Width));
y = Math.Max (0, Math.Min (y, canvas_size.Height - cbImage.Height));
// If requested, create a new layer, make it the current
// layer and record it's creation in the history
if (toNewLayer)
{
UserLayer l = AddNewLayer (string.Empty);
SetCurrentUserLayer (l);
paste_action.Push (new AddLayerHistoryItem ("Menu.Layers.AddNewLayer.png", Catalog.GetString ("Add New Layer"), UserLayers.IndexOf (l)));
}
// Copy the paste to the temp layer, which should be at least the size of this document.
CreateSelectionLayer (Math.Max(ImageSize.Width, cbImage.Width),
Math.Max(ImageSize.Height, cbImage.Height));
ShowSelectionLayer = true;
using (Cairo.Context g = new Cairo.Context (SelectionLayer.Surface))
{
g.DrawPixbuf (cbImage, new Cairo.Point (0, 0));
}
SelectionLayer.Transform.InitIdentity();
SelectionLayer.Transform.Translate (x, y);
PintaCore.Tools.SetCurrentTool (Catalog.GetString ("Move Selected Pixels"));
DocumentSelection old_selection = Selection.Clone();
bool old_show_selection = ShowSelection;
Selection.CreateRectangleSelection (new Cairo.Rectangle (x, y, cbImage.Width, cbImage.Height));
ShowSelection = true;
Workspace.Invalidate ();
paste_action.Push (new PasteHistoryItem (cbImage, old_selection, old_show_selection));
History.PushNewItem (paste_action);
}