/// <summary> /// Invoked after a cell has been added to a parent. This recursively /// creates an Id for the new cell and/or resolves Id collisions. /// </summary> /// <param name="cell">Cell that has been added.</param> protected void CellAdded(Object cell) { if (cell is mxICell) { mxICell mxc = (mxICell)cell; if (mxc.Id == null && IsCreateIds) { mxc.Id = CreateId(cell); } if (mxc.Id != null) { Object collision = GetCell(mxc.Id); if (collision != cell) { while (collision != null) { mxc.Id = CreateId(cell); collision = GetCell(mxc.Id); } if (cells == null) { cells = new Dictionary <Object, Object>(); } cells[mxc.Id] = cell; } } // Makes sure IDs of deleted cells are not reused try { int id = Convert.ToInt32(mxc.Id); nextId = Math.Max(nextId, id + 1); } catch (FormatException e) { Trace.WriteLine(this + ".CellAdded(" + cell + "): " + e.Message); } int childCount = mxc.ChildCount(); for (int i = 0; i < childCount; i++) { CellAdded(mxc.GetChildAt(i)); } } }
/// <summary> /// Encoding of cell hierarchies is built-into the core, but is a /// higher-level function that needs to be explicitely used by the /// respective object encoders (eg. mxModelCodec, mxChildChangeCodec /// and mxRootChangeCodec). This implementation writes the given cell /// and its children as a (flat) sequence into the given node. The /// children are not encoded if the optional includeChildren is false. /// The function is in charge of adding the result into the given node /// and has no return value. /// </summary> /// <param name="cell">mxCell to be encoded.</param> /// <param name="node">Parent XML node to add the encoded cell into.</param> /// <param name="includeChildren">Boolean indicating if the method should /// include all descendents</param> public void EncodeCell(mxICell cell, XmlNode node, bool includeChildren) { node.AppendChild(Encode(cell)); if (includeChildren) { int childCount = cell.ChildCount(); for (int i = 0; i < childCount; i++) { EncodeCell(cell.GetChildAt(i), node, includeChildren); } } }
/// <summary> /// Invoked after a cell has been removed from the model. This recursively /// removes the cell from its terminals and removes the mapping from the Id /// to the cell. /// </summary> /// <param name="cell">Cell that has been removed.</param> protected void CellRemoved(Object cell) { if (cell is mxICell) { mxICell mxc = (mxICell)cell; int childCount = mxc.ChildCount(); for (int i = 0; i < childCount; i++) { CellRemoved(mxc.GetChildAt(i)); } mxc.RemoveFromTerminal(true); mxc.RemoveFromTerminal(false); if (cells != null && mxc.Id != null) { cells.Remove(mxc.Id); } } }
/// <summary> /// Clones the children of the source cell into the given target cell in /// this model and adds an entry to the mapping that maps from the source /// cell to the target cell with the same id or the clone of the source cell /// that was inserted into this model. /// </summary> /// <param name="from"></param> /// <param name="to"></param> /// <param name="cloneAllEdges"></param> /// <param name="mapping"></param> protected void MergeChildrenImpl(mxICell from, mxICell to, bool cloneAllEdges, Dictionary <Object, Object> mapping) { BeginUpdate(); try { int childCount = from.ChildCount(); for (int i = 0; i < childCount; i++) { mxICell cell = from.GetChildAt(i); String id = cell.Id; mxICell target = (mxICell)((id != null && (!IsEdge(cell) || !cloneAllEdges)) ? GetCell(id) : null); // Clones and adds the child if no cell exists for the id if (target == null) { mxCell clone = (mxCell)cell.Clone(); clone.Id = id; // Do *NOT* use model.add as this will move the edge away // from the parent in updateEdgeParent if maintainEdgeParent // is enabled in the target model target = to.Insert(clone); CellAdded(target); } // Stores the mapping for later reconnecting edges mapping[cell] = target; // Recurses MergeChildrenImpl(cell, target, cloneAllEdges, mapping); } } finally { EndUpdate(); } }
/// <summary> /// Encoding of cell hierarchies is built-into the core, but is a /// higher-level function that needs to be explicitely used by the /// respective object encoders (eg. mxModelCodec, mxChildChangeCodec /// and mxRootChangeCodec). This implementation writes the given cell /// and its children as a (flat) sequence into the given node. The /// children are not encoded if the optional includeChildren is false. /// The function is in charge of adding the result into the given node /// and has no return value. /// </summary> /// <param name="cell">mxCell to be encoded.</param> /// <param name="node">Parent XML node to add the encoded cell into.</param> /// <param name="includeChildren">Boolean indicating if the method should /// include all descendents</param> public void EncodeCell(mxICell cell, XmlNode node, bool includeChildren) { node.AppendChild(Encode(cell)); if (includeChildren) { int childCount = cell.ChildCount(); for (int i = 0; i < childCount; i++) { EncodeCell(cell.GetChildAt(i), node, includeChildren); } } }
/// <summary> /// Clones the children of the source cell into the given target cell in /// this model and adds an entry to the mapping that maps from the source /// cell to the target cell with the same id or the clone of the source cell /// that was inserted into this model. /// </summary> /// <param name="from"></param> /// <param name="to"></param> /// <param name="cloneAllEdges"></param> /// <param name="mapping"></param> protected void MergeChildrenImpl(mxICell from, mxICell to, bool cloneAllEdges, Dictionary<Object, Object> mapping) { BeginUpdate(); try { int childCount = from.ChildCount(); for (int i = 0; i < childCount; i++) { mxICell cell = from.GetChildAt(i); String id = cell.Id; mxICell target = (mxICell) ((id != null && (!IsEdge(cell) || !cloneAllEdges)) ? GetCell(id) : null); // Clones and adds the child if no cell exists for the id if (target == null) { mxCell clone = (mxCell) cell.Clone(); clone.Id = id; // Do *NOT* use model.add as this will move the edge away // from the parent in updateEdgeParent if maintainEdgeParent // is enabled in the target model target = to.Insert(clone); CellAdded(target); } // Stores the mapping for later reconnecting edges mapping[cell] = target; // Recurses MergeChildrenImpl(cell, target, cloneAllEdges, mapping); } } finally { EndUpdate(); } }