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

Gopala Krishna A krishna.ggk at gmail.com
Fri Jul 25 19:30:07 UTC 2008


SVN commit 837819 by gopala:

Ported NodeWidget using textitems.



 M  +119 -100  nodewidget.cpp  
 M  +26 -30    nodewidget.h  
 M  +2 -2      widget_factory.cpp  


--- branches/work/soc-umbrello/umbrello/nodewidget.cpp #837818:837819
@@ -12,130 +12,149 @@
 // own header
 #include "nodewidget.h"
 
-// qt/kde includes
-#include <qpainter.h>
-#include <kdebug.h>
-
 // app includes
 #include "node.h"
-#include "uml.h"
-#include "umldoc.h"
-#include "umlview.h"
-#include "umlscene.h"
-#include <QPolygon>
+#include "textitem.h"
+#include "textitemgroup.h"
 
+// qt/kde includes
+#include <QtGui/QPolygonF>
+
 const qreal NodeWidget::DEPTH = 30;  ///< pixels on Z axis
 
-NodeWidget::NodeWidget(UMLScene * view, UMLNode *n )
-  : NewUMLRectWidget(view, n) {
-    NewUMLRectWidget::setBaseType(Uml::wt_Node);
-    setZ(m_origZ = 1);  // above box but below NewUMLRectWidget because may embed widgets
-    setSize(100, 30);
-    if (n && !UMLApp::app()->getDocument()->loading())
-        updateComponentSize();
+/**
+ * Constructs a NodeWidget.
+ *
+ * @param n The UMLNode this will be representing.
+ */
+NodeWidget::NodeWidget(UMLNode *n )
+	: NewUMLRectWidget(n)
+{
+    m_baseType = Uml::wt_Node;
+	createTextItemGroup();
+	// above box but below NewUMLRectWidget because may embed widgets
+    setZValue(1);
 }
 
-NodeWidget::~NodeWidget() {}
+/// Destructor
+NodeWidget::~NodeWidget()
+{
+}
 
+/**
+ * Reimplemented from NewUMLRectWidget::paint to draw node widget
+ * drawing stored in the painter path.
+ */
 void NodeWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *o, QWidget *)
 {
-	QPainter &p = *painter;
-	qreal offsetX = 0, offsetY = 0;
+	painter->setPen(QPen(lineColor(), lineWidth()));
+	painter->setBrush(brush());
+	painter->drawPath(m_nodeWidgetPath);
+}
 
-    setPenFromSettings(p);
-    if ( NewUMLRectWidget::getUseFillColour() ) {
-        p.setBrush( NewUMLRectWidget::getFillColour() );
-    } else {
-        // [PORT]
-        // p.setBrush( umlScene()->viewport()->palette().color(QPalette::Background) );
-    }
-    const qreal w = getWidth();
-    const qreal h = getHeight();
-    const qreal wDepth = (w/3 > DEPTH ? DEPTH : w/3);
-    const qreal hDepth = (h/3 > DEPTH ? DEPTH : h/3);
-    const qreal bodyOffsetY = offsetY + hDepth;
-    const qreal bodyWidth = w - wDepth;
-    const qreal bodyHeight = h - hDepth;
-    QFont font = NewUMLRectWidget::getFont();
-    font.setBold(true);
-    const QFontMetrics &fm = getFontMetrics(FT_BOLD);
-    const qreal fontHeight  = fm.lineSpacing();
-    QString name = getName();
+/**
+ * Reimplemented form NewUMLRectWidget::saveToXMI to save this widget
+ * info into 'nodewidget' xmi element.
+ */
+void NodeWidget::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
+{
+    QDomElement conceptElement = qDoc.createElement("nodewidget");
+    NewUMLRectWidget::saveToXMI(qDoc, conceptElement);
+    qElement.appendChild(conceptElement);
+}
 
-    QPolygon pointArray(5);
-    pointArray.setPoint(0, offsetX, bodyOffsetY);
-    pointArray.setPoint(1, offsetX + wDepth, offsetY);
-    pointArray.setPoint(2, offsetX + w - 1, offsetY);
-    pointArray.setPoint(3, offsetX + w - 1, offsetY + bodyHeight );
-    pointArray.setPoint(4, offsetX + bodyWidth, offsetY + h - 1);
-    p.drawPolygon(pointArray);
-    p.drawRect(offsetX, bodyOffsetY, bodyWidth, bodyHeight);
-    p.drawLine(offsetX + w - 1, offsetY, offsetX + bodyWidth - 2, bodyOffsetY + 1);
+/**
+ * Reimplemented from NewUMLRectWidget::updateGeometry to calculate
+ * minimum size for this widget.
+ */
+void NodeWidget::updateGeometry()
+{
+	TextItemGroup *grp = textItemGroupAt(GroupIndex);
+	QSizeF minSize = grp->minimumSize();
 
-    p.setPen( QPen(Qt::black) );
-    p.setFont(font);
+	const qreal m = 2 * margin(); // This will be added by setMinimumSize call
+	minSize += QSizeF(m, m) + QSizeF(NodeWidget::DEPTH, NodeWidget::DEPTH);
 
-    int lines = 1;
-    if (umlObject()) {
-        QString stereotype = umlObject()->getStereotype();
-        if (!stereotype.isEmpty()) {
-            p.drawText(offsetX, bodyOffsetY + (bodyHeight/2) - fontHeight,
-                       bodyWidth, fontHeight, Qt::AlignCenter, umlObject()->getStereotype(true));
-            lines = 2;
-        }
-    }
+	setMinimumSize(minSize);
 
-    if ( NewUMLRectWidget::getIsInstance() ) {
-        font.setUnderline(true);
-        p.setFont(font);
-        name = NewUMLRectWidget::getInstanceName() + " : " + name;
-    }
+	NewUMLRectWidget::updateGeometry();
+}
 
-    if (lines == 1) {
-        p.drawText(offsetX, bodyOffsetY + (bodyHeight/2) - (fontHeight/2),
-                   bodyWidth, fontHeight, Qt::AlignCenter, name);
-    } else {
-        p.drawText(offsetX, bodyOffsetY + (bodyHeight/2),
-                   bodyWidth, fontHeight, Qt::AlignCenter, name);
-    }
+/**
+ * Reimplemented from NewUMLRectWidget::updateTextItemGroups() to
+ * calculate the texts and also show/hide the texts based on current
+ * state.
+ */
+void NodeWidget::updateTextItemGroups()
+{
+	TextItemGroup *grp = textItemGroupAt(GroupIndex);
+	grp->setTextItemCount(NodeWidget::TextItemCount);
 
-    if(isSelected()) {
-        drawSelected(&p, offsetX, offsetY);
-    }
+	if(umlObject()) {
+		UMLNode *node = static_cast<UMLNode*>(umlObject());
+
+		TextItem *stereo = grp->textItemAt(NodeWidget::StereoItemIndex);
+		stereo->setText(node->getStereotype(true));
+		stereo->setBold(true);
+		stereo->setVisible(!node->getStereotype(false).isEmpty());
+
+		TextItem *nameItem = grp->textItemAt(NodeWidget::NameItemIndex);
+		QString nameText = name();
+		bool underline = false;
+		if(isInstance()) {
+			nameText.prepend(':');
+			nameText.prepend(instanceName());
+			underline = true;
+		}
+		nameItem->setBold(true);
+		nameItem->setUnderline(underline);
+		nameItem->setText(nameText);
+	}
+
+	NewUMLRectWidget::updateTextItemGroups();
 }
 
-QSizeF NodeWidget::calculateSize() {
-    if (umlObject() == NULL) {
-        uDebug() << "umlObject() is NULL";
-        return NewUMLRectWidget::calculateSize();
-    }
+/**
+ * Reimplemented from NewUMLRectWidget::attributeChange to handle @ref
+ * SizeHasChanged to position the texts as well as build the painter
+ * path corresponding to current size.
+ */
+QVariant NodeWidget::attributeChange(WidgetAttributeChange change, const QVariant& oldValue)
+{
+	if(change == SizeHasChanged) {
+		TextItemGroup *grp = textItemGroupAt(GroupIndex);
+		m_nodeWidgetPath = QPainterPath(); // reset path
 
-    const QFontMetrics &fm = getFontMetrics(FT_BOLD_ITALIC);
-    const qreal fontHeight  = fm.lineSpacing();
+		const qreal m = margin();
+		const qreal w = size().width();
+		const qreal h = size().height();
+		const qreal wDepth = qMin(w/3, NodeWidget::DEPTH);
+		const qreal hDepth = qMin(h/3, NodeWidget::DEPTH);
+		const qreal bodyOffsetY = hDepth;
+		const qreal bodyWidth = w - wDepth;
+		const qreal bodyHeight = h - hDepth;
 
-    QString name = umlObject()->getName();
-    if ( NewUMLRectWidget::getIsInstance() ) {
-        name = NewUMLRectWidget::getInstanceName() + " : " + name;
-    }
+		QPolygonF poly;
+		poly << QPointF(0, bodyOffsetY)
+			 << QPointF(wDepth, 0)
+			 << QPointF(w - 1, 0)
+			 << QPointF(w - 1, bodyHeight)
+			 << QPointF(bodyWidth, h - 1)
+			 << QPointF(bodyWidth, bodyOffsetY)
+			 << QPointF(0, bodyOffsetY);
+		m_nodeWidgetPath.addPolygon(poly);
 
-    qreal width = fm.width(name);
+		QRectF bodyRect(0, bodyOffsetY, bodyWidth, bodyHeight);
+		m_nodeWidgetPath.addRect(bodyRect);
 
-    qreal tempWidth = 0;
-    if (!umlObject()->getStereotype().isEmpty()) {
-        tempWidth = fm.width(umlObject()->getStereotype(true));
-    }
-    if (tempWidth > width)
-        width = tempWidth;
-    width += DEPTH;
+		QLineF line(w - 1, 0, bodyWidth - 2, bodyOffsetY + 1);
+		m_nodeWidgetPath.moveTo(line.p1());
+		m_nodeWidgetPath.lineTo(line.p2());
 
-    qreal height = (2*fontHeight) + DEPTH;
+		bodyRect.adjust(+m, +m, -m, -m);
+		grp->setGroupGeometry(bodyRect);
+	}
 
-    return QSizeF(width, height);
+	return NewUMLRectWidget::attributeChange(change, oldValue);
 }
 
-void NodeWidget::saveToXMI(QDomDocument& qDoc, QDomElement& qElement) {
-    QDomElement conceptElement = qDoc.createElement("nodewidget");
-    NewUMLRectWidget::saveToXMI(qDoc, conceptElement);
-    qElement.appendChild(conceptElement);
-}
-
--- branches/work/soc-umbrello/umbrello/nodewidget.h #837818:837819
@@ -12,53 +12,49 @@
 #ifndef NODEWIDGET_H
 #define NODEWIDGET_H
 
-#include "umlwidget.h"
+#include "newumlrectwidget.h"
 
 class UMLNode;
 
 /**
- * Defines a graphical version of the Node.  Most of the functionality
- * will come from the @ref UMLNode class.
+ * Defines a graphical version of the Node used in Deployment diagram.
+ * Most of the functionality will come from the @ref UMLNode class.
  *
  * @short A graphical version of a Node.
  * @author Jonathan Riddell
+ * @author Gopala Krishna
  * @see NewUMLRectWidget
  * Bugs and comments to uml-devel at lists.sf.net or http://bugs.kde.org
  */
-class NodeWidget : public NewUMLRectWidget {
+class NodeWidget : public NewUMLRectWidget
+{
 public:
-
-    /**
-     * Constructs a NodeWidget.
-     *
-     * @param view              The parent of this NodeWidget.
-     * @param n         The UMLNode this will be representing.
-     */
-    NodeWidget(UMLScene * view, UMLNode *n );
-
-    /**
-     * destructor
-     */
+	NodeWidget(UMLNode *n );
     virtual ~NodeWidget();
 
-    /**
-     * Overrides standard method.
-     */
-    void paint(QPainter *p, const QStyleOptionGraphicsItem *item, QWidget *w);
+    virtual void paint(QPainter *p, const QStyleOptionGraphicsItem *o, QWidget *w);
 
-    /**
-     * Saves to the "nodewidget" XMI element.
-     * Note: For loading we use the method inherited from NewUMLRectWidget.
-     */
-    void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
+	// Uses NewUMLRectWidget::loadFromXMI to load info.
+    virtual void saveToXMI(QDomDocument& qDoc, QDomElement& qElement);
 
 protected:
-    /**
-     * Overrides method from NewUMLRectWidget
-     */
-    QSizeF calculateSize();
+	virtual void updateGeometry();
+	virtual void updateTextItemGroups();
+	virtual QVariant attributeChange(WidgetAttributeChange change, const QVariant& oldValue);
 
-    static const qreal DEPTH;  ///< pixels on Z axis
+private:
+	static const qreal DEPTH;  ///< pixels on Z axis
+	enum {
+		GroupIndex
+	};
+	enum {
+		StereoItemIndex,
+		NameItemIndex,
+		TextItemCount
+	};
+
+	/// Path representing the drawing of node widget.
+	QPainterPath m_nodeWidgetPath;
 };
 
 #endif
--- branches/work/soc-umbrello/umbrello/widget_factory.cpp #837818:837819
@@ -94,7 +94,7 @@
         }
         break;
     case Uml::ot_Node:
-        newWidget = new NodeWidget(scene, static_cast<UMLNode*>(o));
+        newWidget = new NodeWidget(static_cast<UMLNode*>(o));
         break;
     case Uml::ot_Artifact:
         newWidget = new ArtifactWidget(static_cast<UMLArtifact*>(o));
@@ -245,7 +245,7 @@
                 widget = new ComponentWidget(static_cast<UMLComponent*>(o));
         } else if (tag == "nodewidget") {
             if (validateObjType(Uml::ot_Node, o, id))
-                widget = new NodeWidget(scene, static_cast<UMLNode*>(o));
+                widget = new NodeWidget(static_cast<UMLNode*>(o));
         } else if (tag == "artifactwidget") {
             if (validateObjType(Uml::ot_Artifact, o, id))
                 widget = new ArtifactWidget(static_cast<UMLArtifact*>(o));




More information about the umbrello-devel mailing list