private bool PrepareConnection(IDiagramPresenter diagramPresenter, MouseState mouseState,
		                               ShapeAtCursorInfo shapeAtCursorInfo, Action action)
		{
			// if we're not dealing with filter shapes... well, what the f**k?! get out of here!
			FilterSetupShapeBase shape = shapeAtCursorInfo.Shape as FilterSetupShapeBase;
			if (shape == null)
				throw new Exception("Can't connect a shape that isn't a FilterSetup shape!");

			if (shape.OutputCount <= 0)
				return false;

			// get the starting control point for the line; ie. the first unused output for the shape, or the selected control point (if the mouse is over an output)
			ControlPointId connectionPoint = ControlPointId.None;

			if (shapeAtCursorInfo.IsCursorAtConnectionPoint &&
			    shape.GetTypeForControlPoint(shapeAtCursorInfo.ControlPointId) ==
			    FilterSetupShapeBase.FilterShapeControlPointType.Output) {
				connectionPoint = shapeAtCursorInfo.ControlPointId;
			}
			else {
				// try and find the first unconnected output if the mouse isn't over a specific control point
				for (int i = 0; i < shape.OutputCount; i++) {
					ControlPointId currentPoint = shape.GetControlPointIdForOutput(i);
					if (shape.GetConnectionInfos(currentPoint, null).Count() == 0) {
						connectionPoint = currentPoint;
						break;
					}
				}

				// if we couldn't find an unconnected point, just default to the first
				if (connectionPoint == ControlPointId.None) {
					connectionPoint = shape.GetControlPointIdForOutput(0);
				}
			}

			DataFlowConnectionLine line =
				(DataFlowConnectionLine) diagramPresenter.Project.ShapeTypes["DataFlowConnectionLine"].CreateInstance();
			diagramPresenter.InsertShape(line);
			diagramPresenter.Diagram.Shapes.SetZOrder(line, 100);
			line.SecurityDomainName = ConfigFiltersAndPatching.SECURITY_DOMAIN_MOVABLE_SHAPE_WITH_CONNECTIONS;
			line.EndCapStyle = diagramPresenter.Project.Design.CapStyles.ClosedArrow;
			line.SourceDataFlowComponentReference = new DataFlowComponentReference(shape.DataFlowComponent,
			                                                                       shape.GetOutputNumberForControlPoint(
			                                                                       	connectionPoint));
			line.DestinationDataComponent = null;

			line.Connect(ControlPointId.FirstVertex, shape, connectionPoint);
			line.Disconnect(ControlPointId.LastVertex);
			line.MoveControlPointTo(ControlPointId.LastVertex, mouseState.X, mouseState.Y, ResizeModifiers.None);
			currentConnectionLine = line;

			StartToolAction(diagramPresenter, (int) action, ActionStartMouseState, true);
			return true;
		}
		/// <summary>
		/// Decide which tool action is suitable for the current mouse state.
		/// </summary>
		private Action DetermineMouseMoveAction(IDiagramPresenter diagramPresenter, MouseState mouseState,
		                                        ShapeAtCursorInfo shapeAtCursorInfo)
		{
			switch (CurrentAction) {
				case Action.None:
				case Action.MoveHandle:
				case Action.MoveShape:
				case Action.SelectWithFrame:
				case Action.ConnectShapes:
					// Do not change the current action
					return CurrentAction;

				case Action.Select:
					if (mouseState.IsButtonDown(MouseButtonsDg.Left)) {
						// if we're doing something with the left mouse button, it will be a 'drag' style action
						if (!IsDragActionFeasible(mouseState)) {
							return CurrentAction;
						}

						// Check if cursor is over a control point and moving grips is feasible
						if (selectedShapeAtCursorInfo.IsCursorAtGrip) {
							if (IsMoveHandleFeasible(diagramPresenter, mouseState, selectedShapeAtCursorInfo))
								return Action.MoveHandle;
							else
								return Action.SelectWithFrame;
						}
						else {
							// If there is no shape under the cursor, start a SelectWithFrame action,
							// otherwise start a MoveShape action
							bool canMove = false;
							if (!selectedShapeAtCursorInfo.IsEmpty) {
								// If there are selected shapes, check these shapes...
								canMove = IsMoveShapeFeasible(diagramPresenter, mouseState, selectedShapeAtCursorInfo);
							}
							else {
								// ... otherwise check the shape under the cursor as it will be selected 
								// before starting a move action
								canMove = IsMoveShapeFeasible(diagramPresenter, mouseState, shapeAtCursorInfo);
							}
							return canMove ? Action.MoveShape : Action.SelectWithFrame;
						}
					}
					else if (mouseState.IsButtonDown(MouseButtonsDg.Right)) {
						if (IsConnectFromShapeFeasible(diagramPresenter, mouseState, shapeAtCursorInfo)) {
							return Action.ConnectShapes;
						}
					}
					return CurrentAction;

				default:
					throw new NShapeUnsupportedValueException(CurrentAction);
			}
		}
		// (Un)Select shape unter the mouse pointer
		private bool PerformSelection(IDiagramPresenter diagramPresenter, MouseState mouseState,
		                              ShapeAtCursorInfo shapeAtCursorInfo)
		{
			bool result = false;
			bool multiSelect = mouseState.IsKeyPressed(KeysDg.Control) || mouseState.IsKeyPressed(KeysDg.Shift);

			// When selecting shapes conteolpoints should be ignored as the user does not see them 
			// until a shape is selected
			const ControlPointCapabilities capabilities = ControlPointCapabilities.None;
			const int range = 0;

			// Determine the shape that has to be selected:
			Shape shapeToSelect = null;
			if (!selectedShapeAtCursorInfo.IsEmpty) {
				// When in multiSelection mode, unselect the selected shape under the cursor
				if (multiSelect) shapeToSelect = selectedShapeAtCursorInfo.Shape;
				else {
					// First, check if the selected shape under the cursor has children that can be selected
					shapeToSelect = selectedShapeAtCursorInfo.Shape.Children.FindShape(mouseState.X, mouseState.Y, capabilities, range,
					                                                                   null);
					// Second, check if the selected shape under the cursor has siblings that can be selected
					if (shapeToSelect == null && selectedShapeAtCursorInfo.Shape.Parent != null) {
						shapeToSelect = selectedShapeAtCursorInfo.Shape.Parent.Children.FindShape(mouseState.X, mouseState.Y, capabilities,
						                                                                          range, selectedShapeAtCursorInfo.Shape);
						// Discard found shape if it is the selected shape at cursor
						if (shapeToSelect == selectedShapeAtCursorInfo.Shape) shapeToSelect = null;
						if (shapeToSelect == null) {
							foreach (
								Shape shape in
									selectedShapeAtCursorInfo.Shape.Parent.Children.FindShapes(mouseState.X, mouseState.Y, capabilities, range)) {
								if (shape == selectedShapeAtCursorInfo.Shape) continue;
								// Ignore layer visibility for child shapes
								shapeToSelect = shape;
								break;
							}
						}
					}
				}
			}

			// If there was a shape to select related to the selected shape under the cursor
			// (a child or a sibling of the selected shape or a shape below it),
			// try to select the first non-selected shape under the cursor
			if (shapeToSelect == null && shapeAtCursorInfo.Shape != null
			    && shapeAtCursorInfo.Shape.ContainsPoint(mouseState.X, mouseState.Y))
				shapeToSelect = shapeAtCursorInfo.Shape;

			// If a new shape to select was found, perform selection
			if (shapeToSelect != null) {
				// (check if multiselection mode is enabled (Shift + Click or Ctrl + Click))
				if (multiSelect) {
					// if multiSelect is enabled, add/remove to/from selected selectedShapes...
					if (diagramPresenter.SelectedShapes.Contains(shapeToSelect)) {
						// if object is selected -> remove from selection
						diagramPresenter.UnselectShape(shapeToSelect);
						RemovePreviewOf(shapeToSelect);
						result = true;
					}
					else {
						// If object is not selected -> add to selection
						diagramPresenter.SelectShape(shapeToSelect, true);
						result = true;
					}
				}
				else {
					// ... otherwise deselect all selectedShapes but the clicked object
					ClearPreviews();
					// check if the clicked shape is a child of an already selected shape
					Shape childShape = null;
					if (diagramPresenter.SelectedShapes.Count == 1
					    && diagramPresenter.SelectedShapes.TopMost.Children != null
					    && diagramPresenter.SelectedShapes.TopMost.Children.Count > 0) {
						childShape = diagramPresenter.SelectedShapes.TopMost.Children.FindShape(mouseState.X, mouseState.Y,
						                                                                        ControlPointCapabilities.None, 0, null);
					}
					diagramPresenter.SelectShape(childShape ?? shapeToSelect, false);
					result = true;
				}

				// validate if the desired shape or its parent was selected
				if (shapeToSelect.Parent != null) {
					if (!diagramPresenter.SelectedShapes.Contains(shapeToSelect))
						if (diagramPresenter.SelectedShapes.Contains(shapeToSelect.Parent))
							shapeToSelect = shapeToSelect.Parent;
				}
			}
			else if (selectedShapeAtCursorInfo.IsEmpty) {
				// if there was no other shape to select and none of the selected shapes is under the cursor,
				// clear selection
				if (!multiSelect) {
					if (diagramPresenter.SelectedShapes.Count > 0) {
						diagramPresenter.UnselectAll();
						ClearPreviews();
						result = true;
					}
				}
			}

			return result;
		}
		private bool IsConnectFromShapeFeasible(IDiagramPresenter diagramPresenter, MouseState mouseState,
		                                        ShapeAtCursorInfo shapeAtCursorInfo)
		{
			if (shapeAtCursorInfo.IsEmpty || mouseState.IsEmpty)
				return false;
			if (!diagramPresenter.Project.SecurityManager.IsGranted(Permission.Connect, shapeAtCursorInfo.Shape))
				return false;

			if (shapeAtCursorInfo.Shape is FilterSetupShapeBase) {
				FilterSetupShapeBase filterShape = shapeAtCursorInfo.Shape as FilterSetupShapeBase;
				// only check OUTPUT count; we want to enforce the 'drag from OUTPUT, to INPUT' paradigm
				if (filterShape.OutputCount > 0)
					return true;
			}

			return false;
		}
		private bool IsMoveHandleFeasible(IDiagramPresenter diagramPresenter, MouseState mouseState,
		                                  ShapeAtCursorInfo shapeAtCursorInfo)
		{
			if (shapeAtCursorInfo.IsEmpty)
				return false;
			// Collides with the resize modifiers
			//if (mouseState.IsKeyPressed(KeysDg.Shift)) return false;
			if (shapeAtCursorInfo.Shape.HasControlPointCapability(shapeAtCursorInfo.ControlPointId, ControlPointCapabilities.Glue)) {
				if (!diagramPresenter.Project.SecurityManager.IsGranted(Permission.Connect, diagramPresenter.SelectedShapes))
					return false;
			}
			else {
				if (!diagramPresenter.Project.SecurityManager.IsGranted(Permission.Layout, diagramPresenter.SelectedShapes))
					return false;
			}
			if (
				!shapeAtCursorInfo.Shape.HasControlPointCapability(shapeAtCursorInfo.ControlPointId,
				                                                   ControlPointCapabilities.Resize | ControlPointCapabilities.Glue
				 	/*| ControlPointCapabilities.Movable*/))
				return false;
			if (diagramPresenter.SelectedShapes.Count > 1) {
				// GluePoints may only be moved alone
				if (shapeAtCursorInfo.Shape.HasControlPointCapability(shapeAtCursorInfo.ControlPointId,
				                                                      ControlPointCapabilities.Glue))
					return false;
				// Check if all shapes that are going to be resizes are of the same type
				Shape lastShape = null;
				foreach (Shape shape in diagramPresenter.SelectedShapes) {
					if (lastShape != null && lastShape.Type != shape.Type)
						return false;
					lastShape = shape;
				}
			}
			return true;
		}
		private bool IsMoveShapeFeasible(IDiagramPresenter diagramPresenter, MouseState mouseState,
		                                 ShapeAtCursorInfo shapeAtCursorInfo)
		{
			if (shapeAtCursorInfo.IsEmpty || mouseState.IsEmpty)
				return false;
			if (!diagramPresenter.Project.SecurityManager.IsGranted(Permission.Layout, shapeAtCursorInfo.Shape))
				return false;
			if (diagramPresenter.SelectedShapes.Count > 0 &&
			    !diagramPresenter.Project.SecurityManager.IsGranted(Permission.Layout, diagramPresenter.SelectedShapes))
				return false;
			if (!shapeAtCursorInfo.Shape.ContainsPoint(mouseState.X, mouseState.Y))
				return false;
			if (shapeAtCursorInfo.Shape.HasControlPointCapability(ControlPointId.Reference, ControlPointCapabilities.Glue))
				if (shapeAtCursorInfo.Shape.IsConnected(ControlPointId.Reference, null) != ControlPointId.None) return false;

			// Check if the shape is connected to other shapes with its glue points
			if (diagramPresenter.SelectedShapes.Count == 0) {
				// Check if the non-selected shape at cursor (which will be selected) owns glue points connected to other shapes
				foreach (ControlPointId id in shapeAtCursorInfo.Shape.GetControlPointIds(ControlPointCapabilities.Glue))
					if (shapeAtCursorInfo.Shape.IsConnected(id, null) != ControlPointId.None) return false;
			}
			else if (diagramPresenter.SelectedShapes.Contains(shapeAtCursorInfo.Shape)) {
				// ToDo: If there are *many* shapes selected (e.g. 10000), this check will be extremly slow...
				if (diagramPresenter.SelectedShapes.Count < 10000) {
					// LinearShapes that own connected gluePoints may not be moved.
					foreach (Shape shape in diagramPresenter.SelectedShapes) {
						if (shape is ILinearShape) {
							foreach (ControlPointId gluePointId in shape.GetControlPointIds(ControlPointCapabilities.Glue)) {
								ShapeConnectionInfo sci = shape.GetConnectionInfo(gluePointId, null);
								if (!sci.IsEmpty) {
									// Allow movement if the connected shapes are moved together
									if (!diagramPresenter.SelectedShapes.Contains(sci.OtherShape))
										return false;
								}
							}
						}
					}
				}
			}
			return true;
		}
Exemple #7
0
		/// <summary>
		/// Creates a new preview line shape
		/// </summary>
		private void ExtendLine(IDiagramPresenter diagramPresenter, MouseState mouseState, ShapeAtCursorInfo targetShapeInfo) {
			// Try to find a connection target
			if (!targetShapeInfo.IsEmpty && targetShapeInfo.ControlPointId != ControlPointId.None) {
				// Start ToolAction
				StartToolAction(diagramPresenter, (int)Action.ExtendLine, mouseState, true);
				modifiedLinearShape = (ILinearShape)targetShapeInfo.Shape;

				// create new preview shape
				CreatePreview(diagramPresenter);
				PreviewShape.CopyFrom(targetShapeInfo.Shape);	// Template will be copied but this is not really necessary as all styles will be overwritten with preview styles
				PreviewShape.MakePreview(diagramPresenter.Project.Design);

				pointAtCursor = targetShapeInfo.ControlPointId;
				Point pointPos = targetShapeInfo.Shape.GetControlPointPosition(pointAtCursor);
				if (pointAtCursor == ControlPointId.FirstVertex) {
					ControlPointId insertId = PreviewLinearShape.GetNextVertexId(pointAtCursor);
					lastInsertedPointId = PreviewLinearShape.InsertVertex(insertId, pointPos.X, pointPos.Y);
				} else lastInsertedPointId = PreviewLinearShape.InsertVertex(pointAtCursor, pointPos.X, pointPos.Y);

				ResizeModifiers resizeModifier = GetResizeModifier(mouseState);
				PreviewShape.MoveControlPointTo(pointAtCursor, mouseState.X, mouseState.Y, resizeModifier);
			}
		}
Exemple #8
0
		private bool IsEditCaptionFeasible(IDiagramPresenter diagramPresenter, MouseState mouseState, ShapeAtCursorInfo shapeAtCursorInfo) {
			if (shapeAtCursorInfo.IsEmpty || mouseState.IsEmpty)
				return false;
			if (!diagramPresenter.Project.SecurityManager.IsGranted(Permission.ModifyData, shapeAtCursorInfo.Shape))
				return false;
			if (!shapeAtCursorInfo.IsCursorAtCaption)
				return false;
			if (mouseState.IsKeyPressed(KeysDg.Control) || mouseState.IsKeyPressed(KeysDg.Shift))
				return false;
			return true;
		}
Exemple #9
0
		private bool IsRotatatingFeasible(IDiagramPresenter diagramPresenter, ShapeAtCursorInfo shapeAtCursorInfo) {
			if (shapeAtCursorInfo.IsEmpty)
				return false;
			if (!diagramPresenter.Project.SecurityManager.IsGranted(Permission.Layout, diagramPresenter.SelectedShapes))
				return false;
			if (!shapeAtCursorInfo.Shape.HasControlPointCapability(shapeAtCursorInfo.ControlPointId, ControlPointCapabilities.Rotate))
				return false;
			if (diagramPresenter.SelectedShapes.Count > 1) {
				// check if all selected shapes have a rotate handle
				foreach (Shape selectedShape in diagramPresenter.SelectedShapes) {
					bool shapeHasRotateHandle = false;
					foreach (ControlPointId ptId in selectedShape.GetControlPointIds(ControlPointCapabilities.Rotate)) {
						shapeHasRotateHandle = true;
						break;
					}
					if (!shapeHasRotateHandle) return false;
				}
			}
			return true;
		}
Exemple #10
0
		/// <summary>
		/// Decide which tool action is suitable for the current mouse state.
		/// </summary>
		private Action DetermineMouseMoveAction(IDiagramPresenter diagramPresenter, MouseState mouseState, ShapeAtCursorInfo shapeAtCursorInfo) {
			switch (CurrentAction) {
				case Action.None:
				case Action.MoveHandle:
				case Action.MoveShape:
				case Action.SelectWithFrame:
					// Do not change the current action
					return CurrentAction;

				case Action.Select:
				case Action.EditCaption:
					if (mouseState.IsButtonDown(MouseButtonsDg.Left)) {
						// Check if cursor is over a control point and moving grips or rotating is feasible
						if (SelectedShapeAtCursorInfo.IsCursorAtGrip) {
							if (IsMoveHandleFeasible(diagramPresenter, SelectedShapeAtCursorInfo))
								return Action.MoveHandle;
							else if (IsRotatatingFeasible(diagramPresenter, SelectedShapeAtCursorInfo))
								return Action.PrepareRotate;
							else return Action.SelectWithFrame;
						} else {
							// If there is no shape under the cursor, start a SelectWithFrame action,
							// otherwise start a MoveShape action
							bool canMove = false;
							if (!SelectedShapeAtCursorInfo.IsEmpty) {
								// If there are selected shapes, check these shapes...
								canMove = IsMoveShapeFeasible(diagramPresenter, mouseState, SelectedShapeAtCursorInfo);
							} else {
								// ... otherwise check the shape under the cursor as it will be selected 
								// before starting a move action
								canMove = IsMoveShapeFeasible(diagramPresenter, mouseState, shapeAtCursorInfo);
							}
							if (canMove)
								return Action.MoveShape;
							else return Action.SelectWithFrame;
						}
					}
					return CurrentAction;

				case Action.PrepareRotate:
					if (mouseState.IsButtonDown(MouseButtonsDg.Left)) {
						// If the mouse has left the min rotate range, start 'real' rotating
						if (IsMinRotateRangeExceeded(diagramPresenter, mouseState))
							return Action.Rotate;
						else return CurrentAction;
					} else return CurrentAction;

				case Action.Rotate:
					if (mouseState.IsButtonDown(MouseButtonsDg.Left)) {
						// If the mouse has entered the min rotate range, start showing rotating hint
						if (!IsMinRotateRangeExceeded(diagramPresenter, mouseState))
							return Action.PrepareRotate;
						else return CurrentAction;
					} else return CurrentAction;

				default: throw new NShapeUnsupportedValueException(CurrentAction);
			}
		}