From 18da388497b5f3cbc77298a70bc83f037f06c013 Mon Sep 17 00:00:00 2001 From: Jesus Sanchez-Palencia Date: Tue, 29 Sep 2009 14:02:27 -0300 Subject: QGraphicsAnchorLayoutPrivate: Handling floating items as an invalid layout situation We make use of the anchor visited on findPaths() to keep track of how many items are visited when walking on the graph. We can use this information of how many items are reachable (non-float) in order to check if we have floating items (not reachable from any graph vertex). If so, we have a situation not supported by now. Signed-off-by: Jesus Sanchez-Palencia Reviewed-by: Caio Marcelo de Oliveira Filho --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 51 +++++++++++++++++++++++- src/gui/graphicsview/qgraphicsanchorlayout_p.h | 3 ++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 8139b2b..e760642 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -1841,6 +1841,11 @@ void QGraphicsAnchorLayoutPrivate::findPaths(Orientation orientation) queue.enqueue(qMakePair(pair.second, v)); } } + + // We will walk through every reachable items (non-float) and mark them + // by keeping their references on m_nonFloatItems. With this we can easily + // identify non-float and float items. + identifyNonFloatItems(visited, orientation); } /*! @@ -1999,6 +2004,46 @@ QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation) } /*! + \internal + + Use all visited Anchors on findPaths() so we can identify non-float Items. +*/ +void QGraphicsAnchorLayoutPrivate::identifyNonFloatItems(QSet visited, Orientation orientation) +{ + m_nonFloatItems[orientation].clear(); + + foreach (const AnchorData *ad, visited) + identifyNonFloatItems_helper(ad, orientation); +} + +/*! + \internal + + Given an anchor, if it is an internal anchor and Normal we must mark it's item as non-float. + If the anchor is Sequential or Parallel, we must iterate on its children recursively until we reach + internal anchors (items). +*/ +void QGraphicsAnchorLayoutPrivate::identifyNonFloatItems_helper(const AnchorData *ad, Orientation orientation) +{ + Q_Q(QGraphicsAnchorLayout); + + switch(ad->type) { + case AnchorData::Normal: + if (ad->from->m_item == ad->to->m_item && ad->to->m_item != q) + m_nonFloatItems[orientation].insert(ad->to->m_item); + break; + case AnchorData::Sequential: + foreach (const AnchorData *d, static_cast(ad)->m_edges) + identifyNonFloatItems_helper(d, orientation); + break; + case AnchorData::Parallel: + identifyNonFloatItems_helper(static_cast(ad)->firstEdge, orientation); + identifyNonFloatItems_helper(static_cast(ad)->secondEdge, orientation); + break; + } +} + +/*! \internal Use the current vertices distance to calculate and set the geometry of @@ -2491,7 +2536,11 @@ bool QGraphicsAnchorLayoutPrivate::hasConflicts() const { QGraphicsAnchorLayoutPrivate *that = const_cast(this); that->calculateGraphs(); - return graphHasConflicts[0] || graphHasConflicts[1]; + + bool floatConflict = (m_nonFloatItems[0].size() < items.size()) + || (m_nonFloatItems[1].size() < items.size()); + + return graphHasConflicts[0] || graphHasConflicts[1] || floatConflict; } #ifdef QT_DEBUG diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index aac4f96..1a74d85 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -445,6 +445,8 @@ public: void constraintsFromPaths(Orientation orientation); QList constraintsFromSizeHints(const QList &anchors); QList > getGraphParts(Orientation orientation); + void identifyNonFloatItems(QSet visited, Orientation orientation); + void identifyNonFloatItems_helper(const AnchorData *ad, Orientation orientation); inline AnchorVertex *internalVertex(const QPair &itemEdge) const { @@ -511,6 +513,7 @@ public: // ### bool graphSimplified[2]; bool graphHasConflicts[2]; + QSet m_nonFloatItems[2]; uint calculateGraphCacheDirty : 1; }; -- cgit v0.12