using System; using System.Collections; using System.Drawing; using System.IO; using System.Runtime.Serialization.Formatters.Binary; using System.Windows.Forms; namespace Netron.Diagramming.Core { // ---------------------------------------------------------------------- /// /// This tool pastes items from the clipboard to the canvas. /// // ---------------------------------------------------------------------- public class PasteTool : AbstractTool { // ------------------------------------------------------------------ /// /// Specifies where the items from the clipboard will be /// inserted at. /// // ------------------------------------------------------------------ public static Point InsertionPoint = new Point(50, 50); #region Fields #endregion #region Constructor /// /// Initializes a new instance of the class. /// /// The name of the tool. public PasteTool(string name) : base(name) { } #endregion #region Methods /// /// Called when the tool is activated. /// protected override void OnActivateTool() { try { // Used to get a collection of entities from the // NetronClipboard. Type entitiesType = typeof(CollectionBase); // First calculate the insertion point based on the // current location of the cursor. InsertionPoint = Point.Round( Controller.View.ViewToWorld( Controller.View.DeviceToView( Controller.ParentControl.PointToClient(Cursor.Position)))); IDataObject data = Clipboard.GetDataObject(); string format = typeof(CopyTool).FullName; if (data.GetDataPresent(format)) { MemoryStream stream = data.GetData(format) as MemoryStream; CollectionBase collection = null; GenericFormatter f = new GenericFormatter(); //Anchors collection is a helper collection to re-connect connectors to their parent Anchors.Clear(); //but is it actually a stream coming this application? collection = f.Deserialize>(stream); UnwrapBundle(collection); } else if (NetronClipboard.ContainsData(entitiesType)) { CollectionBase collection = (CollectionBase)NetronClipboard.Get( entitiesType); UnwrapBundle(collection.DeepCopy()); } else if (data.GetDataPresent(DataFormats.Bitmap)) { Bitmap bmp = data.GetData(DataFormats.Bitmap) as Bitmap; if (bmp != null) { #region Unwrap into an image shape //TODO: Insert the image shape here ImageShape shape = new ImageShape(); shape.Image = bmp; shape.Location = InsertionPoint; Controller.Model.AddShape(shape); #endregion } } else if (data.GetDataPresent(DataFormats.Text)) { string text = (string)data.GetData(typeof(string)); TextOnly textShape = new TextOnly(Controller.Model); textShape.Text = text; textShape.Location = InsertionPoint; Controller.Model.AddShape(textShape); } } catch (Exception exc) { throw new InconsistencyException("The Paste operation failed.", exc); } finally { DeactivateTool(); } } #endregion /// /// Unwraps the given bundle to the diagram. /// /// CollectionBase void UnwrapBundle(CollectionBase collection) { if (collection != null) { #region Unwrap the bundle this.Controller.Model.Unwrap(collection); Rectangle rec = Utils.BoundingRectangle(collection); // The InsertionPoint specifies where the pasted // entities should be. So, shift each entity in the // collection to the InsertionPoint. Point delta = new Point( InsertionPoint.X - rec.Location.X, InsertionPoint.Y - rec.Location.Y); //delta.Offset(rec.Location); foreach (IDiagramEntity entity in collection) { entity.MoveBy(delta); } // Recalculate the bounding rectangle and invalidate // that area on the canvas. rec = Utils.BoundingRectangle(collection); rec.Inflate(30, 30); this.Controller.View.Invalidate(rec); #endregion } } } }