public void OnItemsPasted(List<object> itemsToPaste, List<object> metaData, Point pastePoint, WorkflowViewElement pastePointReference) { if (this.ModelItem.ItemType == typeof(State)) { WorkflowViewElement view = VisualTreeUtils.FindVisualAncestor<WorkflowViewElement>(this); if (view != null) { StateContainerEditor container = (StateContainerEditor)DragDropHelper.GetCompositeView(view); container.OnItemsPasted(itemsToPaste, metaData, pastePoint, pastePointReference); } return; } if (itemsToPaste.Count == 1 && itemsToPaste.First() is Transition) { if (metaData == null || metaData.Count != 1 || !(metaData.First() is string)) { ShowMessageBox(SR.PasteTransitionWithoutDestinationState); return; } ModelItem destinationState = FindState(metaData.First() as string); if (destinationState == null) { ShowMessageBox(SR.PasteTransitionWithoutDestinationState); return; } this.PopulateVirtualizingContainer(destinationState); ModelItem[] selectedItems = this.Context.Items.GetValue<Selection>().SelectedObjects.ToArray(); string errorMessage; if (!CanPasteTransition(destinationState, out errorMessage, selectedItems)) { ShowMessageBox(errorMessage); return; } Transition pastedTransition = itemsToPaste.First() as Transition; Fx.Assert(pastedTransition != null, "Copied Transition should not be null."); using (EditingScope es = (EditingScope)this.ModelItem.BeginEdit(System.Activities.Presentation.SR.PropertyChangeEditingScopeDescription)) { string displayName = pastedTransition.DisplayName; bool isFirst = true; foreach (ModelItem selectedItem in selectedItems) { if (!isFirst) { StringReader reader = new StringReader(XamlServices.Save(pastedTransition)); pastedTransition = (Transition)XamlServices.Load(reader); } ModelItem transitionModelItem = this.Context.Services.GetRequiredService<ModelTreeManager>().WrapAsModelItem(pastedTransition); ModelItem sourceState = selectedItem; sourceState.Properties[StateDesigner.TransitionsPropertyName].Collection.Add(transitionModelItem); transitionModelItem.Properties[TransitionDesigner.ToPropertyName].SetValue(destinationState); if (isFirst) { this.ViewStateService.RemoveViewState(transitionModelItem, ConnectorLocationViewStateKey); this.ViewStateService.RemoveViewState(transitionModelItem, SrcConnectionPointIndexStateKey); this.ViewStateService.RemoveViewState(transitionModelItem, DestConnectionPointIndexStateKey); isFirst = false; } } es.Complete(); } } else { List<ModelItem> modelItemsPasted = new List<ModelItem>(); List<State> states = new List<State>(); foreach (object obj in itemsToPaste) { State state; if (obj is FinalState) { state = new State() { DisplayName = DefaultFinalStateDisplayName, IsFinal = true }; } else { state = (State)obj; if (state.DisplayName == null) { state.DisplayName = DefaultStateDisplayName; } } states.Add(state); } RemoveDanglingTransitions(states); using (EditingScope es = (EditingScope)this.ModelItem.BeginEdit( System.Activities.Presentation.SR.CollectionAddEditingScopeDescription)) { // Fix 157591 by storing the height and width of the container "before" the new states are added to the // panel, and group the insertion inside one editing scope - such that Undo will also restore the // size of the StateMachineContainer to pre-insert size. StoreShapeSizeWithUndoRecursively(this.ModelItem); foreach (State state in states) { ModelItem stateModelItem = (this.ModelItem.ItemType == typeof(StateMachine)) ? this.ModelItem.Properties[StateMachineDesigner.StatesPropertyName].Collection.Add(state) : GetStateMachineModelItem(this.ModelItem).Properties[StateMachineDesigner.StatesPropertyName].Collection.Add(state); modelItemsPasted.Add(stateModelItem); } es.Complete(); } if (modelItemsPasted.Count > 0) { // translate location view states to be in the coordinate system of the pasting target Fx.Assert(this.ModelItem.ItemType == typeof(StateMachine), "Only StateMachine contain the StateContainerEditor."); this.UpdateLocationViewStatesByMetaData(modelItemsPasted, metaData, this); if (pastePoint.X > 0 && pastePoint.Y > 0) { if (pastePointReference != null) { pastePoint = pastePointReference.TranslatePoint(pastePoint, this.panel); pastePoint.X = pastePoint.X < 0 ? 0 : pastePoint.X; pastePoint.Y = pastePoint.Y < 0 ? 0 : pastePoint.Y; } this.UpdateLocationViewStatesByPoint(modelItemsPasted, pastePoint); } // If paste point is not available, paste the items to the top left corner. else { this.UpdateLocationViewStatesToAvoidOverlap(modelItemsPasted); } } this.Dispatcher.BeginInvoke(() => { if (modelItemsPasted.Count > 0 && modelItemsPasted[0] != null) { Keyboard.Focus(modelItemsPasted[0].View as IInputElement); } this.Context.Items.SetValue(new Selection(modelItemsPasted)); }, DispatcherPriority.ApplicationIdle ); } }
public void OnItemsPasted(List<object> itemsToPaste, List<object> metaData, Point pastePoint, WorkflowViewElement pastePointReference) { List<ModelItem> modelItemsPasted = new List<ModelItem>(); List<State> states = new List<State>(); foreach (object obj in itemsToPaste) { State state; if (obj is FinalState) { state = new State() { DisplayName = SR.DefaultFinalStateDisplayName, IsFinal = true }; } else { state = (State)obj; if (state.DisplayName == null) { state.DisplayName = SR.DefaultStateDisplayName; } } states.Add(state); } RemoveDanglingTransitions(states); foreach (State state in states) { ModelItem stateModelItem = this.ModelItem.Properties[ChildStatesPropertyName].Collection.Add(state); modelItemsPasted.Add(stateModelItem); } if (modelItemsPasted.Count > 0) { // translate location view states to be in the coordinate system of the pasting target this.UpdateLocationViewStatesByMetaData(modelItemsPasted, metaData); if (pastePoint.X > 0 && pastePoint.Y > 0) { if (pastePointReference != null) { pastePoint = pastePointReference.TranslatePoint(pastePoint, this.panel); pastePoint.X = pastePoint.X < 0 ? 0 : pastePoint.X; pastePoint.Y = pastePoint.Y < 0 ? 0 : pastePoint.Y; } this.UpdateLocationViewStatesByPoint(modelItemsPasted, pastePoint); } // If paste point is not available, paste the items to the top left corner. else { this.UpdateLocationViewStatesToTopLeft(modelItemsPasted); } } this.Context.Items.SetValue(new Selection(modelItemsPasted)); }
public void OnItemsPasted(List<object> itemsToPaste, List<object> metaData, Point pastePoint, WorkflowViewElement pastePointReference) { Fx.Assert(this.panel != null, "This code shouldn't be hit if panel is null"); HashSet<Activity> workflowElementsPasted = new HashSet<Activity>(); List<ModelItem> modelItemsToSelect = new List<ModelItem>(); bool shouldStoreCurrentSizeViewState = true; Fx.Assert(this.ModelItem is IModelTreeItem, "this.ModelItem must implement IModelTreeItem"); using (EditingScope editingScope = ((IModelTreeItem)this.ModelItem).ModelTreeManager.CreateEditingScope(System.Activities.Presentation.SR.CollectionAddEditingScopeDescription)) { if (metaData != null) { List<ModelItem> modelItemsPerMetaData = new List<ModelItem>(); foreach (object designerMetaData in metaData) { if (designerMetaData is List<FlowNode>) { //This is flowchart metadata. foreach (FlowNode element in designerMetaData as List<FlowNode>) { FlowStep step = element as FlowStep; if (step != null) { workflowElementsPasted.Add(step.Action); } if (shouldStoreCurrentSizeViewState) { // Pasting may change the size of flowchart; need this to undo the size change. this.StoreCurrentSizeViewStateWithUndo(); shouldStoreCurrentSizeViewState = false; } ModelItem item = this.ModelItem.Properties["Nodes"].Collection.Add(element); // if the pasted item is a flowswitch but the default target is not in the pasted selection, // reset the DefaultCaseDisplayName to "Default". if (GenericFlowSwitchHelper.IsGenericFlowSwitch(item.ItemType) && item.Properties["Default"].Value == null) { item.Properties[FlowSwitchLabelFeature.DefaultCaseDisplayNamePropertyName].SetValue(FlowSwitchLabelFeature.DefaultCaseDisplayNameDefaultValue); } modelItemsPerMetaData.Add(item); if (item != null) { if (item.ItemType.Equals(typeof(FlowStep))) { modelItemsToSelect.Add(item.Properties["Action"].Value); } else { modelItemsToSelect.Add(item); } } } if (pastePoint.X > 0 && pastePoint.Y > 0) { Point panelPoint = this.TranslatePoint(pastePoint, this.panel); if (pastePointReference != null && !pastePointReference.Equals(this)) { if (pastePointReference.ModelItem != null && this.modelElement.ContainsKey(pastePointReference.ModelItem)) { panelPoint = pastePointReference.TranslatePoint(pastePoint, this.panel); } } panelPoint.X = panelPoint.X < 0 ? 0 : panelPoint.X; panelPoint.Y = panelPoint.Y < 0 ? 0 : panelPoint.Y; UpdateViewStateOnPastePoint(modelItemsPerMetaData, panelPoint); } else { UpdateViewStateToAvoidOverlapOnPaste(modelItemsPerMetaData); } modelItemsPerMetaData.Clear(); } } } foreach (object itemToPaste in itemsToPaste) { Activity workflowElementToPaste = itemToPaste as Activity; if (workflowElementToPaste != null && !workflowElementsPasted.Contains(workflowElementToPaste)) { FlowStep flowStep = new FlowStep { Action = workflowElementToPaste, Next = null }; if (shouldStoreCurrentSizeViewState) { // Pasting may change the size of flowchart; need this to undo the size change. this.StoreCurrentSizeViewStateWithUndo(); shouldStoreCurrentSizeViewState = false; } // When paste a non-flowstep object to flowchart, the existing hintsize of the object // should be removed, and let flowchart panel to compute the right size. VirtualizedContainerService.SetHintSize(workflowElementToPaste, null); ModelItem flowStepItem = this.ModelItem.Properties["Nodes"].Collection.Add(flowStep); if (flowStepItem != null) { modelItemsToSelect.Add(flowStepItem.Properties["Action"].Value); } } } editingScope.Complete(); } this.Dispatcher.BeginInvoke(() => { if (modelItemsToSelect.Count > 0 && modelItemsToSelect[0] != null) { Keyboard.Focus(modelItemsToSelect[0].View as IInputElement); } this.Context.Items.SetValue(new Selection(modelItemsToSelect)); }, DispatcherPriority.ApplicationIdle ); }