[Uml-devel] branches/work/soc-umbrello/umbrello
Gopala Krishna A
krishna.ggk at gmail.com
Thu Jul 3 08:27:19 UTC 2008
SVN commit 827510 by gopala:
1) Implemented NewEnumWidget in terms of TextItems (hence enabling hover, tooltips for text inside enumwidget)
2) Fixed a bug in WidgetHandle (typo: had used minh instead of minw at 2 places)
3) Changed some test code for generating random gradients.
M +166 -99 newenumwidget.cpp
M +10 -1 newenumwidget.h
M +63 -16 test.cpp
M +4 -0 test.h
M +1 -0 textitem.cpp
M +3 -3 widgethandle.cpp
--- branches/work/soc-umbrello/umbrello/newenumwidget.cpp #827509:827510
@@ -26,14 +26,41 @@
#include "widget_utils.h"
#include "optionstate.h"
#include "umlscene.h"
+#include "textitem.h"
+QBrush randHoverBrush()
+{
+ QLinearGradient grad(QPointF(0,0), QPointF(0, 1));
+ int r, g, b, a;
+ r = qrand() % 255;
+ g = qrand() % 255;
+ b = qrand() % 255;
+ a = 10 + qrand() % 245; // set minimum to atleast 10
+ grad.setColorAt(0, QColor(r, g, b, a));
+
+ r = qrand() % 255;
+ g = qrand() % 255;
+ b = qrand() % 255;
+ a = 10 + qrand() % 245; // set minimum to atleast 10
+ grad.setColorAt(1, QColor(r, g, b, a));
+
+ return QBrush(grad);
+}
+
NewEnumWidget::NewEnumWidget(UMLObject* o) :
NewUMLRectWidget(o),
- m_showPackage(false)
+ m_showPackage(false),
+ m_stereoTypeItem(0),
+ m_nameItem(0)
{
m_baseType = Uml::wt_Enum;
}
+NewEnumWidget::~NewEnumWidget()
+{
+ cleanup();
+}
+
void NewEnumWidget::init()
{
if(umlScene()) {
@@ -65,68 +92,24 @@
const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
- UMLClassifier *classifier = 0;
- UMLClassifierListItemList list;
-
- if(umlObject()) {
- classifier = static_cast<UMLClassifier*>(umlObject());
- list = classifier->getFilteredList(Uml::ot_EnumLiteral);
- }
-
- QFont fnt = NewUMLRectWidget::font();
- // Get font metrics for max font type
- fnt.setBold(true);
- fnt.setItalic(true);
- QFontMetricsF fm(fnt);
- fnt.setItalic(false); // Reset italic.
-
- qreal fontHeight = fm.lineSpacing();
const QSizeF sz = size();
const QSizeF minSz = sizeHint(Qt::MinimumSize);
- if(sz.height() > minSz.height()) {
- fontHeight += (sz.height() - minSz.height()) / qreal(list.size() + 2);
- }
+ // if(sz.height() > minSz.height()) {
+ // fontHeight += (sz.height() - minSz.height()) / qreal(list.size() + 2);
+ // }
- QRectF fontRect(ENUM_MARGIN, 0, sz.width() - ENUM_MARGIN * 2, fontHeight);
-
-
painter->setPen(QPen(lineColor(), lineWidth()));
painter->setBrush(brush());
// First draw the outer rectangle with the pen and brush of this widget.
painter->drawRect(rect());
- painter->drawLine(QLineF(0, fontHeight * 2, sz.width() - 1, fontHeight * 2));
- // Set the font pen and empty brush to draw the font.
- painter->setPen(fontColor());
- painter->setBrush(QBrush(Qt::NoBrush));
- painter->setFont(fnt);
-
- QString text = umlObject() ? umlObject()->getStereotype(true) : "<< >>";
-
- painter->drawText(fontRect, Qt::AlignCenter, text);
-
- bool italicNeeded = umlObject() ? umlObject()->getAbstract() : false;
- fnt.setItalic(italicNeeded);
- painter->setFont(fnt);
- fontRect.moveTop(fontRect.top() + fontHeight);
-
- QString nameText = name();
- if(m_showPackage && umlObject()) {
- nameText = umlObject()->getFullyQualifiedName();
+ if(m_nameItem) {
+ QPointF botLeft = m_nameItem->boundingRect().bottomLeft();
+ botLeft = m_nameItem->mapToParent(botLeft);
+ qreal y = botLeft.y();
+ painter->drawLine(QLineF(0, y, sz.width() - 1, y));
}
- painter->drawText(fontRect, Qt::AlignCenter, nameText);
-
- qreal y = fontHeight * 2;
- fnt.setBold(false);
- fnt.setItalic(false);
- painter->setFont(fnt);
-
- foreach(UMLClassifierListItem* enumLiteral , list ) {
- fontRect.moveTop(y);
- painter->drawText(fontRect, Qt::AlignVCenter, enumLiteral->getName());
- y += fontHeight;
- }
}
bool NewEnumWidget::loadFromXMI( QDomElement & qElement )
@@ -149,67 +132,151 @@
void NewEnumWidget::updateGeometry()
{
- calculateMinimumSize();
+ cleanup();
+ if(umlObject()) {
+ qreal maxWidth = 0;
+ UMLClassifier *classifier = static_cast<UMLClassifier*>(umlObject());
+
+ QBrush hoverBrush = randHoverBrush();
+ // Setup the steretype item first.
+
+ m_stereoTypeItem = new TextItem(umlObject()->getStereotype(true));
+ m_stereoTypeItem->setToolTip(m_stereoTypeItem->toPlainText());
+ m_stereoTypeItem->setDefaultTextColor(fontColor());
+ m_stereoTypeItem->setFont(font());
+ m_stereoTypeItem->setBold(true);
+ m_stereoTypeItem->setAcceptHoverEvents(true);
+ m_stereoTypeItem->setHoverBrush(hoverBrush);
+ m_stereoTypeItem->setAlignment(Qt::AlignCenter);
+ m_stereoTypeItem->adjustSize();
+
+ maxWidth = qMax(maxWidth, m_stereoTypeItem->boundingRect().width());
+
+ // Now setup the name item.
+
+ QString nameText = name();
+ if(m_showPackage) {
+ nameText = umlObject()->getFullyQualifiedName();
+ }
+ m_nameItem = new TextItem(nameText);
+ m_nameItem->setToolTip(m_nameItem->toPlainText());
+ m_nameItem->setDefaultTextColor(fontColor());
+ m_nameItem->setFont(font());
+ m_nameItem->setBold(true);
+ m_nameItem->setItalic(classifier->getAbstract());
+ m_nameItem->setAcceptHoverEvents(true);
+ m_nameItem->setHoverBrush(hoverBrush);
+ m_nameItem->setAlignment(Qt::AlignCenter);
+ m_nameItem->adjustSize();
+
+ maxWidth = qMax(maxWidth, m_nameItem->boundingRect().width());
+
+ // Now setup all the literals
+
+ foreach(UMLClassifierListItem* enumLiteral ,
+ classifier->getFilteredList(Uml::ot_EnumLiteral)) {
+ TextItem *literal = new TextItem(enumLiteral->getName());
+ literal->setToolTip(literal->toPlainText());
+ literal->setDefaultTextColor(fontColor());
+ literal->setFont(font());
+ literal->setAcceptHoverEvents(true);
+ literal->setHoverBrush(hoverBrush);
+ literal->setAlignment(Qt::AlignCenter);
+ literal->adjustSize();
+
+ m_enumLiteralItems.append(literal);
+ maxWidth = qMax(maxWidth, literal->boundingRect().width());
+ }
+
+ // Now align all these text items.
+ maxWidth = qMin(maxWidth, QFontMetricsF(font()).width('w') * 20);
+ maxWidth += ENUM_MARGIN * 2;
+ qreal y = 0;
+ QRectF newBound;
+
+ m_stereoTypeItem->setTextWidth(maxWidth);
+ m_stereoTypeItem->setParentItem(this);
+ m_stereoTypeItem->setPos(0, y);
+ y += m_stereoTypeItem->boundingRect().height();
+ newBound |= m_stereoTypeItem->sceneBoundingRect();
+
+ m_nameItem->setTextWidth(maxWidth);
+ if(umlScene()) {
+ umlScene()->addItem(m_nameItem);
+ }
+ m_nameItem->setParentItem(this);
+ m_nameItem->setPos(0, y);
+ y += m_nameItem->boundingRect().height();
+ newBound |= m_nameItem->sceneBoundingRect();
+
+ foreach(TextItem *literal, m_enumLiteralItems) {
+ literal->setTextWidth(maxWidth);
+ if(umlScene()) {
+ umlScene()->addItem(literal);
+ }
+ literal->setParentItem(this);
+ literal->setPos(0, y);
+ y += literal->boundingRect().height();
+ newBound |= literal->sceneBoundingRect();
+ }
+
+ m_minimumSize = newBound.size();
+ }
NewUMLRectWidget::updateGeometry();
}
-void NewEnumWidget::calculateMinimumSize()
+void NewEnumWidget::sizeHasChanged(const QSizeF& sz)
{
- if(!umlObject()) {
- m_minimumSize.setWidth(100);
- m_minimumSize.setHeight(100);
- return;
- }
+ const QSizeF minSz = sizeHint(Qt::MinimumSize);
- qreal width, height;
- QFont font = this->font();
- font.setItalic(false);
- font.setUnderline(false);
- font.setBold(false);
- const QFontMetricsF fm(font);
+ int visibleItems = 0;
- const qreal fontHeight = fm.lineSpacing();
+ if(m_stereoTypeItem) {
+ m_stereoTypeItem->setTextWidth(sz.width());
+ ++visibleItems;
+ }
- int lines = 1;//always have one line - for name
- lines++; //for the stereotype
+ if(m_nameItem) {
+ m_nameItem->setTextWidth(sz.width());
+ ++visibleItems;
+ }
- const int numberOfEnumLiterals = static_cast<UMLEnum*>(umlObject())->enumLiterals();
- lines += numberOfEnumLiterals;
-
- height = width = 0;
- //set the height of the enum
- if(numberOfEnumLiterals == 0) {
- height += 0.5 * fontHeight; //no enum literals, so just add a bit of space
+ foreach(TextItem *literal, m_enumLiteralItems) {
+ literal->setTextWidth(sz.width());
+ ++visibleItems;
}
- height += lines * fontHeight;
-
- font.setBold(true);
- font.setItalic(true);
- QString nameText = name();
- if(m_showPackage && umlObject()) {
- nameText = umlObject()->getFullyQualifiedName();
+ qreal spacing = 0;
+ if(sz.height() - minSz.height() > 0 && visibleItems != 0) {
+ spacing = (sz.height() - minSz.height()) / qreal(visibleItems);
}
- width = QFontMetricsF(font).boundingRect(nameText).width();
- font.setItalic(false);
- if(umlObject()) {
- qreal w = QFontMetricsF(font).boundingRect(umlObject()->getStereotype(true)).width();
- width = qMax(w, width);
+ if(spacing > 0) {
+ qreal y = 0;
+ if(m_stereoTypeItem) {
+ m_stereoTypeItem->setPos(0, y);
+ y += m_stereoTypeItem->boundingRect().height() + spacing;
+ }
- UMLClassifier *classifier = static_cast<UMLClassifier*>(umlObject());
- UMLClassifierListItemList list = classifier->getFilteredList(Uml::ot_EnumLiteral);
- UMLClassifierListItem* listItem = 0;
+ if(m_nameItem) {
+ m_nameItem->setPos(0, y);
+ y += m_nameItem->boundingRect().height() + spacing;
+ }
- foreach(listItem , list ) {
- qreal w = fm.width(listItem->getName());
- if(w > width)
- width = w;
+ foreach(TextItem *literal, m_enumLiteralItems) {
+ literal->setPos(0, y);
+ y += literal->boundingRect().height() + spacing;
}
}
- //allow for width margin
- width += ENUM_MARGIN * 2;
+ NewUMLRectWidget::sizeHasChanged(sz);
+}
- m_minimumSize.setWidth(width);
- m_minimumSize.setHeight(height);
+void NewEnumWidget::cleanup()
+{
+ delete m_stereoTypeItem;
+ delete m_nameItem;
+ qDeleteAll(m_enumLiteralItems);
+
+ m_stereoTypeItem = m_nameItem = 0;
+ m_enumLiteralItems.clear();
}
--- branches/work/soc-umbrello/umbrello/newenumwidget.h #827509:827510
@@ -24,6 +24,7 @@
#include "newumlrectwidget.h"
#define ENUM_MARGIN 5
+class TextItem;
/**
* @short A uml widget to visualize enum.
@@ -42,6 +43,8 @@
*/
explicit NewEnumWidget(UMLObject* o);
+ ~NewEnumWidget();
+
/**
* Do some initialization which cannot be done inside constructor
* as it involves calling virtual methods.
@@ -93,11 +96,17 @@
*/
void updateGeometry();
+ void sizeHasChanged(const QSizeF& oldSize);
+
private:
+ void cleanup();
+
QSizeF m_minimumSize;
bool m_showPackage;
- void calculateMinimumSize();
+ TextItem *m_stereoTypeItem;
+ TextItem *m_nameItem;
+ QList<TextItem*> m_enumLiteralItems;
};
#endif // NEWENUMWIDGET_H
--- branches/work/soc-umbrello/umbrello/test.cpp #827509:827510
@@ -28,23 +28,29 @@
#include <QtCore/QMetaObject>
#include <QtCore/QMetaProperty>
#include <QtCore/QTimerEvent>
+#include <QtCore/QTime>
+
#include <kdebug.h>
Test* Test::m_self = 0;
struct TestPrivate
{
- TestPrivate() : scene(0), enumWidget(0)
- {}
+ TestPrivate() : scene(0), enumWidget(0), enumObject(0), count(0)
+ {
+ }
UMLScene *scene;
QString xml;
NewEnumWidget *enumWidget;
+ UMLEnum *enumObject;
+ int count;
};
Test::Test() :
d(new TestPrivate)
{
+ qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
}
Test* Test::self()
@@ -73,6 +79,7 @@
uDebug() << "entered test";
UMLEnum *en = new UMLEnum("Qt::SizeHint");
+ d->enumObject = en;
en->createEnumLiteral("MinimumSize");
en->createEnumLiteral("MaximumSize");
en->createEnumLiteral("PreferredSize");
@@ -84,15 +91,8 @@
wid->init();
scene->addItem(wid);
wid->setPos(40, 40);
- QLinearGradient ling(QPointF(0, 0), QPointF(0, 1));
- ling.setCoordinateMode(QGradient::ObjectBoundingMode);
- QColor col1(Qt::darkGray);
- QColor col2(Qt::lightGray);
- ling.setColorAt(0, col1);
- ling.setColorAt(1, col2);
-
- wid->setBrush(QBrush(ling));
+ wid->setBrush(randomGradientBrush());
wid->setSize(220, 120);
QDomDocument doc("TEST");
@@ -104,7 +104,7 @@
d->xml = doc.toString();
d->enumWidget = wid;
- wid->setBrush(Qt::darkYellow);
+ wid->setBrush(randomGradientBrush());
uDebug() << "-------------------";
uDebug() << d->xml;
uDebug() << "-------------------";
@@ -115,15 +115,62 @@
startTimer(3 * 1000);
}
+QBrush Test::randomGradientBrush()
+{
+ QLinearGradient *gradient = new QLinearGradient();
+ gradient->setCoordinateMode(QGradient::ObjectBoundingMode);
+ int h, s, v;
+ h = qrand() % 360;
+ s = qrand() % 255;
+ v = qrand() % 255;
+
+ QColor colorBottom = QColor::fromHsv(h, s, v);
+
+ colorBottom.toHsv().getHsv(&h, &s, &v);
+ int diff = 50;
+ if(v + diff <= 255) {
+ v += diff;
+ }
+ else {
+ v -= diff;
+ }
+
+ diff = 75;
+ if(s + diff <= 255) {
+ s += diff;
+ }
+ else {
+ s -= diff;
+ }
+ QColor colorTop = QColor::fromHsv(h, s, v);
+ gradient->setColorAt(0, colorTop);
+ gradient->setColorAt(1, colorBottom);
+
+ gradient->setStart(0, 0);
+ gradient->setFinalStop(0, 1);
+
+ QBrush retval(*gradient);
+ delete gradient;
+ return retval;
+}
+
void Test::timerEvent(QTimerEvent *event)
{
- QDomDocument doc("TEST");
- doc.setContent(d->xml);
+ if(d->count == 0) {
+ QDomDocument doc("TEST");
+ doc.setContent(d->xml);
- QDomElement ele = doc.documentElement().firstChild().toElement();
- d->enumWidget->loadFromXMI(ele);
- killTimer(event->timerId());
+ QDomElement ele = doc.documentElement().firstChild().toElement();
+ d->enumWidget->loadFromXMI(ele);
+ }
+ else if(d->count < 8) {
+ d->enumObject->createEnumLiteral("MaximumSize" + QString::number(qrand() % 100));
+ }
+ else {
+ killTimer(event->timerId());
+ }
+ ++d->count;
}
#include "test.moc"
--- branches/work/soc-umbrello/umbrello/test.h #827509:827510
@@ -25,6 +25,8 @@
// THIS IS USED TO ONLY TEST FEATURES OF THE PORT
class UMLScene;
class TestPrivate;
+class QBrush;
+
class Test : public QObject
{
Q_OBJECT;
@@ -35,6 +37,8 @@
static Test* self();
static Test *m_self;
+ QBrush randomGradientBrush();
+
protected:
void timerEvent(QTimerEvent *event);
--- branches/work/soc-umbrello/umbrello/textitem.cpp #827509:827510
@@ -102,6 +102,7 @@
p->drawRect(rect);
}
+
QGraphicsTextItem::paint(p, o, w);
}
--- branches/work/soc-umbrello/umbrello/widgethandle.cpp #827509:827510
@@ -218,14 +218,14 @@
}
w = sp.x() - newRect.left();
- if(w >= minh && w <= maxw) {
+ if(w >= minw && w <= maxw) {
newRect.setRight(sp.x());
}
break;
case rh_Right:
w = sp.x() - newRect.left();
- if(w >= minh && w <= maxw) {
+ if(w >= minw && w <= maxw) {
newRect.setRight(sp.x());
}
break;
@@ -237,7 +237,7 @@
}
w = sp.x() - newRect.left();
- if(w >= minh && w <= maxw) {
+ if(w >= minw && w <= maxw) {
newRect.setRight(sp.x());
}
break;
More information about the umbrello-devel
mailing list