static List <ConnectionPoint> GetAllConnectionPoints(UIElement shape)
        {
            List <ConnectionPoint> allConnectionPoints = new List <ConnectionPoint>(6);

            allConnectionPoints.AddRange(FlowchartDesigner.GetConnectionPoints(shape));
            allConnectionPoints.Add(FlowchartDesigner.GetTrueConnectionPoint(shape));
            allConnectionPoints.Add(FlowchartDesigner.GetFalseConnectionPoint(shape));
            return(allConnectionPoints);
        }
        ConnectionPoint ConnectionPointHitTest(UIElement element, Point hitPoint)
        {
            List <ConnectionPoint> connectionPoints        = new List <ConnectionPoint>();
            List <ConnectionPoint> defaultConnectionPoints = FlowchartDesigner.GetConnectionPoints(element);

            connectionPoints.InsertRange(0, defaultConnectionPoints);
            connectionPoints.Add(FlowchartDesigner.GetTrueConnectionPoint(element));
            connectionPoints.Add(FlowchartDesigner.GetFalseConnectionPoint(element));
            return(FreeFormPanel.ConnectionPointHitTest(hitPoint, connectionPoints, this.panel));
        }
        Connector CreatePropertyLink(ModelItem srcModelItem, ModelItem propertyValue, string propertyName)
        {
            Connector newConnector = null;

            if (typeof(FlowStep).IsAssignableFrom(srcModelItem.ItemType))
            {
                ModelItem src  = GetCorrespondingElementOnCanvas(srcModelItem);
                ModelItem dest = GetCorrespondingElementOnCanvas(propertyValue);
                newConnector = CreateLink(modelElement[src], modelElement[dest], srcModelItem);
            }
            else if (typeof(FlowDecision).IsAssignableFrom(srcModelItem.ItemType))
            {
                ModelItem       dest = GetCorrespondingElementOnCanvas(propertyValue);
                ConnectionPoint srcConnPoint;
                if (propertyName.Equals("True"))
                {
                    srcConnPoint = FlowchartDesigner.GetTrueConnectionPoint(modelElement[srcModelItem]);
                }
                else
                {
                    srcConnPoint = FlowchartDesigner.GetFalseConnectionPoint(modelElement[srcModelItem]);
                }
                newConnector = CreateLink(srcConnPoint, modelElement[dest], srcModelItem);
            }
            else if (GenericFlowSwitchHelper.IsGenericFlowSwitch(srcModelItem.ItemType))
            {
                ModelItem       dest = GetCorrespondingElementOnCanvas(propertyValue);
                IFlowSwitchLink link;
                if (propertyName.Equals("Default"))
                {
                    link = GenericFlowSwitchHelper.CreateFlowSwitchLink(srcModelItem.ItemType, srcModelItem, null, true);
                }
                else
                {
                    Fx.Assert(propertyName.Length >= GenericFlowSwitchHelper.FlowSwitchCasesKeyIdentifier.Length, "Case property names should be prepended by the string GenericFlowSwitchHelper.FlowSwitchCasesKeyIdentifier");
                    link = GenericFlowSwitchHelper.CreateFlowSwitchLink(srcModelItem.ItemType, srcModelItem, propertyName.Substring(GenericFlowSwitchHelper.FlowSwitchCasesKeyIdentifier.Length), false);
                }
                IModelTreeItem modelTreeItem = (IModelTreeItem)this.ModelItem;
                ModelItem      linkModelItem = new FakeModelItemImpl(modelTreeItem.ModelTreeManager, link.GetType(), link, null);
                link.ModelItem = linkModelItem;
                newConnector   = CreateLink(modelElement[srcModelItem], modelElement[dest], linkModelItem);
            }
            else // FlowStart
            {
                ModelItem dest = GetCorrespondingElementOnCanvas(propertyValue);
                newConnector = CreateLink(this.StartSymbol, modelElement[dest], this.ModelItem);
            }
            return(newConnector);
        }
Exemplo n.º 4
0
        protected override void OnRender(DrawingContext drawingContext)
        {
            const int textCulture = 9;

            ConnectionPoint trueConnectionPoint  = null;
            ConnectionPoint falseConnectionPoint = null;

            if (this.connectionPoints.Contains(FlowchartDesigner.GetTrueConnectionPoint(this.AdornedElement)))
            {
                trueConnectionPoint = FlowchartDesigner.GetTrueConnectionPoint(this.AdornedElement);
            }
            if (this.connectionPoints.Contains(FlowchartDesigner.GetFalseConnectionPoint(this.AdornedElement)))
            {
                falseConnectionPoint = FlowchartDesigner.GetFalseConnectionPoint(this.AdornedElement);
            }
            Point     actualPoint;
            Point     origin = FreeFormPanel.GetLocation(AdornedElement);
            Thickness margin = ((FrameworkElement)AdornedElement).Margin;

            origin.X += margin.Left;
            origin.Y += margin.Top;

            foreach (ConnectionPoint connPoint in this.connectionPoints)
            {
                actualPoint = new Point(connPoint.Location.X - origin.X, connPoint.Location.Y - origin.Y);
                this.DrawConnectionPoint(connPoint, actualPoint, drawingContext);
            }

            if (trueConnectionPoint != null)
            {
                string trueLabelText = String.Empty;

                VirtualizedContainerService.VirtualizingContainer virtualizingContainer = (VirtualizedContainerService.VirtualizingContainer)trueConnectionPoint.ParentDesigner;
                if (virtualizingContainer != null && virtualizingContainer.ModelItem != null)
                {
                    trueLabelText = (string)virtualizingContainer.ModelItem.Properties["TrueLabel"].ComputedValue;
                }

                actualPoint = new Point(trueConnectionPoint.Location.X - origin.X, trueConnectionPoint.Location.Y - origin.Y);
                FormattedText trueMarkerFormattedText = new FormattedText(trueLabelText, new System.Globalization.CultureInfo(textCulture),
                                                                          this.FlowDirection, FlowchartDesigner.FlowElementCaptionTypeface, FlowchartDesigner.FlowNodeCaptionFontSize,
                                                                          new SolidColorBrush(WorkflowDesignerColors.WorkflowViewElementCaptionColor));
                actualPoint.Y += ConnectionPoint.DrawingLargeSide / 2;
                actualPoint.X -= trueMarkerFormattedText.WidthIncludingTrailingWhitespace;

                DrawtWithTransform(
                    drawingContext,
                    this.isTextRightToLeft,
                    // Mirror the left side text to the right side by using this axis when RTL.
                    actualPoint.X,
                    () =>
                {
                    drawingContext.DrawText(trueMarkerFormattedText, actualPoint);
                });
            }
            if (falseConnectionPoint != null)
            {
                string falseLabelText = String.Empty;

                VirtualizedContainerService.VirtualizingContainer virtualizingContainer = (VirtualizedContainerService.VirtualizingContainer)falseConnectionPoint.ParentDesigner;
                if (virtualizingContainer != null && virtualizingContainer.ModelItem != null)
                {
                    falseLabelText = (string)virtualizingContainer.ModelItem.Properties["FalseLabel"].ComputedValue;
                }

                actualPoint    = new Point(falseConnectionPoint.Location.X - origin.X, falseConnectionPoint.Location.Y - origin.Y);
                actualPoint.Y += ConnectionPoint.DrawingLargeSide / 2;

                FormattedText falseMarkerFormattedText = new FormattedText(falseLabelText, new System.Globalization.CultureInfo(textCulture),
                                                                           this.FlowDirection, FlowchartDesigner.FlowElementCaptionTypeface, FlowchartDesigner.FlowNodeCaptionFontSize,
                                                                           new SolidColorBrush(WorkflowDesignerColors.WorkflowViewElementCaptionColor));

                DrawtWithTransform(
                    drawingContext,
                    this.isTextRightToLeft,
                    // Mirror the left side text to the right side by using this axis when RTL.
                    actualPoint.X,
                    () =>
                {
                    drawingContext.DrawText(falseMarkerFormattedText, actualPoint);
                });
            }

            base.OnRender(drawingContext);
        }
Exemplo n.º 5
0
        bool UpdateFlowChartObject(ConnectionPoint sourceConnPoint, ConnectionPoint destConnPoint, out string errorMessage, bool isLinkValidDueToLinkMove, IFlowSwitchLink caseKey)
        {
            //srcDesigner will be null for the case where source designer is StartSymbol.
            VirtualizedContainerService.VirtualizingContainer srcDesigner  = sourceConnPoint.ParentDesigner as VirtualizedContainerService.VirtualizingContainer;
            VirtualizedContainerService.VirtualizingContainer destDesigner = destConnPoint.ParentDesigner as VirtualizedContainerService.VirtualizingContainer;
            ModelItem       linkSource;
            ModelItem       linkDest           = destDesigner.ModelItem;
            ModelItem       destFlowElementMI  = GetFlowElementMI(linkDest);
            PointCollection connectorViewState = new PointCollection(ConnectorRouter.Route(this.panel, sourceConnPoint, destConnPoint));

            errorMessage = string.Empty;

            if (sourceConnPoint.ParentDesigner is StartSymbol)
            {
                linkSource = this.ModelItem;
                if (linkSource.Properties["StartNode"].Value == null || isLinkValidDueToLinkMove)
                {
                    this.StoreConnectorViewState(linkSource, connectorViewState, sourceConnPoint);
                    linkSource.Properties["StartNode"].SetValue(destFlowElementMI);
                }
                else
                {
                    errorMessage = SR.FCNextLinkDefined;
                }
            }
            else
            {
                linkSource = srcDesigner.ModelItem;
                ModelItem srcFlowElementMI = GetFlowElementMI(linkSource);

                if (typeof(FlowStep).IsAssignableFrom(srcFlowElementMI.ItemType))
                {
                    if (srcFlowElementMI.Properties["Next"].Value == null || isLinkValidDueToLinkMove)
                    {
                        this.StoreConnectorViewState(srcFlowElementMI, connectorViewState, sourceConnPoint);
                        srcFlowElementMI.Properties["Next"].SetValue(destFlowElementMI);
                    }
                    else
                    {
                        errorMessage = SR.FCNextLinkDefined;
                    }
                }
                else if (typeof(FlowDecision).IsAssignableFrom(srcFlowElementMI.ItemType))
                {
                    if (sourceConnPoint.Equals(FlowchartDesigner.GetTrueConnectionPoint(this.modelElement[linkSource])))
                    {
                        if (linkSource.Properties["True"].Value == null || isLinkValidDueToLinkMove)
                        {
                            this.StoreConnectorViewState(srcFlowElementMI, connectorViewState, sourceConnPoint);
                            linkSource.Properties["True"].SetValue(destFlowElementMI);
                        }
                        else
                        {
                            errorMessage = SR.FCTrueBranchExists;
                        }
                    }
                    else if (sourceConnPoint.Equals(FlowchartDesigner.GetFalseConnectionPoint(this.modelElement[linkSource])))
                    {
                        if (linkSource.Properties["False"].Value == null || isLinkValidDueToLinkMove)
                        {
                            this.StoreConnectorViewState(srcFlowElementMI, connectorViewState, sourceConnPoint);
                            linkSource.Properties["False"].SetValue(destFlowElementMI);
                        }
                        else
                        {
                            errorMessage = SR.FCFalseBranchExists;
                        }
                    }
                    else
                    {
                        errorMessage = SR.FCFlowConditionLinkError;
                    }
                }
                else //FlowSwitch
                {
                    if (!CreateFlowSwitchLink(sourceConnPoint, srcFlowElementMI, destFlowElementMI, caseKey, connectorViewState, ref errorMessage))
                    {
                        return(false);
                    }
                }
            }
            return(errorMessage.Equals(string.Empty));
        }
        internal Connector GetLinkOnCanvas(ModelItem srcFlowElementModelItem, ModelItem destflowElementModelItem, string propertyName)
        {
            Connector        linkOnCanvas       = null;
            ModelItem        shapeModelItem     = null;
            List <Connector> outGoingConnectors = null;

            if (!srcFlowElementModelItem.Equals(this.ModelItem))
            {
                shapeModelItem     = this.GetCorrespondingElementOnCanvas(srcFlowElementModelItem);
                outGoingConnectors = GetOutGoingConnectors(this.modelElement[shapeModelItem]);
            }
            else // Must be startNode
            {
                outGoingConnectors = GetOutGoingConnectors(this.StartSymbol);
            }

            foreach (Connector connector in outGoingConnectors)
            {
                ModelItem connectorDestModelItem     = ((VirtualizedContainerService.VirtualizingContainer)FreeFormPanel.GetDestinationConnectionPoint(connector).ParentDesigner).ModelItem;
                ModelItem connectorDestFlowElementMI = this.GetFlowElementMI(connectorDestModelItem);
                //Following condition checks if the destination for current connector is equal to the destination passed in.
                if (destflowElementModelItem != null && destflowElementModelItem.Equals(connectorDestFlowElementMI))
                {
                    if (GenericFlowSwitchHelper.IsGenericFlowSwitch(srcFlowElementModelItem.ItemType))
                    {
                        ModelItem linkModelItem = FlowchartDesigner.GetLinkModelItem(connector);
                        if (linkModelItem.Properties["IsDefaultCase"].Value.GetCurrentValue().Equals(true) && propertyName.Equals("Default"))
                        {
                            linkOnCanvas = connector;
                            break;
                        }
                        else
                        {
                            ModelItem connectorCaseMI = linkModelItem.Properties["Case"].Value;
                            if (linkModelItem.Properties["IsDefaultCase"].Value.GetCurrentValue().Equals(false))
                            {
                                string caseName = connectorCaseMI == null ? null : GenericFlowSwitchHelper.GetString(connectorCaseMI.GetCurrentValue(), connectorCaseMI.ItemType);
                                if (connectorCaseMI != null && caseName.Equals(propertyName.Substring(GenericFlowSwitchHelper.FlowSwitchCasesKeyIdentifier.Length)))
                                {
                                    linkOnCanvas = connector;
                                    break;
                                }
                                else if (connectorCaseMI == null)
                                {
                                    if (GenericFlowSwitchHelper.FlowSwitchNullCaseKeyIdentifier.Equals(propertyName.Substring(GenericFlowSwitchHelper.FlowSwitchCasesKeyIdentifier.Length)))
                                    {
                                        linkOnCanvas = connector;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    else if (typeof(FlowDecision).IsAssignableFrom(srcFlowElementModelItem.ItemType))
                    {
                        ConnectionPoint trueConnPoint         = FlowchartDesigner.GetTrueConnectionPoint(this.modelElement[shapeModelItem]);
                        ConnectionPoint falseConnPoint        = FlowchartDesigner.GetFalseConnectionPoint(this.modelElement[shapeModelItem]);
                        ConnectionPoint connectorSrcConnPoint = FreeFormPanel.GetSourceConnectionPoint(connector);
                        if ((propertyName.Equals("True") && connectorSrcConnPoint.Equals(trueConnPoint)) ||
                            (propertyName.Equals("False") && connectorSrcConnPoint.Equals(falseConnPoint)))
                        {
                            linkOnCanvas = connector;
                            break;
                        }
                    }
                    else    //FlowStep case.
                    {
                        linkOnCanvas = connector;
                        break;
                    }
                }
            }
            return(linkOnCanvas);
        }
        void AddFlowElementsToDesigner(IList <ModelItem> flowElementMICollection, bool addConnectorAfterLoaded = false)
        {
            Queue <ModelItem> flowElementsToProcess = new Queue <ModelItem>();
            List <UIElement>  viewsAdded            = new List <UIElement>();

            foreach (ModelItem model in flowElementMICollection)
            {
                ModelItem itemOnCanvas = GetCorrespondingElementOnCanvas(model);
                if (!this.modelElement.ContainsKey(itemOnCanvas))
                {
                    flowElementsToProcess.Enqueue(model);
                    viewsAdded.Add(ProcessAndGetModelView(itemOnCanvas));
                }
                else if (!this.panel.Children.Contains(this.modelElement[itemOnCanvas]))
                {
                    flowElementsToProcess.Enqueue(model);
                    viewsAdded.Add(this.modelElement[itemOnCanvas]);
                }
            }

            ModelItem startNodeModelItem = null;
            List <Tuple <UIElement, UIElement, ModelItem> >       elem2elemConnections  = new List <Tuple <UIElement, UIElement, ModelItem> >();
            List <Tuple <ConnectionPoint, UIElement, ModelItem> > point2elemConnections = new List <Tuple <ConnectionPoint, UIElement, ModelItem> >();

            while (flowElementsToProcess.Count > 0)
            {
                ModelItem currentMI = flowElementsToProcess.Dequeue();
                //Create links for the current FlowNode.
                //First of all check if this is connected to the start node.
                if (this.ModelItem.Properties["StartNode"].Value != null &&
                    this.ModelItem.Properties["StartNode"].Value.Equals(currentMI))
                {
                    startNodeModelItem = currentMI;
                }
                if (typeof(FlowStep).IsAssignableFrom(currentMI.ItemType))
                {
                    ModelItem linkDest = currentMI.Properties["Next"].Value;
                    if (linkDest != null)
                    {
                        ModelItem src  = GetCorrespondingElementOnCanvas(currentMI);
                        ModelItem dest = GetCorrespondingElementOnCanvas(linkDest);
                        if (!modelElement.ContainsKey(dest))
                        {
                            viewsAdded.Add(ProcessAndGetModelView(dest));
                            flowElementsToProcess.Enqueue(linkDest);
                        }
                        elem2elemConnections.Add(Tuple.Create(modelElement[src], modelElement[dest], currentMI));
                    }
                }
                else if (typeof(FlowDecision).IsAssignableFrom(currentMI.ItemType))
                {
                    ModelItem trueDest  = currentMI.Properties["True"].Value;
                    ModelItem falseDest = currentMI.Properties["False"].Value;
                    if (trueDest != null)
                    {
                        ConnectionPoint srcConnectionPoint = FlowchartDesigner.GetTrueConnectionPoint(modelElement[currentMI]);
                        ModelItem       trueDestOnCanvas   = GetCorrespondingElementOnCanvas(trueDest);
                        if (!modelElement.ContainsKey(trueDestOnCanvas))
                        {
                            viewsAdded.Add(ProcessAndGetModelView(trueDestOnCanvas));
                            flowElementsToProcess.Enqueue(trueDest);
                        }
                        point2elemConnections.Add(Tuple.Create(srcConnectionPoint, modelElement[trueDestOnCanvas], currentMI));
                    }
                    if (falseDest != null)
                    {
                        ConnectionPoint srcConnectionPoint = FlowchartDesigner.GetFalseConnectionPoint(modelElement[currentMI]);
                        ModelItem       falseDestOnCanvas  = GetCorrespondingElementOnCanvas(falseDest);
                        if (!modelElement.ContainsKey(falseDestOnCanvas))
                        {
                            viewsAdded.Add(ProcessAndGetModelView(falseDestOnCanvas));
                            flowElementsToProcess.Enqueue(falseDest);
                        }
                        point2elemConnections.Add(Tuple.Create(srcConnectionPoint, modelElement[falseDestOnCanvas], currentMI));
                    }
                }
                else if (GenericFlowSwitchHelper.IsGenericFlowSwitch(currentMI.ItemType))
                {
                    IModelTreeItem modelTreeItem = this.ModelItem as IModelTreeItem;
                    ModelItem      defaultCase   = currentMI.Properties["Default"].Value;

                    if (defaultCase != null)
                    {
                        ModelItem defaultCaseOnCanvas = GetCorrespondingElementOnCanvas(defaultCase);
                        if (!modelElement.ContainsKey(defaultCaseOnCanvas))
                        {
                            viewsAdded.Add(ProcessAndGetModelView(defaultCaseOnCanvas));
                            flowElementsToProcess.Enqueue(defaultCase);
                        }
                        IFlowSwitchLink link          = GenericFlowSwitchHelper.CreateFlowSwitchLink(currentMI.ItemType, currentMI, null, true);
                        ModelItem       linkModelItem = new FakeModelItemImpl(modelTreeItem.ModelTreeManager, link.GetType(), link, null);
                        link.ModelItem = linkModelItem;

                        elem2elemConnections.Add(Tuple.Create(modelElement[currentMI], modelElement[defaultCaseOnCanvas], linkModelItem));
                    }
                    Type genericType = currentMI.ItemType.GetGenericArguments()[0];

                    foreach (ModelItem key in GenericFlowSwitchHelper.GetCaseKeys(currentMI.Properties["Cases"]))
                    {
                        ModelItem       destFlowElementMI = GenericFlowSwitchHelper.GetCaseModelItem(currentMI.Properties["Cases"], (key == null) ? null : key.GetCurrentValue());
                        IFlowSwitchLink link          = GenericFlowSwitchHelper.CreateFlowSwitchLink(currentMI.ItemType, currentMI, (key == null) ? null : key.GetCurrentValue(), false);
                        ModelItem       linkModelItem = new FakeModelItemImpl(modelTreeItem.ModelTreeManager, link.GetType(), link, null);
                        link.ModelItem = linkModelItem;
                        ModelItem destModelItem = GetCorrespondingElementOnCanvas(destFlowElementMI);
                        if (!modelElement.ContainsKey(destModelItem))
                        {
                            viewsAdded.Add(ProcessAndGetModelView(destModelItem));
                            flowElementsToProcess.Enqueue(destFlowElementMI);
                        }

                        elem2elemConnections.Add(Tuple.Create(modelElement[currentMI], modelElement[destModelItem], linkModelItem));
                    }
                }
                else
                {
                    Fx.Assert(false, "Unknown type of FlowNode");
                }
            }

            if (!this.startNodeAdded)
            {
                panel.Children.Add(this.StartSymbol);
                this.startNodeAdded = true;
            }
            foreach (UIElement view in viewsAdded)
            {
                panel.Children.Add(view);
            }

            // connection between flownode should be create only after all flownodes have been loaded on the canvas
            if (addConnectorAfterLoaded)
            {
                this.Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(() =>
                {
                    if (this.isLoaded)
                    {
                        AddConnectorsToPanel(startNodeModelItem, elem2elemConnections, point2elemConnections);
                    }
                }));
            }
            else
            {
                AddConnectorsToPanel(startNodeModelItem, elem2elemConnections, point2elemConnections);
            }
        }