I need a Load/Save as part of GoDiagram

It is far too difficult to load and save GoDocuments

At the moment i have to do so much work jsut to load save such a tiny subset of funtionality - people are crying out for collapsable sub graphs and i have no idea how i can load and save that sort of thing :¬(
I would realy appreciate a built in Load/Save solution, many vendors of .net components supply these as LoadAsXml etc (infragistics,Divelements etc)
Surely as you have written these components it would be far easier for you to create a generic load save soltuion for GoDocument.
I appreciate its hard but you would be much better suited to this than me.
But i must end on a good note - we all love these components and they have made our program so much more usable and creative - so many thanks :¬)
P.S. we have to use C++ here and it just got worse when MS rewrote C++ again to suit themselves in VS2005 leaving us in compatibility mode :¬(

Two major questions with implementing persistence are deciding what the format is and what the contents should be.
If you don’t care about format (i.e. some XML schema that someone else has defined, or maybe no defined schema at all), that makes it easier.
But the issue of what to save is still a serious one. That also relates to compatibility with future versions, for .NET, for GoDiagram, and for your own classes.
If you don’t care about those issues, you can just use the built-in serialization that .NET provides. This involves System.Runtime.Serialization and System.Runtime.Serialization.Formatters.Soap.
example store:
Stream ofile = File.Open(“test.graph”, FileMode.Create);
IFormatter oformatter = new SoapFormatter();
oformatter.Serialize(ofile, goView1.Document);
ofile.Close();
example load:
Stream ifile = File.Open(“test.graph”, FileMode.Open);
IFormatter iformatter = new SoapFormatter();
GoDocument doc = iformatter.Deserialize(ifile) as GoDocument;
ifile.Close();
goView1.Document = doc;
However, our official position is still to recommend against the use of SoapFormatter (or BinaryFormatter) because of future versioning problems. It’s best to define exactly what you want saved and what you don’t want saved. That would also be much more efficient in time and space.
Why shouldn’t you use a generic .NET or potential GoDiagram XML schema? Imagine that you have implemented an application where users save their diagrams as files in this format. Say it includes all the serializable objects and their data.
Then imagine you introduce a new version of your application that has lots of new visual features. Maybe you have new icons and new pens and brushes and new objects as decorations on some nodes. Maybe you have reorganized some of the information you are displaying in your diagram, perhaps removing some and adding some.
Then what happens when the user opens his old diagram in the new application? Is the user going to see old-looking nodes and links with obsolete information and without the new information that would be expected in the new application? Is your code going to break because suddenly some GoObjects are no longer present in the nodes, or have been moved around? I can tell you from my experience that this situation is a mess that I would desparately want to avoid.
Instead, if you had written out only the application-specific semantically-needed information in the file, you would have complete freedom to display it in any manner you desired. You could even have multiple ways of displaying that information simultaneously.
For example, say you implement your application to display tree-like data in the manner that TreeApp does. But then you want to change your application to make use of GoSubGraphs instead of independent top-level nodes – i.e. nesting. (Or maybe your application started off with GoSubGraphs and now wants something different.)
If you store your data in as presentation-independent way as possible, you would have much more freedom in your application appearance, behavior, and implementation. The data would probably be a lot smaller and simpler too!

Thank you for a very good reply :¬)

I do not want to go anywhere near SoapFormatter and i have implemented a XML solution using this type of thing

int GoDiagram_Save(IO::Stream *file,GoDocument *doc,ImageList *imageList)
{
XmlTextWriter *writer=new XmlTextWriter(file,0);
writer->Formatting=Formatting::Indented;
writer->WriteStartElement(“Graph”);
writer->WriteAttributeString(“Version”,“1.0.0.0”);
writer->WriteAttributeString(“LastPartID”,XmlConvert::ToString(doc->LastPartID));
writer->WriteAttributeString(“Name”,doc->Name);
GoLayerCollectionObjectEnumerator thePain=doc->GetEnumerator();
GoLayerCollectionObjectEnumerator *theChildren=&thePain; theChildren->Reset();
while(theChildren->MoveNext()){
GoTextNode *n=NULL;
try{n=__try_cast<GoTextNode *>(theChildren->Current);}
catch(System::InvalidCastException *){continue;}
if(n==NULL)continue;
if(n->GetType()!=__typeof(GoTextNode))continue;
writer->WriteStartElement(“GoTextNode”);
writer->WriteAttributeString(“Pid”,XmlConvert::ToString(n->PartID));
writer->WriteAttributeString(“Text”,n->Text);
writer->WriteAttributeString(“Color” ,XmlConvert::ToString(n->Label->BackgroundColor.ToArgb ()));
writer->WriteAttributeString(“Color2”,XmlConvert::ToString(n->Label->TextColor.ToArgb()));
if(n->TopPort!=NULL)writer->WriteAttributeString(“PidTop”,XmlConvert::ToString(n->TopPort->PartID));
if(n->BottomPort!=NULL)writer->WriteAttributeString(“PidBottom”,XmlConvert::ToString(n->BottomPort->PartID));
if(n->LeftPort!=NULL)writer->WriteAttributeString(“PidLeft”,XmlConvert::ToString(n->LeftPort->PartID));
if(n->RightPort!=NULL)writer->WriteAttributeString(“PidRight”,XmlConvert::ToString(n->RightPort->PartID));
writer->WriteAttributeString(“X”,XmlConvert::ToString(n->Left));
writer->WriteAttributeString(“Y”,XmlConvert::ToString(n->Top));
writer->WriteAttributeString(“Width”,XmlConvert::ToString(n->Width));
writer->WriteAttributeString(“Height”,XmlConvert::ToString(n->Height));
if(n->UserFlags!=NULL)writer->WriteAttributeString(“UserFlags”,XmlConvert::ToString(n->UserFlags));
if(n->UserObject!=NULL)writer->WriteAttributeString(“UserObject”,dynamic_cast<String *>(n->UserObject));
writer->WriteEndElement();
}
}

I save all my etxt nodes then all my links and then all my balloons etc etc etc

Its a pain to do in C++ and I am stuck i dont know how to implement collapable sub graphs using this method :¬(

I Still cant see why you cant make a generic Xml sav member function for GoDocument i.e.
goDocument1->SaveAsXml(“mygraph.graph”);

you could handle all the versioning problems like i have to in my code snipet above

Sorry if i didnt understand why you cant supply us with this
I am probaly not a good enough programmer to understand :¬(

Well, have you considered using GoXml? That’s a solution that greatly simplifies implementing the persistence process when using XML. But it does require some time to learn. There are several demonstration uses of GoXml in the samples. The GraphML one is probably more complicated than you need, since it heeds the GraphML “standard”, but it does handle GoSubGraph.

Many thanks i forgot about GoXml :¬(
Ill give it a go
have a nice weekend

It looks like my program will not be able to use subgraphs etc
I had a good look at GraphML.cs and saddly i cant convert all that to C++ it just wont work in the end
ill will sit here and cry instead.
Would you consider embeding something like graphMl.cs as a callable member function like i suggested ?
goDocument1->SaveAsXml(“myfile.name”);

OK, try XmlSubGraphTextNode.cs in the latest Demo1 sample.

You’ll need to adapt this for your application, since you may have subclassed GoTextNode, GoSubGraph and GoLabeledLink. I don’t even know if you are using GoLabeledLink or GoLink. So if you specify the GoXmlTransformer.TransformerType correctly, you might not need the overrides of GoXmlTransformer.Allocate() that I included.

And I don't know what properties you want to store/load. I did include a few just for the fun of it.

This code also assumes that nodes are always generated before links, so there isn't any worry about resolving references when loading. That's true recursively for subgraphs, of course.

The only nesting of XML elements is for subgraphs: i.e. you don't need separate elements for ports as parts of nodes.

Anyway, I hope you can see that the code is pretty straight-forward. Complexities usually come about because the schema you use requires references to things that haven't been defined yet, or because the XML has a lot of structural depth to it.

Thank you for taking the time to do this for me I realy appreciate it

I only use GoLabeledLink, GoTextNode, GoBalloon and GoComment
and i run away from subclassing anything if i can get away with it.

I only store colors text and userflags and userobject which is a String
The users when designing the workflows tend to put the links in when ever they want not all right at the end of the design phase :¬(

I will convert to C++ and try it out this week :¬)
Many thanks walter sorry for being a pest