Esempio n. 1
0
        private void Activated(object sender, EventArgs e)
        {
            Gtk.Clipboard cb = Gtk.Clipboard.Get(Gdk.Atom.Intern("CLIPBOARD", false));
            if (PintaCore.Tools.CurrentTool.TryHandlePaste(cb))
            {
                return;
            }

            Document doc = PintaCore.Workspace.ActiveDocument;

            PintaCore.Tools.Commit();

            Path p;

            // Don't dispose this, as we're going to give it to the history
            Gdk.Pixbuf image = cb.WaitForImage();

            if (image == null)
            {
                Dialogs.ClipboardEmptyDialog.Show();
                return;
            }

            Gdk.Size canvas_size = PintaCore.Workspace.ImageSize;

            // Merge the (optional) canvas resize and the pasted image into a single history item.
            var paste_action = new CompoundHistoryItem(Stock.Paste, Catalog.GetString("Paste"));

            // If the image being pasted is larger than the canvas size, allow the user to optionally resize the canvas
            if (image.Width > canvas_size.Width || image.Height > canvas_size.Height)
            {
                ResponseType response = ShowExpandCanvasDialog();

                if (response == ResponseType.Accept)
                {
                    PintaCore.Workspace.ResizeCanvas(image.Width, image.Height,
                                                     Pinta.Core.Anchor.Center, paste_action);
                    PintaCore.Actions.View.UpdateCanvasScale();
                }
                else if (response == ResponseType.Cancel || response == ResponseType.DeleteEvent)
                {
                    return;
                }
            }

            // Copy the paste to the temp layer
            doc.CreateSelectionLayer();
            doc.ShowSelectionLayer = true;

            using (Cairo.Context g = new Cairo.Context(doc.SelectionLayer.Surface))
            {
                g.DrawPixbuf(image, new Cairo.Point(0, 0));
                p = g.CreateRectanglePath(new Rectangle(0, 0, image.Width, image.Height));
            }

            PintaCore.Tools.SetCurrentTool(Catalog.GetString("Move Selected Pixels"));

            DocumentSelection old_selection = doc.Selection.Clone();
            bool old_show_selection         = doc.ShowSelection;

            doc.Selection.SelectionPath = p;
            doc.Selection.SelectionPolygons.Clear();
            doc.ShowSelection = true;

            doc.Workspace.Invalidate();

            paste_action.Push(new PasteHistoryItem(image, old_selection, old_show_selection));
            doc.History.PushNewItem(paste_action);
        }
Esempio n. 2
0
        /// <summary>
        /// Pastes an image from the clipboard.
        /// </summary>
        /// <param name="toNewLayer">Set to TRUE to paste into a
        /// new layer.  Otherwise, will paste to the current layer.</param>
        /// <param name="x">Optional. Location within image to paste to.
        /// Position will be adjusted if pasted image would hang
        /// over right or bottom edges of canvas.</param>
        /// <param name="y">Optional. Location within image to paste to.
        /// Position will be adjusted if pasted image would hang
        /// over right or bottom edges of canvas.</param>
        public static void Paste(Document doc, 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.
            var history_text = toNewLayer ? Translations.GetString("Paste Into New Layer") : Translations.GetString("Paste");
            var paste_action = new CompoundHistoryItem(Resources.StandardIcons.EditPaste, history_text);

            var cb = 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.DoHandlePaste(doc, cb))
                {
                    return;
                }
            }

            // Commit any unfinished tool actions
            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 is null)
            {
                ShowClipboardEmptyDialog();
                return;
            }

            var 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)
            {
                var response = ShowExpandCanvasDialog();

                if (response == ResponseType.Accept)
                {
                    var new_width  = Math.Max(canvas_size.Width, cbImage.Width);
                    var new_height = Math.Max(canvas_size.Height, cbImage.Height);
                    PintaCore.Workspace.ResizeCanvas(new_width, new_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)
            {
                var l = doc.Layers.AddNewLayer(string.Empty);
                doc.Layers.SetCurrentUserLayer(l);
                paste_action.Push(new AddLayerHistoryItem(Resources.Icons.LayerNew, Translations.GetString("Add New Layer"), doc.Layers.IndexOf(l)));
            }

            // Copy the paste to the temp layer, which should be at least the size of this document.
            doc.Layers.CreateSelectionLayer(Math.Max(doc.ImageSize.Width, cbImage.Width),
                                            Math.Max(doc.ImageSize.Height, cbImage.Height));
            doc.Layers.ShowSelectionLayer = true;

            using (var g = new Cairo.Context(doc.Layers.SelectionLayer.Surface))
                g.DrawPixbuf(cbImage, new Cairo.Point(0, 0));

            doc.Layers.SelectionLayer.Transform.InitIdentity();
            doc.Layers.SelectionLayer.Transform.Translate(x, y);

            PintaCore.Tools.SetCurrentTool("MoveSelectedTool");

            var old_selection = doc.Selection.Clone();

            doc.Selection.CreateRectangleSelection(new Cairo.Rectangle(x, y, cbImage.Width, cbImage.Height));
            doc.Selection.Visible = true;

            doc.Workspace.Invalidate();

            paste_action.Push(new PasteHistoryItem(cbImage, old_selection));
            doc.History.PushNewItem(paste_action);
        }