private static void WriteShapes(XmlWriter writer, GraphAbstract g) { writer.WriteStartElement("g"); for (int k = 0; k < g.Shapes.Count; k++) //<rect x="1140" y="30" width="100" height="20" style="fill: url(#two_hues); stroke: black;"/> { writer.WriteStartElement("rect"); writer.WriteAttributeString("x", g.Shapes[k].X.ToString()); writer.WriteAttributeString("y", g.Shapes[k].Y.ToString()); writer.WriteAttributeString("width", g.Shapes[k].Width.ToString()); writer.WriteAttributeString("height", g.Shapes[k].Height.ToString()); writer.WriteAttributeString("rx", "2"); //rounded rectangle //writer.WriteAttributeString("style", "fill: url(#two_hues); stroke: black;"); writer.WriteAttributeString("fill", string.Concat("#", (g.Shapes[k].ShapeColor.ToArgb() & 0x00FFFFFF).ToString("X6"))); writer.WriteEndElement(); //<text text-anchor="middle" x="{$x+50}" y="{$y+15}"> writer.WriteStartElement("text"); writer.WriteAttributeString("x", Convert.ToString(g.Shapes[k].X + 10)); writer.WriteAttributeString("y", Convert.ToString(g.Shapes[k].Y + 15)); writer.WriteAttributeString("text-anchor", "start"); writer.WriteAttributeString("font-size", "9"); writer.WriteString(g.Shapes[k].Text); writer.WriteEndElement(); } writer.WriteEndElement(); }
private static void WriteShapes(XmlWriter writer, GraphAbstract g) { writer.WriteStartElement("g"); for(int k=0; k<g.Shapes.Count; k++) //<rect x="1140" y="30" width="100" height="20" style="fill: url(#two_hues); stroke: black;"/> { writer.WriteStartElement("rect"); writer.WriteAttributeString("x", g.Shapes[k].X.ToString()); writer.WriteAttributeString("y", g.Shapes[k].Y.ToString()); writer.WriteAttributeString("width", g.Shapes[k].Width.ToString()); writer.WriteAttributeString("height", g.Shapes[k].Height.ToString()); writer.WriteAttributeString("rx", "2");//rounded rectangle //writer.WriteAttributeString("style", "fill: url(#two_hues); stroke: black;"); writer.WriteAttributeString("fill", string.Concat("#", (g.Shapes[k].ShapeColor.ToArgb() & 0x00FFFFFF).ToString("X6")) ); writer.WriteEndElement(); //<text text-anchor="middle" x="{$x+50}" y="{$y+15}"> writer.WriteStartElement("text"); writer.WriteAttributeString("x", Convert.ToString(g.Shapes[k].X + 10)); writer.WriteAttributeString("y", Convert.ToString(g.Shapes[k].Y + 15)); writer.WriteAttributeString("text-anchor", "start"); writer.WriteAttributeString("font-size", "9"); writer.WriteString(g.Shapes[k].Text); writer.WriteEndElement(); } writer.WriteEndElement(); }
public void Serialize(XmlWriter writer, GraphAbstract g ) { GraphMLType graphml = new GraphMLType(); graphml.Key.Add(BuildKeyType(nodeShapeTypeKeyName)); graphml.Key.Add(BuildKeyType(edgeConnectionTypeKeyName)); GraphType graph = new GraphType(); graphml.Items.Add(graph); foreach ( Shape s in g.Shapes ) { graph.Items.Add(SerializeNode(s)); } foreach(Connection c in g.Connections) { graph.Items.Add(SerializeEdge(c)); } foreach(DictionaryEntry de in KeyList) { graphml.Key.Add(BuildKeyType((String)de.Key)); } // serialize XmlSerializer ser = new XmlSerializer(typeof(GraphMLType)); ser.Serialize(writer,graphml); }
protected BinaryCapsule(SerializationInfo info, StreamingContext context) { try { this.mBinaryAmbiance = info.GetValue("mBinaryAmbiance", typeof(BinaryAmbiance)) as BinaryAmbiance; } catch (Exception exc) { Trace.WriteLine(exc.Message, "BinaryCapsule.DeserializationConstructor"); //trying to recover the old binaries this.mBinaryAmbiance = info.GetValue("mBinaryAmbience", typeof(BinaryAmbiance)) as BinaryAmbiance; } this.mGraphAbstract = info.GetValue("mGraphAbstract", typeof(GraphAbstract)) as GraphAbstract; if (mGraphAbstract != null && mGraphAbstract.Layers != null) { foreach (GraphLayer tLayer in mGraphAbstract.Layers) { if (tLayer.Name != "Default" && tLayer.Visible) { mGraphAbstract.ActiveLayer(tLayer.Name); break; } } if (mGraphAbstract.CurrentLayer == null) { mGraphAbstract.ActiveLayer("Default"); } } this.mThumbnail = info.GetValue("mThumbnail", typeof(Image)) as Image; }
private static void WriteMetadata(XmlWriter writer, GraphAbstract g) { writer.WriteStartElement("title"); writer.WriteString(g.GraphInformation.Title); writer.WriteEndElement(); writer.WriteStartElement("desc"); writer.WriteString(g.GraphInformation.Description); writer.WriteEndElement(); }
public void LoadWork(GraphAbstract site, GraphControl graph) { for (int i = 0; i < this.mGraphList.Count; i++) { if (this.mGraphList[i] == site) { graph.Abstract = site; } } }
/// <summary> /// Serializes the given graph abstract to XML with the given XmlWriter /// </summary> /// <param name="writer"></param> /// <param name="g"></param> public static void Serialize(XmlWriter writer, GraphAbstract g) { writer.WriteStartElement("svg"); writer.WriteAttributeString("xmlns", "http://www.w3.org/2000/svg"); WriteDefinitions(writer); WriteFilters(writer); WriteMetadata(writer, g); WriteConnections(writer, g); WriteShapes(writer, g); writer.WriteEndElement(); }
/// <summary> /// Serializes the given graph abstract to XML with the given XmlWriter /// </summary> /// <param name="writer"></param> /// <param name="g"></param> public static void Serialize(XmlWriter writer, GraphAbstract g ) { writer.WriteStartElement("svg"); writer.WriteAttributeString("xmlns","http://www.w3.org/2000/svg"); WriteDefinitions(writer); WriteFilters(writer); WriteMetadata(writer, g); WriteConnections(writer, g); WriteShapes(writer, g); writer.WriteEndElement(); }
public DockContent CreateWorkForm(string Title, float width, float height, GraphAbstract site) { lastAdded = tabFactory.GetTab(new TabCodon("W" + GUIDTo16.GuidToLongID(), Title, TabTypes.WorkArea) { MapHeight = height, MapWidth = width }) as WorkForm; WorkForm work = lastAdded as WorkForm; work.GraphControl.Abstract = site; lastAdded.TabText = Title; lastAdded.Text = Title; OnShowTab(lastAdded); return(lastAdded); }
private void 粘贴视图ToolStripMenuItem1_Click(object sender, EventArgs e) { try { if (this.treeView.SelectedNode is FlowProjectNode) { GraphAbstract data = null; IDataObject dataObject = Clipboard.GetDataObject(); if (dataObject.GetDataPresent("Scada.FlowGraphEngine.GraphicsMap.GraphSite.Copy")) { data = dataObject.GetData("Scada.FlowGraphEngine.GraphicsMap.GraphSite.Copy") as GraphAbstract; } if (data != null) { FlowProjectNode selectedNode = this.treeView.SelectedNode as FlowProjectNode; CreateViewDialog dialog = new CreateViewDialog(); if (dialog.ShowDialog(this) == DialogResult.OK) { data.GID = "V_" + GUIDTo16.GuidToLongID(); SCADAViewNode node = new SCADAViewNode { Text = dialog.ViewName, ContextMenuStrip = this.contextMenuView, View = (WorkForm)this.mediator.CreateWorkForm(dialog.ViewName, (float)dialog.PageWidth, (float)dialog.PageHeight) }; node.View.GraphControl.Abstract = data; node.View.GraphControl.Abstract.Site = node.View.GraphControl; node.View.GraphControl.BasicLayer = data.Layers[0]; node.View.GraphControl.SaveViewResult = delegate(bool res, string msg) { if (res) { this.LoadTreeViewTemplate(); } else { MessageBox.Show(this, msg); } }; selectedNode.Nodes.Add(node); selectedNode.Project.GraphList.Add(node.View.GraphControl.Abstract); } Clipboard.Clear(); } } } catch (Exception exception1) { MessageBox.Show(exception1.Message); } }
public void LoadTempViewToProject(string tempFile) { FlowProjectNode selectedNode = null; if (this.treeView.SelectedNode != null) { if (this.treeView.SelectedNode is FlowProjectNode) { selectedNode = this.treeView.SelectedNode as FlowProjectNode; } else if (this.treeView.SelectedNode is SCADAViewNode) { selectedNode = this.treeView.SelectedNode.Parent as FlowProjectNode; } CreateViewDialog dialog = new CreateViewDialog(); if (dialog.ShowDialog(this) == DialogResult.OK) { SCADAViewNode node2 = new SCADAViewNode { Text = dialog.ViewName, ContextMenuStrip = this.contextMenuView, View = (WorkForm)this.mediator.CreateWorkForm(dialog.ViewName, (float)dialog.PageWidth, (float)dialog.PageHeight) }; GraphAbstract @abstract = node2.View.GraphControl.LoadView(tempFile); node2.View.GraphControl.Abstract.MapHeight = @abstract.MapHeight; node2.View.GraphControl.Abstract.MapWidth = @abstract.MapWidth; node2.View.GraphControl.Abstract.ViewTitle = dialog.ViewName; node2.View.GraphControl.Layers.Clear(); node2.View.GraphControl.AddLayer(@abstract.Layers[0]); node2.View.GraphControl.BasicLayer = @abstract.Layers[0]; for (int i = 0; i < @abstract.Shapes.Count; i++) { node2.View.GraphControl.AddShape(@abstract.Shapes[i], AddShapeType.Create, null, -1); } node2.View.GraphControl.SaveViewResult = delegate(bool res, string msg) { if (res) { this.LoadTreeViewTemplate(); } else { MessageBox.Show(this, msg); } }; node2.View.GraphControl.LoadViewResult = (res, msg) => MessageBox.Show(this, msg); selectedNode.Nodes.Add(node2); selectedNode.Project.GraphList.Add(node2.View.GraphControl.Abstract); } } }
/// <summary> /// Starts the serialization process. Takes the abstract of the graph and /// constructs a NMLType proxy-like object which will be serialized via the /// standard .Net XmlSerializer process. /// </summary> /// <param name="writer">An XmlWriter</param> /// <param name="g">The GraphAbstract object to be serialized</param> public void Serialize(XmlWriter writer, GraphAbstract g) { try { //the root of the NML NMLType nml = new NMLType(); //add the version node nml.Version = Assembly.GetExecutingAssembly().GetName().Version.ToString(); //the graph node GraphType graph = new GraphType(); nml.Graph = graph; //add the graph information graph.GraphInformation = new GraphInformationType(g.GraphInformation); //serialize the shapes foreach (Shape s in g.Shapes) { graph.Items.Add(SerializeNode(s)); } //serialize the connections foreach (Connection c in g.Connections) { graph.Items.Add(SerializeEdge(c)); } // foreach(DictionaryEntry de in keyList) // { // nml.Key.Add(BuildKeyType((String)de.Key)); // } // serialize XmlSerializer ser = new XmlSerializer(typeof(NMLType)); ser.Serialize(writer, nml); } catch (Exception exc) { site.OutputInfo(exc.Message, "NMLSerializer.Serialize", OutputInfoLevels.Exception); } catch { site.OutputInfo("Non-CLS exception caught.", "BinarySerializer.Serialize", OutputInfoLevels.Exception); } finally { } }
protected BinaryCapsule(SerializationInfo info, StreamingContext context) { try { this.mBinaryAmbiance = info.GetValue("mBinaryAmbiance", typeof(BinaryAmbiance)) as BinaryAmbiance; } catch(Exception exc) { Trace.WriteLine(exc.Message, "BinaryCapsule.DeserializationConstructor"); //trying to recover the old binaries this.mBinaryAmbiance = info.GetValue("mBinaryAmbience", typeof(BinaryAmbiance)) as BinaryAmbiance; } this.mGraphAbstract = info.GetValue("mGraphAbstract", typeof(GraphAbstract)) as GraphAbstract; this.mThumbnail = info.GetValue("mThumbnail", typeof(Image)) as Image; }
protected BinaryCapsule(SerializationInfo info, StreamingContext context) { try { this.mBinaryAmbiance = info.GetValue("mBinaryAmbiance", typeof(BinaryAmbiance)) as BinaryAmbiance; } catch (Exception exc) { Trace.WriteLine(exc.Message, "BinaryCapsule.DeserializationConstructor"); //trying to recover the old binaries this.mBinaryAmbiance = info.GetValue("mBinaryAmbience", typeof(BinaryAmbiance)) as BinaryAmbiance; } this.mGraphAbstract = info.GetValue("mGraphAbstract", typeof(GraphAbstract)) as GraphAbstract; this.mThumbnail = info.GetValue("mThumbnail", typeof(Image)) as Image; }
/// <summary> /// Returns the NML representation of the given GraphAbstract /// </summary> /// <returns></returns> public string Serialize() { try { GraphAbstract g = this.site.Abstract; System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding(); MemoryStream stream = new MemoryStream(); XmlTextWriter writer = new XmlTextWriter(stream, System.Text.ASCIIEncoding.ASCII); writer.Formatting = System.Xml.Formatting.Indented; this.Serialize(writer, g); //StringReader reader = new StringReader(); int count = 0; stream.Seek(0, SeekOrigin.Begin); byte[] byteArray = new byte[stream.Length]; while (count < stream.Length) { byteArray[count++] = Convert.ToByte(stream.ReadByte()); } // Decode the byte array into a char array // and write it to the console. char[] charArray = new char[asciiEncoding.GetCharCount(byteArray, 0, count)]; asciiEncoding.GetDecoder().GetChars(byteArray, 0, count, charArray, 0); string s = new string(charArray); writer.Close(); stream.Close(); return(s); } catch (Exception exc) { Trace.WriteLine(exc.Message, "NMLSerializer.Serialize"); return(string.Empty); } }
private static void WriteConnections(XmlWriter writer, GraphAbstract g) { /* * <line class="edge" x1="{$x1}" y1="{$y1}" x2="{$x}" y2="{$y+50}"> * <xsl:attribute name="style">marker-end:url(#arrow)</xsl:attribute> * </line> */ writer.WriteStartElement("g"); for (int k = 0; k < g.Connections.Count; k++) { writer.WriteStartElement("line"); writer.WriteAttributeString("x1", g.Connections[k].From.Location.X.ToString()); writer.WriteAttributeString("y1", g.Connections[k].From.Location.Y.ToString()); writer.WriteAttributeString("x2", g.Connections[k].To.Location.X.ToString()); writer.WriteAttributeString("y2", g.Connections[k].To.Location.Y.ToString()); //writer.WriteAttributeString("style", "fill: url(#two_hues); stroke: black;"); writer.WriteEndElement(); } writer.WriteEndElement(); }
private static void WriteConnections(XmlWriter writer, GraphAbstract g) { /* <line class="edge" x1="{$x1}" y1="{$y1}" x2="{$x}" y2="{$y+50}"> <xsl:attribute name="style">marker-end:url(#arrow)</xsl:attribute> </line> */ writer.WriteStartElement("g"); for(int k=0; k<g.Connections.Count; k++) { writer.WriteStartElement("line"); writer.WriteAttributeString("x1", g.Connections[k].From.Location.X.ToString()); writer.WriteAttributeString("y1", g.Connections[k].From.Location.Y.ToString()); writer.WriteAttributeString("x2", g.Connections[k].To.Location.X.ToString()); writer.WriteAttributeString("y2", g.Connections[k].To.Location.Y.ToString()); //writer.WriteAttributeString("style", "fill: url(#two_hues); stroke: black;"); writer.WriteEndElement(); } writer.WriteEndElement(); }
/// <summary> /// Default constructor /// </summary> /// <param name="extract"></param> /// <param name="discardFixed">whether to discard the ixed shapes in the analysis</param> public GraphAnalyzer(GraphAbstract extract, bool discardFixed) : base(extract.Shapes.Count) { this.extract = extract; shapeGluon = new Shape[extract.Shapes.Count]; connectionGluon = new Connection[extract.Shapes.Count, extract.Shapes.Count]; //we assign the index in the Shapes collection to the vertex int m = 0; foreach (Shape shape in extract.Shapes) { if (shape.IsFixed && discardFixed) { continue; } else { AddVertex(m); shapeGluon[m] = extract.Shapes[m]; extract.Shapes[m].Tag = m; m++; } } mCount = extract.Shapes.Count; int v, w; for (int k = 0; k < extract.Connections.Count; k++) { try { v = (int)extract.Connections[k].From.BelongsTo.Tag; w = (int)extract.Connections[k].To.BelongsTo.Tag; this.AddConnection(v, w); connectionGluon[v, w] = extract.Connections[k]; connectionGluon[w, v] = extract.Connections[k]; } catch { continue; } } }
/// <summary> /// Starts the serialization process. Takes the abstract of the graph and /// constructs a NMLType proxy-like object which will be serialized via the /// standard .Net XmlSerializer process. /// </summary> /// <param name="writer">An XmlWriter</param> /// <param name="g">The GraphAbstract object to be serialized</param> public void Serialize(XmlWriter writer, GraphAbstract g ) { try { //the root of the NML NMLType nml = new NMLType(); //add the version node nml.Version = Assembly.GetExecutingAssembly().GetName().Version.ToString(); //the graph node GraphType graph = new GraphType(); nml.Graph = graph; //add the graph information graph.GraphInformation = new GraphInformationType(g.GraphInformation); //serialize the shapes foreach ( Shape s in g.Shapes ) graph.Items.Add(SerializeNode(s)); //serialize the connections foreach(Connection c in g.Connections) graph.Items.Add(SerializeEdge(c)); // foreach(DictionaryEntry de in keyList) // { // nml.Key.Add(BuildKeyType((String)de.Key)); // } // serialize XmlSerializer ser = new XmlSerializer(typeof(NMLType)); ser.Serialize(writer,nml); } catch(Exception exc) { site.OutputInfo(exc.Message, "NMLSerializer.Serialize", OutputInfoLevels.Exception); } catch { site.OutputInfo("Non-CLS exception caught.", "BinarySerializer.Serialize", OutputInfoLevels.Exception); } finally { } }
/// <summary> /// Constructor /// </summary> /// <param name="graphAbstract"></param> /// <param name="ambiance"></param> public BinaryCapsule(GraphAbstract graphAbstract, BinaryAmbiance ambiance) { this.mGraphAbstract = graphAbstract; this.mBinaryAmbiance = ambiance; }
/// <summary> /// Opens the binary-saved diagram /// </summary> /// <param name="fileName"></param> /// <param name="site"></param> public static void Open(string fileName, GraphControl site) { FileStream fs = null; try { fs = File.OpenRead(fileName); } catch (System.IO.DirectoryNotFoundException exc) { System.Windows.Forms.MessageBox.Show(exc.Message); } catch (System.IO.FileLoadException exc) { System.Windows.Forms.MessageBox.Show(exc.Message); } catch (System.IO.FileNotFoundException exc) { System.Windows.Forms.MessageBox.Show(exc.Message); } catch { site.OutputInfo("Non-CLS exception caught.", "BinarySerializer.SaveAs", OutputInfoLevels.Exception); } //donnot open anything if filestream is not there if (fs == null) { return; } try { BinaryFormatter f = new BinaryFormatter(); //this added for temporarily solving the open file issue //of different namespace of customed shapes: SequenceShape, IfShape etc. //if save flowchart data file using one version, open with another version, //exception raised: "无法找到程序集..." //TODO: remove below statement for release version f.Binder = new UBinder(); BinaryCapsule capsule = (BinaryCapsule)f.Deserialize(fs); //so simple, so powerful GraphAbstract tmp = capsule.Abstract; SetControlAmbiance(site, capsule.Ambiance); tmp.Site = site; //site.extract = new GraphAbstract(); site.extract = tmp; //the paintables are not serialized and need to be filled site.extract.paintables.AddRange(site.extract.Shapes); site.extract.paintables.AddRange(site.extract.Connections); site.extract.SortPaintables(); UnwrapBundle(tmp, site); } catch (SerializationException exc) { System.Windows.Forms.MessageBox.Show(exc.Message); } catch (System.Reflection.TargetInvocationException exc) { site.OutputInfo(exc.Message, "BinarySerializer.Open", OutputInfoLevels.Exception); } catch (Exception exc) { site.OutputInfo(exc.Message, "BinarySerializer.Open", OutputInfoLevels.Exception); } catch { site.OutputInfo("Non-CLS exception caught.", "BinarySerializer.Open", OutputInfoLevels.Exception); } finally { if (fs != null) { fs.Close(); } } }
/// <summary> /// Opens the binary-saved diagram /// </summary> /// <param name="fileName"></param> /// <param name="site"></param> public static void Open(string fileName, GraphControl site) { FileStream fs = null; try { fs = File.OpenRead(fileName); } catch (System.IO.DirectoryNotFoundException exc) { System.Windows.Forms.MessageBox.Show(exc.Message); } catch (System.IO.FileLoadException exc) { System.Windows.Forms.MessageBox.Show(exc.Message); } catch (System.IO.FileNotFoundException exc) { System.Windows.Forms.MessageBox.Show(exc.Message); } catch { site.OutputInfo("Non-CLS exception caught.", "BinarySerializer.SaveAs", OutputInfoLevels.Exception); } //donnot open anything if filestream is not there if (fs == null) { return; } try { BinaryFormatter f = new BinaryFormatter(); BinaryCapsule capsule = (BinaryCapsule)f.Deserialize(fs); //so simple, so powerful GraphAbstract tmp = capsule.Abstract; SetControlAmbiance(site, capsule.Ambiance); tmp.Site = site; //site.extract = new GraphAbstract(); site.extract = tmp; //the paintables are not serialized and need to be filled site.extract.paintables.AddRange(site.extract.Shapes); site.extract.paintables.AddRange(site.extract.Connections); site.extract.SortPaintables(); UnwrapBundle(tmp, site); } catch (SerializationException exc) { System.Windows.Forms.MessageBox.Show(exc.Message); } catch (System.Reflection.TargetInvocationException exc) { site.OutputInfo(exc.Message, "BinarySerializer.Open", OutputInfoLevels.Exception); } catch (Exception exc) { site.OutputInfo(exc.Message, "BinarySerializer.Open", OutputInfoLevels.Exception); } catch { site.OutputInfo("Non-CLS exception caught.", "BinarySerializer.Open", OutputInfoLevels.Exception); } finally { if (fs != null) { fs.Close(); } } }
/// <summary> /// Deserializes the graphtype, here's where all the smart stuff happens /// </summary> /// <param name="gml">the graphtype which acts as an intermediate storage between XML and the GraphAbstract /// </param> /// <returns></returns> private GraphAbstract Deserialize(NMLType gml) { GraphAbstract abs = new GraphAbstract(); #region Load the graph information GraphType g = gml.Graph; abs.GraphInformation = g.GraphInformation.ToGraphInformation(); #endregion Shape shape = null; ShapeType node; DataType dt; ConnectorType ct; Connection con = null; ConnectionType et; string linePath = string.Empty; //see the split deserialization of the connection FromToCollection ftc = new FromToCollection(); //temporary store for from-to relations of connections Hashtable connectors = new Hashtable(); //temporary collection of connector #region Loop over all items for (int k = 0; k < g.Items.Count; k++) //loop over all serialized items { try { if (g.Items[k] is ShapeType) { Trace.WriteLine("Node: " + (g.Items[k] as ShapeType).UID, "NMLSerializer.Deserialize"); node = g.Items[k] as ShapeType; #region find out which type of shape needs to be instantiated if (node != null && node.InstanceKey != string.Empty) { shape = GetShape(node.InstanceKey); } if (shape == null) { Trace.WriteLine("...but failed to instantiate the appropriate shape (missing or not loaded library?", "NMLSerializer.Deserialize"); continue; } #endregion #region use the attribs again to reconstruct the props for (int m = 0; m < node.Data.Count; m++) //loop over the serialized data { if (node.Data[m] is DataType) { #region Handle data node dt = node.Data[m] as DataType; if (dt == null) { continue; } foreach (PropertyInfo pi in shape.GetType().GetProperties()) { if (Attribute.IsDefined(pi, typeof(GraphMLDataAttribute))) { try { if (pi.Name == dt.Name) { if (pi.GetIndexParameters().Length == 0) { if (pi.PropertyType.Equals(typeof(int))) { pi.SetValue(shape, Convert.ToInt32(dt.Value[0]), null); } else if (pi.PropertyType.Equals(typeof(Color))) //Color is stored as an integer { pi.SetValue(shape, Color.FromArgb(int.Parse(dt.Value[0].ToString())), null); } else if (pi.PropertyType.Equals(typeof(string))) { pi.SetValue(shape, (string)(dt.Value[0]), null); } else if (pi.PropertyType.Equals(typeof(bool))) { pi.SetValue(shape, Convert.ToBoolean(dt.Value[0]), null); } else if (pi.PropertyType.Equals(typeof(Guid))) { pi.SetValue(shape, new Guid((string)dt.Value[0]), null); } else if (pi.PropertyType.Equals(typeof(float))) { pi.SetValue(shape, Convert.ToSingle(dt.Value[0]), null); } else if (pi.PropertyType.BaseType.Equals(typeof(Enum))) //yesyes, you can imp/exp enum types too { pi.SetValue(shape, Enum.Parse(pi.PropertyType, dt.Value[0].ToString()), null); } else if (dt.IsCollection) { #region Some explanations /* OK, here's the deal. * This part is related to the possibility to imp/exp property-collections from/to NML. * However, since (see more specifically the ClassShape) the collections will usually be defined * where the shapes is defined, i.e. in an external assembly, the collection-type is unknown. * Importing/exporting collections to NML is itsel a problem and in this part of the code the data is reflected again. * To bypass the problem that the collection-type is unknown I hereby assume that the collection can be built up again via * a public constructor of the collection with argument 'ArrayList'. In the ArrayList the collection-elements are of type string[] * whereby the order of the strings reflect the order of the GraphMLData-tagged properties of the collection elements. * For example, the ClassPropertiesCollection has the required constructor and the ClassProperty object is instantiated via the string[] elements in the * ArrayList. * Of course, this brings some restriction but it's for the moment the most flexible way I have found. * If the ClassProperty would itself have a property inheriting from CollectionBase this will not work...one has to draw a line somewhere. * It's the price to pay for using reflection and external assemblies. The whole story can be forgotten if you link the shape-classes at compile-time. * Remember; the Netron graphlib is more a toolkit than a all-in solution to all situations. * However, the current implementation will cover, I beleive, 90% of the needs. */ #endregion ArrayList list = new ArrayList(); for (int p = 0; p < dt.Value.Count; p++) //loop over the collection elements { DataType dat = dt.Value[p] as DataType; //take a collection element if (dat.IsCollection) //is it itself a collection? { string[] str = new string[dat.Value.Count]; for (int l = 0; l < dat.Value.Count; l++) { if ((dat.Value[l] as DataType).Value.Count > 0) { str[l] = (string)(dat.Value[l] as DataType).Value[0]; } else { str[l] = string.Empty; } } list.Add(str); } else { list.Add(new string[] { (string)dat.Value[0] }); } } object o; o = pi.PropertyType.GetConstructor(new Type[] { typeof(ArrayList) }).Invoke(new Object[] { list }); pi.SetValue(shape, o, null); Trace.WriteLine("'" + dt.Name + "' is an array type", "NMLSeriliazer.Deserialize"); } } else { pi.SetValue(shape, dt.Value, null); } Trace.WriteLine("'" + dt.Name + "' deserialized.", "NMLSeriliazer.Deserialize"); break; } } catch (Exception exc) { Trace.WriteLine("Failed '" + dt.Name + "': " + exc.Message, "NMLSeriliazer.Deserialize"); continue; //just try to make the best out of it } } } #endregion } else if (node.Data[m] is ConnectorType) { #region Handle connector data ct = node.Data[m] as ConnectorType; foreach (Connector c in shape.Connectors) { if (c.Name == ct.Name) { c.UID = new Guid(ct.UID); break; } } #endregion } } #endregion //at this point the shape is fully deserialized //but we still need to assign the ambient properties, //i.e. the properties associated to the current hosting of the control if (shape != null) { shape.Site = site; shape.PostDeserialization(); shape.Font = site.Font; //shape.FitSize(false); abs.Shapes.Add(shape); //keep the references to the connectors, to be used when creating the connections foreach (Connector cor in shape.Connectors) { connectors.Add(cor.UID.ToString(), cor); } } } else if (g.Items[k] is ConnectionType) { #region handle the edge //we cannot create the connection here since not all shapes have been instantiated yet //keep the edges in temp collection, treated in next loop et = g.Items[k] as ConnectionType; con = new Connection(site); con.Font = site.Font; con.UID = new Guid(et.ID); Trace.WriteLine("Connection: " + et.ID, "NMLSeriliazer.Deserialize"); #region use the attribs to reconstruct the props for (int m = 0; m < et.Data.Count; m++) //loop over the serialized data { if (et.Data[m] is DataType) { #region Handle data node, same as the shape dt = et.Data[m] as DataType; if (dt == null) { continue; } foreach (PropertyInfo pi in con.GetType().GetProperties()) { if (Attribute.IsDefined(pi, typeof(GraphMLDataAttribute))) { try { if (pi.Name == dt.Name) { if (dt.Name == "LinePath") { //the LinePath will not work without non-null From and To, so set it afterwards linePath = dt.Value[0].ToString(); } else if (pi.GetIndexParameters().Length == 0) { if (pi.PropertyType.Equals(typeof(int))) { pi.SetValue(con, Convert.ToInt32(dt.Value[0]), null); } else if (pi.PropertyType.Equals(typeof(Color))) //Color is stored as an integer { pi.SetValue(con, Color.FromArgb(int.Parse(dt.Value[0].ToString())), null); } else if (pi.PropertyType.Equals(typeof(string))) { pi.SetValue(con, (string)(dt.Value[0]), null); } else if (pi.PropertyType.Equals(typeof(bool))) { pi.SetValue(con, Convert.ToBoolean(dt.Value[0]), null); } else if (pi.PropertyType.Equals(typeof(Guid))) { pi.SetValue(con, new Guid((string)dt.Value[0]), null); } else if (pi.PropertyType.Equals(typeof(float))) { pi.SetValue(con, Convert.ToSingle(dt.Value[0]), null); } else if (pi.PropertyType.Equals(typeof(ConnectionWeight))) { pi.SetValue(con, Enum.Parse(typeof(ConnectionWeight), dt.Value[0].ToString()), null); } } else { pi.SetValue(con, dt.Value, null); } Trace.WriteLine("'" + dt.Name + "' deserialized.", "NMLSeriliazer.Deserialize"); break; } } catch (Exception exc) { Trace.WriteLine("Failed '" + dt.Name + "': " + exc.Message, "NMLSeriliazer.Deserialize"); continue; //just try to make the best out of it } } } #endregion } } #endregion ftc.Add(new FromTo(et.Sourceport, et.Targetport, con)); #endregion } } catch (Exception exc) { Trace.WriteLine(exc.Message, "NMLSeriliazer.Deserialize"); continue; } } //loop over items in the graph-XML #endregion #region now for the edges; //loop over the FromTo collections and pick up the corresponding connectors for (int k = 0; k < ftc.Count; k++) { try { con = ftc[k].Connection; con.From = connectors[ftc[k].From] as Connector; con.To = connectors[ftc[k].To] as Connector; con.From.Connections.Add(con); //if From is null we'll fail in the catch and continue con.LinePath = linePath; //only setable after the From and To are found con.To.Connections.Add(con); abs.Insert(con); Trace.WriteLine("Connection '" + con.UID + "' added.", "NMLSeriliazer.Deserialize"); } catch (Exception exc) { Trace.WriteLine("Connection failed: " + exc.Message, "NMLSeriliazer.Deserialize"); continue; //make the best of it } } #endregion // for(int n=0; n<pcs.Count; n++) // { // from = pcs[n].ChildShape; // to = abs.Shapes[pcs[n].Parent]; // con = new Connection(from, to ); // abs.Connections.Add(con); // con.site = site; // if(pcs[n].ChildShape.visible) // con.visible = true; // from.connection = con; //a lot of crossing...to make life easy really // from.parentNode =to; // to.childNodes.Add(from); // // // } return(abs); }
/// <summary> /// Deserializes the graphtype, here's where all the smart stuff happens /// </summary> /// <param name="gml">the graphtype which acts as an intermediate storage between XML and the GraphAbstract /// </param> /// <returns></returns> private GraphAbstract Deserialize(NMLType gml) { GraphAbstract abs = new GraphAbstract(); #region Load the graph information GraphType g = gml.Graph; abs.GraphInformation = g.GraphInformation.ToGraphInformation(); #endregion Shape shape = null; ShapeType node; DataType dt; ConnectorType ct; Connection con = null; ConnectionType et; string linePath = string.Empty; //see the split deserialization of the connection FromToCollection ftc = new FromToCollection(); //temporary store for from-to relations of connections Hashtable connectors = new Hashtable(); //temporary collection of connector #region Loop over all items for(int k =0; k<g.Items.Count;k++) //loop over all serialized items { try { if(g.Items[k] is ShapeType) { Trace.WriteLine("Node: " + (g.Items[k] as ShapeType).UID,"NMLSerializer.Deserialize"); node = g.Items[k] as ShapeType; #region find out which type of shape needs to be instantiated if(node!=null && node.InstanceKey!=string.Empty) shape = GetShape(node.InstanceKey); if(shape==null) { Trace.WriteLine("...but failed to instantiate the appropriate shape (missing or not loaded library?", "NMLSerializer.Deserialize"); continue; } #endregion #region use the attribs again to reconstruct the props for(int m=0; m<node.Data.Count;m++) //loop over the serialized data { if(node.Data[m] is DataType) { #region Handle data node dt = node.Data[m] as DataType; if(dt==null) continue; foreach (PropertyInfo pi in shape.GetType().GetProperties()) { if (Attribute.IsDefined(pi, typeof(GraphMLDataAttribute))) { try { if(pi.Name==dt.Name) { if(pi.GetIndexParameters().Length==0) { if(pi.PropertyType.Equals(typeof(int))) pi.SetValue(shape,Convert.ToInt32(dt.Value[0]),null); else if(pi.PropertyType.Equals(typeof(Color))) //Color is stored as an integer pi.SetValue(shape,Color.FromArgb(int.Parse(dt.Value[0].ToString())),null); else if(pi.PropertyType.Equals(typeof(string))) pi.SetValue(shape,(string)(dt.Value[0]),null); else if(pi.PropertyType.Equals(typeof(bool))) pi.SetValue(shape,Convert.ToBoolean(dt.Value[0]),null); else if(pi.PropertyType.Equals(typeof(Guid))) pi.SetValue(shape,new Guid((string) dt.Value[0]),null); else if(pi.PropertyType.Equals(typeof(float))) pi.SetValue(shape, Convert.ToSingle(dt.Value[0]),null); else if(pi.PropertyType.BaseType.Equals(typeof(Enum)))//yesyes, you can imp/exp enum types too pi.SetValue(shape, Enum.Parse(pi.PropertyType,dt.Value[0].ToString()),null); else if(dt.IsCollection) { #region Some explanations /* OK, here's the deal. * This part is related to the possibility to imp/exp property-collections from/to NML. * However, since (see more specifically the ClassShape) the collections will usually be defined * where the shapes is defined, i.e. in an external assembly, the collection-type is unknown. * Importing/exporting collections to NML is itsel a problem and in this part of the code the data is reflected again. * To bypass the problem that the collection-type is unknown I hereby assume that the collection can be built up again via * a public constructor of the collection with argument 'ArrayList'. In the ArrayList the collection-elements are of type string[] * whereby the order of the strings reflect the order of the GraphMLData-tagged properties of the collection elements. * For example, the ClassPropertiesCollection has the required constructor and the ClassProperty object is instantiated via the string[] elements in the * ArrayList. * Of course, this brings some restriction but it's for the moment the most flexible way I have found. * If the ClassProperty would itself have a property inheriting from CollectionBase this will not work...one has to draw a line somewhere. * It's the price to pay for using reflection and external assemblies. The whole story can be forgotten if you link the shape-classes at compile-time. * Remember; the Netron graphlib is more a toolkit than a all-in solution to all situations. * However, the current implementation will cover, I beleive, 90% of the needs. */ #endregion ArrayList list = new ArrayList(); for(int p =0; p<dt.Value.Count; p++) //loop over the collection elements { DataType dat = dt.Value[p] as DataType; //take a collection element if(dat.IsCollection) //is it itself a collection? { string[] str = new string[dat.Value.Count]; for(int l=0;l<dat.Value.Count;l++) { if((dat.Value[l] as DataType).Value.Count>0) str[l] = (string) (dat.Value[l] as DataType).Value[0]; else str[l] = string.Empty; } list.Add(str); } else { list.Add(new string[]{(string) dat.Value[0]}); } } object o; o = pi.PropertyType.GetConstructor(new Type[]{typeof(ArrayList)}).Invoke(new Object[]{list}); pi.SetValue(shape,o,null); Trace.WriteLine("'" + dt.Name + "' is an array type","NMLSeriliazer.Deserialize"); } } else pi.SetValue(shape,dt.Value,null); Trace.WriteLine("'" + dt.Name + "' deserialized.","NMLSeriliazer.Deserialize"); break; } } catch(Exception exc) { Trace.WriteLine("Failed '" + dt.Name +"': " + exc.Message,"NMLSeriliazer.Deserialize"); continue;//just try to make the best out of it } } } #endregion } else if (node.Data[m] is ConnectorType) { #region Handle connector data ct = node.Data[m] as ConnectorType; foreach(Connector c in shape.Connectors) if(c.Name==ct.Name) { c.UID = new Guid(ct.UID); break; } #endregion } } #endregion //at this point the shape is fully deserialized //but we still need to assign the ambient properties, //i.e. the properties associated to the current hosting of the control if(shape !=null) { shape.Site = site; shape.PostDeserialization(); shape.Font = site.Font; //shape.FitSize(false); abs.Shapes.Add(shape); //keep the references to the connectors, to be used when creating the connections foreach(Connector cor in shape.Connectors) connectors.Add(cor.UID.ToString(),cor); } } else if(g.Items[k] is ConnectionType) { #region handle the edge //we cannot create the connection here since not all shapes have been instantiated yet //keep the edges in temp collection, treated in next loop et = g.Items[k] as ConnectionType; con = new Connection(site); con.Font = site.Font; con.UID = new Guid(et.ID); Trace.WriteLine("Connection: " + et.ID,"NMLSeriliazer.Deserialize"); #region use the attribs to reconstruct the props for(int m=0; m<et.Data.Count;m++) //loop over the serialized data { if(et.Data[m] is DataType) { #region Handle data node, same as the shape dt = et.Data[m] as DataType; if(dt==null) continue; foreach (PropertyInfo pi in con.GetType().GetProperties()) { if (Attribute.IsDefined(pi, typeof(GraphMLDataAttribute))) { try { if(pi.Name==dt.Name) { if(dt.Name=="LinePath") { //the LinePath will not work without non-null From and To, so set it afterwards linePath = dt.Value[0].ToString(); } else if(pi.GetIndexParameters().Length==0) { if(pi.PropertyType.Equals(typeof(int))) pi.SetValue(con,Convert.ToInt32(dt.Value[0]),null); else if(pi.PropertyType.Equals(typeof(Color))) //Color is stored as an integer pi.SetValue(con,Color.FromArgb(int.Parse(dt.Value[0].ToString())),null); else if(pi.PropertyType.Equals(typeof(string))) pi.SetValue(con,(string)(dt.Value[0]),null); else if(pi.PropertyType.Equals(typeof(bool))) pi.SetValue(con,Convert.ToBoolean(dt.Value[0]),null); else if(pi.PropertyType.Equals(typeof(Guid))) pi.SetValue(con,new Guid((string) dt.Value[0]),null); else if(pi.PropertyType.Equals(typeof(float))) pi.SetValue(con, Convert.ToSingle(dt.Value[0]),null); else if (pi.PropertyType.Equals(typeof(ConnectionWeight))) pi.SetValue(con, Enum.Parse(typeof(ConnectionWeight),dt.Value[0].ToString()),null); else if (pi.PropertyType.Equals(typeof(System.Drawing.Drawing2D.DashStyle))) pi.SetValue(con, Enum.Parse(typeof(System.Drawing.Drawing2D.DashStyle),dt.Value[0].ToString()),null); } else pi.SetValue(con,dt.Value,null); Trace.WriteLine("'" + dt.Name + "' deserialized.","NMLSeriliazer.Deserialize"); break; } } catch(Exception exc) { Trace.WriteLine("Failed '" + dt.Name +"': " + exc.Message,"NMLSeriliazer.Deserialize"); continue;//just try to make the best out of it } } } #endregion } } #endregion ftc.Add(new FromTo(et.Sourceport,et.Targetport, con)); #endregion } } catch(Exception exc) { Trace.WriteLine(exc.Message,"NMLSeriliazer.Deserialize"); continue; } }//loop over items in the graph-XML #endregion #region now for the edges; //loop over the FromTo collections and pick up the corresponding connectors for(int k=0; k<ftc.Count; k++) { try { con = ftc[k].Connection; con.From = connectors[ftc[k].From] as Connector; con.To = connectors[ftc[k].To] as Connector; con.From.Connections.Add(con);//if From is null we'll fail in the catch and continue con.LinePath = linePath; //only setable after the From and To are found con.To.Connections.Add(con); abs.Insert(con); Trace.WriteLine("Connection '" + con.UID + "' added.","NMLSeriliazer.Deserialize"); } catch(Exception exc) { Trace.WriteLine("Connection failed: " + exc.Message,"NMLSeriliazer.Deserialize"); continue; //make the best of it } } #endregion // for(int n=0; n<pcs.Count; n++) // { // from = pcs[n].ChildShape; // to = abs.Shapes[pcs[n].Parent]; // con = new Connection(from, to ); // abs.Connections.Add(con); // con.site = site; // if(pcs[n].ChildShape.visible) // con.visible = true; // from.connection = con; //a lot of crossing...to make life easy really // from.parentNode =to; // to.childNodes.Add(from); // // // } return abs; }