CDiagramEditor-derived project!??! Never did I realize the staggering amount of projects that could be created from a
CWnd-derived class allowing the user to shuffle some vector-graphics around...
The UMLEditor package is, perhaps not surprisingly, a UML-editor. It allows creation and editing of static diagrams, and can generate C++-code and HTML-pages from the diagrams. As a matter of fact, parts of the UMLEditor itself is generated by the UMLEditor.
This is not an article about UML. UML will have to be learned elsewhere, why not on CodeProject? See the Links section at the end of this article!
The editor contains drawing objects for classes, interfaces, packages, notes, lines, and labels.
Classes, interfaces, packages, and notes can be connected with multi-segment lines, with unlimited connection points on the objects. The connections can have the normal UML-styles, inheritance, dependency etc., although aggregation is not supported.
The diagrams can be loaded and saved, of course, but also exported to DHTML (not as pictures, but rather "pure" DHTML), C++-code (only the skeleton, of course), and EMF (enhanced metafiles, that can be included in - for example - Word). You can import class definitions from header-files.
The editor framework has the features of the parent project,
CDiagramEditor, that is, unlimited zoom, undo, copying and pasting between MDI-windows, support for print and print preview, and much more. The editor can be configured by setting colors, grid etc., and also derived from for more advanced overrides.
CUMLEditor itself is an example of an advanced override of
Adding it to your own app
The editor can be used in your own app, the same way as
CFlowchartEditor. It can be used in dialog-applications, and SDI- and MDI-applications. HTML and code generation is built in, so you get it "for free", together with export to EMF (enhanced metafiles). Basically, you just add a
CUMLEditor member object to either your view class or the class of the main dialog of your app. Add UI to draw objects, and then you have added an UML-editor to your application.
The downloadable documentation contains step-by-step instructions on this, together with a complete class reference, How-to's, and a slightly updated documentation on
As a matter of fact, the amount of code in this project makes it impossible to write a single article on the details of the implementation - if you want to do more than plug it into your own project, you'll need to have patience and some time, and will probably be best off tracing the source code of the project. I have made every effort, though, to make the use of the package as simple as possible, to allow you to plug in the editor and UML away!
Also included is a MDI-app, showing the capabilities of the editor, UMLEditorDemo. Use it, rip it apart, scrap it for parts.
I've thrown in another freebie as well - AutoDocumenter. AutoDocumenter will automatically create documentation for code created with UMLEditor. Parts of the AutoDocumenter were created with UMLEditor. The UMLEditor and DiagramEditor class references were created with the AutoDocumenter. The AutoDocumenter class reference was created by AutoDocumenter - although the class diagrams where - of course - created with UMLEditor. I'm beginning to feel like I'm in a P K Dick novel.
Points of interest
This is yet another implementation of links. This time, the links are derived from
CDiagramEntity - the basic drawing object in the editor. The main problem is to keep the integrity of the links, for example, when copying and pasting. As the links can't exist without being linked to something, and that drawing a segment, connecting it, drawing another segment, connecting it etc., would make for a very tedious process when creating diagrams, I had to go through some heavy convolutions in mouse-handling. This can be witnessed in
I also wanted the connection to be free, that is, a line should be possible to link anywhere on a class object side. This leads to some complicated coding to establish the minimum size of objects - I had to communicate back to the container to see if any line was connected to this object, and if so, at what offset. I don't like two-way communication. I could have used redundant info, setting link info in both the line segments and the attached objects, but the maintenance of twice the information was even less appetizing.
The HTML-generation was straightforward, except for the fact that Internet Explorer and Netscape realizes DHTML differently. In this case, I've at least gotten it to work on both browsers, even if I'm less than happy with the NS output. I did not want to write DHTML which adapts to the browser, so IE had to be norm.
The C++-generation... *brrrr* UML lacks selective virtual functions, so I had to add an application specific property for this, and clumsy code to see if a function must be made virtual. As it is, the generation code is spread out in an unhappy way, and one of the future improvements is to allow generation of code from plug-ins instead. Sadly, the information is not so easy to separate - there is information that is specific for a class, but stuff like virtual functions, base class names, dependencies etc., makes it necessary to have, at least, a "container wide" knowledge of the diagram.
Rest assured, this is not the last use you'll see of the
divs. *sigh* But as for the UMLEditor package, this is what I would like to add:
Multiple inheritance (also with interfaces).
- Instance variables.
Stereotypes for lines.
- Connections between lines.
- Automatic linking.
- Automatic linking from file (will that ever be difficult!).
- Alternative views of the diagram (that is, a tree view :-)).
- Separate the code- and HTML-generation to some kind of plug-in architecture.
- More diagram types.
I'm one person. The UML-editor contains an awful amount of code. Not only that, some of it is fairly complicated. Of course, it contains bugs. So, taking the two facts into consideration - me being one person, the code being big, I'm very happy for bug-reports. Don't feel ashamed, step forward, and help me make this an as bug-free package as is possible!
As the question comes up every once in a while, this package has the TISATAAFL-license. There Is Such A Thing As A Free Lunch. It means that you are completely free to use the code in any way you see fit, including derivative classes, applications, packages, whatever, without acknowledging me in any way. This includes commercial use.
More on the editor framework
28/6 2004 - Initial version.
It dances. It sings. It toasts bread, and walks your dog. Well, not yet, but it's a meaty update:
First of all, all the changes in
CDiagramEditor is moved to the UML-editor. This includes a Group object command, panning, and mouse wheel support (as well as some bug-corrections and other small modifications, see CDiagramEditor for details). A new feature has been added to
CDiagramEditor over and above these modifications, the possibility to set the scroll wheel mode. The scroll wheel mode decides the action to be taken when using the scroll wheel, either scrolling or zooming. Scrolling is the default, zooming is set in the UMLEditor.
Second, template classes are implemented. It is now possible to model and generate parameterized classes. They will be exported as well as imported.
Third, multiple inheritance will now be generated to C++-code.
Fourth, generation of interfaces are implemented. They will be generated as mixin-classes using MI.
First of all, the source code is updated as the diagram editor is updated.
There is also an addition to the C++-code generation mechanism - the inheritance line stereotypes are now used when declaring the access level of the base class. In brief, the base class will be protected or private if the appropriate stereotype is selected from the line dropdown combo.
- Added "Export only header files" support (ikolev).
- Setting package to the current one when pasting items from the internal clipboard (ikolev).
- Saving the destination directory between exports (ikolev).
- Added initialization list from class attributes to ctors. All operators having an initial value will have this value set in an initializer list in the ctor(s) generated. This is functionality that somehow got lost in the first release of the package.
- Bug: Corrected jog-drawing when zooming.
- Bug: Corrected line offset movements when zooming.
Far too early, here comes nevertheless a bug correction round. The slightly sparse-of-comments by Johnd1 is a major inspiration for the extended testing leading to this :-) Other attributions after the respective points. A big, fat thanks to you all for the feedback!
CUMLEditor - Corrected jog-drawing when scrolling.
CUMLEntityClass - Removed prefixing
ClassName:: in function names while importing a class from a h-file.
CUMLLineSegment - Not calling
CDiagramEntity::SetRect when setting rects, to keep non-normalization.
CDiagramEditor - Added check for non-normalized rect when hit-testing in
OnLButtonDown, as lines have them.
CDiagramEntity - Setting
NULL in the ctor (Marc G).
CTokenizer - Changed a
TCHAR to allow UNICODE builds (Enrico Detoma).
CDiagramEditor this project is ultimately based on is updated. I've not updated the source for this article, as there are no other changes. Please use the
CDiagramEditor source code - full article can be found here.