static void SetConnectorSrcDestConnectionPoints(Connector connector, ConnectionPoint srcConnectionPoint, ConnectionPoint destConnectionPoint)
 {
     FreeFormPanel.SetSourceConnectionPoint(connector, srcConnectionPoint);
     FreeFormPanel.SetDestinationConnectionPoint(connector, destConnectionPoint);
     srcConnectionPoint.AttachedConnectors.Add(connector);
     destConnectionPoint.AttachedConnectors.Add(connector);
 }
        public static Point CalculateDropLocation(Point mousePosition, Point originalDropLocation, Connector connector, Size droppedSize, HashSet<Point> shapeLocations)
        {
            UIElement srcShape = FreeFormPanel.GetSourceConnectionPoint(connector).ParentDesigner;
            UIElement destShape = FreeFormPanel.GetDestinationConnectionPoint(connector).ParentDesigner;
            Point srcLocation = FreeFormPanel.GetLocation(srcShape);
            Point destLocation = FreeFormPanel.GetLocation(destShape);
            Size srcSize = FreeFormPanel.GetChildSize(srcShape);
            Size destSize = FreeFormPanel.GetChildSize(destShape);

            return CalculateDropLocation(mousePosition, originalDropLocation, droppedSize, srcLocation, destLocation, srcSize, destSize, shapeLocations);
        }
 // The method will return the CaseKey if any.
 // referenceUpdatedModelItems: say A linked to B by linker C, there is a relationship:
 //   A.Properties["Relation"] = B. 
 //   When delete the linker C, A will be updated like, A.Properties["Relation"] = null;
 //   In multiple drag/drop, the A.Properties["Relation"] is set correctly before coming
 //   here, which means we should not set the value again, otherwise the correct,
 //   value which is set previously, will be removed.
 internal IFlowSwitchLink DeleteLink(Connector link, bool isMoveOrAutoSplit = false,
     HashSet<ModelItem> referenceUpdatedModelItems = null)
 {
     IFlowSwitchLink caseKey = null;
     using (EditingScope deleteLinkEditingScope =
                 ((IModelTreeItem)this.ModelItem).ModelTreeManager.CreateEditingScope(SR.FCDeleteLink))
     {
         caseKey = DeleteLinkImpl(link, isMoveOrAutoSplit, referenceUpdatedModelItems);
         deleteLinkEditingScope.Complete();
     }
     return caseKey;
 }
        internal int DeleteConnectorModelItem(Connector connector, bool rerouting = false)
        {
            ModelItem connectorModelItem = StateContainerEditor.GetConnectorModelItem(connector);

            if (!rerouting)
            {
                if (connector is ConnectorWithStartDot)
                {
                    connector.StartDot.MouseDown -= new MouseButtonEventHandler(OnConnectorStartDotMouseDown);
                    connector.StartDot.MouseUp -= new MouseButtonEventHandler(OnConnectorStartDotMouseUp);
                }

                connector.GotKeyboardFocus -= new KeyboardFocusChangedEventHandler(OnConnectorGotKeyboardFocus);
                connector.RequestBringIntoView -= new RequestBringIntoViewEventHandler(OnConnectorRequestBringIntoView);
                connector.GotFocus -= new RoutedEventHandler(OnConnectorGotFocus);
                connector.MouseDoubleClick -= new MouseButtonEventHandler(OnConnectorMouseDoubleClick);
                connector.MouseDown -= new MouseButtonEventHandler(OnConnectorMouseDown);
                connector.KeyDown -= new KeyEventHandler(OnConnectorKeyDown);
                connector.ContextMenuOpening -= new ContextMenuEventHandler(OnConnectorContextMenuOpening);
                connector.Unloaded -= new RoutedEventHandler(OnConnectorUnloaded);
            }

            int removedIndex = InvalidIndex;
            if (connectorModelItem.ItemType == typeof(Transition))
            {
                ModelItemCollection transitions = StateContainerEditor.GetParentStateModelItemForTransition(connectorModelItem).Properties[StateDesigner.TransitionsPropertyName].Collection;
                removedIndex = transitions.IndexOf(connectorModelItem);
                Fx.Assert(removedIndex >= 0, "can't find the connector ModelItem in collection");
                transitions.Remove(connectorModelItem);
            }
            // Connector from initial node
            else if (connectorModelItem.ItemType == typeof(StateMachine))
            {
                using (EditingScope es = (EditingScope)this.ModelItem.BeginEdit(SR.ClearInitialState))
                {
                    connectorModelItem.Properties[StateMachineDesigner.InitialStatePropertyName].SetValue(null);
                    if (!rerouting)
                    {
                        this.ViewStateService.StoreViewStateWithUndo(connectorModelItem, ConnectorLocationViewStateKey, null);
                    }
                    es.Complete();
                }
            }
            return removedIndex;
        }
        static void SetConnectorLabel(Connector connector, ModelItem connectorModelItem)
        {

            connector.SetBinding(Connector.LabelTextProperty,  new Binding()
            {
                Source = connectorModelItem,
                Path = new PropertyPath("DisplayName")
            });

            TextBlock toolTip = new TextBlock();
            toolTip.SetBinding(TextBlock.TextProperty, new Binding()
            {
                Source = connectorModelItem,
                Path = new PropertyPath("DisplayName"),
                StringFormat = TransitionNameToolTip + Environment.NewLine + SR.EditTransitionTooltip + Environment.NewLine + SR.CopyTransitionToolTip
            });

            connector.SetLabelToolTip(toolTip);
        }
Ejemplo n.º 6
0
 public ConnectorEditor(FreeFormPanel panel, Connector connector)
 {
     if (panel == null)
     {
         throw FxTrace.Exception.AsError(new ArgumentNullException("panel"));
     }
     if (connector == null)
     {
         throw FxTrace.Exception.AsError(new ArgumentNullException("connector"));
     }
     this.editPoints = new List<EditPoint>();
     this.parentPanel = panel;
     this.editedConnector = connector;
     this.activeEditPoint = null;
     connector.IsSelected = true;
     // When the ConnectorEditor is active, we allow reconnecting the start point of the Connector instead
     // of creating a new transition that shares the same trigger. So we need to disable tooltips and 
     // highlighting effects for all overlapping start dots.
     this.SetIsHitTestVisibleForOverlappingStartDots(false);
     DisplayEditPoints();
 }
        public static void CalculateEntryExitEdges(Point mousePosition, Connector connector, out EdgeLocation entryEdge, out EdgeLocation exitEdge)
        {
            UIElement srcShape = FreeFormPanel.GetSourceConnectionPoint(connector).ParentDesigner;
            UIElement destShape = FreeFormPanel.GetDestinationConnectionPoint(connector).ParentDesigner;
            Point srcLocation = FreeFormPanel.GetLocation(srcShape);
            Point destLocation = FreeFormPanel.GetLocation(destShape);
            Size srcSize = FreeFormPanel.GetChildSize(srcShape);
            Size destSize = FreeFormPanel.GetChildSize(destShape);

            Point srcCenter = new Point(srcLocation.X + (srcSize.Width / 2), srcLocation.Y + (srcSize.Height / 2));
            Point destCenter = new Point(destLocation.X + (destSize.Width / 2), destLocation.Y + (destSize.Height / 2));

            entryEdge = CalculateEdgeLocation(mousePosition, srcCenter);
            exitEdge = CalculateEdgeLocation(mousePosition, destCenter);

            if (exitEdge == entryEdge)
            {
                switch (entryEdge)
                {
                    case EdgeLocation.Top:
                        exitEdge = EdgeLocation.Bottom;
                        break;

                    case EdgeLocation.Bottom:
                        exitEdge = EdgeLocation.Top;
                        break;

                    case EdgeLocation.Left:
                        exitEdge = EdgeLocation.Right;
                        break;

                    case EdgeLocation.Right:
                        exitEdge = EdgeLocation.Left;
                        break;
                }
            }
        }
        private void OnFlowchartGridKeyDown(object sender, KeyEventArgs e)
        {
            if (srcConnectionPoint != null)
            {
                // Ignore KeyBoard input when creating connector.
                e.Handled = true;
                return;
            }

            Selection currentSelection = this.Context.Items.GetValue<Selection>();
            if (e.Key == Key.Delete && this.selectedConnector != null && currentSelection.SelectionCount <= 1)
            {
                // process the delete if only the connector is selected
                ModelItem primarySelection = currentSelection.PrimarySelection;
                //Delete connector
                ModelItem linkModelItem = FlowchartDesigner.GetLinkModelItem(this.selectedConnector);
                if ((primarySelection == null && !IsLinkModelItemSelectable(linkModelItem)) ||
                    object.Equals(primarySelection, linkModelItem))
                {
                    DeleteLink(this.selectedConnector);
                    this.selectedConnector = null;
                    e.Handled = true;
                }
            }
            else if ((new List<Key> { Key.Left, Key.Right, Key.Up, Key.Down }).Contains(e.Key)
                && currentSelection.SelectedObjects.All<ModelItem>((p) => { return this.modelElement.ContainsKey(p); }))
            {
                KeyboardMove(e.Key);
                e.Handled = true;
            }
        }
        // Move the object to correct position after drop
        private void PostDropUpdateViewState(WorkflowViewElement view,
            ModelItem flownodeMI,
            AutoConnectDirections autoConnectDirection,
            Connector connectorToSplit,
            Point newPoint,
            Point anchorPoint,
            bool keepRelativePosition,
            ShapeOffsetter shapeOffsetter)
        {
            Fx.Assert((view != null && flownodeMI != null),
            "movedItem != null && flownodeMI != null");
            Point shapeLocationPtr;
            if (autoConnectDirection != AutoConnectDirections.None)
            {
                shapeLocationPtr = this.CalculateDropLocationForAutoConnect(autoConnectDirection, view.DesiredSize);
            }
            else
            {
                shapeLocationPtr = SnapVisualToGrid(view, newPoint, anchorPoint, keepRelativePosition);
                if (!keepRelativePosition)
                {
                    // To avoid overlaps
                    shapeLocationPtr = shapeOffsetter.OffsetShapeLocation(shapeLocationPtr);
                }
            }

            if (connectorToSplit != null)
            {
                shapeLocationPtr = this.CalculateDropLocationForAutoSplit(newPoint, shapeLocationPtr, connectorToSplit, view.DesiredSize);
            }

            // 
            if (keepRelativePosition)
            {
                this.OffsetDroppedItemToNewPosition(flownodeMI, shapeLocationPtr);
            }
            else
            {
                this.StoreShapeViewState(flownodeMI, shapeLocationPtr);
            }
        }
 Point CalculateDropLocationForAutoSplit(Point mousePosition, Point originalDropLocation, Connector connector, Size droppedSize)
 {
     return AutoSplitHelper.CalculateDropLocation(mousePosition, originalDropLocation, connector, droppedSize, this.shapeLocations);
 }
        // Returns the last dropped item - used for auto-connect and auto-split where only one item is allowed
        ModelItem DoFlowchartGridDrop(DragEventArgs e, AutoConnectDirections autoConnectDirection, Connector connectorToSplit)
        {
            ModelItem droppedModelItem = null;
            ModelItem newFlowStepMI = null;
            e.Effects = DragDropEffects.None;
            IEnumerable<object> droppedObjects = DragDropHelper.GetDroppedObjects(this, e, Context);
            //Marking the event as being handled. In whichever case we want to route the event, it will be unmarked explicitly.
            e.Handled = true;
            List<WorkflowViewElement> movedViewElements = new List<WorkflowViewElement>();
            ShapeOffsetter shapeOffsetter = new ShapeOffsetter();
            Dictionary<WorkflowViewElement, Point> relativeLocations = DragDropHelper.GetDraggedViewElementRelativeLocations(e);
            ModelItem modelItemDroppedFromToolBox = null;
            Dictionary<object, FlowNode> objToNewFlowNodeMap = null;
            Dictionary<FlowNode, ModelItem> flowNodeModelItemMap = null;
            Dictionary<FlowNode, FlowNode> oldNewFlowNodeMap = null;
            this.PrepareForDrop(droppedObjects,
                out objToNewFlowNodeMap,
                out flowNodeModelItemMap,
                out oldNewFlowNodeMap);
            bool shouldStoreCurrentSizeViewState = true;
            foreach (object droppedObject in droppedObjects)
            {
                if (droppedObject == null)
                {
                    continue;
                }
                droppedModelItem = droppedObject as ModelItem;

                // archor point
                Point anchorPoint = DragDropHelper.GetDragDropAnchorPoint(e);


                ICompositeView srcContainer = droppedModelItem != null
                    ? DragDropHelper.GetCompositeView(droppedModelItem.View as WorkflowViewElement) as ICompositeView
                    : null;
                bool keepRelativePosition = srcContainer is FlowchartDesigner;
                // This is the case of dragging from toolbox
                if (anchorPoint.X < 0 && anchorPoint.Y < 0)
                {
                    keepRelativePosition = false;
                }

                // This is the case of dragging from the designer surface
                else if (droppedModelItem != null)
                {
                    WorkflowViewElement view = (WorkflowViewElement)droppedModelItem.View;
                    anchorPoint.Offset(-relativeLocations[view].X, -relativeLocations[view].Y);
                }


                if (droppedModelItem != null && srcContainer != null && srcContainer.Equals(this))
                {
                    if (shouldStoreCurrentSizeViewState)
                    {
                        // Moving may change the size of flowchart; need this to undo the size change.
                        this.StoreCurrentSizeViewStateWithUndo();
                        shouldStoreCurrentSizeViewState = false;
                    }
                    //InternalMove
                    PerformInternalMove(modelElement[droppedModelItem], e.GetPosition(this.panel), anchorPoint, autoConnectDirection, connectorToSplit);
                }
                else
                {
                    //External model Item drop.
                    if (droppedModelItem != null)
                    {
                        if ((IsFlowStepAction(droppedModelItem)
                            || IsFlowNode(droppedModelItem))
                            && !IsParentOf(droppedModelItem, this.ModelItem))
                        {
                            if (shouldStoreCurrentSizeViewState)
                            {
                                // Drop may change the size of flowchart; need this to undo the size change.
                                this.StoreCurrentSizeViewStateWithUndo();
                                shouldStoreCurrentSizeViewState = false;
                            }

                            FlowNode flowElement = objToNewFlowNodeMap[droppedObject];
                            ModelItem flowElementMI;
                            if (flowNodeModelItemMap.TryGetValue(flowElement, out flowElementMI))
                            {
                                // FlowNode comes from some other flowchart. 
                                this.ModelItem.Properties["Nodes"].Collection.Add(flowElementMI);
                            }
                            else
                            {
                                // FlowNode is a new created one, which means this is an Activity dragged
                                // from somewhere else, outside of Flowchart.
                                flowElementMI = this.ModelItem.Properties["Nodes"].Collection.Add(flowElement);
                                flowNodeModelItemMap[flowElement] = flowElementMI;
                            }
                            newFlowStepMI = flowElementMI;
                        }
                        else
                        {
                            //We want to route the event in the case that the flowchart is dropped upon itself.
                            if (droppedModelItem.Equals(this.ModelItem))
                            {
                                e.Handled = false;
                            }
                            //Don't add anything for what is neither a Activity nor a flowlink.
                            continue;
                        }

                        if (droppedModelItem != null && droppedModelItem.View != null)
                        {
                            movedViewElements.Add((WorkflowViewElement)droppedModelItem.View);
                        }

                        // the external item may come from other panel (sequence) which is already given
                        // a size by its previous layout panel.  That might give an inaccurate size to the
                        // dropped object (i.e. Bug 198290).  Therefore, when the object is dropped externally
                        // the FC should erases its previous hint size, forcing the FC to recompute an appropriate
                        // size based on the workflowelementview size.
                        VirtualizedContainerService.SetHintSize(droppedModelItem.GetCurrentValue(), null);
                    }
                    //Tool box drop.
                    else
                    {
                        if (typeof(Activity).IsAssignableFrom(droppedObject.GetType()))
                        {
                            FlowStep flowStep = new FlowStep();
                            flowStep.Action = (Activity)droppedObject;
                            if (shouldStoreCurrentSizeViewState)
                            {
                                // Drop may change the size of flowchart; need this to undo the size change.
                                this.StoreCurrentSizeViewStateWithUndo();
                                shouldStoreCurrentSizeViewState = false;
                            }

                            newFlowStepMI = this.ModelItem.Properties["Nodes"].Collection.Add(flowStep);
                            droppedModelItem = newFlowStepMI.Properties["Action"].Value;
                        }
                        else if (typeof(FlowNode).IsAssignableFrom(droppedObject.GetType()))
                        {
                            if (shouldStoreCurrentSizeViewState)
                            {
                                // Drop may change the size of flowchart; need this to undo the size change.
                                this.StoreCurrentSizeViewStateWithUndo();
                                shouldStoreCurrentSizeViewState = false;
                            }
                            droppedModelItem = this.ModelItem.Properties["Nodes"].Collection.Add(droppedObject);
                            newFlowStepMI = droppedModelItem;
                        }

                        // Now,  toolbox drop doesn't support multiple drop
                        // If multi-drop from tool box, use an array here.
                        modelItemDroppedFromToolBox = droppedModelItem;
                        keepRelativePosition = false;
                    } // tool box 

                    WorkflowViewElement view = droppedModelItem.View as WorkflowViewElement;
                    if (view == null || view.ExpandState)
                    {
                        //Creating a new view to get the size of collapsed view.
                        view = this.ViewService.GetView(droppedModelItem) as WorkflowViewElement;
                        ViewUtilities.MeasureView(view, true);
                    }

                    if (view != null)
                    {
                        PostDropUpdateViewState(view,
                            newFlowStepMI,
                            autoConnectDirection,
                            connectorToSplit,
                            e.GetPosition(this.panel),
                            anchorPoint,
                            keepRelativePosition,
                            shapeOffsetter);
                    }
                } // external move
            } // foreach

            // Remap references.
            // The re-map here is different from the remaping in copy/paste.
            // In copy paste, all the values are copied. but here, some value are
            // set by Properties["key"].SetValue().
            // Don't move this into PrepareMove. Some value setting is added to 
            // Change. So the operation here will decide the order of Change.Apply().
            // PropertyChange in some case, must happen after ModelItem is moved to 
            // new places.
            foreach (FlowNode flowNode in oldNewFlowNodeMap.Keys)
            {
                UpdateCloneReferenceByModelItem(flowNode, flowNodeModelItemMap, oldNewFlowNodeMap);
            }

            DragDropHelper.SetDragDropMovedViewElements(e, movedViewElements);
            
            //Backward compatibility for 4.0
            if (droppedObjects.Count() == 1 && movedViewElements.Count == 1)
            {
                #pragma warning disable 618
                DragDropHelper.SetDragDropCompletedEffects(e, DragDropEffects.Move);
                #pragma warning restore 618
            }

            if (modelItemDroppedFromToolBox != null)
            {
                // if it is dropped from toolbox, select
                this.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, (Action)(() =>
                {
                    UIElement view = (UIElement)(modelItemDroppedFromToolBox.View);
                    if (view != null)
                    {
                        Keyboard.Focus(view);
                        Selection.SelectOnly(this.Context, modelItemDroppedFromToolBox);
                    }
                }));
            }

            if (droppedModelItem != null)
            {
                if (IsFlowNode(droppedModelItem))
                {
                    return droppedModelItem;
                }
                else if (IsFlowStepAction(droppedModelItem))
                {
                    if (newFlowStepMI != null)
                    {
                        return newFlowStepMI;
                    }
                    else
                    {
                        return this.GetParentFlowStepModelItem(droppedModelItem);
                    }
                }
                return null;
            }

            return null;
        }
        void Reroute(Connector connector, bool withUndo)
        {
            ConnectionPoint source = FreeFormPanel.GetSourceConnectionPoint(connector);
            ConnectionPoint destination = FreeFormPanel.GetDestinationConnectionPoint(connector);

            //Nulling out the PointCollection so that it doesn't interfere in line routing.
            connector.Points = new PointCollection();
            PointCollection viewState = new PointCollection(ConnectorRouter.Route(this.panel, source, destination));
            StoreConnectorViewState(FlowchartDesigner.GetLinkModelItem(connector), viewState, source, withUndo);
        }
 void ClearSelectedConnector()
 {
     if (this.panel.connectorEditor != null && this.panel.connectorEditor.Connector == this.selectedConnector)
     {
         this.panel.RemoveConnectorEditor();
     }
     this.selectedConnector = null;
 }
 //This is to keep this.selectedConnector upto date.
 //Eg. cases included 1. create a link, select it and undo, 2. Move a link from one shape to another.
 void OnFreeFormPanelLayoutUpdated(object sender, EventArgs e)
 {
     if (!this.panel.Children.Contains(this.selectedConnector))
     {
         this.selectedConnector = null;
     }
 }
 void SetConnectorLabelToolTip(Connector connector, BindingBase binding)
 {
     connector.SetBinding(Connector.LabelTextProperty, binding);
     ToolTip toolTip = new ToolTip();
     toolTip.SetBinding(UserControl.ContentProperty, binding);
     connector.SetLabelToolTip(toolTip);
 }
        void OnFreeFormPanelConnectorMoved(object sender, ConnectorMovedEventArgs e)
        {
            Fx.Assert(this.panel != null, "This code should not be hit if panel is null");
            Connector movedConnector = sender as Connector;
            int movedEndConnectorPointIndex = movedConnector.Points.Count - 1;
            int newEndConnectorPointIndex = e.NewConnectorLocation.Count - 1;

            if (movedConnector != null)
            {
                Fx.Assert(e.NewConnectorLocation.Count > 0, "Invalid connector editor");
                if (!e.NewConnectorLocation[0].Equals(movedConnector.Points[0]))
                {
                    //srcMoved
                    ConnectionPoint destConnPoint = FreeFormPanel.GetDestinationConnectionPoint(movedConnector);
                    UpdateFlowchartOnLinkVisualMoved(destConnPoint, e.NewConnectorLocation[0], movedConnector, false);
                }
                else if (!e.NewConnectorLocation[newEndConnectorPointIndex].Equals(movedConnector.Points[movedEndConnectorPointIndex]))
                {
                    //DestMoved
                    ConnectionPoint srcConnPoint = FreeFormPanel.GetSourceConnectionPoint(movedConnector);
                    Point destPoint = e.NewConnectorLocation[newEndConnectorPointIndex];
                    UpdateFlowchartOnLinkVisualMoved(srcConnPoint, destPoint, movedConnector, true);
                }

                this.selectedConnector = movedConnector;
            }
        }
        // Returns the last dropped item - used for auto-connect and auto-split where only one item is allowed
        ModelItem DoStateContainerGridDrop(DragEventArgs e, AutoConnectDirections autoConnectDirection, Connector connectorToSplit)
        {
            ModelItem droppedModelItem = null;
            e.Effects = DragDropEffects.None;
            IEnumerable<object> droppedObjects = DragDropHelper.GetDroppedObjects(this, e, Context);
            // Marking the event as being handled. In whichever case we want to route the event, it will be unmarked explicitly.
            e.Handled = true;
            List<ModelItem> modelItemsToSelect = new List<ModelItem>();

            Dictionary<WorkflowViewElement, Point> relativeLocations = DragDropHelper.GetDraggedViewElementRelativeLocations(e);
            foreach (object droppedObject in droppedObjects)
            {
                if (droppedObject != null)
                {
                    droppedModelItem = droppedObject as ModelItem;
                    bool isAnchorPointValid = true;
                    Point anchorPoint = DragDropHelper.GetDragDropAnchorPoint(e);

                    // This is the case of dragging from toolbox
                    if (anchorPoint.X < 0 && anchorPoint.Y < 0)
                    {
                        isAnchorPointValid = false;
                    }
                    // This is the case of dragging from the designer surface
                    else if (droppedModelItem != null)
                    {
                        WorkflowViewElement view = droppedModelItem.View as WorkflowViewElement;
                        anchorPoint.Offset(-relativeLocations[view].X, -relativeLocations[view].Y);
                    }

                    StateContainerEditor srcContainer = droppedModelItem != null
                        ? DragDropHelper.GetCompositeView(droppedModelItem.View as WorkflowViewElement) as StateContainerEditor
                        : null;
                    bool externalDrop = false;
                    if (droppedModelItem != null && srcContainer != null && srcContainer.Equals(this))
                    {
                        // Internal move
                        PerformInternalMove(this.modelItemToUIElement[droppedModelItem], e.GetPosition(this.panel), anchorPoint, autoConnectDirection, connectorToSplit);
                    }
                    else
                    {
                        // External model Item drop
                        if (droppedModelItem != null)
                        {
                            if (droppedModelItem.ItemType == typeof(State) && this.ModelItem.ItemType == typeof(StateMachine))
                            {
                                this.InsertState(droppedModelItem);
                                externalDrop = true;
                            }
                        }
                        // Toolbox drop.
                        else
                        {
                            if (droppedObject.GetType() == typeof(State))
                            {
                                if (((State)droppedObject).DisplayName == null)
                                {
                                    ((State)droppedObject).DisplayName = GenerateStateName();
                                }

                                droppedModelItem = InsertState(droppedObject);
                            }
                            else if (droppedObject.GetType() == typeof(FinalState))
                            {
                                droppedModelItem = InsertState(new State()
                                {
                                    DisplayName = DefaultFinalStateDisplayName,
                                    IsFinal = true
                                });
                            }
                        }
                        if (droppedModelItem != null)
                        {
                            modelItemsToSelect.Add(droppedModelItem);
                            UIElement view = null;
                            if (this.modelItemToUIElement.ContainsKey(droppedModelItem))
                            {
                                view = this.modelItemToUIElement[droppedModelItem];
                            }
                            else
                            {
                                view = droppedModelItem.View as WorkflowViewElement;
                                if (view == null)
                                {
                                    view = this.Context.Services.GetService<ViewService>().GetView(droppedModelItem) as WorkflowViewElement;
                                    ViewUtilities.MeasureView(view as WorkflowViewElement, true);
                                }
                            }
                            // If drag anchor point is beyond the size of the shape being dropped,
                            if (anchorPoint.X > view.DesiredSize.Width || anchorPoint.Y > view.DesiredSize.Height)
                            {
                                isAnchorPointValid = false;
                            }
                            Point shapeLocation;
                            if (autoConnectDirection != AutoConnectDirections.None)
                            {
                                shapeLocation = this.CalculateDropLocationForAutoConnect(autoConnectDirection, new Size(DefaultStateDesignerWidth, DefaultStateDesignerHeight));
                            }
                            else
                            {
                                shapeLocation = StateContainerEditor.SnapVisualToGrid(view, e.GetPosition(this.panel), anchorPoint, isAnchorPointValid);
                            }
                            if (connectorToSplit != null)
                            {
                                shapeLocation = this.CalculateDropLocationForAutoSplit(e.GetPosition(this.panel), shapeLocation, connectorToSplit, new Size(DefaultStateDesignerWidth, DefaultStateDesignerHeight));
                            }
                            object viewState = this.ViewStateService.RetrieveViewState(droppedModelItem, ShapeLocationViewStateKey);
                            if (externalDrop)
                            {
                                Fx.Assert(viewState != null, "item dropped from external should already have view states");
                                Fx.Assert(droppedModelItem.View != null, "item dropped from extenal should already have view");
                                VirtualizedContainerService.VirtualizingContainer container = VisualTreeUtils.FindVisualAncestor<VirtualizedContainerService.VirtualizingContainer>(droppedModelItem.View);
                                Fx.Assert(container != null, "container should not be null");
                                Point oldLocation = (Point)viewState;
                                oldLocation = srcContainer.panel.GetLocationRelativeToOutmostPanel(oldLocation);
                                Point newLocation = this.panel.GetLocationRelativeToOutmostPanel(shapeLocation);
                                // To make sure the connectors are still connected to the connection points
                                OffsetConnectorViewState(container, oldLocation, newLocation, true);
                            }
                            this.StoreShapeLocationViewState(droppedModelItem, shapeLocation);
                        }
                    }
                }
            }

            DragDropHelper.SetDragDropMovedViewElements(e, new WorkflowViewElement[] { });
            this.Dispatcher.BeginInvoke(() =>
                {
                    bool first = true;
                    foreach (ModelItem modelItem in modelItemsToSelect)
                    {
                        if (first)
                        {
                            Keyboard.Focus((IInputElement)modelItem.View);
                            Selection.SelectOnly(this.Context, modelItem);
                            first = false;
                        }
                        else
                        {
                            Selection.Union(this.Context, modelItem);
                        }
                    }
                },
                DispatcherPriority.ApplicationIdle);

            return droppedModelItem;
        }
 void OnStateContainerGridPreviewMouseDown(object sender, MouseButtonEventArgs e)
 {
     this.selectedConnector = null;
 }
 static bool IsConnectorFromInitialNode(Connector connector)
 {
     return GetConnectorModelItem(connector).ItemType == typeof(StateMachine);
 }
        void Remove(Connector connector)
        {
            ConnectionPoint srcConnectionPoint = FreeFormPanel.GetSourceConnectionPoint(connector);
            ConnectionPoint destConnectionPoint = FreeFormPanel.GetDestinationConnectionPoint(connector);
            // Update ConnectionPoints
            srcConnectionPoint.AttachedConnectors.Remove(connector);
            destConnectionPoint.AttachedConnectors.Remove(connector);

            StateContainerEditor stateMachineContainer = this.GetStateMachineContainerEditor();
            stateMachineContainer.panel.Children.Remove(connector);
            if (stateMachineContainer.selectedConnector == connector)
            {
                stateMachineContainer.ClearSelectedConnector();
            }

            if (connector is ConnectorWithStartDot)
            {
                connector.StartDot.MouseDown -= new MouseButtonEventHandler(OnConnectorStartDotMouseDown);
                connector.StartDot.MouseUp -= new MouseButtonEventHandler(OnConnectorStartDotMouseUp);
            }

            connector.GotKeyboardFocus -= new KeyboardFocusChangedEventHandler(OnConnectorGotKeyboardFocus);
            connector.RequestBringIntoView -= new RequestBringIntoViewEventHandler(OnConnectorRequestBringIntoView);
            connector.GotFocus -= new RoutedEventHandler(OnConnectorGotFocus);
            connector.MouseDoubleClick -= new MouseButtonEventHandler(OnConnectorMouseDoubleClick);
            connector.MouseDown -= new MouseButtonEventHandler(OnConnectorMouseDown);
            connector.KeyDown -= new KeyEventHandler(OnConnectorKeyDown);
            connector.ContextMenuOpening -= new ContextMenuEventHandler(OnConnectorContextMenuOpening);
            connector.Unloaded -= new RoutedEventHandler(OnConnectorUnloaded);
        }
        public void DoAutoSplit(DragEventArgs e, Connector connector)
        {
            bool immediatelyCommit = ModelItemHelper.CanCreateImmediateEditingScope(this.ModelItem);

            using (EditingScope scope = (EditingScope)this.ModelItem.BeginEdit(SR.AutoSplit, immediatelyCommit))
            {
                ModelItem droppedModelItem = this.DoStateContainerGridDrop(e, AutoConnectDirections.None, connector);
                bool autoSplit = false;
                ConnectionPoint sourceConnectionPoint = FreeFormPanel.GetSourceConnectionPoint(connector);
                ConnectionPoint destinationConnectionPoint = FreeFormPanel.GetDestinationConnectionPoint(connector);
                if (droppedModelItem != null)
                {
                    ModelItem oldConnectorModelItem = StateContainerEditor.GetConnectorModelItem(connector);
                    int index = this.DeleteConnectorModelItem(connector);
                    bool autoConnected = this.DoAutoConnect(sourceConnectionPoint.ParentDesigner,
                        droppedModelItem, oldConnectorModelItem.GetCurrentValue() as Transition, index) != null;
                    if (autoConnected)
                    {
                        ModelItem destinationModelItem = ((VirtualizedContainerService.VirtualizingContainer)destinationConnectionPoint.ParentDesigner).ModelItem;
                        ModelItem stateMachineModelItem = GetStateMachineModelItem(destinationModelItem);
                        droppedModelItem.Properties[StateDesigner.TransitionsPropertyName].Collection.Add(new Transition()
                        {
                            DisplayName = StateContainerEditor.GenerateTransitionName(stateMachineModelItem),
                            To = destinationModelItem.GetCurrentValue() as State
                        });
                        autoSplit = true;
                    }
                }
                if (autoSplit)
                {
                    // Auto-split generates 4 changes: 1) drop state, 2) remove the old transition, 3) create a transition from the source state
                    // to the dropped state, and 4) create a transition from the dropped state to the destination state.
                    // Step 1 may result in creating the visual of all outgoing transition from the dropped state. Step 4) also creates the visual
                    // of the new transition from the dropped state. So the visual of the transition will be created twice. To solve that problem,
                    // we need to suppress adding connector when adding state visual (in the UI reaction for step 1).
                    // And to support redo, we must place the suppression in the undo stack.
                    this.Context.Services.GetService<ModelTreeManager>().AddToCurrentEditingScope(new SuppressAddingConnectorWhenAddingStateVisual());
                    this.activeSrcConnectionPointForAutoSplit = sourceConnectionPoint;
                    this.activeDestConnectionPointForAutoSplit = destinationConnectionPoint;
                    AutoSplitHelper.CalculateEntryExitEdges(e.GetPosition(this.panel), connector, out this.entryEdgeForAutoSplit, out this.exitEdgeForAutoSplit);
                    scope.Complete();
                }
                else
                {
                    scope.Revert();
                }
            }
        }
 private void OnFlowchartGridPreviewMouseDown(object sender, MouseButtonEventArgs e)
 {
     this.selectedConnector = null;
 }
        public void DoAutoSplit(DragEventArgs e, Connector connector)
        {
            bool immediatelyCommit = ModelItemHelper.CanCreateImmediateEditingScope(this.ModelItem);

            using (EditingScope scope = (EditingScope)this.ModelItem.BeginEdit(SR.AutoSplit, immediatelyCommit))
            {
                ModelItem droppedModelItem = this.DoFlowchartGridDrop(e, AutoConnectDirections.None, connector);
                bool autoSplit = false;
                ModelItem sourceModelItem = null;
                ModelItem destinationModelItem = null;
                if (droppedModelItem != null)
                {
                    this.StoreConnectorViewState(connector, true);
                    IFlowSwitchLink flowSwitchLink = this.DeleteLink(connector, true);

                    bool linkCreated = true;
                    string message = string.Empty;
                    UIElement srcDesigner = FreeFormPanel.GetSourceConnectionPoint(connector).ParentDesigner;
                    UIElement destDesigner = FreeFormPanel.GetDestinationConnectionPoint(connector).ParentDesigner;
                    if (srcDesigner is StartSymbol)
                    {
                        sourceModelItem = this.ModelItem;
                        this.ModelItem.Properties["StartNode"].SetValue(droppedModelItem);
                    }
                    else if (srcDesigner is VirtualizedContainerService.VirtualizingContainer)
                    {
                        sourceModelItem = ((VirtualizedContainerService.VirtualizingContainer)srcDesigner).ModelItem;
                        ModelItem srcFlowNodeModelItem = sourceModelItem;
                        if (!IsFlowNode(srcFlowNodeModelItem))
                        {
                            srcFlowNodeModelItem = this.GetParentFlowStepModelItem(srcFlowNodeModelItem);
                        }
                        Fx.Assert(IsFlowNode(srcFlowNodeModelItem), "srcFlowNodeModelItem should be a FlowNode");

                        if (typeof(FlowStep) == srcFlowNodeModelItem.ItemType)
                        {
                            srcFlowNodeModelItem.Properties["Next"].SetValue(droppedModelItem);
                        }
                        else if (typeof(FlowDecision) == srcFlowNodeModelItem.ItemType && FreeFormPanel.GetSourceConnectionPoint(connector).Equals(GetTrueConnectionPoint(srcDesigner)))
                        {
                            srcFlowNodeModelItem.Properties["True"].SetValue(droppedModelItem);
                        }
                        else if (typeof(FlowDecision) == srcFlowNodeModelItem.ItemType && FreeFormPanel.GetSourceConnectionPoint(connector).Equals(GetFalseConnectionPoint(srcDesigner)))
                        {
                            srcFlowNodeModelItem.Properties["False"].SetValue(droppedModelItem);
                        }
                        else if (GenericFlowSwitchHelper.IsGenericFlowSwitch(srcFlowNodeModelItem.ItemType))
                        {
                            linkCreated = CreateFlowSwitchLink(FreeFormPanel.GetSourceConnectionPoint(connector), srcFlowNodeModelItem, droppedModelItem, flowSwitchLink, null, ref message);
                        }
                    }

                    if (linkCreated && string.IsNullOrEmpty(message))
                    {
                        destinationModelItem = ((VirtualizedContainerService.VirtualizingContainer)destDesigner).ModelItem;
                        ModelItem destFlowNodeModelItem = destinationModelItem;
                        if (!IsFlowNode(destFlowNodeModelItem))
                        {
                            destFlowNodeModelItem = this.GetParentFlowStepModelItem(destFlowNodeModelItem);
                        }

                        Fx.Assert(IsFlowNode(destFlowNodeModelItem), "destFlowNodeModelItem should be a FlowNode");

                        if (droppedModelItem.ItemType == typeof(FlowStep))
                        {
                            droppedModelItem.Properties["Next"].SetValue(destFlowNodeModelItem);
                            autoSplit = true;
                        }
                        else if (GenericFlowSwitchHelper.IsGenericFlowSwitch(droppedModelItem.ItemType))
                        {
                            droppedModelItem.Properties["Default"].SetValue(destFlowNodeModelItem);
                            autoSplit = true;
                        }
                        else if (droppedModelItem.ItemType == typeof(FlowDecision))
                        {
                            droppedModelItem.Properties["True"].SetValue(destFlowNodeModelItem);
                            autoSplit = true;
                        }
                    }
                }

                if (autoSplit)
                {
                    Fx.Assert(sourceModelItem != null, "sourceModelItem != null");
                    Fx.Assert(destinationModelItem != null, "destinationModelItem != null");

                    int srcIndex = GetConnectionPointIndex(this.GetView(sourceModelItem), FreeFormPanel.GetSourceConnectionPoint(connector));
                    int desIndex = GetConnectionPointIndex(this.GetView(destinationModelItem), FreeFormPanel.GetDestinationConnectionPoint(connector));

                    EdgeLocation entryEdgeForAutoSplit;
                    EdgeLocation exitEdgeForAutoSplit;
                    AutoSplitHelper.CalculateEntryExitEdges(e.GetPosition(this.panel),
                        connector, out entryEdgeForAutoSplit, out exitEdgeForAutoSplit);

                    FlowchartDesigner.SetAutoSplitDataWithUndo(
                        this.ModelItem, sourceModelItem, destinationModelItem, srcIndex, desIndex, entryEdgeForAutoSplit, exitEdgeForAutoSplit);

                    scope.Complete();
                }
                else
                {
                    scope.Revert();
                }
            }
        }
 void PerformInternalMove(UIElement movedElement, Point newPoint, Point? shapeAnchorPoint,
     AutoConnectDirections autoConnectDirection, Connector connectorToSplit)
 {
     using (EditingScope es = (EditingScope)this.ModelItem.BeginEdit(SR.FCLinkMove))
     {
         RemoveAdorner(movedElement, typeof(ConnectionPointsAdorner));
         Point shapeLocation;
         Size size = FreeFormPanel.GetChildSize(movedElement);
         if (autoConnectDirection != AutoConnectDirections.None)
         {
             shapeLocation = this.CalculateDropLocationForAutoConnect(autoConnectDirection, size);
         }
         else if (shapeAnchorPoint.HasValue)
         {
             shapeLocation = SnapVisualToGrid(movedElement, newPoint, shapeAnchorPoint.Value, true);
         }
         else
         {
             Fx.Assert(newPoint.X.IsNoLessThan(0) && newPoint.Y.IsNoLessThan(0),
                 "newPoint is negative");
             shapeLocation = newPoint;
         }
         if (connectorToSplit != null)
         {
             shapeLocation = this.CalculateDropLocationForAutoSplit(newPoint, shapeLocation, connectorToSplit, size);
         }
         StoreShapeViewState(movedElement, shapeLocation);
         RerouteAttachedConnectors(movedElement);
         es.Complete();
     }
 }
        void UpdateFlowchartOnLinkVisualMoved(ConnectionPoint knownConnectionPoint, Point newPoint, Connector movedConnector, bool isSourceKnown)
        {
            Fx.Assert(this.panel != null, "This code should not be hit if panel is null");
            HitTestResult hitTestResult = VisualTreeHelper.HitTest(this.panel, newPoint);
            if (hitTestResult == null)
            {
                return;
            }
            //Test if the last connectionPoint hit, is the new location for the connector.
            UIElement newViewElement = null;
            ConnectionPoint newConnectionPoint = null;

            //The case where the link is dropped on a connectionpoint.
            if (this.lastConnectionPointMouseUpElement != null)
            {
                newConnectionPoint = this.ConnectionPointHitTest(this.lastConnectionPointMouseUpElement, newPoint);
                if (newConnectionPoint != null)
                {
                    newViewElement = this.lastConnectionPointMouseUpElement;
                }
            }
            //The case where the link is dropped on a shape.
            if (newViewElement == null)
            {
                newViewElement = VisualTreeUtils.FindVisualAncestor<StartSymbol>(hitTestResult.VisualHit);
                if (newViewElement == null)
                {
                    newViewElement = VisualTreeUtils.FindVisualAncestor<VirtualizedContainerService.VirtualizingContainer>(hitTestResult.VisualHit);
                }
            }
            if (newViewElement != null)
            {
                if (this.panel.Children.Contains(newViewElement))
                {
                    using (EditingScope es = (EditingScope)this.ModelItem.BeginEdit(SR.FCLinkMove))
                    {
                        //Delete the existing link and keep the caseKey
                        IFlowSwitchLink oldCaseKey = this.DeleteLink(movedConnector, true);

                        //Create new link
                        bool linkCreated = false;
                        string errorMessage = string.Empty;
                        if (isSourceKnown)
                        {
                            if (newConnectionPoint == null)
                            {
                                linkCreated = CreateLinkGesture(knownConnectionPoint, newViewElement, newPoint, out errorMessage, true, oldCaseKey);
                            }
                            else
                            {
                                linkCreated = CreateLinkGesture(knownConnectionPoint, newConnectionPoint, out errorMessage, true, oldCaseKey);
                            }
                        }
                        else
                        {
                            //If the Link source is dropped onto itself, we need to set the isLinkValidDueToLinkMove flag.
                            bool isLinkValidDueToLinkMove = FreeFormPanel.GetSourceConnectionPoint(movedConnector).ParentDesigner.Equals(newViewElement);
                            if (newConnectionPoint == null)
                            {
                                linkCreated = CreateLinkGesture(newViewElement, knownConnectionPoint, newPoint, out errorMessage, isLinkValidDueToLinkMove, oldCaseKey);
                            }
                            else
                            {
                                linkCreated = CreateLinkGesture(newConnectionPoint, knownConnectionPoint, out errorMessage, isLinkValidDueToLinkMove, oldCaseKey);
                            }
                        }
                        if (!linkCreated)
                        {
                            if (!errorMessage.Equals(string.Empty))
                            {
                                ErrorReporting.ShowErrorMessage(errorMessage);
                            }
                            es.Revert();
                        }
                        else
                        {
                            es.Complete();
                        }
                    }
                }
            }
        }
        void PerformInternalMove(UIElement movedElement, Point newPoint, Point? shapeAnchorPoint, AutoConnectDirections autoConnectDirection, Connector connectorToSplit)
        {
            using (EditingScope es = (EditingScope)this.ModelItem.BeginEdit(SR.ItemMove))
            {
                StoreShapeSizeWithUndoRecursively(this.ModelItem);
                this.RemoveConnectionPointsAdorner(movedElement);
                Point newLocation;
                Size size = FreeFormPanel.GetChildSize(movedElement);
                if (autoConnectDirection != AutoConnectDirections.None)
                {
                    newLocation = this.CalculateDropLocationForAutoConnect(autoConnectDirection, size);
                }
                else if (shapeAnchorPoint.HasValue)
                {
                    newLocation = SnapVisualToGrid(movedElement, newPoint, shapeAnchorPoint.Value, true);
                }
                else
                {
                    Fx.Assert(newPoint.X.IsNoLessThan(0) && newPoint.Y.IsNoLessThan(0),
                        "newPoint is negative");
                    newLocation = newPoint;
                }
                if (connectorToSplit != null)
                {
                    newLocation = this.CalculateDropLocationForAutoSplit(newPoint, newLocation, connectorToSplit, size);
                }
                ModelItem modelItem = GetModelItemFromView(movedElement);
                object viewState = this.ViewStateService.RetrieveViewState(modelItem, ShapeLocationViewStateKey);
                if (viewState != null)
                {
                    Point oldLocation = (Point)viewState;
                    // To make sure the connectors are still connected to the connection points.
                    // We don't need to offset non-contained connectors because internal move
                    // won't cause the connectors to be recreated and we have code in FreeFormPanel
                    // to guarantee that connectors will still be connected to the connection points
                    this.OffsetConnectorViewState(movedElement, oldLocation, newLocation, false);
                }
                else
                {
                    this.StoreAttachedConnectorViewStates(movedElement);
                }

                this.StoreShapeLocationViewState(movedElement, newLocation);
                // To make sure the connector changes are undoable
                this.panel.RemoveConnectorEditor();

                es.Complete();
            }
        }
        void SetConnectorLabel(Connector connector, ConnectionPoint srcConnPoint, ModelItem linkModelItem)
        {
            BindingBase labelBinding = null;

            if (typeof(FlowDecision).IsAssignableFrom(linkModelItem.ItemType))
            {
                if (FlowchartDesigner.GetTrueConnectionPoint(srcConnPoint.ParentDesigner).Equals(srcConnPoint))
                {
                    labelBinding = new Binding { Source = linkModelItem, Path = new PropertyPath("TrueLabel") };
                }
                else
                {
                    labelBinding = new Binding { Source = linkModelItem, Path = new PropertyPath("FalseLabel") };
                }

                SetConnectorLabelToolTip(connector, labelBinding);
            }
            else if (typeof(IFlowSwitchLink).IsAssignableFrom(linkModelItem.ItemType))
            {
                IFlowSwitchLink flowSwitchLink = (IFlowSwitchLink)linkModelItem.GetCurrentValue();
                labelBinding = flowSwitchLink.CreateConnectorLabelTextBinding();
                SetConnectorLabelToolTip(connector, labelBinding);
            }
        }
        void OnConnectorGotFocus(object sender, RoutedEventArgs e)
        {
            Connector clickedLine = e.Source as Connector;
            DesignerView designerView = this.Context.Services.GetService<DesignerView>();

            if (!designerView.IsMultipleSelectionMode)
            {

                if (this.panel.connectorEditor == null || !clickedLine.Equals(this.panel.connectorEditor.Connector))
                {
                    this.panel.RemoveConnectorEditor();
                    this.panel.connectorEditor = new ConnectorEditor(this.panel, clickedLine);
                }

                if (this.panel.Children.Contains(clickedLine))
                {
                    this.updatingSelectedConnector = true;
                    ModelItem lineModelItem = FlowchartDesigner.GetLinkModelItem(clickedLine);
                    Selection newSelection = new Selection();
                    // If the linkModelItem is FlowDecision or Flowchart, we don't want to add it to the selection
                    if (IsLinkModelItemSelectable(lineModelItem))
                    {
                        newSelection = new Selection(lineModelItem);
                    }
                    this.Context.Items.SetValue(newSelection);
                    this.selectedConnector = clickedLine;
                    this.updatingSelectedConnector = false;
                    e.Handled = true;
                }
            }
        }
        public FlowchartDesigner()
        {
            InitializeComponent();
            this.modelElement = new Dictionary<ModelItem, UIElement>();
            this.flowNodeToUIElement = new Dictionary<ModelItem, UIElement>();
            this.shapeLocations = new HashSet<Point>();
            this.selectedConnector = null;
            ConstructSetAsStartNodeMenuItem();

            this.Loaded += (s, e) =>
            {
                this.isLoaded = true;

                if (this.ShowExpanded)
                {
                    ((ICompositeViewEvents)this).RegisterDefaultCompositeView(this);
                }
                DesignerView designerView = this.Context.Services.GetService<DesignerView>() as DesignerView;
                if (!designerView.ContextMenu.Items.Contains(setAsStartNode))
                {
                    designerView.ContextMenu.Items.Add(setAsStartNode);
                }

                WorkflowCommandExtensionItem item = this.Context.Items.GetValue<WorkflowCommandExtensionItem>();
                if (item != null)
                {
                    if (item.CommandExtensionCallback is DefaultCommandExtensionCallback)
                    {
                        this.InputBindings.Add(new KeyBinding(FlowchartDesignerCommands.ConnectNodesCommand, new DefaultCommandExtensionCallback.ChordKeyGesture(Key.E, Key.F)));
                    }
                }

                Selection.Subscribe(Context, OnSelectionChanged);
            };

            this.Unloaded += (s, e) =>
            {
                this.isLoaded = false;

                if (object.Equals(this.DefaultCompositeView, this))
                {
                    ((ICompositeViewEvents)this).UnregisterDefaultCompositeView(this);
                }
                DesignerView designerView = this.Context.Services.GetService<DesignerView>() as DesignerView;
                designerView.ContextMenu.Items.Remove(setAsStartNode);

                Selection.Unsubscribe(Context, OnSelectionChanged);
            };
        }
 void StoreConnectorViewState(Connector connector, bool isUndoableViewState)
 {
     //This method will be called whenever the FreeFormPanel raises a location changed event on a connector.
     //Such location changed events are a result of changes already commited in the UI. Hence we do not want to react to such view state changes.
     //Using internalViewStateChange flag for that purpose.
     this.internalViewStateChange = true;
     this.StoreConnectorViewState(FlowchartDesigner.GetLinkModelItem(connector), connector.Points, FreeFormPanel.GetSourceConnectionPoint(connector), isUndoableViewState);
     this.internalViewStateChange = false;
 }