summaryrefslogtreecommitdiffstats
path: root/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp')
-rw-r--r--src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp157
1 files changed, 68 insertions, 89 deletions
diff --git a/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp b/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp
index dac8e61645..53db11d2d7 100644
--- a/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp
+++ b/src/widgets/graphicsview/qgraphicsanchorlayout_p.cpp
@@ -1,36 +1,44 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
+#include "qgraphicsanchorlayout_p.h"
+
#include <QtWidgets/qwidget.h>
#include <QtWidgets/qapplication.h>
#include <QtCore/qlinkedlist.h>
@@ -40,7 +48,7 @@
#include <QtCore/qfile.h>
#endif
-#include "qgraphicsanchorlayout_p.h"
+#include <numeric>
#ifndef QT_NO_GRAPHICSVIEW
QT_BEGIN_NAMESPACE
@@ -602,10 +610,10 @@ QSimplexConstraint *GraphPath::constraint(const GraphPath &path) const
QString GraphPath::toString() const
{
QString string(QLatin1String("Path: "));
- foreach(AnchorData *edge, positives)
+ for (AnchorData *edge : positives)
string += QString::fromLatin1(" (+++) %1").arg(edge->toString());
- foreach(AnchorData *edge, negatives)
+ for (AnchorData *edge : negatives)
string += QString::fromLatin1(" (---) %1").arg(edge->toString());
return string;
@@ -1258,7 +1266,7 @@ void QGraphicsAnchorLayoutPrivate::restoreSimplifiedGraph(Orientation orientatio
// Restore anchor simplification
Graph<AnchorVertex, AnchorData> &g = graph[orientation];
- QList<QPair<AnchorVertex*, AnchorVertex*> > connections = g.connections();
+ QVector<QPair<AnchorVertex*, AnchorVertex*> > connections = g.connections();
for (int i = 0; i < connections.count(); ++i) {
AnchorVertex *v1 = connections.at(i).first;
AnchorVertex *v2 = connections.at(i).second;
@@ -1932,8 +1940,7 @@ void QGraphicsAnchorLayoutPrivate::removeVertex(QGraphicsLayoutItem *item, Qt::A
if (AnchorVertex *v = internalVertex(item, edge)) {
Graph<AnchorVertex, AnchorData> &g = graph[edgeOrientation(edge)];
const QList<AnchorVertex *> allVertices = graph[edgeOrientation(edge)].adjacentVertices(v);
- AnchorVertex *v2;
- foreach (v2, allVertices) {
+ for (auto *v2 : allVertices) {
g.removeEdge(v, v2);
removeInternalVertex(item, edge);
removeInternalVertex(v2->m_item, v2->m_edge);
@@ -2057,9 +2064,8 @@ QList<AnchorData *> getVariables(const QList<QSimplexConstraint *> &constraints)
QSet<AnchorData *> variableSet;
for (int i = 0; i < constraints.count(); ++i) {
const QSimplexConstraint *c = constraints.at(i);
- foreach (QSimplexVariable *var, c->variables.keys()) {
- variableSet += static_cast<AnchorData *>(var);
- }
+ for (auto it = c->variables.cbegin(), end = c->variables.cend(); it != end; ++it)
+ variableSet.insert(static_cast<AnchorData *>(it.key()));
}
return variableSet.toList();
}
@@ -2123,34 +2129,28 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs(
// 2) The floating or semi-floating anchors (items) that are those which
// are connected to only one (or none) of the layout sides, thus are not
// influenced by the layout size.
- QList<QList<QSimplexConstraint *> > parts = getGraphParts(orientation);
+ const auto parts = getGraphParts(orientation);
// Now run the simplex solver to calculate Minimum, Preferred and Maximum sizes
// of the "trunk" set of constraints and variables.
// ### does trunk always exist? empty = trunk is the layout left->center->right
- QList<QSimplexConstraint *> trunkConstraints = parts.at(0);
- QList<AnchorData *> trunkVariables = getVariables(trunkConstraints);
+ const QList<AnchorData *> trunkVariables = getVariables(parts.trunkConstraints);
// For minimum and maximum, use the path between the two layout sides as the
// objective function.
AnchorVertex *v = layoutLastVertex[orientation];
GraphPath trunkPath = graphPaths[orientation].value(v);
- bool feasible = calculateTrunk(orientation, trunkPath, trunkConstraints, trunkVariables);
+ bool feasible = calculateTrunk(orientation, trunkPath, parts.trunkConstraints, trunkVariables);
// For the other parts that not the trunk, solve only for the preferred size
// that is the size they will remain at, since they are not stretched by the
// layout.
- // Skipping the first (trunk)
- for (int i = 1; i < parts.count(); ++i) {
- if (!feasible)
- break;
-
- QList<QSimplexConstraint *> partConstraints = parts.at(i);
- QList<AnchorData *> partVariables = getVariables(partConstraints);
+ if (feasible && !parts.nonTrunkConstraints.isEmpty()) {
+ const QList<AnchorData *> partVariables = getVariables(parts.nonTrunkConstraints);
Q_ASSERT(!partVariables.isEmpty());
- feasible &= calculateNonTrunk(partConstraints, partVariables);
+ feasible = calculateNonTrunk(parts.nonTrunkConstraints, partVariables);
}
// Propagate the new sizes down the simplified graph, ie. tell the
@@ -2180,10 +2180,7 @@ static void shiftConstraints(const QList<QSimplexConstraint *> &constraints, qre
{
for (int i = 0; i < constraints.count(); ++i) {
QSimplexConstraint *c = constraints.at(i);
- qreal multiplier = 0;
- foreach (qreal v, c->variables) {
- multiplier += v;
- }
+ const qreal multiplier = std::accumulate(c->variables.cbegin(), c->variables.cend(), qreal(0));
c->constant += multiplier * amount;
}
}
@@ -2223,12 +2220,10 @@ bool QGraphicsAnchorLayoutPrivate::calculateTrunk(Orientation orientation, const
// Calculate and set the preferred size for the layout,
// from the edge sizes that were calculated above.
qreal pref(0.0);
- foreach (const AnchorData *ad, path.positives) {
+ for (const AnchorData *ad : path.positives)
pref += ad->sizeAtPreferred;
- }
- foreach (const AnchorData *ad, path.negatives) {
+ for (const AnchorData *ad : path.negatives)
pref -= ad->sizeAtPreferred;
- }
sizeHints[orientation][Qt::MinimumSize] = min;
sizeHints[orientation][Qt::PreferredSize] = pref;
@@ -2244,7 +2239,7 @@ bool QGraphicsAnchorLayoutPrivate::calculateTrunk(Orientation orientation, const
Q_ASSERT(path.positives.count() == 1);
Q_ASSERT(path.negatives.count() == 0);
- AnchorData *ad = path.positives.toList()[0];
+ AnchorData *ad = *path.positives.cbegin();
ad->sizeAtMinimum = ad->minSize;
ad->sizeAtPreferred = ad->prefSize;
ad->sizeAtMaximum = ad->maxSize;
@@ -2294,7 +2289,7 @@ bool QGraphicsAnchorLayoutPrivate::calculateNonTrunk(const QList<QSimplexConstra
void QGraphicsAnchorLayoutPrivate::refreshAllSizeHints(Orientation orientation)
{
Graph<AnchorVertex, AnchorData> &g = graph[orientation];
- QList<QPair<AnchorVertex *, AnchorVertex *> > vertices = g.connections();
+ QVector<QPair<AnchorVertex *, AnchorVertex *> > vertices = g.connections();
QLayoutStyleInfo styleInf = styleInfo();
for (int i = 0; i < vertices.count(); ++i) {
@@ -2323,9 +2318,9 @@ void QGraphicsAnchorLayoutPrivate::findPaths(Orientation orientation)
graphPaths[orientation].insert(root, GraphPath());
- foreach (AnchorVertex *v, graph[orientation].adjacentVertices(root)) {
+ const auto adjacentVertices = graph[orientation].adjacentVertices(root);
+ for (AnchorVertex *v : adjacentVertices)
queue.enqueue(qMakePair(root, v));
- }
while(!queue.isEmpty()) {
QPair<AnchorVertex *, AnchorVertex *> pair = queue.dequeue();
@@ -2344,10 +2339,9 @@ void QGraphicsAnchorLayoutPrivate::findPaths(Orientation orientation)
graphPaths[orientation].insert(pair.second, current);
- foreach (AnchorVertex *v,
- graph[orientation].adjacentVertices(pair.second)) {
+ const auto adjacentVertices = graph[orientation].adjacentVertices(pair.second);
+ for (AnchorVertex *v : adjacentVertices)
queue.enqueue(qMakePair(pair.second, v));
- }
}
// We will walk through every reachable items (non-float) store them in a temporary set.
@@ -2368,8 +2362,8 @@ void QGraphicsAnchorLayoutPrivate::findPaths(Orientation orientation)
*/
void QGraphicsAnchorLayoutPrivate::constraintsFromPaths(Orientation orientation)
{
- foreach (AnchorVertex *vertex, graphPaths[orientation].uniqueKeys())
- {
+ const auto vertices = graphPaths[orientation].uniqueKeys();
+ for (AnchorVertex *vertex : vertices) {
int valueCount = graphPaths[orientation].count(vertex);
if (valueCount == 1)
continue;
@@ -2388,7 +2382,7 @@ void QGraphicsAnchorLayoutPrivate::constraintsFromPaths(Orientation orientation)
void QGraphicsAnchorLayoutPrivate::updateAnchorSizes(Orientation orientation)
{
Graph<AnchorVertex, AnchorData> &g = graph[orientation];
- const QList<QPair<AnchorVertex *, AnchorVertex *> > &vertices = g.connections();
+ const QVector<QPair<AnchorVertex *, AnchorVertex *> > &vertices = g.connections();
for (int i = 0; i < vertices.count(); ++i) {
AnchorData *ad = g.edgeData(vertices.at(i).first, vertices.at(i).second);
@@ -2496,9 +2490,11 @@ QList<QSimplexConstraint *> QGraphicsAnchorLayoutPrivate::constraintsFromSizeHin
/*!
\internal
*/
-QList< QList<QSimplexConstraint *> >
+QGraphicsAnchorLayoutPrivate::GraphParts
QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation)
{
+ GraphParts result;
+
Q_ASSERT(layoutFirstVertex[orientation] && layoutLastVertex[orientation]);
AnchorData *edgeL1 = 0;
@@ -2513,15 +2509,8 @@ QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation)
edgeL1 = graph[orientation].edgeData(layoutFirstVertex[orientation], layoutLastVertex[orientation]);
}
- QLinkedList<QSimplexConstraint *> remainingConstraints;
- for (int i = 0; i < constraints[orientation].count(); ++i) {
- remainingConstraints += constraints[orientation].at(i);
- }
- for (int i = 0; i < itemCenterConstraints[orientation].count(); ++i) {
- remainingConstraints += itemCenterConstraints[orientation].at(i);
- }
+ result.nonTrunkConstraints = constraints[orientation] + itemCenterConstraints[orientation];
- QList<QSimplexConstraint *> trunkConstraints;
QSet<QSimplexVariable *> trunkVariables;
trunkVariables += edgeL1;
@@ -2529,12 +2518,11 @@ QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation)
trunkVariables += edgeL2;
bool dirty;
+ auto end = result.nonTrunkConstraints.end();
do {
dirty = false;
- QLinkedList<QSimplexConstraint *>::iterator it = remainingConstraints.begin();
- while (it != remainingConstraints.end()) {
- QSimplexConstraint *c = *it;
+ auto isMatch = [&result, &trunkVariables](QSimplexConstraint *c) -> bool {
bool match = false;
// Check if this constraint have some overlap with current
@@ -2549,10 +2537,10 @@ QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation)
// If so, we add it to trunk, and erase it from the
// remaining constraints.
if (match) {
- trunkConstraints += c;
- trunkVariables += QSet<QSimplexVariable *>::fromList(c->variables.keys());
- it = remainingConstraints.erase(it);
- dirty = true;
+ result.trunkConstraints += c;
+ for (auto jt = c->variables.cbegin(), end = c->variables.cend(); jt != end; ++jt)
+ trunkVariables.insert(jt.key());
+ return true;
} else {
// Note that we don't erase the constraint if it's not
// a match, since in a next iteration of a do-while we
@@ -2562,24 +2550,15 @@ QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation)
// remainingConstraints[1] and it shares with
// remainingConstraints[0], we need a second iteration
// of the do-while loop to match both.
- ++it;
+ return false;
}
- }
+ };
+ const auto newEnd = std::remove_if(result.nonTrunkConstraints.begin(), end, isMatch);
+ dirty = newEnd != end;
+ end = newEnd;
} while (dirty);
- QList< QList<QSimplexConstraint *> > result;
- result += trunkConstraints;
-
- if (!remainingConstraints.isEmpty()) {
- QList<QSimplexConstraint *> nonTrunkConstraints;
- nonTrunkConstraints.reserve(remainingConstraints.size());
- QLinkedList<QSimplexConstraint *>::iterator it = remainingConstraints.begin();
- while (it != remainingConstraints.end()) {
- nonTrunkConstraints += *it;
- ++it;
- }
- result += nonTrunkConstraints;
- }
+ result.nonTrunkConstraints.erase(end, result.nonTrunkConstraints.end());
return result;
}
@@ -2593,7 +2572,7 @@ void QGraphicsAnchorLayoutPrivate::identifyFloatItems(const QSet<AnchorData *> &
{
QSet<QGraphicsLayoutItem *> nonFloating;
- foreach (const AnchorData *ad, visited)
+ for (const AnchorData *ad : visited)
identifyNonFloatItems_helper(ad, &nonFloating);
QSet<QGraphicsLayoutItem *> allItems;
@@ -2707,9 +2686,9 @@ void QGraphicsAnchorLayoutPrivate::calculateVertexPositions(
visited.insert(root);
// Add initial edges to the queue
- foreach (AnchorVertex *v, graph[orientation].adjacentVertices(root)) {
+ const auto adjacentVertices = graph[orientation].adjacentVertices(root);
+ for (AnchorVertex *v : adjacentVertices)
queue.enqueue(qMakePair(root, v));
- }
// Do initial calculation required by "interpolateEdge()"
setupEdgesInterpolation(orientation);
@@ -2796,7 +2775,7 @@ void QGraphicsAnchorLayoutPrivate::interpolateEdge(AnchorVertex *base, AnchorDat
}
bool QGraphicsAnchorLayoutPrivate::solveMinMax(const QList<QSimplexConstraint *> &constraints,
- GraphPath path, qreal *min, qreal *max)
+ const GraphPath &path, qreal *min, qreal *max)
{
QSimplex simplex;
bool feasible = simplex.setConstraints(constraints);
@@ -2983,7 +2962,7 @@ void QGraphicsAnchorLayoutPrivate::dumpGraph(const QString &name)
{
QFile file(QString::fromLatin1("anchorlayout.%1.dot").arg(name));
if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate))
- qWarning("Could not write to %s", file.fileName().toLocal8Bit().constData());
+ qWarning("Could not write to %ls", qUtf16Printable(file.fileName()));
QString str = QString::fromLatin1("digraph anchorlayout {\nnode [shape=\"rect\"]\n%1}");
QString dotContents = graph[0].serializeToDot();