Ejemplo n.º 1
0
        public static void Delete(EditingContext context)
        {
            if (context == null)
            {
                throw FxTrace.Exception.AsError(new ArgumentNullException("context"));
            }
            Selection selection = context.Items.GetValue <Selection>();

            if (null != selection)
            {
                bool selectRoot = false;

                DesignerView designerView = context.Services.GetService <DesignerView>();
                var          toDelete     = selection.SelectedObjects.Where(p => null != p.View && p.View is WorkflowViewElement && !p.View.Equals(designerView.RootDesigner));
                if (toDelete.Count() > 0)
                {
                    using (EditingScope es = (EditingScope)toDelete.FirstOrDefault().BeginEdit(SR.DeleteOperationEditingScopeDescription))
                    {
                        Dictionary <ICompositeView, List <ModelItem> > containerToModelItemsDict = new Dictionary <ICompositeView, List <ModelItem> >();
                        List <ModelItem> modelItemsPerContainer;
                        foreach (var item in toDelete)
                        {
                            ICompositeView container = (ICompositeView)DragDropHelper.GetCompositeView((WorkflowViewElement)item.View);
                            if (null != container)
                            {
                                if (!containerToModelItemsDict.TryGetValue(container, out modelItemsPerContainer))
                                {
                                    modelItemsPerContainer = new List <ModelItem>();
                                    containerToModelItemsDict.Add(container, modelItemsPerContainer);
                                }
                                modelItemsPerContainer.Add(item);
                            }
                        }
                        foreach (ICompositeView container in containerToModelItemsDict.Keys)
                        {
                            container.OnItemsDelete(containerToModelItemsDict[container]);
                            selectRoot = true;
                        }

                        if (selectRoot)
                        {
                            DesignerView view = context.Services.GetService <DesignerView>();
                            if (null != view)
                            {
                                WorkflowViewElement rootView = view.RootDesigner as WorkflowViewElement;
                                if (rootView != null)
                                {
                                    Selection.SelectOnly(context, rootView.ModelItem);
                                }
                            }
                        }
                        es.Complete();
                    }
                }
            }
        }
        static ICompositeView GetContainerForPaste(ModelItem pasteModelItem, Point clickPoint)
        {
            ICompositeView pasteContainer = null;

            if (null != pasteModelItem && null != pasteModelItem.View && pasteModelItem.View is WorkflowViewElement)
            {
                pasteContainer = ((WorkflowViewElement)pasteModelItem.View).ActiveCompositeView;
            }
            if (null == pasteContainer)
            {
                //Get clicked container.
                if (clickPoint.X > 0 && clickPoint.Y > 0)
                {
                    pasteContainer = GetClickedContainer(pasteModelItem, clickPoint);
                }

                //If the container itself is a WVE, there's posibility that it's collapsed.
                //Thus, we need to check this as well.
                if (pasteContainer != null && pasteContainer is WorkflowViewElement)
                {
                    WorkflowViewElement view = pasteContainer as WorkflowViewElement;
                    if (!view.ShowExpanded)
                    {
                        pasteContainer = null;
                    }
                }
                else if (pasteContainer == null) //If the modelitem.View itself is a container.
                {
                    WorkflowViewElement view = pasteModelItem.View as WorkflowViewElement;
                    if (view != null && view.ShowExpanded)
                    {
                        pasteContainer = pasteModelItem.View as ICompositeView;
                    }
                }

                //Get the container registered with modelItem.View if unambigous
                //If nothing works take the container with keyboard focus if one exists.
                if (pasteContainer == null)
                {
                    HashSet <ICompositeView> childrenContainers = CutCopyPasteHelper.GetChildContainers(pasteModelItem.View as WorkflowViewElement);
                    if ((childrenContainers == null || childrenContainers.Count == 0) && null != pasteModelItem.View)
                    {
                        pasteContainer = (ICompositeView)DragDropHelper.GetCompositeView((WorkflowViewElement)pasteModelItem.View);
                    }
                    else if (null != childrenContainers && childrenContainers.Count == 1)
                    {
                        pasteContainer = new List <ICompositeView>(childrenContainers)[0];
                    }
                    else
                    {
                        pasteContainer = Keyboard.FocusedElement as ICompositeView;
                    }
                }
            }
            return(pasteContainer);
        }
        // 1) obj with CompositeView2: sort by IMultipleDragEnabledCompositeView SortSelectedItems.
        // 2) obj with CompoisteView: no sort.
        // 3) obj without CompositeView: just put them at the end of the list as the order in selectedObjects.
        internal static List <object> SortSelectedObjects(IEnumerable <object> selectedObjects)
        {
            //1) Separate objects
            Dictionary <ICompositeView, List <ModelItem> > viewItemListDictionary = new Dictionary <ICompositeView, List <ModelItem> >();
            List <object> nonCompositeView = new List <object>();
            List <object> retList          = new List <object>();

            foreach (object obj in selectedObjects)
            {
                ModelItem modelItem = obj as ModelItem;
                if (modelItem == null || modelItem.View == null)
                {
                    nonCompositeView.Add(obj);
                    continue;
                }
                ICompositeView container = DragDropHelper
                                           .GetCompositeView(modelItem.View as WorkflowViewElement) as ICompositeView;
                if (container == null)
                {
                    nonCompositeView.Add(obj);
                    continue;
                }

                // add to dictionary.
                if (!viewItemListDictionary.ContainsKey(container))
                {
                    viewItemListDictionary.Add(container, new List <ModelItem>());
                }

                viewItemListDictionary[container].Add(modelItem);
            }

            // 2) sort when possible
            foreach (KeyValuePair <ICompositeView, List <ModelItem> > pair in viewItemListDictionary)
            {
                IMultipleDragEnabledCompositeView view2 = pair.Key as IMultipleDragEnabledCompositeView;
                List <ModelItem> sortedList             = view2 == null ?
                                                          pair.Value : view2.SortSelectedItems(new List <ModelItem>(pair.Value));
                if (!AreListsIdenticalExceptOrder(pair.Value, sortedList))
                {
                    // check consistens.
                    throw FxTrace.Exception.AsError(
                              new InvalidOperationException(SR.Error_BadOutputFromSortSelectedItems));
                }
                retList.AddRange(sortedList);
            }

            retList.AddRange(nonCompositeView);
            return(retList);
        }
        bool AllowDragging()
        {
            Selection selection = this.Context.Items.GetValue <Selection>();

            if (!this.DraggingMultipleItemsEnabled)
            {
                if (selection.SelectionCount != 1)
                {
                    return(false);
                }
            }

            return(selection.SelectedObjects.All <ModelItem>((p) =>
            {
                return p != null && p != p.Root && p.View != null && ((WorkflowViewElement)p.View).IsVisible &&
                (DragDropHelper.GetCompositeView((WorkflowViewElement)p.View) as ICompositeView) != null;
            }));
        }
        //This is more efficient than walking up the VisualTree looking for WorkflowViewElements.
        //Assuming that Cut-Copy will always be against selected elements.
        //This implies that only elements under the BreadCrumbRoot can be cut/copied.
        static List <WorkflowViewElement> GetSelectableParentViewElements(WorkflowViewElement childElement)
        {
            List <WorkflowViewElement> parentViewElements = new List <WorkflowViewElement>();

            if (childElement != null)
            {
                UIElement      breadcrumbRoot = childElement.Context.Services.GetService <DesignerView>().RootDesigner;
                ICompositeView container      = (ICompositeView)DragDropHelper.GetCompositeView(childElement);
                while (!childElement.Equals(breadcrumbRoot) && container != null)
                {
                    childElement = CutCopyPasteHelper.GetParentViewElement(container);
                    Fx.Assert(childElement != null, "container should be present in a WorkflowViewElement");
                    parentViewElements.Add(childElement);
                    container = (ICompositeView)DragDropHelper.GetCompositeView(childElement);
                }
            }
            return(parentViewElements);
        }
Ejemplo n.º 6
0
        private List <WorkflowViewElement> ObjectList2WorkflowViewElementList(IEnumerable <object> droppedObjects)
        {
            List <WorkflowViewElement> movedViewElements = new List <WorkflowViewElement>();

            foreach (object droppedObject in droppedObjects)
            {
                if (droppedObject is ModelItem && ((ModelItem)droppedObject).View != null)
                {
                    WorkflowViewElement   view      = (WorkflowViewElement)((ModelItem)droppedObject).View;
                    WorkflowItemPresenter container = DragDropHelper.GetCompositeView(view) as WorkflowItemPresenter;
                    if (container != this)
                    {
                        movedViewElements.Add(view);
                    }
                }
            }
            return(movedViewElements);
        }
        void StartDragging()
        {
            try
            {
                using (ModelEditingScope editingScope = this.ModelItem.BeginEdit(SR.MoveEditingScopeDescription, true))
                {
                    HashSet <WorkflowViewElement>          draggedViews     = new HashSet <WorkflowViewElement>();
                    Dictionary <ModelItem, ICompositeView> sourceContainers = new Dictionary <ModelItem, ICompositeView>();
                    HashSet <ICompositeView> compViewSet = new HashSet <ICompositeView>();
                    Selection selection = this.Context.Items.GetValue <Selection>();
                    IEnumerable <ModelItem> selectedObjects  = selection.SelectedObjects;
                    IEnumerable <ModelItem> modelItemsToDrag = DragDropHelper.GetModelItemsToDrag(selectedObjects);

                    // Save the source containers for the dragged items
                    foreach (ModelItem modelItem in modelItemsToDrag)
                    {
                        WorkflowViewElement view = (WorkflowViewElement)modelItem.View;
                        draggedViews.Add(view);
                        ICompositeView container = DragDropHelper.GetCompositeView(view) as ICompositeView;
                        sourceContainers.Add(modelItem, container);
                        // If Add returns true => the container is added the first time, which is always ok
                        // If Add returns false => the container is added more than once
                        //    it must be a IMultipleDragEnabledCompositeView, otherwise, return, because
                        //    we don't support dragging from ICompositeView.
                        if (!compViewSet.Add(container) && !(container is IMultipleDragEnabledCompositeView))
                        {
                            return;
                        }
                    }

                    // Calculate the anchor point for the dragged items
                    Point relativeLocation = GetRelativeLocation(draggedViews);
                    Point referencePoint   = this.lastMouseDownPoint;
                    referencePoint.Offset(relativeLocation.X, relativeLocation.Y);


                    DataObject dataObject = DragDropHelper.DoDragMoveImpl(draggedViews, referencePoint);
                    IEnumerable <WorkflowViewElement> movedViewElements = DragDropHelper.GetDragDropMovedViewElements(dataObject);

                    // once drag drop is done make sure the CompositeView is notified of the change in data
                    if (movedViewElements != null)
                    {
                        Dictionary <ICompositeView, List <ModelItem> > containerMovedModelItemList = new Dictionary <ICompositeView, List <ModelItem> >();

                        // Create containerMovedModelItemList
                        foreach (WorkflowViewElement view in movedViewElements)
                        {
                            ICompositeView compView = DragDropHelper.GetCompositeView(view) as ICompositeView;
                            Fx.Assert(compView != null, "not an ICompositeView");
                            if (!containerMovedModelItemList.ContainsKey(compView))
                            {
                                containerMovedModelItemList.Add(compView, new List <ModelItem>());
                            }
                            containerMovedModelItemList[compView].Add(view.ModelItem);
                        }

                        // Call OnItemsMoved to notify the source container.
                        foreach (KeyValuePair <ICompositeView, List <ModelItem> > pair in containerMovedModelItemList)
                        {
                            if (pair.Key is IMultipleDragEnabledCompositeView)
                            {
                                ((IMultipleDragEnabledCompositeView)pair.Key).OnItemsMoved(pair.Value);
                            }
                            else
                            {
                                if (pair.Value.Count >= 2)
                                {
                                    throw FxTrace.Exception.AsError(
                                              new InvalidOperationException(SR.Error_MovingMoreThanOneItemsFromICompositeView));
                                }
                                pair.Key.OnItemMoved(pair.Value[0]);
                            }
                        }

                        // animation
                        foreach (WorkflowViewElement view in movedViewElements)
                        {
                            BeginDropAnimation(view);
                        }
                    }
                    // the drop target is using old DragDropHelper API and did not set the moved view elements
                    else
                    {
                        DragDropEffects executedDragDropEffect = DragDropHelper.GetDragDropCompletedEffects(dataObject);
                        if (executedDragDropEffect == DragDropEffects.Move)
                        {
                            if (modelItemsToDrag.Count() == 1)
                            {
                                ModelItem movedItem = modelItemsToDrag.First <ModelItem>();
                                sourceContainers[movedItem].OnItemMoved(movedItem);
                                BeginDropAnimation((WorkflowViewElement)movedItem.View);
                            }
                            else
                            {
                                throw FxTrace.Exception.AsError(new InvalidOperationException(SR.DraggingMulitpleItemsError));
                            }
                        }
                    }
                    editingScope.Complete();

                    bool dropHappened = movedViewElements != null ||
                                        DragDropHelper.GetDragDropCompletedEffects(dataObject) == DragDropEffects.Move;
                    if (dropHappened)
                    {
                        // add the selected objects back into selection.
                        this.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, (Action)(() =>
                        {
                            foreach (ModelItem item in selectedObjects)
                            {
                                // We need only the first one
                                IInputElement viewToFocus = item == null ? null : item.View as IInputElement;
                                if (viewToFocus != null)
                                {
                                    Keyboard.Focus(viewToFocus);
                                    break;
                                }
                            }
                            this.Context.Items.SetValue(new Selection(selectedObjects));
                        }));
                    }
                }
            }
            catch (Exception e)
            {
                ErrorReporting.ShowErrorMessage(e.Message);
            }
        }
        static void CutCopyOperation(List <ModelItem> modelItemsToCutCopy, EditingContext context, bool isCutOperation)
        {
            List <object> objectsOnClipboard = null;
            List <object> metaData           = null;

            if (modelItemsToCutCopy.Count > 0)
            {
                objectsOnClipboard = new List <object>(modelItemsToCutCopy.Count);
                metaData           = new List <object>();
                Dictionary <ICompositeView, List <ModelItem> > notifyDictionary = new Dictionary <ICompositeView, List <ModelItem> >();
                UIElement breadCrumbRootView = ((DesignerView)context.Services.GetService <DesignerView>()).RootDesigner;
                foreach (ModelItem modelItem in modelItemsToCutCopy)
                {
                    object currentElement = modelItem.GetCurrentValue();

                    if (typeof(Activity).IsAssignableFrom(currentElement.GetType()))
                    {
                        string fileName;
                        if (AttachablePropertyServices.TryGetProperty(currentElement, XamlDebuggerXmlReader.FileNameName, out fileName))
                        {
                            AttachablePropertyServices.RemoveProperty(currentElement, XamlDebuggerXmlReader.FileNameName);
                        }
                    }

                    if (modelItem.View != null)
                    {
                        //The case where the breadcrumbroot designer is Cut/Copied. We do not delete the root designer, we only copy it.
                        if (breadCrumbRootView.Equals(modelItem.View))
                        {
                            notifyDictionary.Clear();
                            objectsOnClipboard.Add(modelItem.GetCurrentValue());
                            break;
                        }
                        else
                        {
                            ICompositeView container = (ICompositeView)DragDropHelper.GetCompositeView((WorkflowViewElement)modelItem.View);
                            if (container != null)
                            {
                                //If the parent and some of its children are selected and cut/copied, we ignore the children.
                                //The entire parent will be cut/copied.
                                //HashSet parentModelItems contains all the model items in the parent chain of current modelItem.
                                //We use HashSet.IntersectWith operation to determine if one of the parents is set to be cut.
                                HashSet <ModelItem> parentModelItems = CutCopyPasteHelper.GetSelectableParentModelItems(modelItem);
                                parentModelItems.IntersectWith(modelItemsToCutCopy);
                                if (parentModelItems.Count == 0)
                                {
                                    if (!notifyDictionary.ContainsKey(container))
                                    {
                                        notifyDictionary[container] = new List <ModelItem>();
                                    }
                                    notifyDictionary[container].Add(modelItem);
                                }
                            }
                        }
                    }
                }

                foreach (ICompositeView container in notifyDictionary.Keys)
                {
                    object containerMetaData = false;
                    if (isCutOperation)
                    {
                        containerMetaData = container.OnItemsCut(notifyDictionary[container]);
                    }
                    else
                    {
                        containerMetaData = container.OnItemsCopied(notifyDictionary[container]);
                    }
                    if (containerMetaData != null)
                    {
                        metaData.Add(containerMetaData);
                    }
                    //Put the actual activities and not the modelItems in the clipboard.
                    foreach (ModelItem modelItem in notifyDictionary[container])
                    {
                        objectsOnClipboard.Add(modelItem.GetCurrentValue());
                    }
                }
                if (metaData.Count == 0)
                {
                    metaData = null;
                }
            }
            try
            {
                FrameworkName targetFramework = context.Services.GetService <DesignerConfigurationService>().TargetFrameworkName;
                PutOnClipBoard(objectsOnClipboard, metaData, targetFramework);
            }
            catch (XamlObjectReaderException exception)
            {
                if (modelItemsToCutCopy.Count > 0 && ErrorActivity.GetHasErrorActivities(modelItemsToCutCopy[0].Root.GetCurrentValue()))
                {
                    ErrorReporting.ShowErrorMessage(SR.CutCopyErrorActivityMessage);
                }
                else
                {
                    ErrorReporting.ShowErrorMessage(exception.Message);
                }
            }
        }
Ejemplo n.º 9
0
        void OnItemsDropped(DragEventArgs e, int index)
        {
            ModelItemHelper.TryCreateImmediateEditingScopeAndExecute(this.Items.GetEditingContext(), System.Activities.Presentation.SR.CollectionAddEditingScopeDescription, (es) =>
            {
                DragDropHelper.SetDragDropCompletedEffects(e, DragDropEffects.None);
                List <object> droppedObjects = new List <object>(DragDropHelper.GetDroppedObjects(this, e, Context));
                List <WorkflowViewElement> movedViewElements = new List <WorkflowViewElement>();

                List <object> externalMoveList    = new List <object>();
                List <ModelItem> internalMoveList = new List <ModelItem>();

                // Step 1: Sort the list
                List <object> sortedDroppingList = DragDropHelper.SortSelectedObjects(droppedObjects);


                // Step 2: Categorize dropped objects by their source container.
                foreach (object droppedObject in sortedDroppingList)
                {
                    ModelItem modelItem      = droppedObject as ModelItem;
                    WorkflowViewElement view = (modelItem == null) ? null : (modelItem.View as WorkflowViewElement);
                    if (view == null)
                    {
                        externalMoveList.Add(droppedObject);
                        continue;
                    }
                    UIElement container = DragDropHelper.GetCompositeView(view);
                    if (container == this)
                    {
                        internalMoveList.Add(modelItem);
                        continue;
                    }
                    movedViewElements.Add(view);
                    externalMoveList.Add(droppedObject);
                }

                // Step 3: Internal movement
                if (this.ShouldMoveItems(internalMoveList, index))
                {
                    foreach (ModelItem modelItem in internalMoveList)
                    {
                        int oldIndex = this.Items.IndexOf(modelItem);
                        this.Items.Remove(modelItem);

                        //if element is placed ahead of old location, decrement the index not to include moved object
                        if (oldIndex < index)
                        {
                            this.InsertItem(index - 1, modelItem);
                        }
                        else
                        {
                            this.InsertItem(index, modelItem);
                            index++;
                        }
                    }
                }

                // Step 4: External move and drop from toolbox
                foreach (object droppedObject in externalMoveList)
                {
                    if (!this.IsDropAllowed(droppedObject))
                    {
                        continue;
                    }
                    this.InsertItem(index++, droppedObject);
                    DragDropHelper.SetDragDropCompletedEffects(e, DragDropEffects.Move);
                }
                DragDropHelper.SetDragDropMovedViewElements(e, movedViewElements);
                e.Handled = true;
                if (es != null)
                {
                    es.Complete();
                }
            });
        }