[Kst] branches/work/kst/portto4/kst/src/libkstapp

Adam Treat treat at kde.org
Thu Sep 6 17:59:17 CEST 2007


SVN commit 709131 by treat:

* Add debug stream operator to view items for easier debug
* Set items to handle child events if a layout is present
* Set creation pos to QPointF(0,0)
* Don't create useless commands
* Implement reparenting rules according to the spec


 M  +1 -0      boxitem.cpp  
 M  +1 -0      ellipseitem.cpp  
 M  +1 -0      labelitem.cpp  
 M  +1 -0      lineitem.cpp  
 M  +1 -0      pictureitem.cpp  
 M  +2 -0      plotitem.cpp  
 M  +1 -0      svgitem.cpp  
 M  +79 -31    viewitem.cpp  
 M  +6 -1      viewitem.h  


--- branches/work/kst/portto4/kst/src/libkstapp/boxitem.cpp #709130:709131
@@ -20,6 +20,7 @@
 
 BoxItem::BoxItem(View *parent)
     : ViewItem(parent) {
+  setName("BoxItem");
 }
 
 
--- branches/work/kst/portto4/kst/src/libkstapp/ellipseitem.cpp #709130:709131
@@ -19,6 +19,7 @@
 
 EllipseItem::EllipseItem(View *parent)
   : ViewItem(parent) {
+  setName("EllipseItem");
 }
 
 
--- branches/work/kst/portto4/kst/src/libkstapp/labelitem.cpp #709130:709131
@@ -22,6 +22,7 @@
 
 LabelItem::LabelItem(View *parent, const QString& txt)
   : ViewItem(parent), _parsed(0), _text(txt) {
+  setName("LabelItem");
 }
 
 
--- branches/work/kst/portto4/kst/src/libkstapp/lineitem.cpp #709130:709131
@@ -20,6 +20,7 @@
 
 LineItem::LineItem(View *parent)
   : ViewItem(parent) {
+  setName("LineItem");
 }
 
 
--- branches/work/kst/portto4/kst/src/libkstapp/pictureitem.cpp #709130:709131
@@ -20,6 +20,7 @@
 
 PictureItem::PictureItem(View *parent, const QImage &image)
   : ViewItem(parent), _image(QPixmap::fromImage(image)) {
+  setName("PictureItem");
   setLockAspectRatio(true);
 }
 
--- branches/work/kst/portto4/kst/src/libkstapp/plotitem.cpp #709130:709131
@@ -29,6 +29,8 @@
 PlotItem::PlotItem(View *parent)
   : ViewItem(parent), _marginWidth(0), _marginHeight(0) {
 
+  setName("PlotItem");
+
   // FIXME fake data for testing rendering
   KstVectorPtr xTest = new KstSVector(0.0, 100.0, 10000, KstObjectTag::fromString("X vector"));
   xTest->setLabel("a nice x label");
--- branches/work/kst/portto4/kst/src/libkstapp/svgitem.cpp #709130:709131
@@ -21,6 +21,7 @@
 SvgItem::SvgItem(View *parent, const QString &file)
   : ViewItem(parent), _svg(new QSvgRenderer(file)) {
   //FIXME need to set the element id??
+  setName("SvgItem");
   setLockAspectRatio(true);
 }
 
--- branches/work/kst/portto4/kst/src/libkstapp/viewitem.cpp #709130:709131
@@ -30,6 +30,7 @@
     _layout(0),
     _activeGrip(NoGrip) {
 
+  setName("ViewItem");
   setAcceptsHoverEvents(true);
   setFlags(ItemIsMovable | ItemIsSelectable | ItemIsFocusable);
   connect(parent, SIGNAL(mouseModeChanged(View::MouseMode)),
@@ -73,6 +74,8 @@
   if (_layout) {
     connect(this, SIGNAL(geometryChanged()), _layout, SLOT(update()));
   }
+
+  setHandlesChildEvents(_layout);
 }
 
 
@@ -409,8 +412,8 @@
 void ViewItem::creationPolygonChanged(View::CreationEvent event) {
   if (event == View::MousePress) {
     const QPolygonF poly = mapFromScene(parentView()->creationPolygon(View::MousePress));
-    setViewRect(poly.first().x(), poly.first().y(),
-            poly.last().x() - poly.first().x(), poly.last().y() - poly.first().y());
+    setPos(poly.first().x(), poly.first().y());
+    setViewRect(0, 0, 0, 0);
     parentView()->scene()->addItem(this);
     setZValue(1);
     return;
@@ -464,11 +467,6 @@
 
 void ViewItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
 
-  if (qgraphicsitem_cast<ViewItem*>(parentItem())) {
-    event->ignore();
-    return;
-  }
-
   if (parentView()->mouseMode() == View::Default) {
     if (mouseMode() == ViewItem::Default ||
         mouseMode() == ViewItem::Move ||
@@ -871,21 +869,11 @@
 
 
 void ViewItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) {
-
-  if (qgraphicsitem_cast<ViewItem*>(parentItem())) {
-    event->ignore();
-    return;
-  }
 }
 
 
 void ViewItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
 
-  if (qgraphicsitem_cast<ViewItem*>(parentItem())) {
-    event->ignore();
-    return;
-  }
-
   QPointF p = event->pos();
   if (topLeftGrip().contains(p)) {
     setActiveGrip(TopLeftGrip);
@@ -913,11 +901,6 @@
 
 void ViewItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
 
-  if (qgraphicsitem_cast<ViewItem*>(parentItem())) {
-    event->ignore();
-    return;
-  }
-
   if (parentView()->mouseMode() != View::Default) {
     parentView()->setMouseMode(View::Default);
     parentView()->undoStack()->endMacro();
@@ -970,26 +953,91 @@
              parentView()->mouseMode() == View::Rotate) {
     _originalRect = rect();
     _originalTransform = transform();
-  } else if (oldMode == View::Move) {
-
+  } else if (oldMode == View::Move && _originalPosition != pos()) {
     setPos(parentView()->snapPoint(pos()));
+    new MoveCommand(this, _originalPosition, pos());
 
-    new MoveCommand(this, _originalPosition, pos());
-  } else if (oldMode == View::Resize) {
+    maybeReparent();
+  } else if (oldMode == View::Resize && _originalRect != rect()) {
     new ResizeCommand(this, _originalRect, rect());
-  } else if (oldMode == View::Scale) {
+
+    maybeReparent();
+  } else if (oldMode == View::Scale && _originalTransform != transform()) {
     new ScaleCommand(this, _originalTransform, transform());
-  } else if (oldMode == View::Rotate) {
+
+    maybeReparent();
+  } else if (oldMode == View::Rotate && _originalTransform != transform()) {
     new RotateCommand(this, _originalTransform, transform());
+
+    maybeReparent();
   }
-
-  maybeReparent();
 }
 
 
-void ViewItem::maybeReparent() {
+bool ViewItem::maybeReparent() {
+  //First get a list of all items that collide with this one
+  QList<QGraphicsItem*> collisions = collidingItems(Qt::IntersectsItemShape);
+
+  bool topLevel = !parentItem();
+  QPointF scenePos = topLevel ? pos() : parentItem()->mapToScene(pos());
+
+#ifdef DEBUG_REPARENT
+  qDebug() << "maybeReparent" << this
+           << "topLevel:" << (topLevel ? "true" : "false")
+           << "scenePos:" << scenePos
+           << endl;
+#endif
+
+  //Doesn't collide then reparent to top-level
+  if (collisions.isEmpty() && !topLevel) {
+#ifdef DEBUG_REPARENT
+    qDebug() << "reparent to topLevel" << endl;
+#endif
+    setParentItem(0);
+    setPos(scenePos);
+    return true;
+  }
+
+  //Look for collisions that completely contain us
+  foreach (QGraphicsItem *item, collisions) {
+    ViewItem *viewItem = dynamic_cast<ViewItem*>(item);
+
+    if (!viewItem || viewItem->layout() /*don't break existing layouts*/)
+      continue;
+
+    if (viewItem->collidesWithItem(this, Qt::ContainsItemShape)) {
+
+      if (parentItem() == viewItem) /*already done*/
+        return false;
+
+#ifdef DEBUG_REPARENT
+      qDebug() << "reparent to" << viewItem << endl;
+#endif
+      setParentItem(viewItem);
+      setPos(viewItem->mapFromScene(scenePos));
+      return true;
+    }
+  }
+
+  //No suitable collisions then reparent to top-level
+  if (!topLevel) {
+#ifdef DEBUG_REPARENT
+    qDebug() << "reparent to topLevel" << endl;
+#endif
+    setParentItem(0);
+    setPos(scenePos);
+    return true;
+  }
+
+  return false;
 }
 
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, ViewItem *viewItem) {
+    dbg.nospace() << viewItem->name();
+    return dbg.space();
+}
+#endif
 
 ViewItemCommand::ViewItemCommand(const QString &text, bool addToStack, QUndoCommand *parent)
     : QUndoCommand(text, parent), _item(kstApp->mainWindow()->tabWidget()->currentView()->currentViewItem()) {
--- branches/work/kst/portto4/kst/src/libkstapp/viewitem.h #709130:709131
@@ -20,6 +20,7 @@
 #include "view.h" //forward declare, but enums??
 
 // #define DEBUG_GEOMETRY
+// #define DEBUG_REPARENT
 
 namespace Kst {
 
@@ -137,7 +138,7 @@
   void viewMouseModeChanged(View::MouseMode oldMode);
 
 private:
-  void maybeReparent();
+  bool maybeReparent();
   QLineF originLine() const;
 
 private:
@@ -153,6 +154,10 @@
   QTransform _rotationTransform;
 };
 
+#ifndef QT_NO_DEBUG_STREAM
+Q_CORE_EXPORT QDebug operator<<(QDebug, ViewItem*);
+#endif
+
 class KST_EXPORT ViewItemCommand : public QUndoCommand
 {
 public:


More information about the Kst mailing list