protected override HistoryMemento OnUndo() { ReplaceDocumentHistoryMemento ha = new ReplaceDocumentHistoryMemento(Name, Image, this.historyWorkspace); this.historyWorkspace.Document = ((ReplaceDocumentHistoryMementoData)Data).OldDocument; return(ha); }
protected override HistoryMemento OnUndo(ProgressEventHandler progressCallback) { ReplaceDocumentHistoryMemento memento = new ReplaceDocumentHistoryMemento(base.Name, base.Image, this.historyWorkspace); this.historyWorkspace.Document = ((ReplaceDocumentHistoryMementoData)base.Data).OldDocument; return(memento); }
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; }
public override HistoryMemento OnExecute(IHistoryWorkspace historyWorkspace) { object savedSelection = null; List<HistoryMemento> actions = new List<HistoryMemento>(); if (!historyWorkspace.Selection.IsEmpty) { savedSelection = historyWorkspace.Selection.Save(); DeselectFunction da = new DeselectFunction(); HistoryMemento hm = da.Execute(historyWorkspace); actions.Add(hm); } ReplaceDocumentHistoryMemento rdha = new ReplaceDocumentHistoryMemento(null, null, historyWorkspace); actions.Add(rdha); CompoundHistoryMemento chm = new CompoundHistoryMemento( StaticName, PdnResources.GetImageResource("Icons.MenuImageFlattenIcon.png"), actions); // TODO: we can save memory here by serializing, then flattening on to an existing layer Document flat = historyWorkspace.Document.Flatten(); EnterCriticalRegion(); historyWorkspace.Document = flat; if (savedSelection != null) { SelectionHistoryMemento shm = new SelectionHistoryMemento(null, null, historyWorkspace); historyWorkspace.Selection.Restore(savedSelection); chm.PushNewAction(shm); } return chm; }
public override HistoryMemento OnExecute(IHistoryWorkspace historyWorkspace) { int newWidth; int newHeight; // Get new width and Height switch (rotation) { case RotateType.Clockwise90: case RotateType.Clockwise270: case RotateType.CounterClockwise90: case RotateType.CounterClockwise270: newWidth = historyWorkspace.Document.Height; newHeight = historyWorkspace.Document.Width; break; case RotateType.Clockwise180: case RotateType.CounterClockwise180: newWidth = historyWorkspace.Document.Width; newHeight = historyWorkspace.Document.Height; break; default: throw new InvalidEnumArgumentException("invalid RotateType"); } // Figure out which icon and text to use string iconResName; string suffix; switch (rotation) { case RotateType.Clockwise180: iconResName = "Icons.MenuImageRotate180CWIcon.png"; suffix = PdnResources.GetString("RotateAction.180CW"); break; case RotateType.Clockwise270: iconResName = "Icons.MenuImageRotate270CWIcon.png"; suffix = PdnResources.GetString("RotateAction.270CW"); break; case RotateType.Clockwise90: iconResName = "Icons.MenuImageRotate90CWIcon.png"; suffix = PdnResources.GetString("RotateAction.90CW"); break; case RotateType.CounterClockwise180: iconResName = "Icons.MenuImageRotate180CCWIcon.png"; suffix = PdnResources.GetString("RotateAction.180CCW"); break; case RotateType.CounterClockwise270: iconResName = "Icons.MenuImageRotate270CCWIcon.png"; suffix = PdnResources.GetString("RotateAction.270CCW"); break; case RotateType.CounterClockwise90: iconResName = "Icons.MenuImageRotate90CCWIcon.png"; suffix = PdnResources.GetString("RotateAction.90CCW"); break; default: throw new InvalidEnumArgumentException("invalid RotateType"); } // Initialize the new Doc string haNameFormat = PdnResources.GetString("RotateAction.HistoryMementoName.Format"); string haName = string.Format(haNameFormat, StaticName, suffix); ImageResource haImage = ImageResource.Get(iconResName); List<HistoryMemento> actions = new List<HistoryMemento>(); // do the memory allocation now: if this fails, we can still bail out cleanly Document newDoc = new Document(newWidth, newHeight); if (!historyWorkspace.Selection.IsEmpty) { DeselectFunction da = new DeselectFunction(); EnterCriticalRegion(); HistoryMemento hm = da.Execute(historyWorkspace); actions.Add(hm); } ReplaceDocumentHistoryMemento rdha = new ReplaceDocumentHistoryMemento(null, null, historyWorkspace); actions.Add(rdha); newDoc.ReplaceMetaDataFrom(historyWorkspace.Document); // TODO: serialize oldDoc to disk, and let the GC purge it if needed OnProgress(0.0); for (int i = 0; i < historyWorkspace.Document.Layers.Count; ++i) { Layer layer = historyWorkspace.Document.Layers.GetAt(i); double progressStart = 100.0 * ((double)i / (double)historyWorkspace.Document.Layers.Count); double progressEnd = 100.0 * ((double)(i + 1) / (double)historyWorkspace.Document.Layers.Count); if (layer is BitmapLayer) { Layer nl = RotateLayer((BitmapLayer)layer, rotation, newWidth, newHeight, progressStart, progressEnd); newDoc.Layers.Add(nl); } else { throw new InvalidOperationException("Cannot Rotate non-BitmapLayers"); } if (this.PleaseCancel) { break; } OnProgress(progressEnd); } CompoundHistoryMemento chm = new CompoundHistoryMemento( haName, haImage, actions); if (this.PleaseCancel) { chm = null; } else { EnterCriticalRegion(); historyWorkspace.Document = newDoc; } return chm; }
public override HistoryMemento PerformAction(DocumentWorkspace documentWorkspace) { AnchorEdge initialEdge = PdnSettings.GetLastCanvasSizeAnchorEdge(); Document newDoc = ResizeDocument( documentWorkspace.FindForm(), documentWorkspace.Document, documentWorkspace.Document.Size, initialEdge, documentWorkspace.AppWorkspace.AppEnvironment.SecondaryColor, true, true); if (newDoc != null) { using (new PushNullToolMode(documentWorkspace)) { if (newDoc.DpuUnit != MeasurementUnit.Pixel) { Settings.CurrentUser.SetString(PdnSettings.LastNonPixelUnits, newDoc.DpuUnit.ToString()); if (documentWorkspace.AppWorkspace.Units != MeasurementUnit.Pixel) { documentWorkspace.AppWorkspace.Units = newDoc.DpuUnit; } } ReplaceDocumentHistoryMemento rdha = new ReplaceDocumentHistoryMemento(StaticName, StaticImage, documentWorkspace); documentWorkspace.Document = newDoc; return rdha; } } else { return null; } }
/// <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)) { Image image; try { Utility.GCFullCollect(); image = (Image)clipData.GetData(DataFormats.Bitmap); } 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(); } 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) { DialogResult dr = MessageBox.Show( this.documentWorkspace, PdnResources.GetString("PasteAction.Question.ExpandCanvas"), PdnInfo.GetAppName(), MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); 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; }
public override HistoryMemento OnExecute(IHistoryWorkspace historyWorkspace) { if (historyWorkspace.Selection.IsEmpty) { return null; } else { PdnRegion selectionRegion = historyWorkspace.Selection.CreateRegion(); if (selectionRegion.GetArea() == 0) { selectionRegion.Dispose(); return null; } SelectionHistoryMemento sha = new SelectionHistoryMemento(StaticName, null, historyWorkspace); ReplaceDocumentHistoryMemento rdha = new ReplaceDocumentHistoryMemento(StaticName, null, historyWorkspace); Rectangle boundingBox; Rectangle[] inverseRegionRects = null; boundingBox = Utility.GetRegionBounds(selectionRegion); using (PdnRegion inverseRegion = new PdnRegion(boundingBox)) { inverseRegion.Exclude(selectionRegion); inverseRegionRects = Utility.TranslateRectangles( inverseRegion.GetRegionScansReadOnlyInt(), -boundingBox.X, -boundingBox.Y); } selectionRegion.Dispose(); selectionRegion = null; Document oldDocument = historyWorkspace.Document; // TODO: serialize this to disk so we don't *have* to store the full thing Document newDocument = new Document(boundingBox.Width, boundingBox.Height); // copy the document's meta data over newDocument.ReplaceMetaDataFrom(oldDocument); foreach (Layer layer in oldDocument.Layers) { if (layer is BitmapLayer) { BitmapLayer oldLayer = (BitmapLayer)layer; Surface croppedSurface = oldLayer.Surface.CreateWindow(boundingBox); BitmapLayer newLayer = new BitmapLayer(croppedSurface); ColorBgra clearWhite = ColorBgra.White.NewAlpha(0); foreach (Rectangle rect in inverseRegionRects) { newLayer.Surface.Clear(rect, clearWhite); } newLayer.LoadProperties(oldLayer.SaveProperties()); newDocument.Layers.Add(newLayer); } else { throw new InvalidOperationException("Crop does not support Layers that are not BitmapLayers"); } } CompoundHistoryMemento cha = new CompoundHistoryMemento( StaticName, PdnResources.GetImageResource("Icons.MenuImageCropIcon.png"), new HistoryMemento[] { sha, rdha }); EnterCriticalRegion(); historyWorkspace.Document = newDocument; return cha; } }
protected override HistoryMemento OnUndo() { ReplaceDocumentHistoryMemento ha = new ReplaceDocumentHistoryMemento(Name, Image, this.historyWorkspace); this.historyWorkspace.Document = ((ReplaceDocumentHistoryMementoData)Data).OldDocument; return ha; }
public override HistoryMemento PerformAction(DocumentWorkspace documentWorkspace) { int newWidth; int newHeight; double newDpu; MeasurementUnit newDpuUnit; string resamplingAlgorithm = Settings.CurrentUser.GetString(PdnSettings.LastResamplingMethod, ResamplingAlgorithm.SuperSampling.ToString()); ResamplingAlgorithm alg; try { alg = (ResamplingAlgorithm)Enum.Parse(typeof(ResamplingAlgorithm), resamplingAlgorithm, true); } catch { alg = ResamplingAlgorithm.SuperSampling; } bool maintainAspect = Settings.CurrentUser.GetBoolean(PdnSettings.LastMaintainAspectRatio, true); using (ResizeDialog rd = new ResizeDialog()) { rd.OriginalSize = documentWorkspace.Document.Size; rd.OriginalDpuUnit = documentWorkspace.Document.DpuUnit; rd.OriginalDpu = documentWorkspace.Document.DpuX; rd.ImageHeight = documentWorkspace.Document.Height; rd.ImageWidth = documentWorkspace.Document.Width; rd.ResamplingAlgorithm = alg; rd.LayerCount = documentWorkspace.Document.Layers.Count; rd.Units = rd.OriginalDpuUnit; rd.Resolution = documentWorkspace.Document.DpuX; rd.Units = PdnSettings.GetLastNonPixelUnits(); rd.ConstrainToAspect = maintainAspect; DialogResult result = rd.ShowDialog(documentWorkspace); if (result == DialogResult.Cancel) { return null; } Settings.CurrentUser.SetString(PdnSettings.LastResamplingMethod, rd.ResamplingAlgorithm.ToString()); Settings.CurrentUser.SetBoolean(PdnSettings.LastMaintainAspectRatio, rd.ConstrainToAspect); newDpuUnit = rd.Units; newWidth = rd.ImageWidth; newHeight = rd.ImageHeight; newDpu = rd.Resolution; alg = rd.ResamplingAlgorithm; if (newDpuUnit != MeasurementUnit.Pixel) { Settings.CurrentUser.SetString(PdnSettings.LastNonPixelUnits, newDpuUnit.ToString()); if (documentWorkspace.AppWorkspace.Units != MeasurementUnit.Pixel) { documentWorkspace.AppWorkspace.Units = newDpuUnit; } } // if the new size equals the old size, there's really no point in doing anything if (documentWorkspace.Document.Size == new Size(rd.ImageWidth, rd.ImageHeight) && documentWorkspace.Document.DpuX == newDpu && documentWorkspace.Document.DpuUnit == newDpuUnit) { return null; } } HistoryMemento ha; if (newWidth == documentWorkspace.Document.Width && newHeight == documentWorkspace.Document.Height) { // Only adjusting Dpu or DpuUnit ha = new MetaDataHistoryMemento(StaticName, StaticImage, documentWorkspace); documentWorkspace.Document.DpuUnit = newDpuUnit; documentWorkspace.Document.DpuX = newDpu; documentWorkspace.Document.DpuY = newDpu; } else { try { using (new WaitCursorChanger(documentWorkspace)) { ha = new ReplaceDocumentHistoryMemento(StaticName, StaticImage, documentWorkspace); } Document newDocument = new Document(newWidth, newHeight); newDocument.ReplaceMetaDataFrom(documentWorkspace.Document); newDocument.DpuUnit = newDpuUnit; newDocument.DpuX = newDpu; newDocument.DpuY = newDpu; ResizeProgressDialog rpd = new ResizeProgressDialog(documentWorkspace, newDocument, documentWorkspace.Document, new Size(newWidth, newHeight), alg); Utility.GCFullCollect(); bool result = rpd.DoResize(); if (!result) { return null; } documentWorkspace.Document = newDocument; } catch (WorkerThreadException ex) { if (ex.InnerException is OutOfMemoryException) { Utility.ErrorBox(documentWorkspace, PdnResources.GetString("ResizeAction.PerformAction.OutOfMemory")); return null; } else { throw; } } catch (OutOfMemoryException) { Utility.ErrorBox(documentWorkspace, PdnResources.GetString("ResizeAction.PerformAction.OutOfMemory")); return null; } } return ha; }