[Uml-devel] branches/work/soc-umbrello/umbrello
Gopala Krishna A
krishna.ggk at gmail.com
Mon Dec 7 17:42:51 UTC 2009
SVN commit 1059926 by gopala:
* Ground work for better undo/redo system design.
* Use the new QGraphicsObject as base class instead of QObject and
QGraphicsItem.
M +1 -1 expanderbox.cpp
M +2 -2 expanderbox.h
M +25 -9 umlscene.cpp
M +9 -2 widgets/classifierwidget.cpp
M +1 -1 widgets/classifierwidget.h
M +51 -11 widgets/umlwidget.cpp
M +1 -1 widgets/umlwidget.h
M +36 -1 widgets/widgetbase.cpp
M +18 -0 widgets/widgetbase.h
--- branches/work/soc-umbrello/umbrello/expanderbox.cpp #1059925:1059926
@@ -30,7 +30,7 @@
* \a expanded and parent item being \a parent.
*/
ExpanderBox::ExpanderBox(bool expanded, QGraphicsItem *parent) :
- QGraphicsItem(parent),
+ QGraphicsObject(parent),
m_expanded(expanded),
m_brush(Qt::NoBrush)
{
--- branches/work/soc-umbrello/umbrello/expanderbox.h #1059925:1059926
@@ -23,7 +23,7 @@
#include <QtCore/QObject>
#include <QtGui/QBrush>
-#include <QtGui/QGraphicsItem>
+#include <QtGui/QGraphicsObject>
#include <QtGui/QPen>
/**
@@ -33,7 +33,7 @@
* This can be used as GUI for the user to expand/deexpand
* something. Currently this is used in ClassifierWidget.
*/
-class ExpanderBox : public QObject, public QGraphicsItem
+class ExpanderBox : public QGraphicsObject
{
Q_OBJECT
public:
--- branches/work/soc-umbrello/umbrello/umlscene.cpp #1059925:1059926
@@ -540,6 +540,7 @@
//check to see if we want the message
//may be wanted by someone else e.g. list view
+ uDebug() << endl << endl << "called" << endl << endl;
if (!m_bCreateObject) {
return;
}
@@ -4160,9 +4161,11 @@
qreal smallestX = WidgetList_Utils::getSmallestX(widgetList);
foreach(UMLWidget *widget , widgetList) {
+ widget->setUserChange(WidgetBase::PositionChange, true);
widget->setPos(smallestX, widget->pos().y());
- widget->adjustAssociations();
+ widget->setUserChange(WidgetBase::PositionChange, false);
}
+ //TODO: Push stored cmds to stack.
}
/**
@@ -4177,9 +4180,11 @@
qreal biggestX = WidgetList_Utils::getBiggestX(widgetList);
foreach(UMLWidget *widget , widgetList) {
+ widget->setUserChange(WidgetBase::PositionChange, true);
widget->setPos(biggestX - widget->width(), widget->pos().y());
- widget->adjustAssociations();
+ widget->setUserChange(WidgetBase::PositionChange, false);
}
+ //TODO: Push stored cmds to stack.
}
/**
@@ -4195,9 +4200,11 @@
qreal smallestY = WidgetList_Utils::getSmallestY(widgetList);
foreach(UMLWidget *widget , widgetList) {
+ widget->setUserChange(WidgetBase::PositionChange, true);
widget->setPos(widget->pos().x(), smallestY);
- widget->adjustAssociations();
+ widget->setUserChange(WidgetBase::PositionChange, false);
}
+ //TODO: Push stored cmds to stack.
}
/**
@@ -4212,9 +4219,11 @@
qreal biggestY = WidgetList_Utils::getBiggestY(widgetList);
foreach(UMLWidget *widget , widgetList) {
+ widget->setUserChange(WidgetBase::PositionChange, true);
widget->setPos(widget->pos().x(), biggestY - widget->height());
- widget->adjustAssociations();
+ widget->setUserChange(WidgetBase::PositionChange, false);
}
+ //TODO: Push stored cmds to stack.
}
/**
@@ -4232,9 +4241,11 @@
qreal middle = int((biggestX - smallestX) / 2) + smallestX;
foreach(UMLWidget *widget , widgetList) {
+ widget->setUserChange(WidgetBase::PositionChange, true);
widget->setPos(middle - int(widget->width() / 2), widget->pos().y());
- widget->adjustAssociations();
+ widget->setUserChange(WidgetBase::PositionChange, false);
}
+ //TODO: Push stored cmds to stack.
}
/**
@@ -4252,9 +4263,11 @@
qreal middle = int((biggestY - smallestY) / 2) + smallestY;
foreach(UMLWidget *widget , widgetList) {
+ widget->setUserChange(WidgetBase::PositionChange, true);
widget->setPos(widget->pos().x(), middle - int(widget->height() / 2));
- widget->adjustAssociations();
+ widget->setUserChange(WidgetBase::PositionChange, false);
}
+ //TODO: Push stored cmds to stack.
}
/**
@@ -4280,12 +4293,14 @@
if (i == 1) {
widgetPrev = widget;
} else {
+ widget->setUserChange(WidgetBase::PositionChange, true);
widget->setPos(widgetPrev->pos().x(), widgetPrev->y() + widgetPrev->height() + distance);
- widget->adjustAssociations();
+ widget->setUserChange(WidgetBase::PositionChange, false);
widgetPrev = widget;
}
i++;
}
+ //TODO: Push stored cmds to stack.
}
/**
@@ -4311,14 +4326,15 @@
if (i == 1) {
widgetPrev = widget;
} else {
+ widget->setUserChange(WidgetBase::PositionChange, true);
widget->setPos(widgetPrev->x() + widgetPrev->width() + distance,
widgetPrev->pos().y());
- widget->adjustAssociations();
+ widget->setUserChange(WidgetBase::PositionChange, false);
widgetPrev = widget;
}
i++;
}
-
+ //TODO: Push stored cmds to stack.
}
void UMLScene::test()
--- branches/work/soc-umbrello/umbrello/widgets/classifierwidget.cpp #1059925:1059926
@@ -328,15 +328,22 @@
*
* @todo Implement this properly after implementing AssociationWidget.
*/
-void ClassifierWidget::adjustAssociations()
+void ClassifierWidget::adjustAssociations(bool userAdjustChange)
{
- UMLWidget::adjustAssociations();
+ UMLWidget::adjustAssociations(userAdjustChange);
if (umlDoc()->loading() || m_classAssociationWidget == 0) {
return;
}
+ //TODO: Push undo command
+ if (userAdjustChange) {
+ m_classAssociationWidget->setUserChange(AssocAdjustChange, true);
+ }
m_classAssociationWidget->associationLine()->calculateAssociationClassLine();
+ if (userAdjustChange) {
+ m_classAssociationWidget->setUserChange(AssocAdjustChange, false);
+ }
}
/**
--- branches/work/soc-umbrello/umbrello/widgets/classifierwidget.h #1059925:1059926
@@ -90,7 +90,7 @@
return m_classAssociationWidget;
}
void setClassAssociationWidget(AssociationWidget *assocwidget);
- virtual void adjustAssociations();
+ virtual void adjustAssociations(bool userAdjustChange);
virtual bool loadFromXMI(QDomElement & qElement);
virtual void saveToXMI(QDomDocument & qDoc, QDomElement & qElement);
--- branches/work/soc-umbrello/umbrello/widgets/umlwidget.cpp #1059925:1059926
@@ -244,11 +244,17 @@
*
* Subclasses can reimplement to fine tune this behvaior.
*/
-void UMLWidget::adjustAssociations()
+void UMLWidget::adjustAssociations(bool userChangeAdjust)
{
foreach (AssociationWidget *assoc,
m_associationSpaceManager->associationWidgets()) {
+ if (userChangeAdjust) {
+ assoc->setUserChange(AssocAdjustChange, true);
+ }
assoc->associationLine()->calculateEndPoints();
+ if (userChangeAdjust) {
+ assoc->setUserChange(AssocAdjustChange, false);
+ }
}
// m_associationSpaceManager->adjust();
//TODO: Implement this once AssociationWidget's are implemented.
@@ -312,7 +318,7 @@
if(m_widgetHandle) {
m_widgetHandle->updateHandlePosition();
}
- adjustAssociations();
+ adjustAssociations(true);
return QVariant();
}
else if(change == FontHasChanged) {
@@ -450,8 +456,38 @@
e->setLastScenePos(m_mouseMoveEventStore->lastScenePos());
e->setLastScreenPos(m_mouseMoveEventStore->lastScreenPos());
+ QList<QGraphicsItem*> selection = scene()->selectedItems();
+ if (beganMoveNow) {
+ foreach (QGraphicsItem *item, selection) {
+ if (item != this) {
+ if (item->parentItem() && item->parentItem()->isSelected()) {
+ item->setSelected(false);
+ }
+ } else {
+ if (item->parentItem() && item->parentItem()->isSelected()) {
+ item->parentItem()->setSelected(false);
+ }
+ }
+ }
+ }
+
+
+ foreach (QGraphicsItem *item, selection) {
+ WidgetBase *wid = qobject_cast<WidgetBase*>(item->toGraphicsObject());
+ if (wid) {
+ wid->setUserChange(PositionChange, true);
+ }
+ }
+
WidgetBase::mouseMoveEvent(e);
+ foreach (QGraphicsItem *item, selection) {
+ WidgetBase *wid = qobject_cast<WidgetBase*>(item->toGraphicsObject());
+ if (wid) {
+ wid->setUserChange(PositionChange, false);
+ }
+ }
+
m_mouseMoveEventStore->setLastPos(m_mouseMoveEventStore->pos());
m_mouseMoveEventStore->setLastScenePos(m_mouseMoveEventStore->scenePos());
m_mouseMoveEventStore->setLastScreenPos(m_mouseMoveEventStore->screenPos());
@@ -466,8 +502,11 @@
umlScene()->setIsMouseMovingItems(false);
WidgetBase::mouseReleaseEvent(event);
- delete m_mouseMoveEventStore;
- m_mouseMoveEventStore = 0;
+ if (m_mouseMoveEventStore) {
+ //TODO: Push cmds to stack.
+ delete m_mouseMoveEventStore;
+ m_mouseMoveEventStore = 0;
+ }
}
void UMLWidget::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
@@ -494,22 +533,23 @@
delete m_widgetHandle;
m_widgetHandle = 0;
}
- } else if (change == QGraphicsItem::ItemPositionChange) {
- // move all points of self associations before this widget is moved.
- // normal adjusting is not enough for self association updation.
- QPointF diff(value.toPointF() - pos());
+ } else if (change == QGraphicsItem::ItemPositionHasChanged) {
+ // adjust the association lines by new computations.
+ adjustAssociations(true);
+ // Move the self association widgets separately.
+ QPointF diff(pos() - m_itemPositionChangePos);
foreach (AssociationWidget* assoc,
m_associationSpaceManager->associationWidgets()) {
if (assoc->isSelf()) {
+ assoc->setUserChange(AssocAdjustChange, true);
+ //TODO: Push undo command
AssociationLine *line = assoc->associationLine();
for (int i = 0; i < line->count(); ++i) {
line->setPoint(i, line->point(i) + diff);
}
+ assoc->setUserChange(AssocAdjustChange, false);
}
}
- } else if (change == QGraphicsItem::ItemPositionHasChanged) {
- // adjust the association lines by new computations.
- adjustAssociations();
} else if (change == QGraphicsItem::ItemVisibleHasChanged) {
foreach (TextItemGroup *grp, m_textItemGroups) {
grp->updateVisibility();
--- branches/work/soc-umbrello/umbrello/widgets/umlwidget.h #1059925:1059926
@@ -151,7 +151,7 @@
AssociationWidgetList associationWidgetList() const;
virtual bool activate();
- virtual void adjustAssociations();
+ virtual void adjustAssociations(bool userChangeAdjustAssoc);
virtual void showPropertiesDialog();
--- branches/work/soc-umbrello/umbrello/widgets/widgetbase.cpp #1059925:1059926
@@ -643,6 +643,25 @@
return isActivated();
}
+bool WidgetBase::userChange(UserChangeType c) const
+{
+ return m_userChange.testFlag(c);
+}
+
+WidgetBase::UserChange WidgetBase::userChanges() const
+{
+ return m_userChange;
+}
+
+void WidgetBase::setUserChange(UserChangeType c, bool value)
+{
+ if (value) {
+ m_userChange = m_userChange & c;
+ } else {
+ m_userChange = m_userChange & ~c;
+ }
+}
+
/**
* A virtual method for the widget to display a property dialog box.
* Subclasses should reimplment this appropriately.
@@ -1099,7 +1118,23 @@
*/
QVariant WidgetBase::itemChange(GraphicsItemChange change, const QVariant& value)
{
- return QGraphicsItem::itemChange(change, value);
+ if (change == ItemPositionChange) {
+ m_itemPositionChangePos = pos();
+ if (userChange(PositionChange)) {
+ QPointF pt = value.toPointF();
+ pt = QPointF(qMax(pt.x(), qreal(0)), qMax(pt.y(), qreal(0)));
+ return QGraphicsObject::itemChange(change, pt);
+ }
+ }
+
+ if (change == ItemPositionHasChanged) {
+ if (userChange(PositionChange)) {
+ // TODO: Push move undo command
+
+ }
+ }
+
+ return QGraphicsObject::itemChange(change, value);
}
/**
--- branches/work/soc-umbrello/umbrello/widgets/widgetbase.h #1059925:1059926
@@ -84,6 +84,14 @@
SizeHasChanged
};
+ enum UserChangeType {
+ PositionChange = 0x1,
+ GeometryChange = 0x2,
+ AssocAdjustChange = 0x4
+ };
+ Q_DECLARE_FLAGS(UserChange, UserChangeType)
+
+
explicit WidgetBase(UMLObject *object);
virtual ~WidgetBase();
@@ -142,6 +150,10 @@
virtual bool activate();
+ bool userChange(UserChangeType c) const;
+ UserChange userChanges() const;
+ void setUserChange(UserChangeType c, bool value = true);
+
virtual void showPropertiesDialog();
virtual bool loadFromXMI(QDomElement &qElement);
@@ -172,6 +184,8 @@
QRectF m_boundingRect;
QPainterPath m_shape;
+ QPointF m_itemPositionChangePos;
+
/**
* This acts like stash to temporarily store data in loadFromXMI, which
* are then applied in the activation method.
@@ -205,6 +219,8 @@
bool m_activated;
WidgetInterfaceData *m_widgetInterfaceData;
+ UserChange m_userChange;
+
bool m_usesDiagramLineColor:1;
bool m_usesDiagramLineWidth:1;
bool m_usesDiagramBrush:1;
@@ -231,6 +247,8 @@
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(WidgetBase::UserChange)
+
/**
* @return The bounding rectangle for this widget.
* @see setBoundingRect
More information about the umbrello-devel
mailing list