3.6. Features

I have added several new features to Umbrello since I took over control of the programme.

3.6.1. Canvas Zoom and Resize

Zoom and resize ability for the diagram canvas was a much requested feature. The fixed size canvas that Umbrello had was a severe limitation for creating diagrams of any substantial size. Being able to zoom in and out is important for users to be able to get an overview of their diagram. I was therefore not surprised when these two features were the first to be submitted after the end of the feature freeze for the 1.1 version. The patch used affine matrix transformations for zoom. Using the patch as a starting point I gave the code the ability to save to and load from the file and removed the need for the user to manually resize the canvas by automatically resizing it as needed after anything was moved. The affine matrix transformations caused some problems with the placing of new widgets and right click menus, the positioning for these had to be changed to go through the matrices as well. Toolbar buttons and Properties dialogue widgets were added. This update has been one of the main reasons why people use the unreleased version of Umbrello over the released version.

3.6.2. Undo and Redo

When I was first designing the undo and redo code I thought it would require a mechanism to save and reload every possible change to the user's model and diagrams. This seemed like a nightmare to implement until I realised it would be possible to just save the whole model using the same code used to save it to the file. This required some changes to the save and load code to allow it to work on arbitrary buffers, not just files. Any changes to the model are saved to an undo stack. When the undo function is called, the top item is loaded from the stack and the current model is saved to the redo function. The undo and redo stacks have limits on them to prevent them taking up excessive amount of memory. Loading a whole model afresh on each undo or redo does cause some flickering as the old model is discarded and the new one loaded, I would like to work on the loading mechanism to cause a smoother redraw but this is currently a low priority.

3.6.3. Parameterised Classes

A parameterised class is a fancy name for what C++ calls a template class. I had been getting calls to allow this ability for classes as it is useful for data structures. When it was announced that Java 1.5 would have them added to the language[java-generics] I received even more requests for the feature. Technically templates are a lot like attributes and operations, they are all components of classes. I implemented them by essentially copying the code for attributes and adapting it to the requirements of templates. The amount of duplicated code convinced me that I needed to refactor attributes, operations and templates to make them share much more of their code.

3.6.4. Interfaces

Interfaces are essentially abstract classes (which means their methods are not implemented) without any attributes. In UML they can be drawn either as boxes, in the same way as classes, or as circles. Implementing interfaces required a lot of copying and duplicating existing code from the classes code, in the same way as templates copied code from attributes. While the interfaces code worked perfectly I was unhappy with the amount of duplicated code and made it a priority to refactor this area.

3.6.5. Component Diagrams and Deployment Diagrams

As a UML programme I felt it important that Umbrello implemented as much of UML as possible. The two diagram types specified by UML and missing from Umbrello were component diagrams and deployment diagrams. Implementing these required new widgets - components and nodes - and adding new items to the tree view. I broke the file format when adding to the list view. It is saved out with the rest of the data and the enumerations used to identify the type of each tree view item have to be carefully edited to prevent old documents loading tree view items as incorrect types.

3.6.6. Cut and Delete Selected

One of the most obvious missing features was cut. The programme had a (buggy) copy and paste feature but no ability to cut. Cut is simply a combination of copy followed by deleting the selection. Unfortunately there was no delete function either so I had to define this too as a Qt slot method which iterated over the list of selected widgets deleting each one. Because of the different copy types (widgets, tree list view objects) the cut method had to detect the correct items to delete. The cut method is a good example of how breaking up a function can result in reusable code for other functions.