summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJan-Arve Sæther <jan-arve.saether@nokia.com>2009-09-17 12:10:29 (GMT)
committerJan-Arve Sæther <jan-arve.saether@nokia.com>2009-09-17 12:10:29 (GMT)
commit53dfbd5708cdf64bfd3139cd4b0afc3aef8e186f (patch)
treeec9160f5ba39dd63144fcdd332166e2a6c54dbe7 /src
parent0644e3dce532b1df00a77d3a30c61d6b75d3ff30 (diff)
parentc2443b9d2cadb220012d37e4ed6a5973a6cc6abe (diff)
downloadQt-53dfbd5708cdf64bfd3139cd4b0afc3aef8e186f.zip
Qt-53dfbd5708cdf64bfd3139cd4b0afc3aef8e186f.tar.gz
Qt-53dfbd5708cdf64bfd3139cd4b0afc3aef8e186f.tar.bz2
Merge branch 'orbit-fixes' into 4.6
Diffstat (limited to 'src')
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout.cpp6
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout_p.cpp200
-rw-r--r--src/gui/graphicsview/qgraphicsanchorlayout_p.h14
3 files changed, 148 insertions, 72 deletions
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.cpp b/src/gui/graphicsview/qgraphicsanchorlayout.cpp
index 5897ae4..efad259 100644
--- a/src/gui/graphicsview/qgraphicsanchorlayout.cpp
+++ b/src/gui/graphicsview/qgraphicsanchorlayout.cpp
@@ -194,7 +194,7 @@ QGraphicsAnchorLayout::addAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint
QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge)
{
Q_D(QGraphicsAnchorLayout);
- QGraphicsAnchor *a = d->anchor(firstItem, firstEdge, secondItem, secondEdge);
+ QGraphicsAnchor *a = d->addAnchor(firstItem, firstEdge, secondItem, secondEdge);
invalidate();
return a;
}
@@ -246,12 +246,12 @@ void QGraphicsAnchorLayout::addCornerAnchors(QGraphicsLayoutItem *firstItem,
// Horizontal anchor
Qt::AnchorPoint firstEdge = (firstCorner & 1 ? Qt::AnchorRight: Qt::AnchorLeft);
Qt::AnchorPoint secondEdge = (secondCorner & 1 ? Qt::AnchorRight: Qt::AnchorLeft);
- d->anchor(firstItem, firstEdge, secondItem, secondEdge);
+ d->addAnchor(firstItem, firstEdge, secondItem, secondEdge);
// Vertical anchor
firstEdge = (firstCorner & 2 ? Qt::AnchorBottom: Qt::AnchorTop);
secondEdge = (secondCorner & 2 ? Qt::AnchorBottom: Qt::AnchorTop);
- d->anchor(firstItem, firstEdge, secondItem, secondEdge);
+ d->addAnchor(firstItem, firstEdge, secondItem, secondEdge);
invalidate();
}
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp
index a37ec96..b02adf4 100644
--- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp
+++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp
@@ -59,7 +59,7 @@ QGraphicsAnchorPrivate::QGraphicsAnchorPrivate(int version)
QGraphicsAnchorPrivate::~QGraphicsAnchorPrivate()
{
- layoutPrivate->deleteAnchorData(data);
+ layoutPrivate->removeAnchor(data->from, data->to);
}
void QGraphicsAnchorPrivate::setSpacing(qreal value)
@@ -790,7 +790,7 @@ void QGraphicsAnchorLayoutPrivate::createLayoutEdges()
// Horizontal
AnchorData *data = new AnchorData(0, 0, QWIDGETSIZE_MAX);
- addAnchor(layout, Qt::AnchorLeft, layout,
+ addAnchor_helper(layout, Qt::AnchorLeft, layout,
Qt::AnchorRight, data);
data->skipInPreferred = 1;
@@ -800,7 +800,7 @@ void QGraphicsAnchorLayoutPrivate::createLayoutEdges()
// Vertical
data = new AnchorData(0, 0, QWIDGETSIZE_MAX);
- addAnchor(layout, Qt::AnchorTop, layout,
+ addAnchor_helper(layout, Qt::AnchorTop, layout,
Qt::AnchorBottom, data);
data->skipInPreferred = 1;
@@ -816,8 +816,10 @@ void QGraphicsAnchorLayoutPrivate::deleteLayoutEdges()
Q_ASSERT(internalVertex(q, Qt::AnchorHorizontalCenter) == NULL);
Q_ASSERT(internalVertex(q, Qt::AnchorVerticalCenter) == NULL);
- removeAnchor(q, Qt::AnchorLeft, q, Qt::AnchorRight);
- removeAnchor(q, Qt::AnchorTop, q, Qt::AnchorBottom);
+ removeAnchor_helper(internalVertex(q, Qt::AnchorLeft),
+ internalVertex(q, Qt::AnchorRight));
+ removeAnchor_helper(internalVertex(q, Qt::AnchorTop),
+ internalVertex(q, Qt::AnchorBottom));
}
void QGraphicsAnchorLayoutPrivate::createItemEdges(QGraphicsLayoutItem *item)
@@ -832,7 +834,7 @@ void QGraphicsAnchorLayoutPrivate::createItemEdges(QGraphicsLayoutItem *item)
int maximumSize = item->maximumWidth();
AnchorData *data = new AnchorData(minimumSize, preferredSize, maximumSize);
- addAnchor(item, Qt::AnchorLeft, item,
+ addAnchor_helper(item, Qt::AnchorLeft, item,
Qt::AnchorRight, data);
// Vertical
@@ -841,7 +843,7 @@ void QGraphicsAnchorLayoutPrivate::createItemEdges(QGraphicsLayoutItem *item)
maximumSize = item->maximumHeight();
data = new AnchorData(minimumSize, preferredSize, maximumSize);
- addAnchor(item, Qt::AnchorTop, item,
+ addAnchor_helper(item, Qt::AnchorTop, item,
Qt::AnchorBottom, data);
}
@@ -904,16 +906,16 @@ void QGraphicsAnchorLayoutPrivate::createCenterAnchors(
QSimplexConstraint *c = new QSimplexConstraint;
AnchorData *data = new AnchorData(minimumSize, preferredSize, maximumSize);
c->variables.insert(data, 1.0);
- addAnchor(item, firstEdge, item, centerEdge, data);
+ addAnchor_helper(item, firstEdge, item, centerEdge, data);
data = new AnchorData(minimumSize, preferredSize, maximumSize);
c->variables.insert(data, -1.0);
- addAnchor(item, centerEdge, item, lastEdge, data);
+ addAnchor_helper(item, centerEdge, item, lastEdge, data);
itemCenterConstraints[orientation].append(c);
// Remove old one
- removeAnchor(item, firstEdge, item, lastEdge);
+ removeAnchor_helper(first, last);
}
void QGraphicsAnchorLayoutPrivate::removeCenterAnchors(
@@ -976,11 +978,11 @@ void QGraphicsAnchorLayoutPrivate::removeCenterAnchors(
int maximumSize = oldData->maxSize * 2;
AnchorData *data = new AnchorData(minimumSize, preferredSize, maximumSize);
- addAnchor(item, firstEdge, item, lastEdge, data);
+ addAnchor_helper(item, firstEdge, item, lastEdge, data);
// Remove old anchors
- removeAnchor(item, firstEdge, item, centerEdge);
- removeAnchor(item, centerEdge, item, lastEdge);
+ removeAnchor_helper(first, center);
+ removeAnchor_helper(center, internalVertex(item, lastEdge));
} else {
// this is only called from removeAnchors()
@@ -989,13 +991,13 @@ void QGraphicsAnchorLayoutPrivate::removeCenterAnchors(
for (int i = 0; i < adjacents.count(); ++i) {
AnchorVertex *v = adjacents.at(i);
if (v->m_item != item) {
- removeAnchor(item, centerEdge, v->m_item, v->m_edge);
+ removeAnchor_helper(center, internalVertex(v->m_item, v->m_edge));
}
}
// when all non-internal anchors is removed it will automatically merge the
// center anchor into a left-right (or top-bottom) anchor. We must also delete that.
// by this time, the center vertex is deleted and merged into a non-centered internal anchor
- removeAnchor(item, firstEdge, item, lastEdge);
+ removeAnchor_helper(first, internalVertex(item, lastEdge));
}
}
@@ -1039,7 +1041,7 @@ void QGraphicsAnchorLayoutPrivate::removeCenterConstraints(QGraphicsLayoutItem *
* Helper function that is called from the anchor functions in the public API.
* If \a spacing is 0, it will pick up the spacing defined by the style.
*/
-QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::anchor(QGraphicsLayoutItem *firstItem,
+QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::addAnchor(QGraphicsLayoutItem *firstItem,
Qt::AnchorPoint firstEdge,
QGraphicsLayoutItem *secondItem,
Qt::AnchorPoint secondEdge,
@@ -1112,18 +1114,18 @@ QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::anchor(QGraphicsLayoutItem *first
} else {
data = new AnchorData(0); // spacing should be 0
}
- addAnchor(firstItem, firstEdge, secondItem, secondEdge, data);
+ addAnchor_helper(firstItem, firstEdge, secondItem, secondEdge, data);
} else if (*spacing >= 0) {
data = new AnchorData(*spacing);
- addAnchor(firstItem, firstEdge, secondItem, secondEdge, data);
+ addAnchor_helper(firstItem, firstEdge, secondItem, secondEdge, data);
} else {
data = new AnchorData(-*spacing);
- addAnchor(secondItem, secondEdge, firstItem, firstEdge, data);
+ addAnchor_helper(secondItem, secondEdge, firstItem, firstEdge, data);
}
return acquireGraphicsAnchor(data);
}
-void QGraphicsAnchorLayoutPrivate::addAnchor(QGraphicsLayoutItem *firstItem,
+void QGraphicsAnchorLayoutPrivate::addAnchor_helper(QGraphicsLayoutItem *firstItem,
Qt::AnchorPoint firstEdge,
QGraphicsLayoutItem *secondItem,
Qt::AnchorPoint secondEdge,
@@ -1142,8 +1144,9 @@ void QGraphicsAnchorLayoutPrivate::addAnchor(QGraphicsLayoutItem *firstItem,
// Remove previous anchor
// ### Could we update the existing edgeData rather than creating a new one?
- if (graph[edgeOrientation(firstEdge)].edgeData(v1, v2))
- removeAnchor(firstItem, firstEdge, secondItem, secondEdge);
+ if (graph[edgeOrientation(firstEdge)].edgeData(v1, v2)) {
+ removeAnchor_helper(v1, v2);
+ }
// Create a bi-directional edge in the sense it can be transversed both
// from v1 or v2. "data" however is shared between the two references
@@ -1178,15 +1181,82 @@ QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::getAnchor(QGraphicsLayoutItem *fi
return graphicsAnchor;
}
-void QGraphicsAnchorLayoutPrivate::removeAnchor(QGraphicsLayoutItem *firstItem,
- Qt::AnchorPoint firstEdge,
- QGraphicsLayoutItem *secondItem,
- Qt::AnchorPoint secondEdge)
+/*!
+ * \internal
+ *
+ * Implements the high level "removeAnchor" feature. Called by
+ * the QAnchorData destructor.
+ */
+void QGraphicsAnchorLayoutPrivate::removeAnchor(AnchorVertex *firstVertex,
+ AnchorVertex *secondVertex)
{
- removeAnchor_helper(internalVertex(firstItem, firstEdge),
- internalVertex(secondItem, secondEdge));
+ Q_Q(QGraphicsAnchorLayout);
+
+ // Actually delete the anchor
+ removeAnchor_helper(firstVertex, secondVertex);
+
+ QGraphicsLayoutItem *firstItem = firstVertex->m_item;
+ QGraphicsLayoutItem *secondItem = secondVertex->m_item;
+
+ // Checking if the item stays in the layout or not
+ bool keepFirstItem = false;
+ bool keepSecondItem = false;
+
+ QPair<AnchorVertex *, int> v;
+ int refcount = -1;
+
+ if (firstItem != q) {
+ for (int i = Qt::AnchorLeft; i <= Qt::AnchorBottom; ++i) {
+ v = m_vertexList.value(qMakePair(firstItem, static_cast<Qt::AnchorPoint>(i)));
+ if (v.first) {
+ if (i == Qt::AnchorHorizontalCenter || i == Qt::AnchorVerticalCenter)
+ refcount = 2;
+ else
+ refcount = 1;
+
+ if (v.second > refcount) {
+ keepFirstItem = true;
+ break;
+ }
+ }
+ }
+ } else
+ keepFirstItem = true;
+
+ if (secondItem != q) {
+ for (int i = Qt::AnchorLeft; i <= Qt::AnchorBottom; ++i) {
+ v = m_vertexList.value(qMakePair(secondItem, static_cast<Qt::AnchorPoint>(i)));
+ if (v.first) {
+ if (i == Qt::AnchorHorizontalCenter || i == Qt::AnchorVerticalCenter)
+ refcount = 2;
+ else
+ refcount = 1;
+
+ if (v.second > refcount) {
+ keepSecondItem = true;
+ break;
+ }
+ }
+ }
+ } else
+ keepSecondItem = true;
+
+ if (!keepFirstItem)
+ q->removeAt(items.indexOf(firstItem));
+
+ if (!keepSecondItem)
+ q->removeAt(items.indexOf(secondItem));
+
+ // Removing anchors invalidates the layout
+ q->invalidate();
}
+/*
+ \internal
+
+ Implements the low level "removeAnchor" feature. Called by
+ private methods.
+*/
void QGraphicsAnchorLayoutPrivate::removeAnchor_helper(AnchorVertex *v1, AnchorVertex *v2)
{
Q_ASSERT(v1 && v2);
@@ -1207,17 +1277,6 @@ void QGraphicsAnchorLayoutPrivate::removeAnchor_helper(AnchorVertex *v1, AnchorV
\internal
Only called from outside. (calls invalidate())
*/
-void QGraphicsAnchorLayoutPrivate::deleteAnchorData(AnchorData *data)
-{
- Q_Q(QGraphicsAnchorLayout);
- removeAnchor_helper(data->from, data->to);
- q->invalidate();
-}
-
-/*!
- \internal
- Only called from outside. (calls invalidate())
-*/
void QGraphicsAnchorLayoutPrivate::setAnchorSize(AnchorData *data, const qreal *anchorSize)
{
Q_Q(QGraphicsAnchorLayout);
@@ -1225,12 +1284,35 @@ void QGraphicsAnchorLayoutPrivate::setAnchorSize(AnchorData *data, const qreal *
// search recursively through all composite anchors
Q_ASSERT(data);
restoreSimplifiedGraph(edgeOrientation(data->from->m_edge));
+
+ QGraphicsLayoutItem *firstItem = data->from->m_item;
+ QGraphicsLayoutItem *secondItem = data->to->m_item;
+ Qt::AnchorPoint firstEdge = data->from->m_edge;
+ Qt::AnchorPoint secondEdge = data->to->m_edge;
+
+ // Use heuristics to find out what the user meant with this anchor.
+ correctEdgeDirection(firstItem, firstEdge, secondItem, secondEdge);
+ if (data->from->m_item != firstItem)
+ qSwap(data->from, data->to);
+
if (anchorSize) {
- data->setFixedSize(*anchorSize);
+ // ### The current implementation makes "setAnchorSize" behavior
+ // dependent on the argument order for cases where we have
+ // no heuristic. Ie. two widgets, same anchor point.
+
+ // We cannot have negative sizes inside the graph. This would cause
+ // the simplex solver to fail because all simplex variables are
+ // positive by definition.
+ // "negative spacing" is handled by inverting the standard item order.
+ if (*anchorSize >= 0) {
+ data->setFixedSize(*anchorSize);
+ } else {
+ data->setFixedSize(-*anchorSize);
+ qSwap(data->from, data->to);
+ }
} else {
data->unsetSize();
}
-
q->invalidate();
}
@@ -1360,25 +1442,23 @@ void QGraphicsAnchorLayoutPrivate::correctEdgeDirection(QGraphicsLayoutItem *&fi
{
Q_Q(QGraphicsAnchorLayout);
- Qt::AnchorPoint effectiveFirst = firstEdge;
- Qt::AnchorPoint effectiveSecond = secondEdge;
-
- if (firstItem == q)
- effectiveFirst = QGraphicsAnchorLayoutPrivate::oppositeEdge(firstEdge);
- if (secondItem == q)
- effectiveSecond = QGraphicsAnchorLayoutPrivate::oppositeEdge(secondEdge);
-
- if (effectiveFirst < effectiveSecond) {
-
- // ### DEBUG
- /* printf("Swapping Anchor from %s %d --to--> %s %d\n",
- firstItem->isLayout() ? "<layout>" :
- qPrintable(static_cast<QGraphicsWidget *>(firstItem)->data(0).toString()),
- firstEdge,
- secondItem->isLayout() ? "<layout>" :
- qPrintable(static_cast<QGraphicsWidget *>(secondItem)->data(0).toString()),
- secondEdge);
- */
+ if ((firstItem != q) && (secondItem != q)) {
+ // If connection is between widgets (not the layout itself)
+ // Ensure that "right-edges" sit to the left of "left-edges".
+ if (firstEdge < secondEdge) {
+ qSwap(firstItem, secondItem);
+ qSwap(firstEdge, secondEdge);
+ }
+ } else if (firstItem == q) {
+ // If connection involves the right or bottom of a layout, ensure
+ // the layout is the second item.
+ if ((firstEdge == Qt::AnchorRight) || (firstEdge == Qt::AnchorBottom)) {
+ qSwap(firstItem, secondItem);
+ qSwap(firstEdge, secondEdge);
+ }
+ } else if ((secondEdge != Qt::AnchorRight) && (secondEdge != Qt::AnchorBottom)) {
+ // If connection involves the left, center or top of layout, ensure
+ // the layout is the first item.
qSwap(firstItem, secondItem);
qSwap(firstEdge, secondEdge);
}
diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h
index f701c3f..4d746bf 100644
--- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h
+++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h
@@ -403,15 +403,15 @@ public:
return data->graphicsAnchor;
}
- // helper function used by the 4 API functions
- QGraphicsAnchor *anchor(QGraphicsLayoutItem *firstItem,
+ // function used by the 4 API functions
+ QGraphicsAnchor *addAnchor(QGraphicsLayoutItem *firstItem,
Qt::AnchorPoint firstEdge,
QGraphicsLayoutItem *secondItem,
Qt::AnchorPoint secondEdge,
qreal *spacing = 0);
- // Anchor Manipulation methods
- void addAnchor(QGraphicsLayoutItem *firstItem,
+ // Helper for Anchor Manipulation methods
+ void addAnchor_helper(QGraphicsLayoutItem *firstItem,
Qt::AnchorPoint firstEdge,
QGraphicsLayoutItem *secondItem,
Qt::AnchorPoint secondEdge,
@@ -420,12 +420,8 @@ public:
QGraphicsAnchor *getAnchor(QGraphicsLayoutItem *firstItem, Qt::AnchorPoint firstEdge,
QGraphicsLayoutItem *secondItem, Qt::AnchorPoint secondEdge);
- void removeAnchor(QGraphicsLayoutItem *firstItem,
- Qt::AnchorPoint firstEdge,
- QGraphicsLayoutItem *secondItem,
- Qt::AnchorPoint secondEdge);
+ void removeAnchor(AnchorVertex *firstVertex, AnchorVertex *secondVertex);
void removeAnchor_helper(AnchorVertex *v1, AnchorVertex *v2);
- void deleteAnchorData(AnchorData *data);
void setAnchorSize(AnchorData *data, const qreal *anchorSize);
void anchorSize(const AnchorData *data,
qreal *minSize = 0,