[Uml-devel] branches/work/soc-umbrello/umbrello

Gopala Krishna A krishna.ggk at gmail.com
Thu Jul 31 11:07:24 UTC 2008


SVN commit 840098 by gopala:

Implemented a somewhat hacky solution for showing lines inside
classifier widget. The technique is to use dummy TextItems with empty
text when there aren't visible Attributes or Operations.



 M  +72 -4     classifierwidget.cpp  
 M  +12 -2     classifierwidget.h  


--- branches/work/soc-umbrello/umbrello/classifierwidget.cpp #840097:840098
@@ -29,6 +29,7 @@
 #include "umlview.h"
 
 const qreal ClassifierWidget::CircleMinimumRadius = 30;
+const int ClassifierWidget::InvalidIndex = 99999;
 
 /**
  * Constructs a ClassifierWidget.
@@ -41,6 +42,10 @@
     createTextItemGroup(); // For classifier text items
     createTextItemGroup(); // For template text items'
 
+    // Null initially
+    m_dummyAttributeItem = m_dummyOperationItem = 0;
+    m_lineItem1Index = m_lineItem2Index = InvalidIndex;
+
     m_baseType = Uml::wt_Class;
     // Set the following properties by default. The remaining
     // properties are not set.
@@ -412,7 +417,7 @@
         // The elements not to be drawn will have null dimension and
         // hence it effectively is not drawn. (automatic ;) )
         painter->drawRect(m_classifierRect);
-        painter->drawLines(m_classifierLines);
+        painter->drawLines(m_classifierLines, 2);
 
         pen.setStyle(Qt::DotLine);
         painter->setPen(pen);
@@ -527,6 +532,7 @@
 
         QRectF groupRect(m, m_classifierRect.bottom() + m, w - 2 * m, fontHeight);
         classifierGroup->setGroupGeometry(groupRect);
+        m_classifierLines[0] = m_classifierLines[1] = QLineF();
     }
     else {
         // Utilize entire space if template box is empty.
@@ -536,11 +542,23 @@
         else {
             m_classifierRect.setTop(m_templateRect.bottom() - m);
             m_classifierRect.setLeft(0);
-            m_classifierRect.setBottomRight(QPointF(w, h));
+            m_classifierRect.setBottomRight(QPointF(m_templateRect.center().x(), h));
         }
 
         classifierGroup->setGroupGeometry(m_classifierRect.adjusted(+m, +m, -m, -m));
+        const int cnt = classifierGroup->textItemCount();
+        if (cnt > m_lineItem1Index) {
+            TextItem *item = classifierGroup->textItemAt(m_lineItem1Index);
+            qreal y = item->mapToParent(item->boundingRect().bottomLeft()).y();
+            m_classifierLines[0].setLine(m_classifierRect.left(), y, m_classifierRect.right(), y);
+        }
+        if (cnt > m_lineItem1Index) {
+            TextItem *item = classifierGroup->textItemAt(m_lineItem2Index);
+            qreal y = item->mapToParent(item->boundingRect().bottomLeft()).y();
+            m_classifierLines[1].setLine(m_classifierRect.left(), y, m_classifierRect.right(), y);
+        }
     }
+    classifierGroup->setHoverBrush(QBrush(Qt::blue, Qt::Dense6Pattern));
 }
 
 /**
@@ -550,6 +568,9 @@
  */
 void ClassifierWidget::updateTextItemGroups()
 {
+    // Invalidate stuff and recalculate them.
+    invalidateDummies();
+
     TextItemGroup *classifierGroup = textItemGroupAt(ClassifierGroupIndex);
     TextItemGroup *templateGroup = textItemGroupAt(TemplateGroupIndex);
     UMLClassifier *umlC = classifier();
@@ -589,10 +610,18 @@
     if (visualProperty(ShowPackage) == true) {
         nameText = umlC->getFullyQualifiedName();
     }
+
+    bool showNameOnly = (!visualProperty(ShowAttributes) && !visualProperty(ShowOperations)
+                         && !visualProperty(ShowStereotype) && !shouldDrawAsCircle());
     nameItem->setText(nameText);
+    if (!showNameOnly) {
+        m_lineItem1Index = NameItemIndex;
+    }
 
+    int attribStartIndex = NameItemIndex + 1;
+    int opStartIndex = attribStartIndex + attribList.size();
+
     // Now setup attribute texts.
-    int attribStartIndex = NameItemIndex + 1;
     for (int i=0; i < attribList.size(); ++i) {
         UMLClassifierListItem *obj = attribList[i];
 
@@ -608,8 +637,22 @@
 
         item->setVisible(v);
     }
+    const QString dummyText;
+    // Setup line and dummies.
+    if (!showNameOnly) {
+        // Stuff in a dummy item as spacer if there are no attributes,
+        if (attribList.isEmpty() || !visualProperty(ShowAttributes)) {
+            m_dummyAttributeItem = new TextItem(dummyText);
+            classifierGroup->insertTextItemAt(attribStartIndex, m_dummyAttributeItem);
+            m_lineItem2Index = attribStartIndex;
+            ++opStartIndex;
+        }
+        else {
+            // Now set the second index.
+            m_lineItem2Index = opStartIndex - 1;
+        }
+    }
 
-    int opStartIndex = attribStartIndex + attribList.size();
     for (int i=0; i < opList.size(); ++i) {
         UMLClassifierListItem *obj = opList[i];
 
@@ -626,6 +669,11 @@
         item->setVisible(v);
     }
 
+    if (!showNameOnly && opList.isEmpty()) {
+        m_dummyOperationItem = new TextItem(dummyText);
+        classifierGroup->insertTextItemAt(opStartIndex, m_dummyOperationItem);
+    }
+
     NewUMLRectWidget::updateTextItemGroups();
 }
 
@@ -744,3 +792,23 @@
         break;
     }
 }
+
+/**
+ * Invalidates all dummies used so that they can be recalculated again.
+ */
+void ClassifierWidget::invalidateDummies()
+{
+    TextItemGroup *grp = textItemGroupAt(ClassifierGroupIndex);
+    if (m_dummyAttributeItem) {
+        grp->deleteTextItem(m_dummyAttributeItem);
+        m_dummyAttributeItem = 0;
+    }
+
+    if (m_dummyOperationItem) {
+        grp->deleteTextItem(m_dummyOperationItem);
+        m_dummyOperationItem = 0;
+    }
+
+    m_lineItem1Index = m_lineItem2Index = InvalidIndex;
+    m_classifierLines[0] = m_classifierLines[1] = QLineF();
+}
--- branches/work/soc-umbrello/umbrello/classifierwidget.h #840097:840098
@@ -14,8 +14,9 @@
 
 #include "newumlrectwidget.h"
 
+class AssociationWidget;
+class TextItem;
 class UMLClassifier;
-class AssociationWidget;
 
 /**
  * @short Common implementation for class widget and interface widget
@@ -140,7 +141,16 @@
 
     QRectF m_classifierRect;
     QRectF m_templateRect;
-    QVector<QLineF> m_classifierLines;
+    QLineF m_classifierLines[2];
+
+    void invalidateDummies();
+
+    int m_lineItem1Index;
+    int m_lineItem2Index;
+    TextItem *m_dummyAttributeItem;
+    TextItem *m_dummyOperationItem;
+
+    static const int InvalidIndex;
 };
 
 Q_DECLARE_OPERATORS_FOR_FLAGS(ClassifierWidget::VisualProperties)




More information about the umbrello-devel mailing list