Basic Design (High level)
Here is how the graphicsview components map to their counterparts in Umbrello.

Infact most of the UMView features are moved to UMLScene with document-view model in mind. Also this means in future we can have split views quite easily as any number of Views can view a scene at a time.

XMI load/save
All the widgets should reimplement loadFromXMI and saveToXMI appropriately as the name indicates. The approach used is DOM style.
saveToXMI should be reimplemented by all widget even though the UMLWidget saves the common attributes. This is because UMLWidget::saveToXMI and UMLRectWidget::saveToXMI do not create a “new dom element”.
The newly created dom element can then be passed to base method to save info into it.
Menu/Dialog
Context menu dropping is implemented in UMLWidget::contextMenuEvent which pops out a ListPopupMenu. ListPopupMenu is a reimplemented from KMenu and it does all the heavy lifting of adding appropriate actions based on the widget/object/scene popping it. Also a virtual method – setupContextMenuActions is called so that derived widgets can add additional actions.
After the menu action is selected a virtual slot called slotMenuSelection(QAction *action) is called with the action selected as the parameter. Its ensured that the parent of action is a ListPopupMenu invoking that action. This is required in many situations, especially the action identifier mechanism is implemented in ListPopupMenu which is needed in the slot.
Geometry management
“Position handling” is already provided by QGraphicsItem::setPos. UMLRectWidget provides the other geometry handling features. UMLRectWidget has an inherent property called size and the geometry of widget is provided by rect with topleft at (0,0) and bottom right at (size.width(), size.height()).
The “size constraints” are handled by UMLRectWidget::setMinimumSize and UMLRectWidget::setMaximumSize. Infact these two methods also take an extra parameter called SizeHintOption which can be used to specify whether to add margin for the size being set or not. By default SizeHintOption value is DontAddMargin which does as the name tells.
UMLRectWidget::setSize ensures that these constraints are satisfied.
The “margin attribute” is stored in UMLRectWidget. The default margin value is 5 pixels. This ensures not every widget have to declare a constant for its margin and allow dynamic changing of margin.
UMLRectWidgets are free to set “resizable” property to true or false depending on whether it should display widget handle and allow resizing by using the handles.
WidgetHandle is a custom QGraphicsItem which displays 8 handles surrounding the UMLRectWidget::rect(). An appropriate mouse cursor is set when mouse hovers on one of the handles. The user can then click and drag any handle to resize. While resizing size hint constraints are respected.
UMLRectWidget::updateGeometry is an important virtual method. The default implementation ensures the current size repects size hint constraints and updates the widget painting. This has to be also called after modifying the constraints, after setting a new line width...
However it also doesn't cause much overhead to always calculate the size constraints in Widget::updateGeometry as it isn't called very often. The reimplemented method can then call base method to ensure constraints satisfaction. This is the convention currently used.
snapToGrid snaps the position to grid while snapSizeToGrid snaps even the size to grid. (yet to implement)
UMLObject interface
Most of the UMLWidgets are views of UMLObject. For example DataTypeWidget is a view of UMLClassifier. This is clear model-view separation which ensures data sharing and provides high flexibility.
Any UMLWidget can be set with a new UMLObject anytime by calling UMLWidget::setUMLObject. On calling this a umlObjectChanged notification(not signal) is sent for the derived classes to react.
Also a virtual slot – slotUMLObjectDataChanged is called on any changes to the UMLObject. The texts to be displayed are refreshed and displayed to reflect the change in object data using updateTextItemGroups()
For the widgets without UMLObject interface, WidgetInterfaceData stores the id, documentation and name. The interface data is automatically created in setUMLObject call if the object passed in is null.
Whenever setName, documentation() etc is called a check is made if there is associated UMLObject. If so the corresponding method of object is called. If not, these values are set/get from the interface data object.
WidgetAttributeChange
This is a notification mechanism which is conveyed through
QVariant attributeChange(WidgetAttributeChange change, const QVariant& oldValue)
method.
Subclasses can react to any of the notification by simply reimplementing this method. The new value can be fetched by the value's getter and the passed oldValue can be used if required say for example some computation.
Currently the return value is unused. Its used here because this is based on QGaphicsItem::itemChange and hence a similar signature is adopted for convenience. In future we may decide to use the return value.
The most commonly handled notification is SizeHasChanged where usually the TextItemGroups' geometry is set. More about this later.
Text Management
This is a newly done mechanism which encapsulates text displaying, font calculations, provides hovering mechanism.. and hence makes it easier to implement text handling in widgets.
The basic unit of text is a TextItem which inherits QGraphicsTextItem as of now. This provides us with rich set of features like highlighting specific parts of text, aligning the text, hovering support, font handling, linebreaking support and inplace text editing.
Another class called TextItemGroup encapsulates all the “TextItem” managerial task and makes it easier to treat the collection of TextItems as one. This class helps us to calculate the minimum size for the group, add/remove text items, margin handling, alignment, TextItems geometry management and many more.
The TextItemGroup::setGroupGeometry method nicely arranges the visible TextItems of the group with the geometry passed in. Thus the extra space can be neatly distributed.
UMLRectWidget has this TextItemGroup management support built into it and stores a list of groups handled by it.
UMLRectWidget::createTextItemGroup should be called in constructor of widget for the number of times as number of groups required. The following are the functionality of this method.
Creates a new TextItemGroup parented to the caller widget.
Applies the default properties with also taking hints from the widget.
Appends the group to its internal list and
Returns a pointer to it.
UMLRectWidget::textItemGroupAt(int) can be used to get a pointer to the group at index passed in and UMLRectWidget::indexOfTextItemGroup returns the index for the passed in group parameter.
TextItemGroup::textItemAt(int index) returns the TextItem present at the passed in index. It is important to note that the passed in index be valid. Otherwise it results in assert failure. So a runtime check for “toBeUsedIndex < TextItemGroup::textItemCount()” before usage is recommended when not sure.
UMLRectWidget::updateTextItemGroups() is an important virtual protected method.
This method is usally called in slotUMLObjectDataChanged slot and can be called elsewhere by the derived widgets whenever needed.
Subclasses using TextItemGroup should implement this
To create/delete the text items as needed. This is accomplished using TextItemGroup::setTextItemCount(int count) which inserts/deletes TextItems to attain the count passed in.
Hide/Show the TextItems based on the widget state. The idea is to create as many TextItems as needed and hide the unnessary items.
For example most of the widgets have a TextItem to display stereotype text which is usually hidden unless user shows it. In our case, we create this TextItem and hide/show it based on the m_showStereotype property of that widget.
Set appropriate “visible” text for all the TextItems using TextItem::setText.
Apply the appropriate attributes for all the TextItems . The attributes can be bold, italic, underline. Usually the other attributes like hover brush, alignment, font are all set only once in UMLRectWidget::createTextItemGroup call and are only set when some identicle property of widget like font changes.
Important: The bold, italic and underline should always be set using TextItem::setBold, TextItem::setItalic
and TextItem::setUnderline methods only. Setting a font with these attributes set won't affect the
actual property as TextItem::setFont retains boldness, italicity and underline property while
changing the font for convenience.
Finally call base method to reflect the changes done.
There are still more features and functionality (some yet to be implemented) to be featured in this document and help is appreciated :-)