public IUndoRedoAction Execute(Workspace sender) { if (m_toAdd is AbstractProcessUnit) { sender.AddProcessUnit(m_toAdd as AbstractProcessUnit); return(new RemoveProcessUnit(m_toAdd as AbstractProcessUnit)); } else if (m_toAdd is AbstractStream) { sender.AddStream(m_toAdd as AbstractStream); return(new RemoveStream(m_toAdd as AbstractStream)); } else { sender.StickyNotes.Add(m_toAdd as ChemProV.Logic.StickyNote); return(new RemoveStickyNote(m_toAdd as ChemProV.Logic.StickyNote)); } }
public void TestSaveLoad() { int i; Workspace ws1 = new Workspace(); Random rand = new Random(); // Add a random number of process units List <int> puIDs = new List <int>(); int numPU = rand.Next(25); for (i = 0; i < numPU; i++) { AbstractProcessUnit pu = new Mixer(); ws1.AddProcessUnit(pu); puIDs.Add(pu.Id); } // Add a random number of chemical streams int numStreams = rand.Next(10); for (i = 0; i < numStreams; i++) { AbstractStream stream = new ChemicalStream(AbstractStream.GetNextUID()); ws1.AddStream(stream); // Don't forget that the properties table needs to be created separately stream.PropertiesTable = new StreamPropertiesTable(stream); // 50% chance of connecting a destination (attempting a connect that is) if (0 == (rand.Next() % 2)) { AbstractProcessUnit pu = ws1.ProcessUnits[rand.Next(ws1.ProcessUnitCount)]; if (pu.AttachIncomingStream(stream)) { stream.Destination = pu; } } } // Save the workspace to a memory stream MemoryStream ms = new MemoryStream(); ws1.Save(ms, "TEST_VersionNA"); // Load to a new workspace Workspace ws2 = new Workspace(); ws2.Load(ms); // Make sure the number of process units and streams match Assert.IsTrue(numPU == ws2.ProcessUnitCount, "Number of process units between saved document (" + numPU.ToString() + ") and loaded document (" + ws2.ProcessUnitCount.ToString() + ") do not match"); Assert.IsTrue(numStreams == ws2.Streams.Count, "Number of streams between saved document (" + numStreams.ToString() + ") and loaded document (" + ws2.Streams.Count.ToString() + ") do not match"); // Test that the incoming/outgoing streams for process units match foreach (AbstractProcessUnit pu1 in ws1.ProcessUnits) { AbstractProcessUnit pu2 = ws2.GetProcessUnit(pu1.Id); Assert.IsNotNull(pu2, "Process unit with ID=" + pu1.Id.ToString() + " from workspace 1 (saved) was not " + "found in workspace 2 (loaded)."); // For now just compare outoging stream count Assert.IsTrue(pu1.OutgoingStreamCount == pu2.OutgoingStreamCount, "Mis-match outgoing stream count"); } }
public void MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { // We don't process messages if the placement icon is null if (null == m_placementIcon) { return; } // Handle heat exchanger with utility as a special case if (m_type.Equals(typeof(HeatExchangerWithUtility))) { MLBD_HEWU(sender, e); return; } // Start by getting the mouse position Point pos = e.GetPosition(m_canvas); MathCore.Vector vPos = new MathCore.Vector(pos.X, pos.Y); // See if we have a DraggableStreamEndpoint where we clicked DraggableStreamEndpoint endpoint = m_canvas.GetChildAt(pos, m_placementIcon) as DraggableStreamEndpoint; // Remove the placement icon and then set it to null to indicate state completion m_canvas.RemoveChild(m_placementIcon); m_placementIcon = null; // Determine a unique identifier for the process unit int uid; do { uid = AbstractProcessUnit.GetNextUID(); }while (null != m_workspace.GetProcessUnit(uid)); // If there's not an endpoint, we create the process unit with no stream connections if (null == endpoint) { AbstractProcessUnit unit = (AbstractProcessUnit)Activator.CreateInstance( m_type, uid); // Set the location unit.Location = new MathCore.Vector(pos.X, pos.Y); // Add it to the workspace m_workspace.AddProcessUnit(unit); // Add an undo that will remove it m_workspace.AddUndo(new UndoRedoCollection("Undo process unit creation", new ChemProV.Logic.Undos.RemoveProcessUnit(unit))); m_canvas.SelectedElement = null; // Tell the control palette to switch back to select mode and then return m_palette.SwitchToSelect(); return; } // Otherwise, if we HAVE clicked on an endpoint... // Check to see if we can't connect this way AbstractProcessUnit temp = (AbstractProcessUnit) Activator.CreateInstance(m_type, -1); if (!endpoint.CanConnectTo(temp)) { // The usability here may be debatable. But for now we'll cancel placement and // give the user an error message m_palette.SwitchToSelect(); Core.App.MessageBox("The stream endpoint that you clicked cannot connect with " + "the process unit that you were placing."); return; } // Otherwise, if we CAN connect this way... // Create the process unit AbstractProcessUnit apu = (AbstractProcessUnit) Activator.CreateInstance(m_type, uid); // Make the undo and then the actual attachment if (DraggableStreamEndpoint.EndpointType.StreamDestination == endpoint.Type) { // Set the location apu.Location = endpoint.ParentStream.Stream.DestinationLocation; // Create an undo that sets the stream destination back to what it was and removes the // process unit m_workspace.AddUndo(new UndoRedoCollection("Undo process unit creation + attachment", new Logic.Undos.SetStreamDestination(endpoint.ParentStream.Stream, null, apu, vPos), new Logic.Undos.RemoveProcessUnit(apu))); apu.AttachIncomingStream(endpoint.ParentStream.Stream); endpoint.ParentStream.Stream.Destination = apu; } else { // Set the location apu.Location = endpoint.ParentStream.Stream.SourceLocation; // Create an undo that sets the stream source back to what it was and removes the // process unit from the canvas AbstractStream stream = endpoint.ParentStream.Stream; m_workspace.AddUndo(new UndoRedoCollection("Undo process unit creation + attachment", new Logic.Undos.SetStreamSource(stream, null, apu, stream.SourceLocation), new Logic.Undos.RemoveProcessUnit(apu))); apu.AttachOutgoingStream(endpoint.ParentStream.Stream); endpoint.ParentStream.Stream.Source = apu; } // Don't forget to add the process unit to the workspace. Event handlers will update the // UI appropriately. m_workspace.AddProcessUnit(apu); m_canvas.SelectedElement = null; // Go back to select mode m_palette.SwitchToSelect(); }
public void TestCommentMerge() { // Build a workspace with 2 process units Workspace ws1 = new Workspace(); AbstractProcessUnit apu1 = new Separator(); AbstractProcessUnit apu2 = new Separator(); ws1.AddProcessUnit(apu1); ws1.AddProcessUnit(apu2); // Add 2 comments to the first and 3 to the second. These will be comments shared // between the two workspaces apu1.Comments.Add(new StickyNote() { Text = "Comment 1 on APU1" }); apu1.Comments.Add(new StickyNote() { Text = "Comment 2 on APU1" }); apu2.Comments.Add(new StickyNote() { Text = "Comment 1 on APU2" }); apu2.Comments.Add(new StickyNote() { Text = "Comment 2 on APU2" }); apu2.Comments.Add(new StickyNote() { Text = "Comment 3 on APU2" }); // Save the workspace to a memory stream MemoryStream ms1 = new MemoryStream(); ws1.Save(ms1); // Load to a new workspace. The two workspaces should have identical content after // the load. Workspace ws2 = new Workspace(); ws2.Load(ms1); // Get the process units from the second workspace AbstractProcessUnit ws2_apu1 = ws2.GetProcessUnit(apu1.Id); AbstractProcessUnit ws2_apu2 = ws2.GetProcessUnit(apu2.Id); // Make sure that they both exist if (null == ws2_apu1 || null == ws2_apu2) { Assert.Fail("After save, one or more process units was not found (TestCommentMerge)"); return; } // Now is where we add comments that are unique to the different workspaces apu1.Comments.Add(new StickyNote() { Text = "Comment on APU1 only in WS1" }); apu2.Comments.Add(new StickyNote() { Text = "Comment on APU2 only in WS1" }); ws2_apu1.Comments.Add(new StickyNote() { Text = "Comment on APU1 only in WS2" }); ws2_apu2.Comments.Add(new StickyNote() { Text = "Comment on APU2 only in WS2" }); ws2_apu2.Comments.Add(new StickyNote() { Text = "Another comment on APU2 only in WS2" }); // (Re-)create the memory streams and save both workspaces ms1 = new MemoryStream(); MemoryStream ms2 = new MemoryStream(); ws1.Save(ms1); ws2.Save(ms2); // Allocate a third memory stream for the merge MemoryStream msMerged = new MemoryStream(); // Merge Core.CommentMerger.Merge(ms1, "WS1_User", ms2, "WS2_User", msMerged); // Load back into a workspace and verify ws1.Load(msMerged); // ------ VERIFICATION ------ // There should be 2 process units apu1 = ws1.GetProcessUnit(apu1.Id); apu2 = ws1.GetProcessUnit(apu2.Id); if (null == ws2_apu1 || null == ws2_apu2) { Assert.Fail("After comment merge, one or more process units was not found (TestCommentMerge)"); return; } // The first one should have 4 comments. 2 from the original two that are in both documents, 1 // unique to the first workspace and 1 unique to the second Assert.IsTrue(4 == apu1.Comments.Count, "Process unit APU1 in document after merge should have 4 comments but has " + apu1.Comments.Count.ToString()); // The second one should have 6 comments. 3 from the original two that are in both documents, 1 // unique to the first workspace and 2 unique to the second Assert.IsTrue(6 == apu2.Comments.Count, "Process unit APU2 in document after merge should have 5 comments but has " + apu2.Comments.Count.ToString()); }