protected override HistoryMemento OnUndo()
        {
            ReplaceDocumentHistoryMemento ha = new ReplaceDocumentHistoryMemento(Name, Image, this.historyWorkspace);

            this.historyWorkspace.Document = ((ReplaceDocumentHistoryMementoData)Data).OldDocument;
            return(ha);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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;
        }
예제 #4
0
        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;
        }
예제 #6
0
        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;
            }
        }
예제 #7
0
        /// <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;
        }
예제 #8
0
        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;
 }
예제 #10
0
        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;
        }