private HistoryMemento DoCanvasResize(DocumentWorkspace documentWorkspace, Size newLayerSize) { HistoryMemento retHA; int layerIndex = documentWorkspace.ActiveLayerIndex; Size newSize = new Size(Math.Max(newLayerSize.Width, documentWorkspace.Document.Width), Math.Max(newLayerSize.Height, documentWorkspace.Document.Height)); Document newDoc; try { using (new WaitCursorChanger(documentWorkspace)) { Utility.GCFullCollect(); newDoc = CanvasSizeAction.ResizeDocument(documentWorkspace.Document, newSize, AnchorEdge.TopLeft, documentWorkspace.AppWorkspace.AppEnvironment.SecondaryColor); } } catch (OutOfMemoryException) { Utility.ErrorBox(documentWorkspace, PdnResources.GetString("ImportFromFileAction.AskForCanvasResize.OutOfMemory")); newDoc = null; } if (newDoc == null) { retHA = null; } else { retHA = new ReplaceDocumentHistoryMemento(string.Empty, null, documentWorkspace); using (new WaitCursorChanger(documentWorkspace)) { documentWorkspace.Document = newDoc; } documentWorkspace.ActiveLayer = (Layer)documentWorkspace.Document.Layers[layerIndex]; } return(retHA); }
/// <summary> /// Pastes from the clipboard into the document. /// </summary> /// <returns>true if the paste operation completed, false if there was an error or if it was cancelled for some reason</returns> public bool PerformAction() { SurfaceForClipboard surfaceForClipboard = null; IDataObject clipData = null; try { Utility.GCFullCollect(); clipData = Clipboard.GetDataObject(); } catch (ExternalException) { Utility.ErrorBox(this.documentWorkspace, PdnResources.GetString("PasteAction.Error.TransferFromClipboard")); return(false); } catch (OutOfMemoryException) { Utility.ErrorBox(this.documentWorkspace, PdnResources.GetString("PasteAction.Error.OutOfMemory")); return(false); } // First "ask" the current tool if it wants to handle it bool handledByTool = false; if (this.documentWorkspace.Tool != null) { this.documentWorkspace.Tool.PerformPaste(clipData, out handledByTool); } if (handledByTool) { return(true); } if (clipData.GetDataPresent(typeof(SurfaceForClipboard))) { try { Utility.GCFullCollect(); surfaceForClipboard = clipData.GetData(typeof(SurfaceForClipboard)) as SurfaceForClipboard; } catch (OutOfMemoryException) { Utility.ErrorBox(this.documentWorkspace, PdnResources.GetString("PasteAction.Error.OutOfMemory")); return(false); } } if (surfaceForClipboard != null && surfaceForClipboard.MaskedSurface.IsDisposed) { // Have been getting crash reports where sfc contains a disposed MaskedSurface ... surfaceForClipboard = null; } if (surfaceForClipboard == null && (clipData.GetDataPresent(DataFormats.Bitmap, true) || clipData.GetDataPresent(DataFormats.EnhancedMetafile, true))) { Image image; try { Utility.GCFullCollect(); image = clipData.GetData(DataFormats.Bitmap, true) as Image; if (image == null) { image = SystemLayer.Clipboard.GetEmfFromClipboard(this.documentWorkspace); } } catch (OutOfMemoryException) { Utility.ErrorBox(this.documentWorkspace, PdnResources.GetString("PasteAction.Error.OutOfMemory")); return(false); } // Sometimes we get weird errors if we're in, say, 16-bit mode but the image was copied // to the clipboard in 32-bit mode if (image == null) { Utility.ErrorBox(this.documentWorkspace, PdnResources.GetString("PasteAction.Error.NotRecognized")); return(false); } MaskedSurface maskedSurface = null; try { Utility.GCFullCollect(); Bitmap bitmap; Surface surface = null; if (image is Bitmap) { bitmap = (Bitmap)image; image = null; } else { bitmap = new Bitmap(image); image.Dispose(); image = null; } surface = Surface.CopyFromBitmap(bitmap); bitmap.Dispose(); bitmap = null; maskedSurface = new MaskedSurface(surface, new PdnRegion(surface.Bounds)); surface.Dispose(); surface = null; } catch (Exception) { Utility.ErrorBox(this.documentWorkspace, PdnResources.GetString("PasteAction.Error.OutOfMemory")); return(false); } surfaceForClipboard = new SurfaceForClipboard(maskedSurface); } if (surfaceForClipboard == null || surfaceForClipboard.MaskedSurface == null) { // silently fail: like what if a program overwrote the clipboard in between the time // we enabled the "Paste" menu item and the user actually clicked paste? // it could happen! Utility.ErrorBox(this.documentWorkspace, PdnResources.GetString("PasteAction.Error.NoImage")); return(false); } // If the image is larger than the document, ask them if they'd like to make the image larger first Rectangle bounds = surfaceForClipboard.Bounds; if (bounds.Width > this.documentWorkspace.Document.Width || bounds.Height > this.documentWorkspace.Document.Height) { Surface thumb; try { using (new WaitCursorChanger(this.documentWorkspace)) { thumb = CreateThumbnail(surfaceForClipboard); } } catch (OutOfMemoryException) { thumb = null; } DialogResult dr = ShowExpandCanvasTaskDialog(this.documentWorkspace, thumb); int layerIndex = this.documentWorkspace.ActiveLayerIndex; switch (dr) { case DialogResult.Yes: Size newSize = new Size(Math.Max(bounds.Width, this.documentWorkspace.Document.Width), Math.Max(bounds.Height, this.documentWorkspace.Document.Height)); Document newDoc = CanvasSizeAction.ResizeDocument( this.documentWorkspace.Document, newSize, AnchorEdge.TopLeft, this.documentWorkspace.AppWorkspace.AppEnvironment.SecondaryColor); if (newDoc == null) { return(false); // user clicked cancel! } else { HistoryMemento rdha = new ReplaceDocumentHistoryMemento( CanvasSizeAction.StaticName, CanvasSizeAction.StaticImage, this.documentWorkspace); this.documentWorkspace.Document = newDoc; this.documentWorkspace.History.PushNewMemento(rdha); this.documentWorkspace.ActiveLayer = (Layer)this.documentWorkspace.Document.Layers[layerIndex]; } break; case DialogResult.No: break; case DialogResult.Cancel: return(false); default: throw new InvalidEnumArgumentException("Internal error: DialogResult was neither Yes, No, nor Cancel"); } } // Decide where to paste to: If the paste is within bounds of the document, do as normal // Otherwise, center it. Rectangle docBounds = this.documentWorkspace.Document.Bounds; Rectangle intersect1 = Rectangle.Intersect(docBounds, bounds); bool doMove = intersect1 != bounds; //intersect1.IsEmpty; Point pasteOffset; if (doMove) { pasteOffset = new Point(-bounds.X + (docBounds.Width / 2) - (bounds.Width / 2), -bounds.Y + (docBounds.Height / 2) - (bounds.Height / 2)); } else { pasteOffset = new Point(0, 0); } // Paste to the place it was originally copied from (for PDN-to-PDN transfers) // and then if its not pasted within the viewable rectangle we pan to that location RectangleF visibleDocRectF = this.documentWorkspace.VisibleDocumentRectangleF; Rectangle visibleDocRect = Utility.RoundRectangle(visibleDocRectF); Rectangle bounds2 = new Rectangle(new Point(bounds.X + pasteOffset.X, bounds.Y + pasteOffset.Y), bounds.Size); Rectangle intersect2 = Rectangle.Intersect(bounds2, visibleDocRect); bool doPan = intersect2.IsEmpty; this.documentWorkspace.SetTool(null); this.documentWorkspace.SetToolFromType(typeof(MoveTool)); ((MoveTool)this.documentWorkspace.Tool).PasteMouseDown(surfaceForClipboard, pasteOffset); if (doPan) { Point centerPtView = new Point(visibleDocRect.Left + (visibleDocRect.Width / 2), visibleDocRect.Top + (visibleDocRect.Height / 2)); Point centerPtPasted = new Point(bounds2.Left + (bounds2.Width / 2), bounds2.Top + (bounds2.Height / 2)); Size delta = new Size(centerPtPasted.X - centerPtView.X, centerPtPasted.Y - centerPtView.Y); PointF docScrollPos = this.documentWorkspace.DocumentScrollPositionF; PointF newDocScrollPos = new PointF(docScrollPos.X + delta.Width, docScrollPos.Y + delta.Height); this.documentWorkspace.DocumentScrollPositionF = newDocScrollPos; } return(true); }