From 933e74473a23c0090eaaae9c6122a0e0d192df15 Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Tue, 22 Sep 2009 16:24:07 -0300 Subject: QGraphicsAnchorLayout: add autotests for QSizePolicy::ExpandFlag Add autotests that use the ExpandFlag via QSizePolicy::Expanding policy. Those tests cover the simple cases and behaviours with sequential and parallel anchor setups. Signed-off-by: Caio Marcelo de Oliveira Filho Reviewed-by: Jesus Sanchez-Palencia --- .../tst_qgraphicsanchorlayout.cpp | 214 +++++++++++++++++++++ 1 file changed, 214 insertions(+) diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index 9f13aca..e898edb 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -69,6 +69,9 @@ private slots: void delete_anchor(); void conflicts(); void sizePolicy(); + void expandingSequence(); + void expandingSequenceFairDistribution(); + void expandingParallel(); }; class RectWidget : public QGraphicsWidget @@ -586,6 +589,20 @@ void tst_QGraphicsAnchorLayout::snake() QCOMPARE(b->geometry(), QRectF(90.0, 100.0, 10.0, 100.0)); QCOMPARE(c->geometry(), QRectF(90.0, 200.0, 100.0, 100.0)); QCOMPARE(p.size(), layoutMaximumSize); + + QVERIFY(layoutHasConflict(l) == false); + + // Test QSizePolicy::ExpandFlag, it shouldn't change the extreme + // points of the layout... + b->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + + QSizeF newLayoutMinimumSize = l->effectiveSizeHint(Qt::MinimumSize); + QSizeF newLayoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize); + QSizeF newLayoutPreferredSize = l->effectiveSizeHint(Qt::PreferredSize); + + QCOMPARE(layoutMinimumSize, newLayoutMinimumSize); + QCOMPARE(layoutMaximumSize, newLayoutMaximumSize); + QCOMPARE(layoutPreferredSize, newLayoutPreferredSize); } void tst_QGraphicsAnchorLayout::snakeOppositeDirections() @@ -1308,5 +1325,202 @@ void tst_QGraphicsAnchorLayout::conflicts() delete p; } +void tst_QGraphicsAnchorLayout::expandingSequence() +{ + QSizeF min(10, 10); + QSizeF pref(50, 10); + QSizeF max(100, 10); + + QGraphicsWidget *a = createItem(min, pref, max, "a"); + QGraphicsWidget *b = createItem(min, pref, max, "b"); + + b->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + + QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; + l->setContentsMargins(0, 0, 0, 0); + + // horizontal + setAnchor(l, l, Qt::AnchorLeft, a, Qt::AnchorLeft, 0); + setAnchor(l, a, Qt::AnchorRight, b, Qt::AnchorLeft, 0); + setAnchor(l, b, Qt::AnchorRight, l, Qt::AnchorRight, 0); + + // vertical + l->addAnchors(l, a, Qt::Vertical); + l->addAnchors(l, b, Qt::Vertical); + + QCOMPARE(l->count(), 2); + + QGraphicsWidget p; + p.setLayout(l); + + QSizeF layoutMinimumSize = l->effectiveSizeHint(Qt::MinimumSize); + QCOMPARE(layoutMinimumSize.width(), qreal(20)); + + QSizeF layoutExpandedSize(pref.width() + max.width(), layoutMinimumSize.height()); + p.resize(layoutExpandedSize); + + QEXPECT_FAIL("", "Support for QSizePolicy::ExpandFlag not yet available", Abort); + QCOMPARE(a->geometry().size(), pref); + QCOMPARE(b->geometry().size(), max); + + QSizeF layoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize); + QCOMPARE(layoutMaximumSize.width(), qreal(200)); +} + +void tst_QGraphicsAnchorLayout::expandingSequenceFairDistribution() +{ + QSizeF min(10, 10); + QSizeF pref(50, 10); + QSizeF max(100, 10); + + QGraphicsWidget *a = createItem(min, pref, max, "a"); + QGraphicsWidget *b = createItem(min, pref, max, "b"); + QGraphicsWidget *c = createItem(min, pref, max, "c"); + QGraphicsWidget *d = createItem(min, pref, max, "d"); + + b->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + d->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + + QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; + l->setContentsMargins(0, 0, 0, 0); + + // horizontal + setAnchor(l, l, Qt::AnchorLeft, a, Qt::AnchorLeft, 0); + setAnchor(l, a, Qt::AnchorRight, b, Qt::AnchorLeft, 0); + setAnchor(l, b, Qt::AnchorRight, c, Qt::AnchorLeft, 0); + setAnchor(l, c, Qt::AnchorRight, d, Qt::AnchorLeft, 0); + setAnchor(l, d, Qt::AnchorRight, l, Qt::AnchorRight, 0); + + // vertical + l->addAnchors(l, a, Qt::Vertical); + l->addAnchors(l, b, Qt::Vertical); + l->addAnchors(l, c, Qt::Vertical); + l->addAnchors(l, d, Qt::Vertical); + + QCOMPARE(l->count(), 4); + + QGraphicsWidget p; + p.setLayout(l); + + QSizeF layoutMinimumSize = l->effectiveSizeHint(Qt::MinimumSize); + QCOMPARE(layoutMinimumSize.width(), qreal(40)); + + QSizeF layoutPartialExpandedSize((2 * pref.width()) + (2 * (pref.width() + 10)), + layoutMinimumSize.height()); + p.resize(layoutPartialExpandedSize); + + QEXPECT_FAIL("", "Support for QSizePolicy::ExpandFlag not yet available", Abort); + QCOMPARE(a->geometry().size(), pref); + QCOMPARE(b->geometry().size(), pref + QSizeF(10, 0)); + QCOMPARE(c->geometry().size(), pref); + QCOMPARE(d->geometry().size(), pref + QSizeF(10, 0)); + + QSizeF layoutExpandedSize((2 * pref.width()) + (2 * max.width()), + layoutMinimumSize.height()); + p.resize(layoutExpandedSize); + + QCOMPARE(a->geometry().size(), pref); + QCOMPARE(b->geometry().size(), max); + QCOMPARE(c->geometry().size(), pref); + QCOMPARE(d->geometry().size(), max); + + QSizeF layoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize); + QCOMPARE(layoutMaximumSize.width(), qreal(400)); + + // Now we change D to have more "room for growth" from its preferred size + // to its maximum size. We expect a proportional fair distribution. Note that + // this seems to not conform with what QGraphicsLinearLayout does. + d->setMaximumSize(QSizeF(150, 10)); + + QSizeF newLayoutExpandedSize((2 * pref.width()) + (max.width() + 150), + layoutMinimumSize.height()); + p.resize(newLayoutExpandedSize); + + QCOMPARE(a->geometry().size(), pref); + QCOMPARE(b->geometry().size(), max); + QCOMPARE(c->geometry().size(), pref); + QCOMPARE(d->geometry().size(), QSizeF(150, 10)); + + QSizeF newLayoutPartialExpandedSize((4 * pref.width()) + 75, + layoutMinimumSize.height()); + + QCOMPARE(a->geometry().size(), pref); + QCOMPARE(b->geometry().size(), pref + QSizeF(25, 0)); + QCOMPARE(c->geometry().size(), pref); + QCOMPARE(d->geometry().size(), pref + QSizeF(50, 0)); +} + +void tst_QGraphicsAnchorLayout::expandingParallel() +{ + QSizeF min(10, 10); + QSizeF pref(50, 10); + QSizeF max(100, 50); + + QGraphicsWidget *a = createItem(min, pref, max, "a"); + QGraphicsWidget *b = createItem(min, pref, max, "b"); + QGraphicsWidget *c = createItem(min, pref, max, "c"); + + b->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + + QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; + l->setContentsMargins(0, 0, 0, 0); + + // horizontal + setAnchor(l, l, Qt::AnchorLeft, a, Qt::AnchorLeft, 0); + setAnchor(l, l, Qt::AnchorLeft, b, Qt::AnchorLeft, 0); + + setAnchor(l, a, Qt::AnchorRight, c, Qt::AnchorLeft, 0); + setAnchor(l, b, Qt::AnchorRight, c, Qt::AnchorLeft, 0); + + setAnchor(l, c, Qt::AnchorRight, l, Qt::AnchorRight, 0); + + // vertical + l->addAnchors(l, c, Qt::Vertical); + setAnchor(l, l, Qt::AnchorTop, a, Qt::AnchorTop, 0); + setAnchor(l, a, Qt::AnchorBottom, c, Qt::AnchorVerticalCenter, 0); + setAnchor(l, b, Qt::AnchorTop, c, Qt::AnchorVerticalCenter, 0); + setAnchor(l, b, Qt::AnchorBottom, l, Qt::AnchorBottom, 0); + + QCOMPARE(l->count(), 3); + + QGraphicsWidget p; + p.setLayout(l); + + QSizeF layoutMinimumSize = l->effectiveSizeHint(Qt::MinimumSize); + QCOMPARE(layoutMinimumSize.width(), qreal(20)); + + QSizeF layoutExpandedSize(pref.width() + max.width(), layoutMinimumSize.height()); + p.resize(layoutExpandedSize); + + QEXPECT_FAIL("", "Support for QSizePolicy::ExpandFlag not yet available", Abort); + QCOMPARE(a->geometry().size(), max); + QCOMPARE(b->geometry().size(), max); + QCOMPARE(c->geometry().size(), pref); + + QSizeF layoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize); + QCOMPARE(layoutMaximumSize.width(), qreal(200)); + + // + // Change the parallel connection to a paralell connection of b with a center... + // + QGraphicsAnchor *anchor = l->anchor(b, Qt::AnchorRight, c, Qt::AnchorLeft); + delete anchor; + setAnchor(l, b, Qt::AnchorRight, a, Qt::AnchorHorizontalCenter, 0); + a->setMaximumSize(max + QSizeF(100, 0)); + + QSizeF newLayoutMinimumSize = l->effectiveSizeHint(Qt::MinimumSize); + QCOMPARE(newLayoutMinimumSize.width(), qreal(30)); + + QSizeF newLayoutExpandedSize(pref.width() + max.width(), layoutMinimumSize.height()); + p.resize(newLayoutExpandedSize); + + QCOMPARE(a->geometry().size(), max); + QCOMPARE(b->geometry().size(), max); + QCOMPARE(c->geometry().size(), pref); + + QSizeF newLayoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize); + QCOMPARE(newLayoutMaximumSize.width(), qreal(300)); +} + QTEST_MAIN(tst_QGraphicsAnchorLayout) #include "tst_qgraphicsanchorlayout.moc" -- cgit v0.12 From bfc1a75616e1c96a018349084fae844d7efbc177 Mon Sep 17 00:00:00 2001 From: "Eduardo M. Fleury" Date: Tue, 22 Sep 2009 14:20:10 -0300 Subject: QGraphicsAnchorLayout: Add data structures for Expanding size policy Adding required members for the upcoming support of the QSizePolicy::Expand flag. In this state, running with simplification will probably not work. Signed-off-by: Eduardo M. Fleury Reviewed-by: Artur Duque de Souza --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 44 +++++++++++++++++++----- src/gui/graphicsview/qgraphicsanchorlayout_p.h | 20 ++++++++--- 2 files changed, 51 insertions(+), 13 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index f75118b..fc3bc8a 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -94,7 +94,9 @@ qreal QGraphicsAnchorPrivate::spacing() const void AnchorData::refreshSizeHints(qreal effectiveSpacing) { - if (!isLayoutAnchor && from->m_item == to->m_item) { + isExpanding = 0; + + if (!isLayoutAnchor && (from->m_item == to->m_item)) { QGraphicsLayoutItem *item = from->m_item; const QGraphicsAnchorLayoutPrivate::Orientation orient = QGraphicsAnchorLayoutPrivate::edgeOrientation(from->m_edge); @@ -138,6 +140,9 @@ void AnchorData::refreshSizeHints(qreal effectiveSpacing) if (policy & QSizePolicy::IgnoreFlag) prefSize = minSize; + if (policy & QSizePolicy::ExpandFlag) + isExpanding = 1; + bool hasCenter = (from->m_edge == centerEdge || to->m_edge == centerEdge); if (hasCenter) { @@ -155,6 +160,7 @@ void AnchorData::refreshSizeHints(qreal effectiveSpacing) // recalculate and override the values we set here. sizeAtMinimum = prefSize; sizeAtPreferred = prefSize; + sizeAtExpanding = prefSize; sizeAtMaximum = prefSize; } else if (!hasSize) { @@ -165,6 +171,7 @@ void AnchorData::refreshSizeHints(qreal effectiveSpacing) sizeAtMinimum = prefSize; sizeAtPreferred = prefSize; + sizeAtExpanding = prefSize; sizeAtMaximum = prefSize; } } @@ -357,6 +364,12 @@ QGraphicsAnchorLayoutPrivate::QGraphicsAnchorLayoutPrivate() : calculateGraphCacheDirty(1) { for (int i = 0; i < NOrientations; ++i) { + for (int j = 0; j < 3; ++j) { + sizeHints[i][j] = -1; + } + sizeAtExpanding[i] = -1; + interpolationProgress[i] = -1; + spacings[i] = -1; graphSimplified[i] = false; graphHasConflicts[i] = false; @@ -1649,6 +1662,10 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( sizeHints[orientation][Qt::PreferredSize] = pref; sizeHints[orientation][Qt::MaximumSize] = max; + // XXX implement Expanding simplex + for (int i = 0; i < trunkVariables.count(); ++i) + trunkVariables.at(i)->sizeAtExpanding = trunkVariables.at(i)->sizeAtPreferred; + sizeAtExpanding[orientation] = pref; } } else { #if 0 @@ -1664,6 +1681,7 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( AnchorData *ad = trunkPath.positives.toList()[0]; ad->sizeAtMinimum = ad->minSize; ad->sizeAtPreferred = ad->prefSize; + ad->sizeAtExpanding = ad->prefSize; ad->sizeAtMaximum = ad->maxSize; // Propagate @@ -1672,6 +1690,7 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( sizeHints[orientation][Qt::MinimumSize] = ad->sizeAtMinimum; sizeHints[orientation][Qt::PreferredSize] = ad->sizeAtPreferred; sizeHints[orientation][Qt::MaximumSize] = ad->sizeAtMaximum; + sizeAtExpanding[orientation] = ad->sizeAtPreferred; } // Delete the constraints, we won't use them anymore. @@ -1701,6 +1720,7 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( AnchorData *ad = partVariables[j]; Q_ASSERT(ad); ad->sizeAtMinimum = ad->sizeAtPreferred; + ad->sizeAtExpanding = ad->sizeAtPreferred; ad->sizeAtMaximum = ad->sizeAtPreferred; ad->updateChildrenSizes(); } @@ -2058,9 +2078,13 @@ void QGraphicsAnchorLayoutPrivate::setupEdgesInterpolation( interpolationInterval[orientation] = MinToPreferred; lower = sizeHints[orientation][Qt::MinimumSize]; upper = sizeHints[orientation][Qt::PreferredSize]; - } else { - interpolationInterval[orientation] = PreferredToMax; + } else if (current < sizeAtExpanding[orientation]) { + interpolationInterval[orientation] = PreferredToExpanding; lower = sizeHints[orientation][Qt::PreferredSize]; + upper = sizeAtExpanding[orientation]; + } else { + interpolationInterval[orientation] = ExpandingToMax; + lower = sizeAtExpanding[orientation]; upper = sizeHints[orientation][Qt::MaximumSize]; } @@ -2075,11 +2099,12 @@ void QGraphicsAnchorLayoutPrivate::setupEdgesInterpolation( \internal Calculate the current Edge size based on the current Layout size and the - size the edge is supposed to have when: + size the edge is supposed to have when the layout is at its: - - the layout is at its minimum size. - - the layout is at its preferred size. - - the layout is at its maximum size. + - minimum size, + - preferred size, + - size when all expanding anchors are expanded, + - maximum size. These three key values are calculated in advance using linear programming (more expensive) or the simplification algorithm, then @@ -2099,8 +2124,11 @@ void QGraphicsAnchorLayoutPrivate::interpolateEdge(AnchorVertex *base, if (interpolationInterval[orientation] == MinToPreferred) { lower = edge->sizeAtMinimum; upper = edge->sizeAtPreferred; - } else { + } else if (interpolationInterval[orientation] == PreferredToExpanding) { lower = edge->sizeAtPreferred; + upper = edge->sizeAtExpanding; + } else { + lower = edge->sizeAtExpanding; upper = edge->sizeAtMaximum; } diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index c86bfa3..4c6c2aa 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -153,7 +153,8 @@ struct AnchorData : public QSimplexVariable { : QSimplexVariable(), from(0), to(0), minSize(minimumSize), prefSize(preferredSize), maxSize(maximumSize), sizeAtMinimum(preferredSize), - sizeAtPreferred(preferredSize), sizeAtMaximum(preferredSize), + sizeAtPreferred(preferredSize), sizeAtExpanding(preferredSize), + sizeAtMaximum(preferredSize), graphicsAnchor(0), skipInPreferred(0), type(Normal), hasSize(true), isLayoutAnchor(false) {} @@ -161,7 +162,8 @@ struct AnchorData : public QSimplexVariable { AnchorData(qreal size) : QSimplexVariable(), from(0), to(0), minSize(size), prefSize(size), maxSize(size), - sizeAtMinimum(size), sizeAtPreferred(size), sizeAtMaximum(size), + sizeAtMinimum(size), sizeAtPreferred(size), sizeAtExpanding(size), + sizeAtMaximum(size), graphicsAnchor(0), skipInPreferred(0), type(Normal), hasSize(true), isLayoutAnchor(false) {} @@ -169,7 +171,8 @@ struct AnchorData : public QSimplexVariable { AnchorData() : QSimplexVariable(), from(0), to(0), minSize(0), prefSize(0), maxSize(0), - sizeAtMinimum(0), sizeAtPreferred(0), sizeAtMaximum(0), + sizeAtMinimum(0), sizeAtPreferred(0), sizeAtExpanding(0), + sizeAtMaximum(0), graphicsAnchor(0), skipInPreferred(0), type(Normal), hasSize(false), isLayoutAnchor(false) {} @@ -192,6 +195,7 @@ struct AnchorData : public QSimplexVariable { maxSize = size; sizeAtMinimum = size; sizeAtPreferred = size; + sizeAtExpanding = size; sizeAtMaximum = size; hasSize = true; } @@ -218,6 +222,7 @@ struct AnchorData : public QSimplexVariable { // calculated by the Simplex solver based on the current layout setup. qreal sizeAtMinimum; qreal sizeAtPreferred; + qreal sizeAtExpanding; qreal sizeAtMaximum; QGraphicsAnchor *graphicsAnchor; @@ -225,12 +230,15 @@ struct AnchorData : public QSimplexVariable { uint type : 2; // either Normal, Sequential or Parallel uint hasSize : 1; // if false, get size from style. uint isLayoutAnchor : 1; // if this anchor is connected to a layout 'edge' + uint isExpanding : 1; // if true, expands before other anchors + protected: AnchorData(Type type, qreal size = 0) : QSimplexVariable(), from(0), to(0), minSize(size), prefSize(size), maxSize(size), sizeAtMinimum(size), - sizeAtPreferred(size), sizeAtMaximum(size), + sizeAtPreferred(size), sizeAtExpanding(size), + sizeAtMaximum(size), graphicsAnchor(0), skipInPreferred(0), type(type), hasSize(true), isLayoutAnchor(false) {} @@ -355,7 +363,8 @@ public: // Interval represents which interpolation interval are we operating in. enum Interval { MinToPreferred = 0, - PreferredToMax + PreferredToExpanding, + ExpandingToMax }; // Several structures internal to the layout are duplicated to handle @@ -496,6 +505,7 @@ public: qreal spacings[NOrientations]; // Size hints from simplex engine qreal sizeHints[2][3]; + qreal sizeAtExpanding[2]; // Items QVector items; -- cgit v0.12 From 1728f846d9fb53a699782005d6478c0f23f9b82e Mon Sep 17 00:00:00 2001 From: "Eduardo M. Fleury" Date: Wed, 23 Sep 2009 16:02:35 -0300 Subject: QGraphicsAnchorLayout: Enabling Simplex support for Expanding size policy To support the expanding size policy we had to change the way the setup process work. Previously we used to calculate three key-frames using the simplex solver: - sizeAtMinimum: the value an anchor should be in when the layout is at its minimum size. Calculated using simplex solver to minimize the layout size. - sizeAtPreferred: the value an anchor should be in when the layout is at its preferred size. Calculated using simplex solver to minimize the deviation from the items preferred sizes. - sizeAtMaximum: the value an anchor should be in when the layout is at its maximum size. Calculated using simplex solver to maximize the layout size. That worked fine but didn't diferentiate standard items from the "expanding" ones. In other words, all items would grow from their sizeAtPreferred to their sizeAtMaximum at the same rate. To support the idea of "expanding" items, ie. items that should grow faster than the others, we added a fourth state, between preferred and maximum. Now we have the following interpolation order: sizeAtMinimum -> sizeAtPreferred -> sizeAtExpanding -> sizeAtMaximum. The definition of the "expanding" state is that all "expanding" items should have grown all the way to their "sizeAtMaximum" values whereas non expanding items should have kept their preferred sizes. The only exception is that non-expanding items are allowed to grow if that is necessary to allow the "expanding" items to reach their sizeAtMaximum. So, the visual result is that if the layout is resized from its preferred size to its maximum size, the expanding items will grow first and then, in a second phase, the other items will grow. This commit adds QGALPrivate::solveExpanding() and calls it from calculateGraphs(). Signed-off-by: Eduardo M. Fleury Reviewed-by: Artur Duque de Souza --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 98 +++++++++++++++++++++--- src/gui/graphicsview/qgraphicsanchorlayout_p.h | 1 + 2 files changed, 88 insertions(+), 11 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index fc3bc8a..93ccf83 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -1635,11 +1635,18 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( qreal min, max; feasible = solveMinMax(trunkConstraints, trunkPath, &min, &max); - // Solve for preferred. The objective function is calculated from the constraints - // and variables internally. - feasible &= solvePreferred(trunkConstraints); - if (feasible) { + // Solve for preferred. The objective function is calculated from the constraints + // and variables internally. + solvePreferred(trunkConstraints); + + // remove sizeHintConstraints from trunkConstraints + trunkConstraints = parts[0]; + + // Solve for expanding. The objective function and the constraints from items + // are calculated internally. + solveExpanding(trunkConstraints); + // Propagate the new sizes down the simplified graph, ie. tell the // group anchors to set their children anchors sizes. @@ -1649,23 +1656,23 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( for (int i = 0; i < trunkVariables.count(); ++i) trunkVariables.at(i)->updateChildrenSizes(); - // Calculate and set the preferred size for the layout from the edge sizes that - // were calculated above. + // Calculate and set the preferred and expanding sizes for the layout, + // from the edge sizes that were calculated above. qreal pref(0.0); + qreal expanding(0.0); foreach (const AnchorData *ad, trunkPath.positives) { pref += ad->sizeAtPreferred; + expanding += ad->sizeAtExpanding; } foreach (const AnchorData *ad, trunkPath.negatives) { pref -= ad->sizeAtPreferred; + expanding -= ad->sizeAtExpanding; } + sizeHints[orientation][Qt::MinimumSize] = min; sizeHints[orientation][Qt::PreferredSize] = pref; sizeHints[orientation][Qt::MaximumSize] = max; - - // XXX implement Expanding simplex - for (int i = 0; i < trunkVariables.count(); ++i) - trunkVariables.at(i)->sizeAtExpanding = trunkVariables.at(i)->sizeAtPreferred; - sizeAtExpanding[orientation] = pref; + sizeAtExpanding[orientation] = expanding; } } else { #if 0 @@ -2315,6 +2322,75 @@ bool QGraphicsAnchorLayoutPrivate::solvePreferred(QList co return feasible; } +void QGraphicsAnchorLayoutPrivate::solveExpanding(QList constraints) +{ + QList variables = getVariables(constraints); + QList itemConstraints; + QSimplexConstraint *objective = new QSimplexConstraint; + + // Use all items that belong to trunk to: + // - add solveExpanding-specific item constraints + // - create the objective function + for (int i = 0; i < variables.size(); ++i) { + AnchorData *ad = variables[i]; + if (ad->isExpanding) { + // Add constraint to lock expanding anchor in its sizeAtMaximum + QSimplexConstraint *itemC = new QSimplexConstraint; + itemC->ratio = QSimplexConstraint::Equal; + itemC->variables.insert(ad, 1.0); + itemC->constant = ad->sizeAtMaximum; + itemConstraints << itemC; + } else { + // Add constraints to lock anchor between their sizeAtPreferred and sizeAtMaximum + QSimplexConstraint *itemC = new QSimplexConstraint; + itemC->ratio = QSimplexConstraint::MoreOrEqual; + itemC->variables.insert(ad, 1.0); + itemC->constant = qMin(ad->sizeAtPreferred, ad->sizeAtMaximum); + itemConstraints << itemC; + + itemC = new QSimplexConstraint; + itemC->ratio = QSimplexConstraint::LessOrEqual; + itemC->variables.insert(ad, 1.0); + itemC->constant = qMax(ad->sizeAtPreferred, ad->sizeAtMaximum); + itemConstraints << itemC; + + // Add anchor to objective function + if (ad->sizeAtPreferred < ad->sizeAtMaximum) { + // Try to shrink this variable towards its sizeAtPreferred value + objective->variables.insert(ad, 1.0); + } else { + // Try to grow this variable towards its sizeAtPreferred value + objective->variables.insert(ad, -1.0); + } + } + } + + // Solve + if (objective->variables.size() == variables.size()) { + // If no anchors are expanding, we don't need to run the simplex + // Set all variables to their preferred size + for (int i = 0; i < variables.size(); ++i) { + variables[i]->sizeAtExpanding = variables[i]->sizeAtPreferred; + } + } else { + // Run simplex + QSimplex simplex; + bool feasible = simplex.setConstraints(constraints + itemConstraints); + Q_ASSERT(feasible); + + simplex.setObjective(objective); + simplex.solveMin(); + + // Collect results + for (int i = 0; i < variables.size(); ++i) { + variables[i]->sizeAtExpanding = variables[i]->result; + } + } + + delete objective; + qDeleteAll(itemConstraints); +} + /*! \internal Returns true if there are no arrangement that satisfies all constraints. diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 4c6c2aa..47df786 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -495,6 +495,7 @@ public: bool solveMinMax(QList constraints, GraphPath path, qreal *min, qreal *max); bool solvePreferred(QList constraints); + void solveExpanding(QList constraints); bool hasConflicts() const; #ifdef QT_DEBUG -- cgit v0.12 From e210bea72ef65f99babb4c6f5bd442184c671d3b Mon Sep 17 00:00:00 2001 From: "Eduardo M. Fleury" Date: Thu, 24 Sep 2009 11:16:16 -0300 Subject: QGraphicsAnchorLayout Tests: Enable expanding tests Removing QEXPECT_FAIL and making minor corrections on expected values. Signed-off-by: Eduardo M. Fleury Reviewed-by: Artur Duque de Souza --- .../qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index e898edb..4ad48c7 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -1359,7 +1359,6 @@ void tst_QGraphicsAnchorLayout::expandingSequence() QSizeF layoutExpandedSize(pref.width() + max.width(), layoutMinimumSize.height()); p.resize(layoutExpandedSize); - QEXPECT_FAIL("", "Support for QSizePolicy::ExpandFlag not yet available", Abort); QCOMPARE(a->geometry().size(), pref); QCOMPARE(b->geometry().size(), max); @@ -1409,7 +1408,6 @@ void tst_QGraphicsAnchorLayout::expandingSequenceFairDistribution() layoutMinimumSize.height()); p.resize(layoutPartialExpandedSize); - QEXPECT_FAIL("", "Support for QSizePolicy::ExpandFlag not yet available", Abort); QCOMPARE(a->geometry().size(), pref); QCOMPARE(b->geometry().size(), pref + QSizeF(10, 0)); QCOMPARE(c->geometry().size(), pref); @@ -1443,6 +1441,7 @@ void tst_QGraphicsAnchorLayout::expandingSequenceFairDistribution() QSizeF newLayoutPartialExpandedSize((4 * pref.width()) + 75, layoutMinimumSize.height()); + p.resize(newLayoutPartialExpandedSize); QCOMPARE(a->geometry().size(), pref); QCOMPARE(b->geometry().size(), pref + QSizeF(25, 0)); @@ -1454,11 +1453,12 @@ void tst_QGraphicsAnchorLayout::expandingParallel() { QSizeF min(10, 10); QSizeF pref(50, 10); - QSizeF max(100, 50); + QSizeF max(100, 10); + QSizeF max2(100, 50); QGraphicsWidget *a = createItem(min, pref, max, "a"); QGraphicsWidget *b = createItem(min, pref, max, "b"); - QGraphicsWidget *c = createItem(min, pref, max, "c"); + QGraphicsWidget *c = createItem(min, pref, max2, "c"); b->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); @@ -1492,10 +1492,9 @@ void tst_QGraphicsAnchorLayout::expandingParallel() QSizeF layoutExpandedSize(pref.width() + max.width(), layoutMinimumSize.height()); p.resize(layoutExpandedSize); - QEXPECT_FAIL("", "Support for QSizePolicy::ExpandFlag not yet available", Abort); QCOMPARE(a->geometry().size(), max); QCOMPARE(b->geometry().size(), max); - QCOMPARE(c->geometry().size(), pref); + QCOMPARE(c->geometry().size(), QSizeF(pref.width(), 20)); QSizeF layoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize); QCOMPARE(layoutMaximumSize.width(), qreal(200)); @@ -1511,12 +1510,12 @@ void tst_QGraphicsAnchorLayout::expandingParallel() QSizeF newLayoutMinimumSize = l->effectiveSizeHint(Qt::MinimumSize); QCOMPARE(newLayoutMinimumSize.width(), qreal(30)); - QSizeF newLayoutExpandedSize(pref.width() + max.width(), layoutMinimumSize.height()); + QSizeF newLayoutExpandedSize = layoutExpandedSize + QSizeF(100, 0); p.resize(newLayoutExpandedSize); - QCOMPARE(a->geometry().size(), max); + QCOMPARE(a->geometry().size(), max + QSizeF(100, 0)); QCOMPARE(b->geometry().size(), max); - QCOMPARE(c->geometry().size(), pref); + QCOMPARE(c->geometry().size(), QSizeF(pref.width(), 20)); QSizeF newLayoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize); QCOMPARE(newLayoutMaximumSize.width(), qreal(300)); -- cgit v0.12 From 5dd77be3acfb53b44d7d6b0015af0c33124ab84a Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Thu, 24 Sep 2009 17:09:16 -0300 Subject: QGraphicsAnchorLayout: cleaning up AnchorData Use just one constructor for AnchorData and tweak the struct when necessary. Also use the function refreshSizeHints() for Normal anchors to get the item information instead of passing to the constructor. This has the advantage that we don't need to replicate the code for checking and updating the size hint and size policies. Note that the code before only considered the size policies after the first refreshSizeHints() -- which we know will be called after the simplification, so the assumption seems to be correct, but we don't depend on that anymore.. Signed-off-by: Caio Marcelo de Oliveira Filho Reviewed-by: Eduardo M. Fleury --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 89 ++++++++++++------------ src/gui/graphicsview/qgraphicsanchorlayout_p.h | 53 ++++---------- 2 files changed, 59 insertions(+), 83 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 93ccf83..dc8d211 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -94,8 +94,6 @@ qreal QGraphicsAnchorPrivate::spacing() const void AnchorData::refreshSizeHints(qreal effectiveSpacing) { - isExpanding = 0; - if (!isLayoutAnchor && (from->m_item == to->m_item)) { QGraphicsLayoutItem *item = from->m_item; @@ -140,9 +138,6 @@ void AnchorData::refreshSizeHints(qreal effectiveSpacing) if (policy & QSizePolicy::IgnoreFlag) prefSize = minSize; - if (policy & QSizePolicy::ExpandFlag) - isExpanding = 1; - bool hasCenter = (from->m_edge == centerEdge || to->m_edge == centerEdge); if (hasCenter) { @@ -151,6 +146,14 @@ void AnchorData::refreshSizeHints(qreal effectiveSpacing) maxSize /= 2; } + if (policy & QSizePolicy::ExpandFlag) { + isExpanding = 1; + expSize = maxSize; + } else { + isExpanding = 0; + expSize = prefSize; + } + // Set the anchor effective sizes to preferred. // // Note: The idea here is that all items should remain at their @@ -167,8 +170,11 @@ void AnchorData::refreshSizeHints(qreal effectiveSpacing) // Anchor has no size defined, use given default information minSize = effectiveSpacing; prefSize = effectiveSpacing; + expSize = effectiveSpacing; maxSize = effectiveSpacing; + isExpanding = 0; + sizeAtMinimum = prefSize; sizeAtPreferred = prefSize; sizeAtExpanding = prefSize; @@ -830,9 +836,10 @@ void QGraphicsAnchorLayoutPrivate::createLayoutEdges() QGraphicsLayoutItem *layout = q; // Horizontal - AnchorData *data = new AnchorData(0, 0, QWIDGETSIZE_MAX); + AnchorData *data = new AnchorData; addAnchor_helper(layout, Qt::AnchorLeft, layout, - Qt::AnchorRight, data); + Qt::AnchorRight, data); + data->maxSize = QWIDGETSIZE_MAX; data->skipInPreferred = 1; // Set the Layout Left edge as the root of the horizontal graph. @@ -840,9 +847,10 @@ void QGraphicsAnchorLayoutPrivate::createLayoutEdges() graph[Horizontal].setRootVertex(v); // Vertical - data = new AnchorData(0, 0, QWIDGETSIZE_MAX); + data = new AnchorData; addAnchor_helper(layout, Qt::AnchorTop, layout, - Qt::AnchorBottom, data); + Qt::AnchorBottom, data); + data->maxSize = QWIDGETSIZE_MAX; data->skipInPreferred = 1; // Set the Layout Top edge as the root of the vertical graph. @@ -869,19 +877,15 @@ void QGraphicsAnchorLayoutPrivate::createItemEdges(QGraphicsLayoutItem *item) items.append(item); - QSizeF minSize = item->effectiveSizeHint(Qt::MinimumSize); - QSizeF prefSize = item->effectiveSizeHint(Qt::PreferredSize); - QSizeF maxSize = item->effectiveSizeHint(Qt::MaximumSize); - - // Horizontal - AnchorData *data = new AnchorData(minSize.width(), prefSize.width(), maxSize.width()); - addAnchor_helper(item, Qt::AnchorLeft, item, - Qt::AnchorRight, data); + // Create horizontal and vertical internal anchors for the item and + // refresh its size hint / policy values. + AnchorData *data = new AnchorData; + addAnchor_helper(item, Qt::AnchorLeft, item, Qt::AnchorRight, data); + data->refreshSizeHints(0); // 0 = effectiveSpacing, will not be used - // Vertical - data = new AnchorData(minSize.height(), prefSize.height(), maxSize.height()); - addAnchor_helper(item, Qt::AnchorTop, item, - Qt::AnchorBottom, data); + data = new AnchorData; + addAnchor_helper(item, Qt::AnchorTop, item, Qt::AnchorBottom, data); + data->refreshSizeHints(0); // 0 = effectiveSpacing, will not be used } /*! @@ -934,20 +938,17 @@ void QGraphicsAnchorLayoutPrivate::createCenterAnchors( Q_ASSERT(first && last); // Create new anchors - AnchorData *oldData = graph[orientation].edgeData(first, last); - - qreal minimumSize = oldData->minSize / 2; - qreal preferredSize = oldData->prefSize / 2; - qreal maximumSize = oldData->maxSize / 2; - QSimplexConstraint *c = new QSimplexConstraint; - AnchorData *data = new AnchorData(minimumSize, preferredSize, maximumSize); + + AnchorData *data = new AnchorData; c->variables.insert(data, 1.0); addAnchor_helper(item, firstEdge, item, centerEdge, data); + data->refreshSizeHints(0); - data = new AnchorData(minimumSize, preferredSize, maximumSize); + data = new AnchorData; c->variables.insert(data, -1.0); addAnchor_helper(item, centerEdge, item, lastEdge, data); + data->refreshSizeHints(0); itemCenterConstraints[orientation].append(c); @@ -1008,14 +1009,9 @@ void QGraphicsAnchorLayoutPrivate::removeCenterAnchors( if (substitute) { // Create the new anchor that should substitute the left-center-right anchors. - AnchorData *oldData = g.edgeData(first, center); - - qreal minimumSize = oldData->minSize * 2; - qreal preferredSize = oldData->prefSize * 2; - qreal maximumSize = oldData->maxSize * 2; - - AnchorData *data = new AnchorData(minimumSize, preferredSize, maximumSize); + AnchorData *data = new AnchorData; addAnchor_helper(item, firstEdge, item, lastEdge, data); + data->refreshSizeHints(0); // Remove old anchors removeAnchor_helper(first, center); @@ -1133,7 +1129,7 @@ QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::addAnchor(QGraphicsLayoutItem *fi // Use heuristics to find out what the user meant with this anchor. correctEdgeDirection(firstItem, firstEdge, secondItem, secondEdge); - AnchorData *data; + AnchorData *data = new AnchorData; if (!spacing) { // If firstItem or secondItem is the layout itself, the spacing will default to 0. // Otherwise, the following matrix is used (questionmark means that the spacing @@ -1143,22 +1139,25 @@ QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::addAnchor(QGraphicsLayoutItem *fi // Left 0 0 ? // HCenter 0 0 0 // Right ? 0 0 - if (firstItem != q - && secondItem != q - && pickEdge(firstEdge, Horizontal) != Qt::AnchorHorizontalCenter - && oppositeEdge(firstEdge) == secondEdge) { - data = new AnchorData; // ask the style later + if (firstItem == q + || secondItem == q + || pickEdge(firstEdge, Horizontal) == Qt::AnchorHorizontalCenter + || oppositeEdge(firstEdge) != secondEdge) { + data->setFixedSize(0); } else { - data = new AnchorData(0); // spacing should be 0 + data->unsetSize(); } addAnchor_helper(firstItem, firstEdge, secondItem, secondEdge, data); + } else if (*spacing >= 0) { - data = new AnchorData(*spacing); + data->setFixedSize(*spacing); addAnchor_helper(firstItem, firstEdge, secondItem, secondEdge, data); + } else { - data = new AnchorData(-*spacing); + data->setFixedSize(-*spacing); addAnchor_helper(secondItem, secondEdge, firstItem, firstEdge, data); } + return acquireGraphicsAnchor(data); } diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 47df786..047be39 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -149,33 +149,15 @@ struct AnchorData : public QSimplexVariable { Sequential, Parallel }; - AnchorData(qreal minimumSize, qreal preferredSize, qreal maximumSize) - : QSimplexVariable(), from(0), to(0), - minSize(minimumSize), prefSize(preferredSize), - maxSize(maximumSize), sizeAtMinimum(preferredSize), - sizeAtPreferred(preferredSize), sizeAtExpanding(preferredSize), - sizeAtMaximum(preferredSize), - graphicsAnchor(0), - skipInPreferred(0), type(Normal), hasSize(true), - isLayoutAnchor(false) {} - - AnchorData(qreal size) - : QSimplexVariable(), from(0), to(0), - minSize(size), prefSize(size), maxSize(size), - sizeAtMinimum(size), sizeAtPreferred(size), sizeAtExpanding(size), - sizeAtMaximum(size), - graphicsAnchor(0), - skipInPreferred(0), type(Normal), hasSize(true), - isLayoutAnchor(false) {} AnchorData() : QSimplexVariable(), from(0), to(0), - minSize(0), prefSize(0), maxSize(0), - sizeAtMinimum(0), sizeAtPreferred(0), sizeAtExpanding(0), - sizeAtMaximum(0), - graphicsAnchor(0), - skipInPreferred(0), type(Normal), hasSize(false), - isLayoutAnchor(false) {} + minSize(0), prefSize(0), expSize(0), maxSize(0), + sizeAtMinimum(0), sizeAtPreferred(0), + sizeAtExpanding(0), sizeAtMaximum(0), + graphicsAnchor(0), skipInPreferred(0), + type(Normal), hasSize(true), isLayoutAnchor(false), + isExpanding(false) {} virtual void updateChildrenSizes() {} virtual void refreshSizeHints(qreal effectiveSpacing); @@ -192,6 +174,7 @@ struct AnchorData : public QSimplexVariable { { minSize = size; prefSize = size; + expSize = size; maxSize = size; sizeAtMinimum = size; sizeAtPreferred = size; @@ -215,6 +198,7 @@ struct AnchorData : public QSimplexVariable { // size. qreal minSize; qreal prefSize; + qreal expSize; qreal maxSize; // These attributes define which sizes should that anchor be in when the @@ -231,17 +215,6 @@ struct AnchorData : public QSimplexVariable { uint hasSize : 1; // if false, get size from style. uint isLayoutAnchor : 1; // if this anchor is connected to a layout 'edge' uint isExpanding : 1; // if true, expands before other anchors - -protected: - AnchorData(Type type, qreal size = 0) - : QSimplexVariable(), from(0), to(0), - minSize(size), prefSize(size), - maxSize(size), sizeAtMinimum(size), - sizeAtPreferred(size), sizeAtExpanding(size), - sizeAtMaximum(size), - graphicsAnchor(0), - skipInPreferred(0), type(type), hasSize(true), - isLayoutAnchor(false) {} }; #ifdef QT_DEBUG @@ -253,8 +226,10 @@ inline QString AnchorData::toString() const struct SequentialAnchorData : public AnchorData { - SequentialAnchorData() : AnchorData(AnchorData::Sequential) + SequentialAnchorData() : AnchorData() { + type = AnchorData::Sequential; + hasSize = true; #ifdef QT_DEBUG name = QLatin1String("SequentialAnchorData"); #endif @@ -278,9 +253,11 @@ struct SequentialAnchorData : public AnchorData struct ParallelAnchorData : public AnchorData { ParallelAnchorData(AnchorData *first, AnchorData *second) - : AnchorData(AnchorData::Parallel), - firstEdge(first), secondEdge(second) + : AnchorData(), firstEdge(first), secondEdge(second) { + type = AnchorData::Parallel; + hasSize = true; + // ### Those asserts force that both child anchors have the same direction, // but can't we simplify a pair of anchors in opposite directions? Q_ASSERT(first->from == second->from); -- cgit v0.12 From bcd08ab82b5df13f7687a504f868cb8b6ff8b75e Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Fri, 25 Sep 2009 16:13:18 -0300 Subject: QGraphicsAnchorLayout: avoid code duplication when initializing complex anchors Now we can use refreshSizeHints_helper() to initialize complex anchors (parallel and sequential). This avoids duplication of code in the function simplifySequentialChunk(). This commit also 'disable' ExpandFlag temporarily, stabilizing the tests for the simplification. The next commit should re-enable it implementing the necessary code for simplification as well. Signed-off-by: Caio Marcelo de Oliveira Filho Reviewed-by: Eduardo M. Fleury --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 102 +++++++++++------------ src/gui/graphicsview/qgraphicsanchorlayout_p.h | 4 + 2 files changed, 54 insertions(+), 52 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index dc8d211..dd46722 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -146,13 +146,15 @@ void AnchorData::refreshSizeHints(qreal effectiveSpacing) maxSize /= 2; } - if (policy & QSizePolicy::ExpandFlag) { - isExpanding = 1; - expSize = maxSize; - } else { - isExpanding = 0; - expSize = prefSize; - } + // ### + expSize = prefSize; + // if (policy & QSizePolicy::ExpandFlag) { + // isExpanding = 1; + // expSize = maxSize; + // } else { + // isExpanding = 0; + // expSize = prefSize; + // } // Set the anchor effective sizes to preferred. // @@ -187,6 +189,7 @@ void ParallelAnchorData::updateChildrenSizes() firstEdge->sizeAtMinimum = secondEdge->sizeAtMinimum = sizeAtMinimum; firstEdge->sizeAtPreferred = secondEdge->sizeAtPreferred = sizeAtPreferred; firstEdge->sizeAtMaximum = secondEdge->sizeAtMaximum = sizeAtMaximum; + firstEdge->sizeAtExpanding = secondEdge->sizeAtExpanding = sizeAtPreferred; firstEdge->updateChildrenSizes(); secondEdge->updateChildrenSizes(); @@ -194,9 +197,16 @@ void ParallelAnchorData::updateChildrenSizes() void ParallelAnchorData::refreshSizeHints(qreal effectiveSpacing) { - // First refresh children information - firstEdge->refreshSizeHints(effectiveSpacing); - secondEdge->refreshSizeHints(effectiveSpacing); + refreshSizeHints_helper(effectiveSpacing); +} + +void ParallelAnchorData::refreshSizeHints_helper(qreal effectiveSpacing, + bool refreshChildren) +{ + if (refreshChildren) { + firstEdge->refreshSizeHints(effectiveSpacing); + secondEdge->refreshSizeHints(effectiveSpacing); + } // ### should we warn if the parallel connection is invalid? // e.g. 1-2-3 with 10-20-30, the minimum of the latter is @@ -208,9 +218,13 @@ void ParallelAnchorData::refreshSizeHints(qreal effectiveSpacing) prefSize = qMax(firstEdge->prefSize, secondEdge->prefSize); prefSize = qMin(prefSize, maxSize); + // ### + expSize = prefSize; + // See comment in AnchorData::refreshSizeHints() about sizeAt* values sizeAtMinimum = prefSize; sizeAtPreferred = prefSize; + sizeAtExpanding = prefSize; sizeAtMaximum = prefSize; } @@ -277,30 +291,46 @@ void SequentialAnchorData::updateChildrenSizes() bandSize = maxFactor > 0 ? e->maxSize - e->prefSize : e->prefSize - e->minSize; e->sizeAtMaximum = e->prefSize + bandSize * maxFactor; + // ### + e->sizeAtExpanding = e->sizeAtPreferred; + e->updateChildrenSizes(); } } void SequentialAnchorData::refreshSizeHints(qreal effectiveSpacing) { + refreshSizeHints_helper(effectiveSpacing); +} + +void SequentialAnchorData::refreshSizeHints_helper(qreal effectiveSpacing, + bool refreshChildren) +{ minSize = 0; prefSize = 0; + expSize = 0; maxSize = 0; for (int i = 0; i < m_edges.count(); ++i) { AnchorData *edge = m_edges.at(i); - // First refresh children information - edge->refreshSizeHints(effectiveSpacing); + // If it's the case refresh children information first + if (refreshChildren) + edge->refreshSizeHints(effectiveSpacing); minSize += edge->minSize; prefSize += edge->prefSize; + expSize += edge->expSize; maxSize += edge->maxSize; } + // ### + expSize = prefSize; + // See comment in AnchorData::refreshSizeHints() about sizeAt* values sizeAtMinimum = prefSize; sizeAtPreferred = prefSize; + sizeAtExpanding = prefSize; sizeAtMaximum = prefSize; } @@ -441,39 +471,21 @@ static bool simplifySequentialChunk(Graph *graph, qDebug("simplifying [%s] to [%s - %s]", qPrintable(strPath), qPrintable(before->toString()), qPrintable(after->toString())); #endif - qreal min = 0; - qreal pref = 0; - qreal max = 0; - SequentialAnchorData *sequence = new SequentialAnchorData; AnchorVertex *prev = before; AnchorData *data; for (i = 0; i <= vertices.count(); ++i) { AnchorVertex *next = (i < vertices.count()) ? vertices.at(i) : after; data = graph->takeEdge(prev, next); - min += data->minSize; - pref += data->prefSize; - max = checkAdd(max, data->maxSize); sequence->m_edges.append(data); prev = next; } - - // insert new - sequence->minSize = min; - sequence->prefSize = pref; - sequence->maxSize = max; - - // Unless these values are overhidden by the simplex solver later-on, - // anchors will keep their own preferred size. - sequence->sizeAtMinimum = pref; - sequence->sizeAtPreferred = pref; - sequence->sizeAtMaximum = pref; - sequence->setVertices(vertices); - sequence->from = before; sequence->to = after; + sequence->refreshSizeHints_helper(0, false); + // data here is the last edge in the sequence // ### this seems to be here for supporting reverse order sequences, // but doesnt seem to be used right now @@ -488,25 +500,11 @@ static bool simplifySequentialChunk(Graph *graph, AnchorData *newAnchor = sequence; if (AnchorData *oldAnchor = graph->takeEdge(before, after)) { - newAnchor = new ParallelAnchorData(oldAnchor, sequence); - - newAnchor->isLayoutAnchor = (oldAnchor->isLayoutAnchor + ParallelAnchorData *parallel = new ParallelAnchorData(oldAnchor, sequence); + parallel->isLayoutAnchor = (oldAnchor->isLayoutAnchor || sequence->isLayoutAnchor); - - min = qMax(oldAnchor->minSize, sequence->minSize); - max = qMin(oldAnchor->maxSize, sequence->maxSize); - - pref = qMax(oldAnchor->prefSize, sequence->prefSize); - pref = qMin(pref, max); - - newAnchor->minSize = min; - newAnchor->prefSize = pref; - newAnchor->maxSize = max; - - // Same as above, by default, keep preferred size. - newAnchor->sizeAtMinimum = pref; - newAnchor->sizeAtPreferred = pref; - newAnchor->sizeAtMaximum = pref; + parallel->refreshSizeHints_helper(0, false); + newAnchor = parallel; } graph->createEdge(before, after, newAnchor); @@ -1687,7 +1685,7 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( AnchorData *ad = trunkPath.positives.toList()[0]; ad->sizeAtMinimum = ad->minSize; ad->sizeAtPreferred = ad->prefSize; - ad->sizeAtExpanding = ad->prefSize; + ad->sizeAtExpanding = ad->expSize; ad->sizeAtMaximum = ad->maxSize; // Propagate @@ -1696,7 +1694,7 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( sizeHints[orientation][Qt::MinimumSize] = ad->sizeAtMinimum; sizeHints[orientation][Qt::PreferredSize] = ad->sizeAtPreferred; sizeHints[orientation][Qt::MaximumSize] = ad->sizeAtMaximum; - sizeAtExpanding[orientation] = ad->sizeAtPreferred; + sizeAtExpanding[orientation] = ad->sizeAtExpanding; } // Delete the constraints, we won't use them anymore. diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 047be39..8f67b2c 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -238,6 +238,8 @@ struct SequentialAnchorData : public AnchorData virtual void updateChildrenSizes(); virtual void refreshSizeHints(qreal effectiveSpacing); + void refreshSizeHints_helper(qreal effectiveSpacing, bool refreshChildren = true); + void setVertices(const QVector &vertices) { m_children = vertices; @@ -272,6 +274,8 @@ struct ParallelAnchorData : public AnchorData virtual void updateChildrenSizes(); virtual void refreshSizeHints(qreal effectiveSpacing); + void refreshSizeHints_helper(qreal effectiveSpacing, bool refreshChildren = true); + AnchorData* firstEdge; AnchorData* secondEdge; }; -- cgit v0.12 From ad69bb73754534f61658a83e85dadb75e603c90a Mon Sep 17 00:00:00 2001 From: "Eduardo M. Fleury" Date: Fri, 25 Sep 2009 19:02:21 -0300 Subject: QGraphicsAnchorLayout: Update solveExpanding to handle simplified graphs The previous implementation of solveExpanding would assume that anchors were either completely expanding (would grow to their sizeAtMaximum) or non-expanding (would try to remain at their sizeAtPreferred). What happens however is that with simplification enabled, we may have anchors that are "partially" expanding. An example is a sequential anchor that groups together two leaf anchors where only one of them is expanding. In this case, the expected size of that group anchor would be the sum of the max size of the expanding child plus the preferred size of the non-expanding child. To handle the above case we added the "expSize" variable. It holds the expected value at Expanding for each anchor. Based on this, and the already calculated values of sizeAtMaximum and sizeAtPreferred, the solver calculates the actual sizeAtExpanding for them. Signed-off-by: Eduardo M. Fleury Reviewed-by: Caio Marcelo de Oliveira Filho --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 84 ++++++++++++++++++++---- 1 file changed, 72 insertions(+), 12 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index dd46722..cf1429c 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -2319,40 +2319,97 @@ bool QGraphicsAnchorLayoutPrivate::solvePreferred(QList co return feasible; } +/*! Calculate the "expanding" keyframe + + This new keyframe sits between the already existing sizeAtPreferred and + sizeAtMaximum keyframes. Its goal is to modify the interpolation between + the latter as to respect the "expanding" size policy of some anchors. + + Previously all items would be subject to a linear interpolation between + sizeAtPreferred and sizeAtMaximum values. This will change now, the + expanding anchors will change their size before the others. To calculate + this keyframe we use the following logic: + + 1) Ask each anchor for their desired expanding size (ad->expSize), this + value depends on the anchor expanding property in the following way: + + - Expanding anchors want to grow towards their maximum size + - Non-expanding anchors want to remain at their preferred size. + - Composite anchors want to grow towards somewhere between their + preferred sizes. (*) + + 2) Clamp their desired values to the value they assume in the neighbour + keyframes (sizeAtPreferred and sizeAtExpanding) + + 3) Run simplex with a setup that ensures the following: + + a. Anchors will change their value from their sizeAtPreferred towards + their sizeAtMaximum as much as required to ensure that ALL anchors + reach their respective "desired" expanding sizes. + + b. No anchors will change their value beyond what is NEEDED to satisfy + the requirement above. + + The final result is that, at the "expanding" keyframe expanding anchors + will grow and take with them all anchors that are parallel to them. + However, non-expanding anchors will remain at their preferred size unless + they are forced to grow by a parallel expanding anchor. + + Note: For anchors where the sizeAtPreferred is bigger than sizeAtPreferred, + the visual effect when the layout grows from its preferred size is + the following: Expanding anchors will keep their size while non + expanding ones will shrink. Only after non-expanding anchors have + shrinked all the way, the expanding anchors will start to shrink too. +*/ void QGraphicsAnchorLayoutPrivate::solveExpanding(QList constraints) { QList variables = getVariables(constraints); QList itemConstraints; QSimplexConstraint *objective = new QSimplexConstraint; + bool hasExpanding = false; - // Use all items that belong to trunk to: - // - add solveExpanding-specific item constraints - // - create the objective function + // Construct the simplex constraints and objective for (int i = 0; i < variables.size(); ++i) { + // For each anchor AnchorData *ad = variables[i]; - if (ad->isExpanding) { - // Add constraint to lock expanding anchor in its sizeAtMaximum + + // Clamp the desired expanding size + qreal upperBoundary = qMax(ad->sizeAtPreferred, ad->sizeAtMaximum); + qreal lowerBoundary = qMin(ad->sizeAtPreferred, ad->sizeAtMaximum); + qreal boundedExpSize = qBound(lowerBoundary, ad->expSize, upperBoundary); + + // Expanding anchors are those that want to move from their preferred size + if (boundedExpSize != ad->sizeAtPreferred) + hasExpanding = true; + + // Lock anchor between boundedExpSize and sizeAtMaximum (ensure 3.a) + if (boundedExpSize == ad->sizeAtMaximum) { + // The interval has only one possible value, we can use an "Equal" + // constraint and don't need to add this variable to the objective. QSimplexConstraint *itemC = new QSimplexConstraint; itemC->ratio = QSimplexConstraint::Equal; itemC->variables.insert(ad, 1.0); - itemC->constant = ad->sizeAtMaximum; + itemC->constant = boundedExpSize; itemConstraints << itemC; } else { - // Add constraints to lock anchor between their sizeAtPreferred and sizeAtMaximum + // Add MoreOrEqual and LessOrEqual constraints. QSimplexConstraint *itemC = new QSimplexConstraint; itemC->ratio = QSimplexConstraint::MoreOrEqual; itemC->variables.insert(ad, 1.0); - itemC->constant = qMin(ad->sizeAtPreferred, ad->sizeAtMaximum); + itemC->constant = qMin(boundedExpSize, ad->sizeAtMaximum); itemConstraints << itemC; itemC = new QSimplexConstraint; itemC->ratio = QSimplexConstraint::LessOrEqual; itemC->variables.insert(ad, 1.0); - itemC->constant = qMax(ad->sizeAtPreferred, ad->sizeAtMaximum); + itemC->constant = qMax(boundedExpSize, ad->sizeAtMaximum); itemConstraints << itemC; - // Add anchor to objective function - if (ad->sizeAtPreferred < ad->sizeAtMaximum) { + // Create objective to avoid the anchos from moving away from + // the preferred size more than the needed amount. (ensure 3.b) + // The objective function is the distance between sizeAtPreferred + // and sizeAtExpanding, it will be minimized. + if (ad->sizeAtExpanding < ad->sizeAtMaximum) { // Try to shrink this variable towards its sizeAtPreferred value objective->variables.insert(ad, 1.0); } else { @@ -2363,7 +2420,7 @@ void QGraphicsAnchorLayoutPrivate::solveExpanding(QList co } // Solve - if (objective->variables.size() == variables.size()) { + if (hasExpanding == false) { // If no anchors are expanding, we don't need to run the simplex // Set all variables to their preferred size for (int i = 0; i < variables.size(); ++i) { @@ -2372,9 +2429,12 @@ void QGraphicsAnchorLayoutPrivate::solveExpanding(QList co } else { // Run simplex QSimplex simplex; + + // Satisfy expanding (3.a) bool feasible = simplex.setConstraints(constraints + itemConstraints); Q_ASSERT(feasible); + // Reduce damage (3.b) simplex.setObjective(objective); simplex.solveMin(); -- cgit v0.12 From ba66cc0bde91e1143ac0a34f249f98e4573a5737 Mon Sep 17 00:00:00 2001 From: "Eduardo M. Fleury" Date: Mon, 28 Sep 2009 11:49:42 -0300 Subject: QSimplex: Remove overly conservative assertion This assertion started failing after the addition of expanding state. After some investigation we felt that the assertion itself was too strong and would fail in some valid cases. The new assertion is formally right as it tests whether the simplex solver was able to satisfy the simplex constraints, _exactly_ what it is expected to do. Signed-off-by: Eduardo M. Fleury Reviewed-by: Caio Marcelo de Oliveira Filho --- src/gui/graphicsview/qsimplex_p.cpp | 24 ++++++------------------ src/gui/graphicsview/qsimplex_p.h | 26 +++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/src/gui/graphicsview/qsimplex_p.cpp b/src/gui/graphicsview/qsimplex_p.cpp index 00fc204..95003d2 100644 --- a/src/gui/graphicsview/qsimplex_p.cpp +++ b/src/gui/graphicsview/qsimplex_p.cpp @@ -285,24 +285,6 @@ bool QSimplex::setConstraints(const QList newConstraints) // anymore. clearColumns(firstArtificial, columns - 2); - #ifdef QT_DEBUG - // Ensure that at the end of the simplex each row should either: - // - Have a positive value on the column associated to its variable, or - // - Have zero values in all columns. - // - // This avoids a regression where restrictions would be lost - // due to randomness in the pivotRowForColumn method. - for (int i = 1; i < rows; ++i) { - int variableIndex = valueAt(i, 0); - if (valueAt(i, variableIndex) > 0) - continue; - - for (int j = 1; j < columns; ++j) { - Q_ASSERT(valueAt(i, j) == 0); - } - } - #endif - return true; } @@ -537,6 +519,12 @@ qreal QSimplex::solver(solverFactor factor) solveMaxHelper(); collectResults(); + #ifdef QT_DEBUG + for (int i = 0; i < constraints.size(); ++i) { + Q_ASSERT(constraints[i]->isSatisfied()); + } + #endif + return factor * valueAt(0, columns - 1); } diff --git a/src/gui/graphicsview/qsimplex_p.h b/src/gui/graphicsview/qsimplex_p.h index 54b080d..b517cb9 100644 --- a/src/gui/graphicsview/qsimplex_p.h +++ b/src/gui/graphicsview/qsimplex_p.h @@ -94,8 +94,32 @@ struct QSimplexConstraint QPair helper; QSimplexVariable * artificial; -}; + #ifdef QT_DEBUG + bool isSatisfied() { + qreal leftHandSide(0); + + QHash::const_iterator iter; + for (iter = variables.constBegin(); iter != variables.constEnd(); ++iter) { + leftHandSide += iter.value() * iter.key()->result; + } + + Q_ASSERT(constant > 0 || qFuzzyCompare(1, 1 + constant)); + + if (qFuzzyCompare(1000 + leftHandSide, 1000 + constant)) + return true; + + switch (ratio) { + case LessOrEqual: + return leftHandSide < constant; + case MoreOrEqual: + return leftHandSide > constant; + default: + return false; + } + } + #endif +}; class QSimplex { -- cgit v0.12 From 0536b996759ef367e784310f472089eec583213f Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Fri, 25 Sep 2009 19:35:25 -0300 Subject: QGraphicsAnchorLayout: Add support for expanding SizePolicy with simplification Updating "refreshSizeHints" and "updateChildrenSizes" methods for standard, parallel and sequential anchors, in order to support the expanding SizePolicy flag. This adds the logic required to calculate equivalent expected/nominal expanding size (AnchorData::expSize) as well as the logic to propagate the effective size when in the expanding state (AnchorData::sizeAtExpected). Signed-off-by: Caio Marcelo de Oliveira Filho Reviewed-by: Eduardo M. Fleury --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 59 ++++++++++++++---------- src/gui/graphicsview/qgraphicsanchorlayout_p.h | 4 +- 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index cf1429c..20ff03b 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -146,15 +146,11 @@ void AnchorData::refreshSizeHints(qreal effectiveSpacing) maxSize /= 2; } - // ### - expSize = prefSize; - // if (policy & QSizePolicy::ExpandFlag) { - // isExpanding = 1; - // expSize = maxSize; - // } else { - // isExpanding = 0; - // expSize = prefSize; - // } + if (policy & QSizePolicy::ExpandFlag) { + expSize = maxSize; + } else { + expSize = prefSize; + } // Set the anchor effective sizes to preferred. // @@ -175,8 +171,6 @@ void AnchorData::refreshSizeHints(qreal effectiveSpacing) expSize = effectiveSpacing; maxSize = effectiveSpacing; - isExpanding = 0; - sizeAtMinimum = prefSize; sizeAtPreferred = prefSize; sizeAtExpanding = prefSize; @@ -188,8 +182,8 @@ void ParallelAnchorData::updateChildrenSizes() { firstEdge->sizeAtMinimum = secondEdge->sizeAtMinimum = sizeAtMinimum; firstEdge->sizeAtPreferred = secondEdge->sizeAtPreferred = sizeAtPreferred; + firstEdge->sizeAtExpanding = secondEdge->sizeAtExpanding = sizeAtExpanding; firstEdge->sizeAtMaximum = secondEdge->sizeAtMaximum = sizeAtMaximum; - firstEdge->sizeAtExpanding = secondEdge->sizeAtExpanding = sizeAtPreferred; firstEdge->updateChildrenSizes(); secondEdge->updateChildrenSizes(); @@ -215,11 +209,11 @@ void ParallelAnchorData::refreshSizeHints_helper(qreal effectiveSpacing, minSize = qMax(firstEdge->minSize, secondEdge->minSize); maxSize = qMin(firstEdge->maxSize, secondEdge->maxSize); - prefSize = qMax(firstEdge->prefSize, secondEdge->prefSize); - prefSize = qMin(prefSize, maxSize); + expSize = qMax(firstEdge->expSize, secondEdge->expSize); + expSize = qMin(expSize, maxSize); - // ### - expSize = prefSize; + prefSize = qMax(firstEdge->prefSize, secondEdge->prefSize); + prefSize = qMin(prefSize, expSize); // See comment in AnchorData::refreshSizeHints() about sizeAt* values sizeAtMinimum = prefSize; @@ -260,6 +254,21 @@ static qreal getFactor(qreal value, qreal min, qreal pref, qreal max) } } +static qreal getExpandingFactor(const qreal &expSize, const qreal &sizeAtPreferred, + const qreal &sizeAtExpanding, const qreal &sizeAtMaximum) +{ + const qreal lower = qMin(sizeAtPreferred, sizeAtMaximum); + const qreal upper = qMax(sizeAtPreferred, sizeAtMaximum); + const qreal boundedExpSize = qBound(lower, expSize, upper); + + const qreal bandSize = sizeAtMaximum - boundedExpSize; + if (bandSize == 0) { + return 0; + } else { + return (sizeAtExpanding - boundedExpSize) / bandSize; + } +} + void SequentialAnchorData::updateChildrenSizes() { // ### REMOVE ME @@ -269,15 +278,18 @@ void SequentialAnchorData::updateChildrenSizes() Q_ASSERT(sizeAtMinimum < maxSize || qFuzzyCompare(sizeAtMinimum, maxSize)); Q_ASSERT(sizeAtPreferred > minSize || qFuzzyCompare(sizeAtPreferred, minSize)); Q_ASSERT(sizeAtPreferred < maxSize || qFuzzyCompare(sizeAtPreferred, maxSize)); + Q_ASSERT(sizeAtExpanding > minSize || qFuzzyCompare(sizeAtExpanding, minSize)); + Q_ASSERT(sizeAtExpanding < maxSize || qFuzzyCompare(sizeAtExpanding, maxSize)); Q_ASSERT(sizeAtMaximum > minSize || qFuzzyCompare(sizeAtMaximum, minSize)); Q_ASSERT(sizeAtMaximum < maxSize || qFuzzyCompare(sizeAtMaximum, maxSize)); // Band here refers if the value is in the Minimum To Preferred // band (the lower band) or the Preferred To Maximum (the upper band). - qreal minFactor = getFactor(sizeAtMinimum, minSize, prefSize, maxSize); - qreal prefFactor = getFactor(sizeAtPreferred, minSize, prefSize, maxSize); - qreal maxFactor = getFactor(sizeAtMaximum, minSize, prefSize, maxSize); + const qreal minFactor = getFactor(sizeAtMinimum, minSize, prefSize, maxSize); + const qreal prefFactor = getFactor(sizeAtPreferred, minSize, prefSize, maxSize); + const qreal maxFactor = getFactor(sizeAtMaximum, minSize, prefSize, maxSize); + const qreal expFactor = getExpandingFactor(expSize, sizeAtPreferred, sizeAtExpanding, sizeAtMaximum); for (int i = 0; i < m_edges.count(); ++i) { AnchorData *e = m_edges.at(i); @@ -291,8 +303,10 @@ void SequentialAnchorData::updateChildrenSizes() bandSize = maxFactor > 0 ? e->maxSize - e->prefSize : e->prefSize - e->minSize; e->sizeAtMaximum = e->prefSize + bandSize * maxFactor; - // ### - e->sizeAtExpanding = e->sizeAtPreferred; + const qreal lower = qMin(e->sizeAtPreferred, e->sizeAtMaximum); + const qreal upper = qMax(e->sizeAtPreferred, e->sizeAtMaximum); + const qreal edgeBoundedExpSize = qBound(lower, e->expSize, upper); + e->sizeAtExpanding = edgeBoundedExpSize + expFactor * (e->sizeAtMaximum - edgeBoundedExpSize); e->updateChildrenSizes(); } @@ -324,9 +338,6 @@ void SequentialAnchorData::refreshSizeHints_helper(qreal effectiveSpacing, maxSize += edge->maxSize; } - // ### - expSize = prefSize; - // See comment in AnchorData::refreshSizeHints() about sizeAt* values sizeAtMinimum = prefSize; sizeAtPreferred = prefSize; diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 8f67b2c..aac4f96 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -156,8 +156,7 @@ struct AnchorData : public QSimplexVariable { sizeAtMinimum(0), sizeAtPreferred(0), sizeAtExpanding(0), sizeAtMaximum(0), graphicsAnchor(0), skipInPreferred(0), - type(Normal), hasSize(true), isLayoutAnchor(false), - isExpanding(false) {} + type(Normal), hasSize(true), isLayoutAnchor(false) {} virtual void updateChildrenSizes() {} virtual void refreshSizeHints(qreal effectiveSpacing); @@ -214,7 +213,6 @@ struct AnchorData : public QSimplexVariable { uint type : 2; // either Normal, Sequential or Parallel uint hasSize : 1; // if false, get size from style. uint isLayoutAnchor : 1; // if this anchor is connected to a layout 'edge' - uint isExpanding : 1; // if true, expands before other anchors }; #ifdef QT_DEBUG -- cgit v0.12 From 89ea5d0cc0b00a1d4e8f3e700b86f168cf4437ed Mon Sep 17 00:00:00 2001 From: "Eduardo M. Fleury" Date: Wed, 30 Sep 2009 12:25:34 -0300 Subject: QGraphicsAnchorLayout: Fix creation of internal layout anchors Since the AnchorData cleanup commit (c974aca8) all anchor initialization is being done by refreshSizeHints. However that method was not able to properly initialize the internal layout anchors. This commit refactors that method both to add the functionality and improve readability. Signed-off-by: Eduardo M. Fleury Reviewed-by: Caio Marcelo de Oliveira Filho --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 145 ++++++++++++--------- .../tst_qgraphicsanchorlayout.cpp | 2 +- 2 files changed, 84 insertions(+), 63 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 20ff03b..8139b2b 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -92,90 +92,111 @@ qreal QGraphicsAnchorPrivate::spacing() const } +static void sizeHintsFromItem(QGraphicsLayoutItem *item, + const QGraphicsAnchorLayoutPrivate::Orientation orient, + qreal *minSize, qreal *prefSize, + qreal *expSize, qreal *maxSize) +{ + QSizePolicy::Policy policy; + qreal minSizeHint; + qreal prefSizeHint; + qreal maxSizeHint; + + if (orient == QGraphicsAnchorLayoutPrivate::Horizontal) { + policy = item->sizePolicy().horizontalPolicy(); + minSizeHint = item->effectiveSizeHint(Qt::MinimumSize).width(); + prefSizeHint = item->effectiveSizeHint(Qt::PreferredSize).width(); + maxSizeHint = item->effectiveSizeHint(Qt::MaximumSize).width(); + } else { + policy = item->sizePolicy().verticalPolicy(); + minSizeHint = item->effectiveSizeHint(Qt::MinimumSize).height(); + prefSizeHint = item->effectiveSizeHint(Qt::PreferredSize).height(); + maxSizeHint = item->effectiveSizeHint(Qt::MaximumSize).height(); + } + + // minSize, prefSize and maxSize are initialized + // with item's preferred Size: this is QSizePolicy::Fixed. + // + // Then we check each flag to find the resultant QSizePolicy, + // according to the following table: + // + // constant value + // QSizePolicy::Fixed 0 + // QSizePolicy::Minimum GrowFlag + // QSizePolicy::Maximum ShrinkFlag + // QSizePolicy::Preferred GrowFlag | ShrinkFlag + // QSizePolicy::Ignored GrowFlag | ShrinkFlag | IgnoreFlag + + if (policy & QSizePolicy::ShrinkFlag) + *minSize = minSizeHint; + else + *minSize = prefSizeHint; + + if (policy & QSizePolicy::GrowFlag) + *maxSize = maxSizeHint; + else + *maxSize = prefSizeHint; + + // Note that these two initializations are affected by the previous flags + if (policy & QSizePolicy::IgnoreFlag) + *prefSize = *maxSize; + else + *prefSize = prefSizeHint; + + if (policy & QSizePolicy::ExpandFlag) + *expSize = *maxSize; + else + *expSize = *prefSize; +} + void AnchorData::refreshSizeHints(qreal effectiveSpacing) { - if (!isLayoutAnchor && (from->m_item == to->m_item)) { - QGraphicsLayoutItem *item = from->m_item; + const bool isInternalAnchor = from->m_item == to->m_item; - const QGraphicsAnchorLayoutPrivate::Orientation orient = QGraphicsAnchorLayoutPrivate::edgeOrientation(from->m_edge); - const Qt::AnchorPoint centerEdge = QGraphicsAnchorLayoutPrivate::pickEdge(Qt::AnchorHorizontalCenter, orient); + if (isInternalAnchor) { + const QGraphicsAnchorLayoutPrivate::Orientation orient = + QGraphicsAnchorLayoutPrivate::edgeOrientation(from->m_edge); - QSizePolicy::Policy policy; - qreal minSizeHint, prefSizeHint, maxSizeHint; - if (orient == QGraphicsAnchorLayoutPrivate::Horizontal) { - policy = item->sizePolicy().horizontalPolicy(); - minSizeHint = item->effectiveSizeHint(Qt::MinimumSize).width(); - prefSizeHint = item->effectiveSizeHint(Qt::PreferredSize).width(); - maxSizeHint = item->effectiveSizeHint(Qt::MaximumSize).width(); + if (isLayoutAnchor) { + minSize = 0; + prefSize = 0; + expSize = 0; + maxSize = QWIDGETSIZE_MAX; } else { - policy = item->sizePolicy().verticalPolicy(); - minSizeHint = item->effectiveSizeHint(Qt::MinimumSize).height(); - prefSizeHint = item->effectiveSizeHint(Qt::PreferredSize).height(); - maxSizeHint = item->effectiveSizeHint(Qt::MaximumSize).height(); + QGraphicsLayoutItem *item = from->m_item; + sizeHintsFromItem(item, orient, &minSize, &prefSize, &expSize, &maxSize); } - // minSize, prefSize and maxSize are initialized - // with item's preferred Size: this is QSizePolicy::Fixed. - // - // Then we check each flag to find the resultant QSizePolicy, - // according to the following table: - // - // constant value - // QSizePolicy::Fixed 0 - // QSizePolicy::Minimum GrowFlag - // QSizePolicy::Maximum ShrinkFlag - // QSizePolicy::Preferred GrowFlag | ShrinkFlag - // QSizePolicy::Ignored GrowFlag | ShrinkFlag | IgnoreFlag - prefSize = prefSizeHint; - minSize = prefSize; - maxSize = prefSize; - - if (policy & QSizePolicy::GrowFlag) - maxSize = maxSizeHint; - - if (policy & QSizePolicy::ShrinkFlag) - minSize = minSizeHint; - - if (policy & QSizePolicy::IgnoreFlag) - prefSize = minSize; + const Qt::AnchorPoint centerEdge = + QGraphicsAnchorLayoutPrivate::pickEdge(Qt::AnchorHorizontalCenter, orient); bool hasCenter = (from->m_edge == centerEdge || to->m_edge == centerEdge); if (hasCenter) { minSize /= 2; prefSize /= 2; + expSize /= 2; maxSize /= 2; } - if (policy & QSizePolicy::ExpandFlag) { - expSize = maxSize; - } else { - expSize = prefSize; - } - - // Set the anchor effective sizes to preferred. - // - // Note: The idea here is that all items should remain at their - // preferred size unless where that's impossible. In cases where - // the item is subject to restrictions (anchored to the layout - // edges, for instance), the simplex solver will be run to - // recalculate and override the values we set here. - sizeAtMinimum = prefSize; - sizeAtPreferred = prefSize; - sizeAtExpanding = prefSize; - sizeAtMaximum = prefSize; - } else if (!hasSize) { // Anchor has no size defined, use given default information minSize = effectiveSpacing; prefSize = effectiveSpacing; expSize = effectiveSpacing; maxSize = effectiveSpacing; - - sizeAtMinimum = prefSize; - sizeAtPreferred = prefSize; - sizeAtExpanding = prefSize; - sizeAtMaximum = prefSize; } + + // Set the anchor effective sizes to preferred. + // + // Note: The idea here is that all items should remain at their + // preferred size unless where that's impossible. In cases where + // the item is subject to restrictions (anchored to the layout + // edges, for instance), the simplex solver will be run to + // recalculate and override the values we set here. + sizeAtMinimum = prefSize; + sizeAtPreferred = prefSize; + sizeAtExpanding = prefSize; + sizeAtMaximum = prefSize; } void ParallelAnchorData::updateChildrenSizes() diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index 4ad48c7..91e5bb3 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -1271,7 +1271,7 @@ void tst_QGraphicsAnchorLayout::sizePolicy() w1->adjustSize(); QCOMPARE(l->effectiveSizeHint(Qt::MinimumSize), QSizeF(0, 0)); - QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(0, 0)); + QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(100, 100)); QCOMPARE(l->effectiveSizeHint(Qt::MaximumSize), QSizeF(100, 100)); delete p; -- cgit v0.12 From 0d1e86fdfb7958a1affb93c7760c22fca9a0fcb2 Mon Sep 17 00:00:00 2001 From: Jesus Sanchez-Palencia Date: Fri, 25 Sep 2009 18:53:15 -0300 Subject: QGraphicsAnchorLayout: Adding a Float Conflict test case Now we don't support floating items and so we should consider that the layout has a conflict when handling this situation. Signed-off-by: Jesus Sanchez-Palencia Reviewed-by: Caio Marcelo de Oliveira Filho --- .../tst_qgraphicsanchorlayout.cpp | 69 ++++++++++++++++++++++ .../tst_qgraphicsanchorlayout1.cpp | 4 +- 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index 91e5bb3..b076631 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -72,6 +72,7 @@ private slots: void expandingSequence(); void expandingSequenceFairDistribution(); void expandingParallel(); + void floatConflict(); }; class RectWidget : public QGraphicsWidget @@ -158,7 +159,17 @@ void tst_QGraphicsAnchorLayout::simple() QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; l->setContentsMargins(0, 0, 0, 0); + + // Horizontal + l->addAnchor(w1, Qt::AnchorLeft, l, Qt::AnchorLeft); l->addAnchor(w1, Qt::AnchorRight, w2, Qt::AnchorLeft); + l->addAnchor(w2, Qt::AnchorRight, l, Qt::AnchorRight); + + // Vertical + l->addAnchor(w1, Qt::AnchorTop, l, Qt::AnchorTop); + l->addAnchor(w2, Qt::AnchorTop, l, Qt::AnchorTop); + l->addAnchor(w1, Qt::AnchorBottom, l, Qt::AnchorBottom); + l->addAnchor(w2, Qt::AnchorBottom, l, Qt::AnchorBottom); QGraphicsWidget p; p.setLayout(l); @@ -1152,12 +1163,22 @@ void tst_QGraphicsAnchorLayout::delete_anchor() QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; l->setSpacing(0); l->setContentsMargins(0, 0, 0, 0); + + // Horizontal l->addAnchor(l, Qt::AnchorLeft, w1, Qt::AnchorLeft); l->addAnchor(w1, Qt::AnchorRight, w2, Qt::AnchorLeft); l->addAnchor(w2, Qt::AnchorRight, l, Qt::AnchorRight); l->addAnchor(w1, Qt::AnchorRight, w3, Qt::AnchorLeft); l->addAnchor(w3, Qt::AnchorRight, l, Qt::AnchorRight); + // Vertical + l->addAnchor(w1, Qt::AnchorTop, l, Qt::AnchorTop); + l->addAnchor(w1, Qt::AnchorBottom, l, Qt::AnchorBottom); + l->addAnchor(w2, Qt::AnchorTop, l, Qt::AnchorTop); + l->addAnchor(w2, Qt::AnchorBottom, l, Qt::AnchorBottom); + l->addAnchor(w3, Qt::AnchorTop, l, Qt::AnchorTop); + l->addAnchor(w3, Qt::AnchorBottom, l, Qt::AnchorBottom); + QGraphicsAnchor *anchor = l->anchor(w3, Qt::AnchorRight, l, Qt::AnchorRight); anchor->setSpacing(10); @@ -1521,5 +1542,53 @@ void tst_QGraphicsAnchorLayout::expandingParallel() QCOMPARE(newLayoutMaximumSize.width(), qreal(300)); } +void tst_QGraphicsAnchorLayout::floatConflict() +{ + QGraphicsWidget *a = createItem(QSizeF(80,10), QSizeF(90,10), QSizeF(100,10), "a"); + QGraphicsWidget *b = createItem(QSizeF(80,10), QSizeF(90,10), QSizeF(100,10), "b"); + + QGraphicsAnchorLayout *l; + QGraphicsWidget *p = new QGraphicsWidget(0, Qt::Window); + + l = new QGraphicsAnchorLayout; + l->setContentsMargins(0, 0, 0, 0); + + p->setLayout(l); + + // horizontal + // with this anchor we have two floating items + setAnchor(l, a, Qt::AnchorRight, b, Qt::AnchorLeft); + + // Just checking if the layout is handling well the removal of floating items + delete l->anchor(a, Qt::AnchorRight, b, Qt::AnchorLeft); + QCOMPARE(l->count(), 0); + QCOMPARE(layoutHasConflict(l), false); + + // setting back the same anchor + setAnchor(l, a, Qt::AnchorRight, b, Qt::AnchorLeft); + + // We don't support floating items but they should be counted as if they are in the layout + QCOMPARE(l->count(), 2); + // Although, we have an invalid situation + QCOMPARE(layoutHasConflict(l), true); + + // Semi-floats are supported + setAnchor(l, a, Qt::AnchorLeft, l, Qt::AnchorLeft); + QCOMPARE(l->count(), 2); + + // Vertically the layout has floating items. Therefore, we have a conflict + QCOMPARE(layoutHasConflict(l), true); + + // No more floating items + setAnchor(l, b, Qt::AnchorRight, l, Qt::AnchorRight); + setAnchor(l, a, Qt::AnchorTop, l, Qt::AnchorTop); + setAnchor(l, a, Qt::AnchorBottom, l, Qt::AnchorBottom); + setAnchor(l, b, Qt::AnchorTop, l, Qt::AnchorTop); + setAnchor(l, b, Qt::AnchorBottom, l, Qt::AnchorBottom); + QCOMPARE(layoutHasConflict(l), false); + + delete p; +} + QTEST_MAIN(tst_QGraphicsAnchorLayout) #include "tst_qgraphicsanchorlayout.moc" diff --git a/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp b/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp index a521b78..caf078e 100644 --- a/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp +++ b/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp @@ -530,16 +530,18 @@ void tst_QGraphicsAnchorLayout1::testIsValid() TestWidget *widget1 = new TestWidget(); TestWidget *widget2 = new TestWidget(); + // Vertically the layout has floating items. Therefore, we have a conflict layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1); layout->setAnchor(layout, Qt::AnchorRight, widget1, Qt::AnchorRight, -0.1); + // Horizontally the layout has floating items. Therefore, we have a conflict layout->setAnchor(layout, Qt::AnchorTop, widget2, Qt::AnchorTop, 0.1); layout->setAnchor(layout, Qt::AnchorBottom, widget2, Qt::AnchorBottom, -0.1); widget->setLayout(layout); widget->setGeometry(QRectF(0,0,100,100)); - QCOMPARE(layout->isValid(), true); + QCOMPARE(layout->isValid(), false); delete widget; } } -- cgit v0.12 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 From 6367a702b13a440557d4e0a405ae6d34ef0b778f Mon Sep 17 00:00:00 2001 From: Jesus Sanchez-Palencia Date: Tue, 29 Sep 2009 15:22:26 -0300 Subject: QGraphicsAnchorLayoutPrivate: Fixing initial geometry values for new layout items Now every item starts with its geometry on ((0,0), preferredSize()). By doing this we guarantee that every item will have a known initial value, which can be specially useful on float cases for instance. Signed-off-by: Jesus Sanchez-Palencia Reviewed-by: Caio Marcelo de Oliveira Filho --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 37 ++++++++++++++++-------- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index e760642..87f5aa0 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -2068,22 +2068,35 @@ void QGraphicsAnchorLayoutPrivate::setItemsGeometries(const QRectF &geom) right = geom.right() - right; foreach (QGraphicsLayoutItem *item, items) { - firstH = internalVertex(item, Qt::AnchorLeft); - secondH = internalVertex(item, Qt::AnchorRight); - firstV = internalVertex(item, Qt::AnchorTop); - secondV = internalVertex(item, Qt::AnchorBottom); - QRectF newGeom; - newGeom.setTop(top + firstV->distance); - newGeom.setBottom(top + secondV->distance); + QSizeF itemPreferredSize = item->effectiveSizeHint(Qt::PreferredSize); + if (m_nonFloatItems[Horizontal].contains(item)) { + firstH = internalVertex(item, Qt::AnchorLeft); + secondH = internalVertex(item, Qt::AnchorRight); + + if (visualDir == Qt::LeftToRight) { + newGeom.setLeft(left + firstH->distance); + newGeom.setRight(left + secondH->distance); + } else { + newGeom.setLeft(right - secondH->distance); + newGeom.setRight(right - firstH->distance); + } + } else { + newGeom.setLeft(0); + newGeom.setRight(itemPreferredSize.width()); + } + + if (m_nonFloatItems[Vertical].contains(item)) { + firstV = internalVertex(item, Qt::AnchorTop); + secondV = internalVertex(item, Qt::AnchorBottom); - if (visualDir == Qt::LeftToRight) { - newGeom.setLeft(left + firstH->distance); - newGeom.setRight(left + secondH->distance); + newGeom.setTop(top + firstV->distance); + newGeom.setBottom(top + secondV->distance); } else { - newGeom.setLeft(right - secondH->distance); - newGeom.setRight(right - firstH->distance); + newGeom.setTop(0); + newGeom.setBottom(itemPreferredSize.height()); } + item->setGeometry(newGeom); } } -- cgit v0.12 From 709cc9140407280aa5c871d4650c123002dfdd19 Mon Sep 17 00:00:00 2001 From: "Eduardo M. Fleury" Date: Thu, 1 Oct 2009 15:04:20 -0300 Subject: QGraphicsAnchorLayout: Enable "float" Orbit test Now supported after float patches. Signed-off-by: Eduardo M. Fleury Reviewed-by: Jesus Sanchez-Palencia --- tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp b/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp index caf078e..148b2c8 100644 --- a/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp +++ b/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp @@ -1415,9 +1415,6 @@ void tst_QGraphicsAnchorLayout1::testMixedSpacing_data() QTest::newRow("One widget, unsolvable") << QSizeF(10, 10) << theData << theResult; } - // ### BUG. We are not handling "floating" elements properly. Ie. elements that - // have no anchors in a given orientation. - if (0) // Two widgets, one has fixed size { BasicLayoutTestDataList theData; -- cgit v0.12 From 9cf618492d1c89b489bf7e52e45c9577f9d52c1c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 6 Oct 2009 20:47:52 +0200 Subject: Autotest: use port 12346 instead of 1, to ensure that it's not a firewall issue Also check if we're not timing out instead of being able to fail. --- tests/auto/networkselftest/tst_networkselftest.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/auto/networkselftest/tst_networkselftest.cpp b/tests/auto/networkselftest/tst_networkselftest.cpp index c6a3119..e927a7a 100644 --- a/tests/auto/networkselftest/tst_networkselftest.cpp +++ b/tests/auto/networkselftest/tst_networkselftest.cpp @@ -335,10 +335,15 @@ void tst_NetworkSelfTest::dnsResolution() void tst_NetworkSelfTest::serverReachability() { - // check that we get a proper error connecting to port 1 + // check that we get a proper error connecting to port 12346 QTcpSocket socket; - socket.connectToHost(QtNetworkSettings::serverName(), 1); + socket.connectToHost(QtNetworkSettings::serverName(), 12346); + + QTime timer; + timer.start(); socket.waitForConnected(10000); + QVERIFY2(timer.elapsed() < 9900, "Connection to closed port timed out instead of refusing, something is wrong"); + QVERIFY2(socket.state() == QAbstractSocket::UnconnectedState, "Socket connected unexpectedly!"); QVERIFY2(socket.error() == QAbstractSocket::ConnectionRefusedError, QString("Could not reach server: %1").arg(socket.errorString()).toLocal8Bit()); -- cgit v0.12 From d47b7e6d0adcd675ba9da11818b3fa9acc3caff5 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 6 Oct 2009 20:51:18 +0200 Subject: Autotest: add a few more tests, with IP address and actual hostname --- tests/auto/networkselftest/tst_networkselftest.cpp | 78 ++++++++++++++++++++-- 1 file changed, 74 insertions(+), 4 deletions(-) diff --git a/tests/auto/networkselftest/tst_networkselftest.cpp b/tests/auto/networkselftest/tst_networkselftest.cpp index e927a7a..5a82f28 100644 --- a/tests/auto/networkselftest/tst_networkselftest.cpp +++ b/tests/auto/networkselftest/tst_networkselftest.cpp @@ -46,6 +46,10 @@ class tst_NetworkSelfTest: public QObject { Q_OBJECT + QHostAddress cachedIpAddress; +public: + QHostAddress serverIpAddress(); + private slots: void hostTest(); void dnsResolution_data(); @@ -303,6 +307,16 @@ static void netChat(int port, const QList &chat) } } +QHostAddress tst_NetworkSelfTest::serverIpAddress() +{ + if (cachedIpAddress.protocol() == QAbstractSocket::UnknownNetworkLayerProtocol) { + // need resolving + QHostInfo resolved = QHostInfo::fromName(QtNetworkSettings::serverName()); + cachedIpAddress = resolved.addresses().first(); + } + return cachedIpAddress; +} + void tst_NetworkSelfTest::hostTest() { // this is a localhost self-test @@ -331,6 +345,9 @@ void tst_NetworkSelfTest::dnsResolution() QHostInfo resolved = QHostInfo::fromName(hostName); QVERIFY2(resolved.error() == QHostInfo::NoError, QString("Failed to resolve hostname %1: %2").arg(hostName, resolved.errorString()).toLocal8Bit()); + QVERIFY2(resolved.addresses().size() > 0, "Got 0 addresses for server IP"); + + cachedIpAddress = resolved.addresses().first(); } void tst_NetworkSelfTest::serverReachability() @@ -469,7 +486,18 @@ void tst_NetworkSelfTest::httpsServer() void tst_NetworkSelfTest::httpProxy() { netChat(3128, QList() - // proxy GET + // proxy GET by IP + << Chat::send("GET http://" + serverIpAddress().toString().toLatin1() + "/ HTTP/1.0\r\n" + "Host: " + QtNetworkSettings::serverName().toLatin1() + "\r\n" + "Proxy-connection: close\r\n" + "\r\n") + << Chat::expect("HTTP/1.") + << Chat::discardUntil(" ") + << Chat::expect("200 ") + << Chat::DiscardUntilDisconnect + + // proxy GET by hostname + << Chat::Reconnect << Chat::send("GET http://" + QtNetworkSettings::serverName().toLatin1() + "/ HTTP/1.0\r\n" "Host: " + QtNetworkSettings::serverName().toLatin1() + "\r\n" "Proxy-connection: close\r\n" @@ -479,7 +507,17 @@ void tst_NetworkSelfTest::httpProxy() << Chat::expect("200 ") << Chat::DiscardUntilDisconnect - // proxy CONNECT + // proxy CONNECT by IP + << Chat::Reconnect + << Chat::send("CONNECT " + serverIpAddress().toString().toLatin1() + ":21 HTTP/1.0\r\n" + "\r\n") + << Chat::expect("HTTP/1.") + << Chat::discardUntil(" ") + << Chat::expect("200 ") + << Chat::discardUntil("\r\n\r\n") + << ftpChat() + + // proxy CONNECT by hostname << Chat::Reconnect << Chat::send("CONNECT " + QtNetworkSettings::serverName().toLatin1() + ":21 HTTP/1.0\r\n" "\r\n") @@ -487,7 +525,8 @@ void tst_NetworkSelfTest::httpProxy() << Chat::discardUntil(" ") << Chat::expect("200 ") << Chat::discardUntil("\r\n\r\n") - << ftpChat()); + << ftpChat() + ); } void tst_NetworkSelfTest::httpProxyBasicAuth() @@ -540,11 +579,22 @@ static const char handshakeAuthPassword[] = "\5\1\2\1\12qsockstest\10password"; static const char handshakeOkPasswdAuth[] = "\5\2\1\0"; static const char handshakeAuthNotOk[] = "\5\377"; static const char connect1[] = "\5\1\0\1\177\0\0\1\0\25"; // Connect IPv4 127.0.0.1 port 21 +static const char connect1a[] = "\5\1\0\1"; // just "Connect to IPv4" +static const char connect1b[] = "\0\25"; // just "port 21" static const char connect2[] = "\5\1\0\3\11localhost\0\25"; // Connect hostname localhost 21 +static const char connect2a[] = "\5\1\0\3"; // just "Connect to hostname" static const char connected[] = "\5\0\0"; +#define QBA(x) (QByteArray::fromRawData(x, -1 + sizeof(x))) + void tst_NetworkSelfTest::socks5Proxy() { + union { + char buf[4]; + quint32 data; + } ip4Address; + ip4Address.data = qToBigEndian(serverIpAddress().toIPv4Address()); + netChat(1080, QList() // IP address connection << Chat::send(QByteArray(handshakeNoAuth, -1 + sizeof handshakeNoAuth)) @@ -555,7 +605,17 @@ void tst_NetworkSelfTest::socks5Proxy() << Chat::skipBytes(6) // the server's local address and port << ftpChat() - // hostname connection + // connect by IP + << Chat::Reconnect + << Chat::send(QByteArray(handshakeNoAuth, -1 + sizeof handshakeNoAuth)) + << Chat::expect(QByteArray(handshakeOkNoAuth, -1 + sizeof handshakeOkNoAuth)) + << Chat::send(QBA(connect1a) + QByteArray::fromRawData(ip4Address.buf, 4) + QBA(connect1b)) + << Chat::expect(QByteArray(connected, -1 + sizeof connected)) + << Chat::expect("\1") // IPv4 address following + << Chat::skipBytes(6) // the server's local address and port + << ftpChat() + + // connect to "localhost" by hostname << Chat::Reconnect << Chat::send(QByteArray(handshakeNoAuth, -1 + sizeof handshakeNoAuth)) << Chat::expect(QByteArray(handshakeOkNoAuth, -1 + sizeof handshakeOkNoAuth)) @@ -564,6 +624,16 @@ void tst_NetworkSelfTest::socks5Proxy() << Chat::expect("\1") // IPv4 address following << Chat::skipBytes(6) // the server's local address and port << ftpChat() + + // connect to server by its official name + << Chat::Reconnect + << Chat::send(QByteArray(handshakeNoAuth, -1 + sizeof handshakeNoAuth)) + << Chat::expect(QByteArray(handshakeOkNoAuth, -1 + sizeof handshakeOkNoAuth)) + << Chat::send(QBA(connect2a) + char(QtNetworkSettings::serverName().size()) + QtNetworkSettings::serverName().toLatin1() + QBA(connect1b)) + << Chat::expect(QByteArray(connected, -1 + sizeof connected)) + << Chat::expect("\1") // IPv4 address following + << Chat::skipBytes(6) // the server's local address and port + << ftpChat() ); } -- cgit v0.12 From d6d0b2ef5223b4a40e8907104eb1d9e827507a42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Wed, 7 Oct 2009 10:51:26 +0200 Subject: Cosmetic fixes to the previous patches. There is only one change in the actual code here, and it simply removes an unnecessary initialization of hasSize in the ctors of the composite anchors. --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 68 +++++++++++++----------- src/gui/graphicsview/qgraphicsanchorlayout_p.h | 2 - src/gui/graphicsview/qsimplex_p.cpp | 4 +- src/gui/graphicsview/qsimplex_p.h | 4 +- 4 files changed, 40 insertions(+), 38 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 87f5aa0..34071cc 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -2409,47 +2409,51 @@ bool QGraphicsAnchorLayoutPrivate::solvePreferred(QList co return feasible; } -/*! Calculate the "expanding" keyframe +/*! + \internal + Calculate the "expanding" keyframe - This new keyframe sits between the already existing sizeAtPreferred and - sizeAtMaximum keyframes. Its goal is to modify the interpolation between - the latter as to respect the "expanding" size policy of some anchors. + This new keyframe sits between the already existing sizeAtPreferred and + sizeAtMaximum keyframes. Its goal is to modify the interpolation between + the latter as to respect the "expanding" size policy of some anchors. - Previously all items would be subject to a linear interpolation between - sizeAtPreferred and sizeAtMaximum values. This will change now, the - expanding anchors will change their size before the others. To calculate - this keyframe we use the following logic: + Previously all items would be subject to a linear interpolation between + sizeAtPreferred and sizeAtMaximum values. This will change now, the + expanding anchors will change their size before the others. To calculate + this keyframe we use the following logic: - 1) Ask each anchor for their desired expanding size (ad->expSize), this - value depends on the anchor expanding property in the following way: + 1) Ask each anchor for their desired expanding size (ad->expSize), this + value depends on the anchor expanding property in the following way: - - Expanding anchors want to grow towards their maximum size - - Non-expanding anchors want to remain at their preferred size. - - Composite anchors want to grow towards somewhere between their - preferred sizes. (*) + - Expanding normal anchors want to grow towards their maximum size + - Non-expanding normal anchors want to remain at their preferred size. + - Sequential anchors wants to grow towards a size that is calculated by: + summarizing it's child anchors, where it will use preferred size for non-expanding anchors + and maximum size for expanding anchors. + - Parallel anchors want to grow towards the smallest maximum size of all the expanding anchors. - 2) Clamp their desired values to the value they assume in the neighbour - keyframes (sizeAtPreferred and sizeAtExpanding) + 2) Clamp their desired values to the value they assume in the neighbour + keyframes (sizeAtPreferred and sizeAtExpanding) - 3) Run simplex with a setup that ensures the following: + 3) Run simplex with a setup that ensures the following: - a. Anchors will change their value from their sizeAtPreferred towards - their sizeAtMaximum as much as required to ensure that ALL anchors - reach their respective "desired" expanding sizes. + a. Anchors will change their value from their sizeAtPreferred towards + their sizeAtMaximum as much as required to ensure that ALL anchors + reach their respective "desired" expanding sizes. - b. No anchors will change their value beyond what is NEEDED to satisfy - the requirement above. + b. No anchors will change their value beyond what is NEEDED to satisfy + the requirement above. - The final result is that, at the "expanding" keyframe expanding anchors - will grow and take with them all anchors that are parallel to them. - However, non-expanding anchors will remain at their preferred size unless - they are forced to grow by a parallel expanding anchor. + The final result is that, at the "expanding" keyframe expanding anchors + will grow and take with them all anchors that are parallel to them. + However, non-expanding anchors will remain at their preferred size unless + they are forced to grow by a parallel expanding anchor. - Note: For anchors where the sizeAtPreferred is bigger than sizeAtPreferred, - the visual effect when the layout grows from its preferred size is - the following: Expanding anchors will keep their size while non - expanding ones will shrink. Only after non-expanding anchors have - shrinked all the way, the expanding anchors will start to shrink too. + Note: For anchors where the sizeAtPreferred is bigger than sizeAtMaximum, + the visual effect when the layout grows from its preferred size is + the following: Expanding anchors will keep their size while non + expanding ones will shrink. Only after non-expanding anchors have + shrinked all the way, the expanding anchors will start to shrink too. */ void QGraphicsAnchorLayoutPrivate::solveExpanding(QList constraints) { @@ -2495,7 +2499,7 @@ void QGraphicsAnchorLayoutPrivate::solveExpanding(QList co itemC->constant = qMax(boundedExpSize, ad->sizeAtMaximum); itemConstraints << itemC; - // Create objective to avoid the anchos from moving away from + // Create objective to avoid the anchors from moving away from // the preferred size more than the needed amount. (ensure 3.b) // The objective function is the distance between sizeAtPreferred // and sizeAtExpanding, it will be minimized. diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 1a74d85..24b25de 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -227,7 +227,6 @@ struct SequentialAnchorData : public AnchorData SequentialAnchorData() : AnchorData() { type = AnchorData::Sequential; - hasSize = true; #ifdef QT_DEBUG name = QLatin1String("SequentialAnchorData"); #endif @@ -256,7 +255,6 @@ struct ParallelAnchorData : public AnchorData : AnchorData(), firstEdge(first), secondEdge(second) { type = AnchorData::Parallel; - hasSize = true; // ### Those asserts force that both child anchors have the same direction, // but can't we simplify a pair of anchors in opposite directions? diff --git a/src/gui/graphicsview/qsimplex_p.cpp b/src/gui/graphicsview/qsimplex_p.cpp index 95003d2..b8f8fb4 100644 --- a/src/gui/graphicsview/qsimplex_p.cpp +++ b/src/gui/graphicsview/qsimplex_p.cpp @@ -519,11 +519,11 @@ qreal QSimplex::solver(solverFactor factor) solveMaxHelper(); collectResults(); - #ifdef QT_DEBUG +#ifdef QT_DEBUG for (int i = 0; i < constraints.size(); ++i) { Q_ASSERT(constraints[i]->isSatisfied()); } - #endif +#endif return factor * valueAt(0, columns - 1); } diff --git a/src/gui/graphicsview/qsimplex_p.h b/src/gui/graphicsview/qsimplex_p.h index b517cb9..51991a9 100644 --- a/src/gui/graphicsview/qsimplex_p.h +++ b/src/gui/graphicsview/qsimplex_p.h @@ -95,7 +95,7 @@ struct QSimplexConstraint QPair helper; QSimplexVariable * artificial; - #ifdef QT_DEBUG +#ifdef QT_DEBUG bool isSatisfied() { qreal leftHandSide(0); @@ -118,7 +118,7 @@ struct QSimplexConstraint return false; } } - #endif +#endif }; class QSimplex -- cgit v0.12 From dde11ce47c2d83bae685f3ff032ee9e6e372058f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Wed, 7 Oct 2009 11:30:30 +0200 Subject: Make some lines in the autotest more readable. --- .../qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index b076631..286ea2d 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -161,15 +161,13 @@ void tst_QGraphicsAnchorLayout::simple() l->setContentsMargins(0, 0, 0, 0); // Horizontal - l->addAnchor(w1, Qt::AnchorLeft, l, Qt::AnchorLeft); + l->addAnchor(l, Qt::AnchorLeft, w1, Qt::AnchorLeft); l->addAnchor(w1, Qt::AnchorRight, w2, Qt::AnchorLeft); l->addAnchor(w2, Qt::AnchorRight, l, Qt::AnchorRight); // Vertical - l->addAnchor(w1, Qt::AnchorTop, l, Qt::AnchorTop); - l->addAnchor(w2, Qt::AnchorTop, l, Qt::AnchorTop); - l->addAnchor(w1, Qt::AnchorBottom, l, Qt::AnchorBottom); - l->addAnchor(w2, Qt::AnchorBottom, l, Qt::AnchorBottom); + l->addAnchors(l, w1, Qt::Vertical); + l->addAnchors(l, w2, Qt::Vertical); QGraphicsWidget p; p.setLayout(l); @@ -1172,12 +1170,9 @@ void tst_QGraphicsAnchorLayout::delete_anchor() l->addAnchor(w3, Qt::AnchorRight, l, Qt::AnchorRight); // Vertical - l->addAnchor(w1, Qt::AnchorTop, l, Qt::AnchorTop); - l->addAnchor(w1, Qt::AnchorBottom, l, Qt::AnchorBottom); - l->addAnchor(w2, Qt::AnchorTop, l, Qt::AnchorTop); - l->addAnchor(w2, Qt::AnchorBottom, l, Qt::AnchorBottom); - l->addAnchor(w3, Qt::AnchorTop, l, Qt::AnchorTop); - l->addAnchor(w3, Qt::AnchorBottom, l, Qt::AnchorBottom); + l->addAnchors(l, w1, Qt::Vertical); + l->addAnchors(l, w2, Qt::Vertical); + l->addAnchors(l, w3, Qt::Vertical); QGraphicsAnchor *anchor = l->anchor(w3, Qt::AnchorRight, l, Qt::AnchorRight); anchor->setSpacing(10); -- cgit v0.12 From 591f5353c88439594b9340226b4843d7ca2888ef Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Wed, 7 Oct 2009 11:48:08 +0200 Subject: Fix ASSERT caused by Plastique style when setting an application font with a pixel size Use QFontInfo to query the pointSize() instead of asking the font directly, fixing this assert: ASSERT failure in QFont::setPointSize: "point size must be greater than 0", file text/qfont.cpp, line 855 Task-number: QTBUG-3555 Reviewed-by: Simon Hausmann --- src/gui/styles/qplastiquestyle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/styles/qplastiquestyle.cpp b/src/gui/styles/qplastiquestyle.cpp index 349a60d..8e19022 100644 --- a/src/gui/styles/qplastiquestyle.cpp +++ b/src/gui/styles/qplastiquestyle.cpp @@ -3328,7 +3328,7 @@ void QPlastiqueStyle::drawControl(ControlElement element, const QStyleOption *op // Draw the text centered QFont font = painter->font(); - font.setPointSize(font.pointSize() - 1); + font.setPointSize(QFontInfo(font).pointSize() - 1); painter->setFont(font); painter->setPen(dockWidget->palette.windowText().color()); painter->drawText(titleRect, -- cgit v0.12 From 1c5b84937a7dd993e188f2a6fbf4e28916f683c9 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 7 Oct 2009 12:01:06 +0200 Subject: fix ts and qm targets under windows --- translations/translations.pri | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/translations/translations.pri b/translations/translations.pri index 0c5c1ee..0fb91e8 100644 --- a/translations/translations.pri +++ b/translations/translations.pri @@ -9,12 +9,9 @@ defineReplace(prependAll) { } defineReplace(fixPath) { -WIN { - return ($$replace($$1, /, \)) -} ELSE { + win32:1 ~= s|/|\\| return ($$1) } -} LUPDATE = $$fixPath($$QT_BUILD_TREE/bin/lupdate) -locations relative -no-ui-lines LRELEASE = $$fixPath($$QT_BUILD_TREE/bin/lrelease) -- cgit v0.12 From cc95666378ee0aef1cc6b02b544fdf52645f6d9b Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 7 Oct 2009 15:52:59 +0200 Subject: ignore invalid WM_KEYDOWN messages on Windows For some strange reason, I get the following message if I press a non-numerical key on the SIP of a Samsung Omnia device, running Windows mobile 6.1: WM_KEYDOWN wParam == 0 lParam == 1 That message is invalid. We must ignore it. Reviewed-by: mauricek --- src/gui/kernel/qkeymapper_win.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qkeymapper_win.cpp b/src/gui/kernel/qkeymapper_win.cpp index 25b6dce..8138839 100644 --- a/src/gui/kernel/qkeymapper_win.cpp +++ b/src/gui/kernel/qkeymapper_win.cpp @@ -949,8 +949,8 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, const MSG &msg, bool if(msg.wParam == VK_PROCESSKEY) return true; - // Ignore invalid virtual keycode (see bug 127424) - if (msg.wParam == 0xFF) + // Ignore invalid virtual keycodes (see bugs 127424, QTBUG-3630) + if (msg.wParam == 0 || msg.wParam == 0xFF) return true; // Translate VK_* (native) -> Key_* (Qt) keys -- cgit v0.12 From aa863c61ec5e68ff73c02e25a2954cdba9c2ef15 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Fri, 3 Jul 2009 16:40:32 +0200 Subject: QHeaderView: fixed the sizeHint with hidden sections We used to check the 100 first sections and 100 last sections Now we make sure we check 100 visible sections Task-number: 255574 --- src/gui/itemviews/qheaderview.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/gui/itemviews/qheaderview.cpp b/src/gui/itemviews/qheaderview.cpp index c5e6fed..b1306cc 100644 --- a/src/gui/itemviews/qheaderview.cpp +++ b/src/gui/itemviews/qheaderview.cpp @@ -526,20 +526,24 @@ QSize QHeaderView::sizeHint() const return d->cachedSizeHint; int width = 0; int height = 0; + d->executePostedLayout(); + // get size hint for the first n sections - int c = qMin(count(), 100); - for (int i = 0; i < c; ++i) { + int i = 0; + for (int checked = 0; checked < 100 && i < d->sectionCount; ++i) { if (isSectionHidden(i)) continue; + checked++; QSize hint = sectionSizeFromContents(i); width = qMax(hint.width(), width); height = qMax(hint.height(), height); } // get size hint for the last n sections - c = qMax(count() - 100, c); - for (int j = count() - 1; j >= c; --j) { + i = qMax(i, d->sectionCount - 100 ); + for (int j = d->sectionCount - 1, checked = 0; j > i && checked < 100; --j) { if (isSectionHidden(j)) continue; + checked++; QSize hint = sectionSizeFromContents(j); width = qMax(hint.width(), width); height = qMax(hint.height(), height); -- cgit v0.12 From fd99d512fdb3864fe750015916b8e6a2a27401c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Wed, 7 Oct 2009 13:20:39 +0200 Subject: Store the floating items instead of the non-floating items. Makes the code a bit easier to read and speeds up setItemsGeometries() in the normal use-case. --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 41 +++++++++++++----------- src/gui/graphicsview/qgraphicsanchorlayout_p.h | 6 ++-- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 34071cc..296930c 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -2008,14 +2008,20 @@ QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation) Use all visited Anchors on findPaths() so we can identify non-float Items. */ -void QGraphicsAnchorLayoutPrivate::identifyNonFloatItems(QSet visited, Orientation orientation) +void QGraphicsAnchorLayoutPrivate::identifyNonFloatItems(const QSet &visited, Orientation orientation) { - m_nonFloatItems[orientation].clear(); + QSet nonFloating; foreach (const AnchorData *ad, visited) - identifyNonFloatItems_helper(ad, orientation); + identifyNonFloatItems_helper(ad, &nonFloating); + + QSet allItems; + foreach (QGraphicsLayoutItem *item, items) + allItems.insert(item); + m_floatItems[orientation] = allItems - nonFloating; } + /*! \internal @@ -2023,22 +2029,22 @@ void QGraphicsAnchorLayoutPrivate::identifyNonFloatItems(QSet visi 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) +void QGraphicsAnchorLayoutPrivate::identifyNonFloatItems_helper(const AnchorData *ad, QSet *nonFloatingItemsIdentifiedSoFar) { 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); + nonFloatingItemsIdentifiedSoFar->insert(ad->to->m_item); break; case AnchorData::Sequential: foreach (const AnchorData *d, static_cast(ad)->m_edges) - identifyNonFloatItems_helper(d, orientation); + identifyNonFloatItems_helper(d, nonFloatingItemsIdentifiedSoFar); break; case AnchorData::Parallel: - identifyNonFloatItems_helper(static_cast(ad)->firstEdge, orientation); - identifyNonFloatItems_helper(static_cast(ad)->secondEdge, orientation); + identifyNonFloatItems_helper(static_cast(ad)->firstEdge, nonFloatingItemsIdentifiedSoFar); + identifyNonFloatItems_helper(static_cast(ad)->secondEdge, nonFloatingItemsIdentifiedSoFar); break; } } @@ -2070,7 +2076,10 @@ void QGraphicsAnchorLayoutPrivate::setItemsGeometries(const QRectF &geom) foreach (QGraphicsLayoutItem *item, items) { QRectF newGeom; QSizeF itemPreferredSize = item->effectiveSizeHint(Qt::PreferredSize); - if (m_nonFloatItems[Horizontal].contains(item)) { + if (m_floatItems[Horizontal].contains(item)) { + newGeom.setLeft(0); + newGeom.setRight(itemPreferredSize.width()); + } else { firstH = internalVertex(item, Qt::AnchorLeft); secondH = internalVertex(item, Qt::AnchorRight); @@ -2081,20 +2090,17 @@ void QGraphicsAnchorLayoutPrivate::setItemsGeometries(const QRectF &geom) newGeom.setLeft(right - secondH->distance); newGeom.setRight(right - firstH->distance); } - } else { - newGeom.setLeft(0); - newGeom.setRight(itemPreferredSize.width()); } - if (m_nonFloatItems[Vertical].contains(item)) { + if (m_floatItems[Vertical].contains(item)) { + newGeom.setTop(0); + newGeom.setBottom(itemPreferredSize.height()); + } else { firstV = internalVertex(item, Qt::AnchorTop); secondV = internalVertex(item, Qt::AnchorBottom); newGeom.setTop(top + firstV->distance); newGeom.setBottom(top + secondV->distance); - } else { - newGeom.setTop(0); - newGeom.setBottom(itemPreferredSize.height()); } item->setGeometry(newGeom); @@ -2554,8 +2560,7 @@ bool QGraphicsAnchorLayoutPrivate::hasConflicts() const QGraphicsAnchorLayoutPrivate *that = const_cast(this); that->calculateGraphs(); - bool floatConflict = (m_nonFloatItems[0].size() < items.size()) - || (m_nonFloatItems[1].size() < items.size()); + bool floatConflict = !m_floatItems[0].isEmpty() || !m_floatItems[1].isEmpty(); return graphHasConflicts[0] || graphHasConflicts[1] || floatConflict; } diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 24b25de..0f045e5 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -443,8 +443,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); + void identifyNonFloatItems(const QSet &visited, Orientation orientation); + void identifyNonFloatItems_helper(const AnchorData *ad, QSet *nonFloatingItemsIdentifiedSoFar); inline AnchorVertex *internalVertex(const QPair &itemEdge) const { @@ -511,7 +511,7 @@ public: // ### bool graphSimplified[2]; bool graphHasConflicts[2]; - QSet m_nonFloatItems[2]; + QSet m_floatItems[2]; uint calculateGraphCacheDirty : 1; }; -- cgit v0.12 From 9e59f3e021e78a5b825b7673248e0bf37ac935f1 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 8 Oct 2009 12:55:21 +0200 Subject: Revert "Ensure that qmake doesn't lose the error code when processing subdirs" This reverts commit c15b370c9db16fdbfd9e7bec89ee9bf8c1110827 since it is causing a problem with the autotests so that will be investigated further before this is resubmitted. --- qmake/generators/metamakefile.cpp | 14 ++++++-------- qmake/generators/metamakefile.h | 2 +- qmake/main.cpp | 5 +---- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/qmake/generators/metamakefile.cpp b/qmake/generators/metamakefile.cpp index 3acb2dd..69dd627 100644 --- a/qmake/generators/metamakefile.cpp +++ b/qmake/generators/metamakefile.cpp @@ -291,7 +291,7 @@ SubdirsMetaMakefileGenerator::init() if(init_flag) return false; init_flag = true; - bool hasError = false; + if(Option::recursive) { QString old_output_dir = Option::output_dir; QString old_output = Option::output.fileName(); @@ -336,7 +336,7 @@ SubdirsMetaMakefileGenerator::init() } qmake_setpwd(sub->input_dir); Option::output_dir = sub->output_dir; - hasError |= !sub_proj->read(subdir.fileName()); + sub_proj->read(subdir.fileName()); if(!sub_proj->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) { fprintf(stderr, "Project file(%s) not recursed because all requirements not met:\n\t%s\n", subdir.fileName().toLatin1().constData(), @@ -351,7 +351,7 @@ SubdirsMetaMakefileGenerator::init() } else { const QString output_name = Option::output.fileName(); Option::output.setFileName(sub->output_file); - hasError |= !sub->makefile->write(sub->output_dir); + sub->makefile->write(sub->output_dir); delete sub; qmakeClearCaches(); sub = 0; @@ -376,7 +376,7 @@ SubdirsMetaMakefileGenerator::init() self->makefile->init(); subs.append(self); - return !hasError; + return true; } bool @@ -745,7 +745,7 @@ MetaMakefileGenerator::createMakefileGenerator(QMakeProject *proj, bool noIO) } MetaMakefileGenerator * -MetaMakefileGenerator::createMetaGenerator(QMakeProject *proj, const QString &name, bool op, bool *success) +MetaMakefileGenerator::createMetaGenerator(QMakeProject *proj, const QString &name, bool op) { MetaMakefileGenerator *ret = 0; if ((Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || @@ -758,9 +758,7 @@ MetaMakefileGenerator::createMetaGenerator(QMakeProject *proj, const QString &na } if (!ret) ret = new BuildsMetaMakefileGenerator(proj, name, op); - bool res = ret->init(); - if (success) - *success = res; + ret->init(); return ret; } diff --git a/qmake/generators/metamakefile.h b/qmake/generators/metamakefile.h index f74f4a2..e69304a 100644 --- a/qmake/generators/metamakefile.h +++ b/qmake/generators/metamakefile.h @@ -62,7 +62,7 @@ public: virtual ~MetaMakefileGenerator(); - static MetaMakefileGenerator *createMetaGenerator(QMakeProject *proj, const QString &name, bool op=true, bool *success = 0); + static MetaMakefileGenerator *createMetaGenerator(QMakeProject *proj, const QString &name, bool op=true); static MakefileGenerator *createMakefileGenerator(QMakeProject *proj, bool noIO = false); inline QMakeProject *projectFile() const { return project; } diff --git a/qmake/main.cpp b/qmake/main.cpp index 8117a4c..73fdda9 100644 --- a/qmake/main.cpp +++ b/qmake/main.cpp @@ -168,10 +168,7 @@ int runQMake(int argc, char **argv) continue; } - bool success = true; - MetaMakefileGenerator *mkfile = MetaMakefileGenerator::createMetaGenerator(&project, QString(), false, &success); - if (!success) - exit_val = 3; + MetaMakefileGenerator *mkfile = MetaMakefileGenerator::createMetaGenerator(&project, QString(), false); if(mkfile && !mkfile->write(oldpwd)) { if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) fprintf(stderr, "Unable to generate project file.\n"); -- cgit v0.12 From 8050a8ea1b30b0d35fc20e9d09ff48c242a924cd Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 7 Oct 2009 14:41:33 +0200 Subject: Mac: fix auto test to reflect recent changes in wheel event handling ...on mac. Since mouse wheel events are accelerated by the OS on mac, we cannot multiply the delta with QApplication::wheelScrollLines, since this will make scrolling behave far to fast. To change the speed of wheel events on Mac, one should use system preferences. This patch updates the test to reflect his difference. Rev-By: ogoffart --- tests/auto/qabstractslider/tst_qabstractslider.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tests/auto/qabstractslider/tst_qabstractslider.cpp b/tests/auto/qabstractslider/tst_qabstractslider.cpp index 9f7a78e..5c70bde 100644 --- a/tests/auto/qabstractslider/tst_qabstractslider.cpp +++ b/tests/auto/qabstractslider/tst_qabstractslider.cpp @@ -714,7 +714,11 @@ void tst_QAbstractSlider::wheelEvent_data() << 1 // delta << int(Qt::Vertical) // orientation of slider << int(Qt::Vertical) // orientation of wheel +#ifdef Q_WS_MAC + << 1 // expected position after +#else << 20 // expected position after +#endif << QPoint(0,0); QTest::newRow("Normal data page") << 0 // initial position @@ -773,7 +777,11 @@ void tst_QAbstractSlider::wheelEvent_data() << 1 // delta << int(Qt::Horizontal) // orientation of slider << int(Qt::Horizontal) // orientation of wheel +#ifdef Q_WS_MAC + << 49 // expected position after +#else << 30 // expected position after +#endif << QPoint(1,1); QTest::newRow("Past end") << 50 // initial position @@ -784,7 +792,11 @@ void tst_QAbstractSlider::wheelEvent_data() << false // inverted controls << 1 // wheel scroll lines << false // with modifiers +#ifdef Q_WS_MAC + << 60 // delta +#else << 2 // delta +#endif << int(Qt::Horizontal) // orientation of slider << int(Qt::Horizontal) // orientation of wheel << 100 // expected position after @@ -798,7 +810,11 @@ void tst_QAbstractSlider::wheelEvent_data() << false // inverted controls << 1 // wheel scroll lines << false // with modifiers - << -2 // delta +#ifdef Q_WS_MAC + << -60 // delta +#else + << -2 // delta +#endif << int(Qt::Horizontal) // orientation of slider << int(Qt::Horizontal) // orientation of wheel << 0 // expected position after -- cgit v0.12 From 52aaffaf17c4d1bf11a469fe3cc692c3bea6cfe2 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 7 Oct 2009 14:46:43 +0200 Subject: Carbon: better wheel acceleration patch It turns out that scrolling appears to be slow when using non-mac mice with the carbon build. This patch introduces a an acceleration algorithm that closer resembles the one used by Cocoa. Rev-By: prasanth --- src/gui/kernel/qapplication_mac.mm | 26 ++++++++++++++++++++++---- src/gui/widgets/qabstractslider.cpp | 3 +-- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm index a95ae9d..f9c8aa3 100644 --- a/src/gui/kernel/qapplication_mac.mm +++ b/src/gui/kernel/qapplication_mac.mm @@ -1708,12 +1708,30 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event sizeof(axis), 0, &axis); // The 'new' event has acceleration applied by the OS, while the old (on - // Carbon only), has not. So we introduce acceleration here to be consistent: - int scrollFactor = 120 * qMin(5, qAbs(mdelt)); + // Carbon only), has not. So we introduce acceleration here to be consistent. + // The acceleration is trying to respect both pixel based and line scrolling, + // which turns out to be rather difficult. + int linesToScroll = mdelt > 0 ? 1 : -1; + static QTime t; + int elapsed = t.elapsed(); + t.restart(); + if (elapsed < 20) + linesToScroll *= 120; + else if (elapsed < 30) + linesToScroll *= 60; + else if (elapsed < 50) + linesToScroll *= 30; + else if (elapsed < 100) + linesToScroll *= 6; + else if (elapsed < 200) + linesToScroll *= 3; + else if (elapsed < 300) + linesToScroll *= 2; + if (axis == kEventMouseWheelAxisX) - wheel_deltaX = mdelt * scrollFactor; + wheel_deltaX = linesToScroll * 120; else - wheel_deltaY = mdelt * scrollFactor; + wheel_deltaY = linesToScroll * 120; } } diff --git a/src/gui/widgets/qabstractslider.cpp b/src/gui/widgets/qabstractslider.cpp index 19a8b63..588a48e 100644 --- a/src/gui/widgets/qabstractslider.cpp +++ b/src/gui/widgets/qabstractslider.cpp @@ -715,8 +715,7 @@ void QAbstractSlider::wheelEvent(QWheelEvent * e) #else stepsToScroll = int(d->offset_accumulated) * QApplication::wheelScrollLines() * d->singleStep; #endif - if (qAbs(stepsToScroll) > d->pageStep) - stepsToScroll = currentOffset > 0 ? d->pageStep : -d->pageStep; + stepsToScroll = qBound(-d->pageStep, stepsToScroll, d->pageStep); } if (d->invertedControls) -- cgit v0.12 From e1f7d33dcd8267fd2fc9658df6245ca30df3741e Mon Sep 17 00:00:00 2001 From: ninerider Date: Thu, 8 Oct 2009 14:05:54 +0200 Subject: Comparison tolerance increased for handhelds The 'fuzzy' value for the was not relaxed enoough for small devices such as Windows Mobile and the like. Reviewed-by: Joerg --- tests/auto/qgraphicstransform/tst_qgraphicstransform.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/auto/qgraphicstransform/tst_qgraphicstransform.cpp b/tests/auto/qgraphicstransform/tst_qgraphicstransform.cpp index e8979ea..b407fef 100644 --- a/tests/auto/qgraphicstransform/tst_qgraphicstransform.cpp +++ b/tests/auto/qgraphicstransform/tst_qgraphicstransform.cpp @@ -159,7 +159,11 @@ void tst_QGraphicsTransform::scale() // definitions correct for the difference. static inline bool fuzzyCompare(qreal p1, qreal p2) { - return (qAbs(p1 - p2) <= 0.00001f * qMin(qAbs(p1), qAbs(p2))); + // increase delta on small machines using float instead of double + if (sizeof(qreal) == sizeof(float)) + return (qAbs(p1 - p2) <= 0.00002f * qMin(qAbs(p1), qAbs(p2))); + else + return (qAbs(p1 - p2) <= 0.00001f * qMin(qAbs(p1), qAbs(p2))); } static bool fuzzyCompare(const QTransform& t1, const QTransform& t2) { -- cgit v0.12 From cbd0020a4db3c67bb73f6c42ec2ce06a710b00db Mon Sep 17 00:00:00 2001 From: ninerider Date: Thu, 8 Oct 2009 14:16:05 +0200 Subject: Non-Zero timer livelock test expected to fail on Windows CE Timing issues prevent this test from working correctly on Windows CE. Reviewed-by: Joerg --- tests/auto/qtimer/tst_qtimer.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tests/auto/qtimer/tst_qtimer.cpp b/tests/auto/qtimer/tst_qtimer.cpp index 0877500..01a6317 100644 --- a/tests/auto/qtimer/tst_qtimer.cpp +++ b/tests/auto/qtimer/tst_qtimer.cpp @@ -46,10 +46,6 @@ #include #include - - - - #if defined Q_OS_UNIX #include #endif @@ -242,7 +238,6 @@ public: // sleep for 2ms QTest::qSleep(2); - killTimer(te->timerId()); } @@ -277,9 +272,11 @@ void tst_QTimer::livelock() #elif defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) QEXPECT_FAIL("zero timer", "", Continue); QEXPECT_FAIL("non-zero timer", "", Continue); -#elif defined(Q_OS_WIN) +#elif defined(Q_OS_WIN) && !defined(Q_OS_WINCE) if (QSysInfo::WindowsVersion < QSysInfo::WV_XP) QEXPECT_FAIL("non-zero timer", "Multimedia timers are not available on Windows 2000", Continue); +#elif defined(Q_OS_WINCE) + QEXPECT_FAIL("non-zero timer", "Windows CE devices often too slow", Continue); #endif QVERIFY(tester.postEventAtRightTime); } -- cgit v0.12 From 00b198b1cdf48bd88d61bb256ec3ff455735e38c Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Thu, 8 Oct 2009 11:46:05 +0200 Subject: Conservative fix for link error with ARM RVCT compiler on symbian sbsv2 Not exporting the whole class prevents the capabilities example from linking, because the vtable is not exported. However windows builds don't support export of templated class, and export the vtable implicitly when there is an exported member function. Task-number: QTBUG-4593 Reviewed-by: Thierry Bastian --- .../phonon/phonon/objectdescriptionmodel.h | 23 ++++++++++++++++++---- src/s60installs/eabi/phononu.def | 20 +++++++++---------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/3rdparty/phonon/phonon/objectdescriptionmodel.h b/src/3rdparty/phonon/phonon/objectdescriptionmodel.h index ba3cb42..a3c72b2 100644 --- a/src/3rdparty/phonon/phonon/objectdescriptionmodel.h +++ b/src/3rdparty/phonon/phonon/objectdescriptionmodel.h @@ -139,6 +139,21 @@ namespace Phonon ObjectDescriptionModelDataPrivate *const d; }; +/* Required to ensure template class vtables are exported on both symbian +and existing builds. */ +#if defined(Q_OS_SYMBIAN) && defined(Q_CC_RVCT) +// RVCT compiler (2.2.686) requires the export declaration to be on the class to export vtables +// MWC compiler works both ways +// GCCE compiler is unknown (it can't compile QtCore yet) +#define PHONON_TEMPLATE_CLASS_EXPORT PHONON_EXPORT +#define PHONON_TEMPLATE_CLASS_MEMBER_EXPORT +#else +// Windows builds (at least) do not support export declaration on templated class +// But if you export a member function, the vtable is implicitly exported +#define PHONON_TEMPLATE_CLASS_EXPORT +#define PHONON_TEMPLATE_CLASS_MEMBER_EXPORT PHONON_EXPORT +#endif + /** \class ObjectDescriptionModel objectdescriptionmodel.h Phonon/ObjectDescriptionModel * \short The ObjectDescriptionModel class provides a model from * a list of ObjectDescription objects. @@ -175,7 +190,7 @@ namespace Phonon * \author Matthias Kretz */ template - class ObjectDescriptionModel : public QAbstractListModel + class PHONON_TEMPLATE_CLASS_EXPORT ObjectDescriptionModel : public QAbstractListModel { public: Q_OBJECT_CHECK @@ -188,11 +203,11 @@ namespace Phonon */ #if !defined(Q_CC_MINGW) || __MINGW32_MAJOR_VERSION >= 4 /** \internal */ - static PHONON_EXPORT const QMetaObject staticMetaObject; + static PHONON_TEMPLATE_CLASS_MEMBER_EXPORT const QMetaObject staticMetaObject; /** \internal */ - PHONON_EXPORT const QMetaObject *metaObject() const; + PHONON_TEMPLATE_CLASS_MEMBER_EXPORT const QMetaObject *metaObject() const; /** \internal */ - PHONON_EXPORT void *qt_metacast(const char *_clname); + PHONON_TEMPLATE_CLASS_MEMBER_EXPORT void *qt_metacast(const char *_clname); //int qt_metacall(QMetaObject::Call _c, int _id, void **_a); #endif diff --git a/src/s60installs/eabi/phononu.def b/src/s60installs/eabi/phononu.def index d407ba4..d70942c 100644 --- a/src/s60installs/eabi/phononu.def +++ b/src/s60installs/eabi/phononu.def @@ -495,11 +495,11 @@ EXPORTS _ZTIN6Phonon19AbstractVideoOutputE @ 494 NONAME _ZTIN6Phonon19BackendCapabilities8NotifierE @ 495 NONAME ABSENT _ZTIN6Phonon22MediaControllerPrivateE @ 496 NONAME ABSENT - _ZTIN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE0EEE @ 497 NONAME ABSENT - _ZTIN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE1EEE @ 498 NONAME ABSENT - _ZTIN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE2EEE @ 499 NONAME ABSENT - _ZTIN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE3EEE @ 500 NONAME ABSENT - _ZTIN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE4EEE @ 501 NONAME ABSENT + _ZTIN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE0EEE @ 497 NONAME + _ZTIN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE1EEE @ 498 NONAME + _ZTIN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE2EEE @ 499 NONAME + _ZTIN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE3EEE @ 500 NONAME + _ZTIN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE4EEE @ 501 NONAME _ZTIN6Phonon24VolumeFaderEffectPrivateE @ 502 NONAME ABSENT _ZTIN6Phonon26AbstractAudioOutputPrivateE @ 503 NONAME ABSENT _ZTIN6Phonon26AbstractMediaStreamPrivateE @ 504 NONAME @@ -532,11 +532,11 @@ EXPORTS _ZTVN6Phonon19AbstractVideoOutputE @ 531 NONAME _ZTVN6Phonon19BackendCapabilities8NotifierE @ 532 NONAME ABSENT _ZTVN6Phonon22MediaControllerPrivateE @ 533 NONAME ABSENT - _ZTVN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE0EEE @ 534 NONAME ABSENT - _ZTVN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE1EEE @ 535 NONAME ABSENT - _ZTVN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE2EEE @ 536 NONAME ABSENT - _ZTVN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE3EEE @ 537 NONAME ABSENT - _ZTVN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE4EEE @ 538 NONAME ABSENT + _ZTVN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE0EEE @ 534 NONAME + _ZTVN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE1EEE @ 535 NONAME + _ZTVN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE2EEE @ 536 NONAME + _ZTVN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE3EEE @ 537 NONAME + _ZTVN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE4EEE @ 538 NONAME _ZTVN6Phonon24VolumeFaderEffectPrivateE @ 539 NONAME ABSENT _ZTVN6Phonon26AbstractAudioOutputPrivateE @ 540 NONAME ABSENT _ZTVN6Phonon26AbstractMediaStreamPrivateE @ 541 NONAME -- cgit v0.12 From 77eceb53ee6fc7f20570f070124cd4a5f79698ab Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Thu, 8 Oct 2009 14:51:04 +0200 Subject: Remove incorrect optimisation in S60 widget / control stack sync Incorrect optimisation - for popup windows, Qt's focus is moved before hide_sys is called, resulting in the popup window keeping its elevated position in the CONE control stack. This can result in keyboard focus being in an invisible widget in some conditions - e.g. QTBUG-4733 Task-number: QTBUG-4733 Reviewed-by: axis --- src/gui/kernel/qwidget_s60.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 3328cee..b0d405a 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -434,7 +434,7 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de void QWidgetPrivate::show_sys() { Q_Q(QWidget); - + if (q->testAttribute(Qt::WA_OutsideWSRange)) return; @@ -490,7 +490,12 @@ void QWidgetPrivate::hide_sys() QSymbianControl *id = static_cast(q->internalWinId()); if (id) { - if(id->IsFocused()) // Avoid unnecessary calls to FocusChanged() + //Incorrect optimisation - for popup windows, Qt's focus is moved before + //hide_sys is called, resulting in the popup window keeping its elevated + //position in the CONE control stack. + //This can result in keyboard focus being in an invisible widget in some + //conditions - e.g. QTBUG-4733 + //if(id->IsFocused()) // Avoid unnecessary calls to FocusChanged() id->setFocusSafely(false); id->MakeVisible(false); if (QWidgetBackingStore *bs = maybeBackingStore()) @@ -1253,7 +1258,7 @@ void QWidget::grabMouse() WId id = effectiveWinId(); id->SetPointerCapture(true); QWidgetPrivate::mouseGrabber = this; - + #ifndef QT_NO_CURSOR QApplication::setOverrideCursor(cursor()); #endif -- cgit v0.12 From d64c806a7876937cceffd3d3185cf44510ec554e Mon Sep 17 00:00:00 2001 From: ninerider Date: Thu, 8 Oct 2009 15:27:05 +0200 Subject: Skipped test for Windows Mobile involving mouse move events. Events caused by dragging a mouse are currently unavailable in Windows Mobile. Reviewed-by: Joerg --- tests/auto/qmenu/tst_qmenu.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/auto/qmenu/tst_qmenu.cpp b/tests/auto/qmenu/tst_qmenu.cpp index 726ca55..4eb149f 100644 --- a/tests/auto/qmenu/tst_qmenu.cpp +++ b/tests/auto/qmenu/tst_qmenu.cpp @@ -812,6 +812,9 @@ public: void tst_QMenu::task258920_mouseBorder() { +#ifdef Q_OS_WINCE_WM + QSKIP("Mouse move related signals for Windows Mobile unavailable", SkipAll); +#endif Menu258920 menu; QAction *action = menu.addAction("test"); -- cgit v0.12 From dc69ddd069d687c748027790660818d2c79d3dfc Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 8 Oct 2009 16:01:22 +0200 Subject: doc: Changed the format of the since list. This is a big change from the original, and I expect we will want modifications. --- doc/src/qt4-intro.qdoc | 5 +- tools/qdoc3/codemarker.h | 2 + tools/qdoc3/cppcodeparser.cpp | 6 +- tools/qdoc3/htmlgenerator.cpp | 380 +++++++++++++++++++++++++++++++----------- tools/qdoc3/htmlgenerator.h | 59 +++++-- tools/qdoc3/node.cpp | 106 ++++++++++-- tools/qdoc3/node.h | 22 ++- 7 files changed, 433 insertions(+), 147 deletions(-) diff --git a/doc/src/qt4-intro.qdoc b/doc/src/qt4-intro.qdoc index 6224cd4..38f346f 100644 --- a/doc/src/qt4-intro.qdoc +++ b/doc/src/qt4-intro.qdoc @@ -661,10 +661,9 @@ See the \l{QtMultimedia Module} documentation for more information. - \section1 Classes, functions, and other items introduced in 4.6 + \section1 Classes, functions, etc new in 4.6 - Links to classes, function, and other items that were added in - 4.6. + Links to classes, functions, and other items that are new in 4.6. \sincelist 4.6 diff --git a/tools/qdoc3/codemarker.h b/tools/qdoc3/codemarker.h index e400f8a..9858484 100644 --- a/tools/qdoc3/codemarker.h +++ b/tools/qdoc3/codemarker.h @@ -71,6 +71,8 @@ struct Section : name(name0), singularMember(singularMember0), pluralMember(pluralMember0) { } + void appendMember(Node* node) { members.append(node); } + void appendReimpMember(Node* node) { reimpMembers.append(node); } }; struct FastSection diff --git a/tools/qdoc3/cppcodeparser.cpp b/tools/qdoc3/cppcodeparser.cpp index ec5ce96..d93e24c 100644 --- a/tools/qdoc3/cppcodeparser.cpp +++ b/tools/qdoc3/cppcodeparser.cpp @@ -541,9 +541,10 @@ Node *CppCodeParser::processTopicCommand(const Doc& doc, else { lastPath = parentPath; } - - if (func) + if (func) { func->borrowParameterNames(clone); + func->setParentPath(clone->parentPath()); + } delete clone; } return func; @@ -1371,6 +1372,7 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent, func->setAccess(access); func->setLocation(location()); func->setReturnType(returnType.toString()); + func->setParentPath(parentPath); func->setTemplateStuff(templateStuff); if (compat) func->setStatus(Node::Compat); diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index 291f60b..e883dfa 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -59,6 +59,24 @@ QT_BEGIN_NAMESPACE #define COMMAND_VERSION Doc::alias("version") +QString HtmlGenerator::sinceTitles[] = + { + " New Namespaces", + " New Classes", + " New Member Functions", + " New Functions in Namespaces", + " New Global Functions", + " New Macros", + " New Enum Types", + " New Typedefs", + " New Properties", + " New Variables", + " New Qml Properties", + " New Qml Signals", + " New Qml Methods", + "" + }; + static bool showBrokenLinks = false; static QRegExp linkTag("(<@link node=\"([^\"]+)\">).*()"); @@ -186,7 +204,7 @@ HtmlGenerator::HtmlGenerator() : helpProjectWriter(0), inLink(false), inContents(false), inSectionHeading(false), inTableHeader(false), numTableRows(0), threeColumnEnumValueTable(true), funcLeftParen("\\S(\\()"), - tre(0), slow(false), obsoleteLinks(false) + myTree(0), slow(false), obsoleteLinks(false) { } @@ -313,7 +331,7 @@ void HtmlGenerator::generateTree(const Tree *tree, CodeMarker *marker) ++styleIter; } - tre = tree; + myTree = tree; nonCompatClasses.clear(); mainClasses.clear(); compatClasses.clear(); @@ -433,7 +451,7 @@ void HtmlGenerator::generateTree(const Tree *tree, CodeMarker *marker) projectUrl, projectDescription); - helpProjectWriter->generate(tre); + helpProjectWriter->generate(myTree); } void HtmlGenerator::startText(const Node * /* relative */, @@ -598,13 +616,12 @@ int HtmlGenerator::generateAtom(const Atom *atom, break; case Atom::AnnotatedList: { - QList values = tre->groups().values(atom->string()); - QMap nodeMap; + QList values = myTree->groups().values(atom->string()); + NodeMap nodeMap; for (int i = 0; i < values.size(); ++i) { const Node* n = values.at(i); if ((n->status() != Node::Internal) && (n->access() != Node::Private)) { nodeMap.insert(n->nameForLists(),n); - //qDebug() << " " << n->nameForLists(); } } generateAnnotatedList(relative, marker, nodeMap); @@ -633,7 +650,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, if (editionModuleMap.contains(editionName)) { // Add all classes in the modules listed for that edition. - QMap editionClasses; + NodeMap editionClasses; foreach (const QString &moduleName, editionModuleMap[editionName]) { if (moduleClassMap.contains(moduleName)) editionClasses.unite(moduleClassMap[moduleName]); @@ -642,7 +659,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, // Add additional groups and remove groups of classes that // should be excluded from the edition. - QMultiMap groups = tre->groups(); + QMultiMap groups = myTree->groups(); foreach (const QString &groupName, editionGroupMap[editionName]) { QList groupClasses; if (groupName.startsWith("-")) { @@ -689,7 +706,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, else if (atom->string() == "related") { const FakeNode *fake = static_cast(relative); if (fake && !fake->groupMembers().isEmpty()) { - QMap groupMembersMap; + NodeMap groupMembersMap; foreach (const Node *node, fake->groupMembers()) { if (node->type() == Node::Fake) groupMembersMap[fullName(node, relative, marker)] = node; @@ -713,18 +730,125 @@ int HtmlGenerator::generateAtom(const Atom *atom, break; case Atom::SinceList: { - QList nodes; - SinceVersionMap::const_iterator v; - v = sinceVersions.find(atom->string()); - if ((v != sinceVersions.constEnd()) && !v.value().isEmpty()) { + NodeMultiMapMap::const_iterator v; + v = nodeMultiMapMap.find(atom->string()); + NodeMapMap::const_iterator nc; + nc = nodeMapMap.find(atom->string()); + if ((v != nodeMultiMapMap.constEnd()) && !v.value().isEmpty()) { + QList
sections; + QList
::ConstIterator s; + for (int i=0; itype()) { + case Node::Namespace: + sections[Namespace].appendMember((Node*)node); + break; + case Node::Class: + sections[Class].appendMember((Node*)node); + break; + case Node::Enum: + sections[Enum].appendMember((Node*)node); + break; + case Node::Typedef: + sections[Typedef].appendMember((Node*)node); + break; + case Node::Function: + const FunctionNode* fn = static_cast(node); + if (fn->isMacro()) + sections[Macro].appendMember((Node*)node); + else { + Node* p = fn->parent(); + if (p) { + if (p->type() == Node::Class) + sections[MemberFunction].appendMember((Node*)node); + else if (p->type() == Node::Namespace) { + if (p->name().isEmpty()) + sections[GlobalFunction].appendMember((Node*)node); + else + sections[NamespaceFunction].appendMember((Node*)node); + } + else + sections[GlobalFunction].appendMember((Node*)node); + } + else + sections[GlobalFunction].appendMember((Node*)node); + } + break; + case Node::Property: + sections[Property].appendMember((Node*)node); + break; + case Node::Variable: + sections[Variable].appendMember((Node*)node); + break; + case Node::QmlProperty: + sections[QmlProperty].appendMember((Node*)node); + break; + case Node::QmlSignal: + sections[QmlSignal].appendMember((Node*)node); + break; + case Node::QmlMethod: + sections[QmlMethod].appendMember((Node*)node); + break; + default: + break; + } + ++n; + } + int idx = 0; + s = sections.constBegin(); + while (s != sections.constEnd()) { + if (!(*s).members.isEmpty()) { + out() << "\n"; + out() << "

" << protect((*s).name) << "

\n"; + if (idx == Class) + generateCompactList(0, marker, nc.value(), QString("Q")); + else if (idx == MemberFunction) { + NodeMultiMapMap nodemultimapmap; + NodeMultiMapMap::iterator nmmap; + NodeList::const_iterator i = s->members.constBegin(); + while (i != s->members.constEnd()) { + Node* p = (*i)->parent(); + nmmap = nodemultimapmap.find(p->name()); + if (nmmap == nodemultimapmap.end()) + nmmap = nodemultimapmap.insert(p->name(),NodeMultiMap()); + nmmap->insert((*i)->name(),(*i)); + ++i; + } + nmmap = nodemultimapmap.begin(); + while (nmmap != nodemultimapmap.end()) { + NodeList nlist = nmmap->values(); + out() << "

New functions in " << protect(nmmap.key()) << ":

\n"; + generateSection(nlist, 0, marker, CodeMarker::Summary); + out() << "
"; + ++nmmap; + } + } + else + generateSection(s->members, 0, marker, CodeMarker::Summary); + } + ++idx; + ++s; + } +#if 0 for (int i=0; !Node::typeName(i).isEmpty(); i++) { Node::Type t = (Node::Type) i; SinceNodeMultiMap::const_iterator n=v.value().constBegin(); QMultiMap nodeMap; while (n != v.value().constEnd()) { const Node* node = n.value(); - if (node->type() == t) + if (node->type() == t) { nodeMap.insert(node->nameForLists(),node); + if (node->type() == Node::Function) { + const FunctionNode* fn = static_cast(node); + qDebug() << "SIGNATURE:" << fn->signature(); + } + } ++n; } if (!nodeMap.isEmpty()) { @@ -737,10 +861,11 @@ int HtmlGenerator::generateAtom(const Atom *atom, nodeMap.clear(); } } +#endif } } break; -case Atom::Image: + case Atom::Image: case Atom::InlineImage: { QString fileName = imageFileName(relative, atom->string()); @@ -1151,7 +1276,7 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner, subtitleText << "[" << Atom(Atom::AutoLink, fixedModule) << " module]"; if (fixedModule.isEmpty()) { - QMultiMap publicGroups = tre->publicGroups(); + QMultiMap publicGroups = myTree->publicGroups(); QList groupNames = publicGroups.values(inner->name()); if (!groupNames.isEmpty()) { qSort(groupNames.begin(), groupNames.end()); @@ -1492,7 +1617,7 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker) generateAlsoList(fake, marker); if (!fake->groupMembers().isEmpty()) { - QMap groupMembersMap; + NodeMap groupMembersMap; foreach (const Node *node, fake->groupMembers()) { if (node->type() == Node::Class || node->type() == Node::Namespace) groupMembersMap[node->name()] = node; @@ -1564,7 +1689,7 @@ void HtmlGenerator::generateHeader(const QString& title, if (node && !node->doc().location().isEmpty()) out() << "\n"; - shortVersion = tre->version(); + shortVersion = myTree->version(); if (shortVersion.count(QChar('.')) == 2) shortVersion.truncate(shortVersion.lastIndexOf(QChar('.'))); if (!shortVersion.isEmpty()) { @@ -1686,7 +1811,7 @@ void HtmlGenerator::generateHeader(const QString& title, "\n"; if (mainPage) generateMacRef(node, marker); - out() << QString(postHeader).replace("\\" + COMMAND_VERSION, tre->version()); + out() << QString(postHeader).replace("\\" + COMMAND_VERSION, myTree->version()); if (node && !node->links().empty()) @@ -1717,8 +1842,8 @@ void HtmlGenerator::generateFooter(const Node *node) if (node && !node->links().empty()) out() << "

\n" << navigationLinks << "

\n"; - out() << QString(footer).replace("\\" + COMMAND_VERSION, tre->version()) - << QString(address).replace("\\" + COMMAND_VERSION, tre->version()) + out() << QString(footer).replace("\\" + COMMAND_VERSION, myTree->version()) + << QString(address).replace("\\" + COMMAND_VERSION, myTree->version()) << "\n" "\n"; } @@ -1970,8 +2095,8 @@ void HtmlGenerator::generateClassHierarchy(const Node *relative, if (classMap.isEmpty()) return; - QMap topLevel; - QMap::ConstIterator c = classMap.begin(); + NodeMap topLevel; + NodeMap::ConstIterator c = classMap.begin(); while (c != classMap.end()) { const ClassNode *classe = static_cast(*c); if (classe->baseClasses().isEmpty()) @@ -1979,7 +2104,7 @@ void HtmlGenerator::generateClassHierarchy(const Node *relative, ++c; } - QStack > stack; + QStack stack; stack.push(topLevel); out() << "
    \n"; @@ -1996,7 +2121,7 @@ void HtmlGenerator::generateClassHierarchy(const Node *relative, out() << "\n"; stack.top().erase(stack.top().begin()); - QMap newTop; + NodeMap newTop; foreach (const RelatedClass &d, child->derivedClasses()) { if (d.access != Node::Private) newTop.insert(d.node->name(), d.node); @@ -2011,7 +2136,7 @@ void HtmlGenerator::generateClassHierarchy(const Node *relative, void HtmlGenerator::generateAnnotatedList(const Node *relative, CodeMarker *marker, - const QMap &nodeMap) + const NodeMap &nodeMap) { out() << "

    \n"; @@ -2049,9 +2174,19 @@ void HtmlGenerator::generateAnnotatedList(const Node *relative, out() << "

    \n"; } +/*! + This function finds the common prefix of the names of all + the classes in \a classMap and then generates a compact + list of the class names alphabetized on the part of the + name not including the common prefix. You can tell the + function to use \a comonPrefix as the common prefix, but + normally you let it figure it out itself by looking at + the name of the first and last classes in \a classMap. + */ void HtmlGenerator::generateCompactList(const Node *relative, CodeMarker *marker, - const QMap &classMap) + const NodeMap &classMap, + QString commonPrefix) { const int NumParagraphs = 37; // '0' to '9', 'A' to 'Z', '_' const int NumColumns = 4; // number of columns in the result @@ -2060,67 +2195,78 @@ void HtmlGenerator::generateCompactList(const Node *relative, return; /* - First, find out the common prefix of all non-namespaced classes. - For Qt, the prefix is Q. It can easily be derived from the first - and last classes in alphabetical order (QAccel and QXtWidget in Qt 2.1). - */ - int commonPrefixLen = 0; - QString commonPrefix; - QString first; - QString last; - - QMap::const_iterator iter = classMap.begin(); - while (iter != classMap.end()) { - if (!iter.key().contains("::")) { - first = iter.key(); - break; + If commonPrefix is not empty, then the caller knows what + the common prefix is, so just use that. + */ + int commonPrefixLen = commonPrefix.length(); + if (commonPrefixLen == 0) { + QString first; + QString last; + + /* + First, find out the common prefix of all non-namespaced + classes. For Qt, the prefix is Q. It can easily be derived + from the first and last classes in alphabetical order + (QAccel and QXtWidget in Qt 2.1). + */ + + NodeMap::const_iterator iter = classMap.begin(); + while (iter != classMap.end()) { + if (!iter.key().contains("::")) { + first = iter.key(); + break; + } + ++iter; } - ++iter; - } - if (first.isEmpty()) - first = classMap.begin().key(); + if (first.isEmpty()) + first = classMap.begin().key(); - iter = classMap.end(); - while (iter != classMap.begin()) { - --iter; - if (!iter.key().contains("::")) { - last = iter.key(); - break; + iter = classMap.end(); + while (iter != classMap.begin()) { + --iter; + if (!iter.key().contains("::")) { + last = iter.key(); + break; + } } - } - if (last.isEmpty()) - last = classMap.begin().key(); + if (last.isEmpty()) + last = classMap.begin().key(); - if (classMap.size() > 1) { - while (commonPrefixLen < first.length() + 1 && - commonPrefixLen < last.length() + 1 && - first[commonPrefixLen] == last[commonPrefixLen]) - ++commonPrefixLen; - } + if (classMap.size() > 1) { + while (commonPrefixLen < first.length() + 1 && + commonPrefixLen < last.length() + 1 && + first[commonPrefixLen] == last[commonPrefixLen]) + ++commonPrefixLen; + } - commonPrefix = first.left(commonPrefixLen); + commonPrefix = first.left(commonPrefixLen); + } /* Divide the data into 37 paragraphs: 0, ..., 9, A, ..., Z, underscore (_). QAccel will fall in paragraph 10 (A) and QXtWidget in paragraph 33 (X). This is the only place where we assume that NumParagraphs is 37. Each paragraph is a - QMap. + NodeMap. */ - QMap paragraph[NumParagraphs+1]; + NodeMap paragraph[NumParagraphs+1]; QString paragraphName[NumParagraphs+1]; - QMap::ConstIterator c = classMap.begin(); + qDebug() << "START COMPACT LIST"; + NodeMap::ConstIterator c = classMap.begin(); while (c != classMap.end()) { QStringList pieces = c.key().split("::"); QString key; + int idx = commonPrefixLen; + if (!pieces.last().startsWith(commonPrefix)) + idx = 0; if (pieces.size() == 1) - key = pieces.last().mid(commonPrefixLen).toLower(); + key = pieces.last().mid(idx).toLower(); else key = pieces.last().toLower(); - + qDebug() << " KEY:" << key; int paragraphNo = NumParagraphs - 1; if (key[0].digitValue() != -1) { @@ -2134,6 +2280,7 @@ void HtmlGenerator::generateCompactList(const Node *relative, paragraph[paragraphNo].insert(key, c.value()); ++c; } + qDebug() << "END COMPACT LIST"; /* Each paragraph j has a size: paragraph[j].count(). In the @@ -2206,7 +2353,7 @@ void HtmlGenerator::generateCompactList(const Node *relative, if ((currentParagraphNo[i] < NumParagraphs) && !paragraphName[currentParagraphNo[i]].isEmpty()) { - QMap::Iterator it; + NodeMap::Iterator it; it = paragraph[currentParagraphNo[i]].begin(); for (j = 0; j < currentOffsetInParagraph[i]; j++) ++it; @@ -2253,7 +2400,7 @@ void HtmlGenerator::generateFunctionIndex(const Node *relative, #if 1 out() << "
      \n"; #endif - QMap >::ConstIterator f = funcIndex.begin(); + QMap::ConstIterator f = funcIndex.begin(); while (f != funcIndex.end()) { #if 1 out() << "
    • "; @@ -2268,7 +2415,7 @@ void HtmlGenerator::generateFunctionIndex(const Node *relative, nextLetter++; } - QMap::ConstIterator s = (*f).begin(); + NodeMap::ConstIterator s = (*f).begin(); while (s != (*f).end()) { out() << " "; generateFullName((*s)->parent(), relative, marker, *s); @@ -2384,7 +2531,7 @@ void HtmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* m QMap uncategorizedNodeMap; QRegExp singleDigit("\\b([0-9])\\b"); - const NodeList children = tre->root()->childNodes(); + const NodeList children = myTree->root()->childNodes(); foreach (Node *child, children) { if (child->type() == Node::Fake && child != relative) { FakeNode *fakeNode = static_cast(child); @@ -2436,7 +2583,7 @@ void HtmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* m else if (!isGroupPage) { // If we encounter a page that belongs to a group then // we add that page to the list for that group. - const FakeNode *groupNode = static_cast(tre->root()->findNode(group, Node::Fake)); + const FakeNode *groupNode = static_cast(myTree->root()->findNode(group, Node::Fake)); if (groupNode) fakeNodeMap[groupNode].insert(sortKey, fakeNode); //else @@ -2748,7 +2895,7 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, if (parseArg(src, funcTag, &i, n, &arg, &par1)) { QString link = linkForNode( marker->resolveTarget(par1.toString(), - tre, + myTree, relative), relative); addLink(link, arg, &html); @@ -2777,7 +2924,7 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, if (parseArg(src, typeTags[k], &i, n, &arg, &par1)) { par1 = QStringRef(); QString link = linkForNode( - marker->resolveTarget(arg.toString(), tre, relative), + marker->resolveTarget(arg.toString(), myTree, relative), relative); addLink(link, arg, &html); handled = true; @@ -3018,7 +3165,7 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, if (parseArg(src, funcTag, &i, n, &arg, &par1)) { QString link = linkForNode( marker->resolveTarget(par1.toString(), - tre, + myTree, relative), relative); addLink(link, arg, &html); @@ -3047,7 +3194,7 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, if (parseArg(src, typeTags[k], &i, n, &arg, &par1)) { par1 = QStringRef(); QString link = linkForNode( - marker->resolveTarget(arg.toString(), tre, relative), + marker->resolveTarget(arg.toString(), myTree, relative), relative); addLink(link, arg, &html); handled = true; @@ -3591,15 +3738,44 @@ void HtmlGenerator::findAllSince(const InnerNode *node) while (c != node->childNodes().constEnd()) { QString sinceVersion = (*c)->since(); if (((*c)->access() != Node::Private) && !sinceVersion.isEmpty()) { - SinceVersionMap::iterator vmap = sinceVersions.find(sinceVersion); - if (vmap == sinceVersions.end()) - vmap = sinceVersions.insert(sinceVersion,SinceNodeMultiMap()); + NodeMultiMapMap::iterator vmap = nodeMultiMapMap.find(sinceVersion); + if (vmap == nodeMultiMapMap.end()) + vmap = nodeMultiMapMap.insert(sinceVersion,NodeMultiMap()); + NodeMapMap::iterator ncmap = nodeMapMap.find(sinceVersion); + if (ncmap == nodeMapMap.end()) + ncmap = nodeMapMap.insert(sinceVersion,NodeMap()); + if ((*c)->type() == Node::Function) { FunctionNode *func = static_cast(*c); if ((func->status() > Node::Obsolete) && (func->metaness() != FunctionNode::Ctor) && (func->metaness() != FunctionNode::Dtor)) { vmap.value().insert(func->name(),(*c)); +#if 0 + qDebug() << "FUNCTION:" << func->name(); + Node* p = func->parent(); + if (p) { + if (p->type() == Node::Namespace) { + if (p->name().isEmpty()) + qDebug() << " Global namespace"; + else + qDebug() << " Namespace:" << p->name(); + } + else if (p->type() == Node::Class) + qDebug() << " Class:" << p->name(); + Node* q = p->parent(); + if (q) { + if (q->type() == Node::Namespace) { + if (q->name().isEmpty()) + qDebug() << " Grandparent Global namespace"; + else + qDebug() << " Grandparent Namespace:" << q->name(); + } + else if (q->type() == Node::Class) + qDebug() << " Grandparent Class:" << q->name(); + } + } +#endif } } else if ((*c)->url().isEmpty()) { @@ -3610,6 +3786,7 @@ void HtmlGenerator::findAllSince(const InnerNode *node) !(*c)->parent()->name().isEmpty()) className = (*c)->parent()->name()+"::"+className; vmap.value().insert(className,(*c)); + ncmap.value().insert(className,(*c)); } } else { @@ -3619,7 +3796,6 @@ void HtmlGenerator::findAllSince(const InnerNode *node) !(*c)->parent()->name().isEmpty()) name = (*c)->parent()->name()+"::"+name; vmap.value().insert(name,(*c)); - qDebug() << "GOT HEAH" << name; } if ((*c)->isInnerNode()) { findAllSince(static_cast(*c)); @@ -3646,9 +3822,10 @@ void HtmlGenerator::findAllFunctions(const InnerNode *node) } else if ((*c)->type() == Node::Function) { const FunctionNode *func = static_cast(*c); - if (func->status() > Node::Obsolete && func->metaness() != FunctionNode::Ctor - && func->metaness() != FunctionNode::Dtor) { - funcIndex[(*c)->name()].insert(tre->fullDocumentName((*c)->parent()), *c); + if ((func->status() > Node::Obsolete) && + (func->metaness() != FunctionNode::Ctor) && + (func->metaness() != FunctionNode::Dtor)) { + funcIndex[(*c)->name()].insert(myTree->fullDocumentName((*c)->parent()), *c); } } } @@ -3762,14 +3939,14 @@ const Node *HtmlGenerator::findNodeForTarget(const QString &target, node = relative; } else if (target.endsWith(".html")) { - node = tre->root()->findNode(target, Node::Fake); + node = myTree->root()->findNode(target, Node::Fake); } else if (marker) { - node = marker->resolveTarget(target, tre, relative); + node = marker->resolveTarget(target, myTree, relative); if (!node) - node = tre->findFakeNodeByTitle(target); + node = myTree->findFakeNodeByTitle(target); if (!node && atom) { - node = tre->findUnambiguousTarget(target, + node = myTree->findUnambiguousTarget(target, *const_cast(&atom)); } } @@ -3827,14 +4004,14 @@ QString HtmlGenerator::getLink(const Atom *atom, *node = relative; } else if (first.endsWith(".html")) { - *node = tre->root()->findNode(first, Node::Fake); + *node = myTree->root()->findNode(first, Node::Fake); } else { - *node = marker->resolveTarget(first, tre, relative); + *node = marker->resolveTarget(first, myTree, relative); if (!*node) - *node = tre->findFakeNodeByTitle(first); + *node = myTree->findFakeNodeByTitle(first); if (!*node) - *node = tre->findUnambiguousTarget(first, targetAtom); + *node = myTree->findUnambiguousTarget(first, targetAtom); } if (*node) { @@ -3886,7 +4063,7 @@ QString HtmlGenerator::getLink(const Atom *atom, } while (!path.isEmpty()) { - targetAtom = tre->findTarget(path.first(), *node); + targetAtom = myTree->findTarget(path.first(), *node); if (targetAtom == 0) break; path.removeFirst(); @@ -3915,7 +4092,7 @@ void HtmlGenerator::generateIndex(const QString &fileBase, const QString &url, const QString &title) { - tre->generateIndex(outputDir() + "/" + fileBase + ".index", url, title); + myTree->generateIndex(outputDir() + "/" + fileBase + ".index", url, title); } void HtmlGenerator::generateStatus(const Node *node, CodeMarker *marker) @@ -3930,18 +4107,21 @@ void HtmlGenerator::generateStatus(const Node *node, CodeMarker *marker) case Node::Compat: if (node->isInnerNode()) { text << Atom::ParaLeft - << Atom(Atom::FormattingLeft,ATOM_FORMATTING_BOLD) << "This " - << typeString(node) << " is part of the Qt 3 support library." + << Atom(Atom::FormattingLeft,ATOM_FORMATTING_BOLD) + << "This " + << typeString(node) + << " is part of the Qt 3 support library." << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) - << " It is provided to keep old source code working. We strongly advise against " + << " It is provided to keep old source code working. " + << "We strongly advise against " << "using it in new code. See "; - const FakeNode *fakeNode = tre->findFakeNodeByTitle("Porting To Qt 4"); + const FakeNode *fakeNode = myTree->findFakeNodeByTitle("Porting To Qt 4"); Atom *targetAtom = 0; if (fakeNode && node->type() == Node::Class) { QString oldName(node->name()); - targetAtom = tre->findTarget(oldName.replace("3", ""), - fakeNode); + targetAtom = myTree->findTarget(oldName.replace("3", ""), + fakeNode); } if (targetAtom) { @@ -4151,7 +4331,7 @@ void HtmlGenerator::generateQmlInherits(const QmlClassNode* cn, QPair linkPair; linkPair = cn->links()[Node::InheritsLink]; QStringList strList(linkPair.first); - const Node* n = tre->findNode(strList,Node::Fake); + const Node* n = myTree->findNode(strList,Node::Fake); if (n && n->subType() == Node::QmlClass) { const QmlClassNode* qcn = static_cast(n); out() << "

      "; @@ -4210,7 +4390,7 @@ void HtmlGenerator::generateInstantiatedBy(const ClassNode* cn, CodeMarker* marker) { if (cn && cn->status() != Node::Internal && !cn->qmlElement().isEmpty()) { - const Node* n = tre->root()->findNode(cn->qmlElement(),Node::Fake); + const Node* n = myTree->root()->findNode(cn->qmlElement(),Node::Fake); if (n && n->subType() == Node::QmlClass) { out() << "

      "; Text text; diff --git a/tools/qdoc3/htmlgenerator.h b/tools/qdoc3/htmlgenerator.h index 3f6e564..fabfed1 100644 --- a/tools/qdoc3/htmlgenerator.h +++ b/tools/qdoc3/htmlgenerator.h @@ -67,14 +67,34 @@ struct NavigationBar }; #endif -typedef QMultiMap SinceNodeMultiMap; -typedef QMap SinceVersionMap; +typedef QMultiMap NodeMultiMap; +typedef QMap NodeMultiMapMap; +typedef QMap NodeMap; +typedef QMap NodeMapMap; class HelpProjectWriter; class HtmlGenerator : public PageGenerator { public: + enum SinceType { + Namespace, + Class, + MemberFunction, + NamespaceFunction, + GlobalFunction, + Macro, + Enum, + Typedef, + Property, + Variable, + QmlProperty, + QmlSignal, + QmlMethod, + LastSinceType + }; + + public: HtmlGenerator(); ~HtmlGenerator(); @@ -85,6 +105,7 @@ class HtmlGenerator : public PageGenerator static QString protect(const QString& string); static QString cleanRef(const QString& ref); + static QString sinceTitle(int i) { return sinceTitles[i]; } protected: virtual void startText(const Node *relative, CodeMarker *marker); @@ -134,13 +155,14 @@ class HtmlGenerator : public PageGenerator CodeMarker::Status status); void generateClassHierarchy(const Node *relative, CodeMarker *marker, - const QMap &classMap); + const NodeMap &classMap); void generateAnnotatedList(const Node *relative, CodeMarker *marker, - const QMap &nodeMap); + const NodeMap &nodeMap); void generateCompactList(const Node *relative, CodeMarker *marker, - const QMap &classMap); + const NodeMap &classMap, + QString commonPrefix = QString()); void generateFunctionIndex(const Node *relative, CodeMarker *marker); void generateLegaleseList(const Node *relative, CodeMarker *marker); void generateOverviewList(const Node *relative, CodeMarker *marker); @@ -273,23 +295,25 @@ class HtmlGenerator : public PageGenerator QString navigationLinks; QStringList stylesheets; QStringList customHeadElements; - const Tree *tre; + const Tree *myTree; bool slow; bool obsoleteLinks; - QMap > moduleClassMap; - QMap > moduleNamespaceMap; - QMap nonCompatClasses; - QMap mainClasses; - QMap compatClasses; - QMap obsoleteClasses; - QMap namespaceIndex; - QMap serviceClasses; + QMap moduleClassMap; + QMap moduleNamespaceMap; + NodeMap nonCompatClasses; + NodeMap mainClasses; + NodeMap compatClasses; + NodeMap obsoleteClasses; + NodeMap namespaceIndex; + NodeMap serviceClasses; #ifdef QDOC_QML - QMap qmlClasses; + NodeMap qmlClasses; #endif - QMap > funcIndex; + QMap funcIndex; QMap legaleseTexts; - SinceVersionMap sinceVersions; + NodeMultiMapMap nodeMultiMapMap; + static QString sinceTitles[]; + NodeMapMap nodeMapMap; }; #define HTMLGENERATOR_ADDRESS "address" @@ -303,3 +327,4 @@ class HtmlGenerator : public PageGenerator QT_END_NAMESPACE #endif + diff --git a/tools/qdoc3/node.cpp b/tools/qdoc3/node.cpp index d547d20..558808f 100644 --- a/tools/qdoc3/node.cpp +++ b/tools/qdoc3/node.cpp @@ -48,29 +48,17 @@ QT_BEGIN_NAMESPACE -QString Node::typeNames[] = - { - "Namespaces", - "Classes", - "Fake", - "Enums", - "Typedefs", - "Functions and Macros", - "Properties", - "Variables", - "Targets", - "Qml Properties", - "Qml Signals", - "Qml Methods", - "" - }; - /*! \class Node - \brief A node in a Tree. + \brief The Node class is a node in the Tree. + + A Node represents a class or function or something else + from the source code.. */ /*! + When this Node is destroyed, if it has a parent Node, it + removes itself from the parent node's child list. */ Node::~Node() { @@ -81,6 +69,11 @@ Node::~Node() } /*! + Sets this Node's Doc to \a doc. If \a replace is false and + this Node already has a Doc, a warning is reported that the + Doc is being overridden, and it reports where the previous + Doc was found. If \a replace is true, the Doc is replaced + silently. */ void Node::setDoc(const Doc& doc, bool replace) { @@ -840,9 +833,17 @@ void TypedefNode::setAssociatedEnum(const EnumNode *enume) /*! \class Parameter + \brief The class Parameter contains one parameter. + + A parameter can be a function parameter or a macro + parameter. */ /*! + Constructs this parameter from the left and right types + \a leftType and rightType, the parameter \a name, and the + \a defaultValue. In practice, \a rightType is not used, + and I don't know what is was meant for. */ Parameter::Parameter(const QString& leftType, const QString& rightType, @@ -853,6 +854,7 @@ Parameter::Parameter(const QString& leftType, } /*! + The standard copy constructor copies the strings from \a p. */ Parameter::Parameter(const Parameter& p) : lef(p.lef), rig(p.rig), nam(p.nam), def(p.def) @@ -860,6 +862,8 @@ Parameter::Parameter(const Parameter& p) } /*! + Assigning Parameter \a p to this Parameter copies the + strings across. */ Parameter& Parameter::operator=(const Parameter& p) { @@ -871,6 +875,23 @@ Parameter& Parameter::operator=(const Parameter& p) } /*! + Reconstructs the text describing the parameter and + returns it. If \a value is true, the default value + will be included, if there is one. + */ +QString Parameter::reconstruct(bool value) const +{ + QString p = lef + rig; + if (!p.endsWith(QChar('*')) && !p.endsWith(QChar('&')) && !p.endsWith(QChar(' '))) + p += " "; + p += nam; + if (value) + p += def; + return p; +} + + +/*! \class FunctionNode */ @@ -924,6 +945,8 @@ void FunctionNode::borrowParameterNames(const FunctionNode *source) } /*! + If this function is a reimplementation, \a from points + to the FunctionNode of the function being reimplemented. */ void FunctionNode::setReimplementedFrom(FunctionNode *from) { @@ -932,6 +955,8 @@ void FunctionNode::setReimplementedFrom(FunctionNode *from) } /*! + Sets the "associated" property to \a property. The function + might be the setter or getter for a property, for example. */ void FunctionNode::setAssociatedProperty(PropertyNode *property) { @@ -939,6 +964,8 @@ void FunctionNode::setAssociatedProperty(PropertyNode *property) } /*! + Returns the overload number for this function obtained + from the parent. */ int FunctionNode::overloadNumber() const { @@ -946,6 +973,8 @@ int FunctionNode::overloadNumber() const } /*! + Returns the number of times this function name has been + overloaded, obtained from the parent. */ int FunctionNode::numOverloads() const { @@ -953,6 +982,7 @@ int FunctionNode::numOverloads() const } /*! + Returns the list of parameter names. */ QStringList FunctionNode::parameterNames() const { @@ -966,6 +996,46 @@ QStringList FunctionNode::parameterNames() const } /*! + Returns the list of reconstructed parameters. If \a values + is true, the default values are included, if any are present. + */ +QStringList FunctionNode::reconstructParams(bool values) const +{ + QStringList params; + QList::ConstIterator p = parameters().begin(); + while (p != parameters().end()) { + params << (*p).reconstruct(values); + ++p; + } + return params; +} + +/*! + Reconstructs and returns the function's signature. If \a values + is true, the default values of the parameters are included, if + present. + */ +QString FunctionNode::signature(bool values) const +{ + QString s; + if (!returnType().isEmpty()) + s = returnType() + " "; + s += name() + "("; + QStringList params = reconstructParams(values); + int p = params.size(); + if (p > 0) { + for (int i=0; i &reimplementedBy() const { return rb; } const PropertyNode *associatedProperty() const { return ap; } + const QStringList& parentPath() const { return pp; } + + QStringList reconstructParams(bool values = false) const; + QString signature(bool values = false) const; private: void setAssociatedProperty(PropertyNode *property); @@ -576,9 +583,10 @@ class FunctionNode : public LeafNode friend class InnerNode; friend class PropertyNode; - QString rt; + QString rt; + QStringList pp; #ifdef Q_WS_WIN - Metaness met; + Metaness met; Virtualness vir; #else Metaness met : 4; -- cgit v0.12 From 712bdb01662a5724fa593937cfbb447f936998d4 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 8 Oct 2009 16:07:10 +0200 Subject: qdoc: Removed some debug code and #if 0 code. --- tools/qdoc3/htmlgenerator.cpp | 114 +----------------------------------------- 1 file changed, 1 insertion(+), 113 deletions(-) diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index e883dfa..ed3a485 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -350,64 +350,6 @@ void HtmlGenerator::generateTree(const Tree *tree, CodeMarker *marker) #endif findAllSince(tree->root()); -#if 0 - if (!sinceVersions.isEmpty()) { - SinceVersionMap::const_iterator v = sinceVersions.constEnd(); - do { - --v; - qDebug() << "SINCE:" << v.key(); - if (!v.value().isEmpty()) { - QString type; - SinceNodeMultiMap::const_iterator n = v.value().constBegin(); - while (n != v.value().constEnd()) { - switch (n.value()->type()) { - case Node::Namespace: - type = "namespace"; - break; - case Node::Class: - type = "class"; - break; - case Node::Fake: - type = "fake"; - break; - case Node::Enum: - type = "enum"; - break; - case Node::Typedef: - type = "typedef"; - break; - case Node::Function: - type = "function"; - break; - case Node::Property: - type = "property"; - break; - case Node::Variable: - type = "variable"; - break; - case Node::Target: - type = "target"; - break; - case Node::QmlProperty: - type = "QML property"; - break; - case Node::QmlSignal: - type = "QML signal"; - break; - case Node::QmlMethod: - type = "QML method"; - break; - default: - type = "No type"; - } - qDebug() << " " << type << n.key(); - ++n; - } - } - } while (v != sinceVersions.constBegin()); - } -#endif - PageGenerator::generateTree(tree, marker); dcfClassesRoot.ref = "classes.html"; @@ -835,33 +777,6 @@ int HtmlGenerator::generateAtom(const Atom *atom, ++idx; ++s; } -#if 0 - for (int i=0; !Node::typeName(i).isEmpty(); i++) { - Node::Type t = (Node::Type) i; - SinceNodeMultiMap::const_iterator n=v.value().constBegin(); - QMultiMap nodeMap; - while (n != v.value().constEnd()) { - const Node* node = n.value(); - if (node->type() == t) { - nodeMap.insert(node->nameForLists(),node); - if (node->type() == Node::Function) { - const FunctionNode* fn = static_cast(node); - qDebug() << "SIGNATURE:" << fn->signature(); - } - } - ++n; - } - if (!nodeMap.isEmpty()) { - out() << "

      " - << Node::typeName(i) - << " new in Qt " - << atom->string() - << "

      "; - generateAnnotatedList(relative, marker, nodeMap); - nodeMap.clear(); - } - } -#endif } } break; @@ -2254,7 +2169,6 @@ void HtmlGenerator::generateCompactList(const Node *relative, NodeMap paragraph[NumParagraphs+1]; QString paragraphName[NumParagraphs+1]; - qDebug() << "START COMPACT LIST"; NodeMap::ConstIterator c = classMap.begin(); while (c != classMap.end()) { QStringList pieces = c.key().split("::"); @@ -2266,7 +2180,7 @@ void HtmlGenerator::generateCompactList(const Node *relative, key = pieces.last().mid(idx).toLower(); else key = pieces.last().toLower(); - qDebug() << " KEY:" << key; + int paragraphNo = NumParagraphs - 1; if (key[0].digitValue() != -1) { @@ -2280,7 +2194,6 @@ void HtmlGenerator::generateCompactList(const Node *relative, paragraph[paragraphNo].insert(key, c.value()); ++c; } - qDebug() << "END COMPACT LIST"; /* Each paragraph j has a size: paragraph[j].count(). In the @@ -3751,31 +3664,6 @@ void HtmlGenerator::findAllSince(const InnerNode *node) (func->metaness() != FunctionNode::Ctor) && (func->metaness() != FunctionNode::Dtor)) { vmap.value().insert(func->name(),(*c)); -#if 0 - qDebug() << "FUNCTION:" << func->name(); - Node* p = func->parent(); - if (p) { - if (p->type() == Node::Namespace) { - if (p->name().isEmpty()) - qDebug() << " Global namespace"; - else - qDebug() << " Namespace:" << p->name(); - } - else if (p->type() == Node::Class) - qDebug() << " Class:" << p->name(); - Node* q = p->parent(); - if (q) { - if (q->type() == Node::Namespace) { - if (q->name().isEmpty()) - qDebug() << " Grandparent Global namespace"; - else - qDebug() << " Grandparent Namespace:" << q->name(); - } - else if (q->type() == Node::Class) - qDebug() << " Grandparent Class:" << q->name(); - } - } -#endif } } else if ((*c)->url().isEmpty()) { -- cgit v0.12 From e38529caa8e188b83c529e3eaca4eab8b8ab393d Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 8 Oct 2009 13:52:15 +0200 Subject: Stabilize Tests --- tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp | 8 +++----- tests/auto/qspinbox/tst_qspinbox.cpp | 10 ++++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index 8459331..f5e9acb 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -2819,17 +2819,15 @@ void tst_QGraphicsScene::update2() CustomView view; view.setScene(&scene); view.show(); -#ifdef Q_WS_X11 - qt_x11_wait_for_window_manager(&view); -#endif - QTest::qWait(250); + QTest::qWaitForWindowShown(&view); + QTRY_VERIFY(view.repaints >= 1); view.repaints = 0; // Make sure QGraphicsScene::update only requires one event-loop iteration // before the view is updated. scene.update(); qApp->processEvents(); - QCOMPARE(view.repaints, 1); + QTRY_COMPARE(view.repaints, 1); view.repaints = 0; // The same for partial scene updates. diff --git a/tests/auto/qspinbox/tst_qspinbox.cpp b/tests/auto/qspinbox/tst_qspinbox.cpp index 4829b6b..2389060 100644 --- a/tests/auto/qspinbox/tst_qspinbox.cpp +++ b/tests/auto/qspinbox/tst_qspinbox.cpp @@ -980,26 +980,28 @@ void tst_QSpinBox::sizeHint() sizeHint_SpinBox *spinBox = new sizeHint_SpinBox; layout->addWidget(spinBox); widget->show(); - QTest::qWait(100); + QTest::qWaitForWindowShown(widget); // Prefix spinBox->sizeHintRequests = 0; spinBox->setPrefix(QLatin1String("abcdefghij")); qApp->processEvents(); - QVERIFY(spinBox->sizeHintRequests > 0); + QTRY_VERIFY(spinBox->sizeHintRequests > 0); // Suffix spinBox->sizeHintRequests = 0; spinBox->setSuffix(QLatin1String("abcdefghij")); qApp->processEvents(); - QVERIFY(spinBox->sizeHintRequests > 0); + QTRY_VERIFY(spinBox->sizeHintRequests > 0); // Range spinBox->sizeHintRequests = 0; spinBox->setRange(0, 1234567890); spinBox->setValue(spinBox->maximum()); qApp->processEvents(); - QVERIFY(spinBox->sizeHintRequests > 0); + QTRY_VERIFY(spinBox->sizeHintRequests > 0); + + delete widget; } QTEST_MAIN(tst_QSpinBox) -- cgit v0.12 From db1162da76f1d257ba9bfcaef574275e7430385f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Thu, 8 Oct 2009 16:17:58 +0200 Subject: Rename identifyNonFloatItems -> identifyFloatItems. We changed the behaviour of that, so the name should reflect that. --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 14 +++++++------- src/gui/graphicsview/qgraphicsanchorlayout_p.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 2b3e405..f9b5c8c 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -275,8 +275,8 @@ static qreal getFactor(qreal value, qreal min, qreal pref, qreal max) } } -static qreal getExpandingFactor(qreal expSize, qreal sizeAtPreferred, - qreal sizeAtExpanding, qreal sizeAtMaximum) +static qreal getExpandingFactor(const qreal &expSize, const qreal &sizeAtPreferred, + const qreal &sizeAtExpanding, const qreal &sizeAtMaximum) { const qreal lower = qMin(sizeAtPreferred, sizeAtMaximum); const qreal upper = qMax(sizeAtPreferred, sizeAtMaximum); @@ -1842,10 +1842,10 @@ void QGraphicsAnchorLayoutPrivate::findPaths(Orientation orientation) } } - // 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); + // We will walk through every reachable items (non-float) store them in a temporary set. + // We them create a set of all items and subtract the non-floating items from the set in + // order to get the floating items. The floating items is then stored in m_floatItems + identifyFloatItems(visited, orientation); } /*! @@ -2008,7 +2008,7 @@ QGraphicsAnchorLayoutPrivate::getGraphParts(Orientation orientation) Use all visited Anchors on findPaths() so we can identify non-float Items. */ -void QGraphicsAnchorLayoutPrivate::identifyNonFloatItems(const QSet &visited, Orientation orientation) +void QGraphicsAnchorLayoutPrivate::identifyFloatItems(const QSet &visited, Orientation orientation) { QSet nonFloating; diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 0f045e5..9ac0e19 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -443,7 +443,7 @@ public: void constraintsFromPaths(Orientation orientation); QList constraintsFromSizeHints(const QList &anchors); QList > getGraphParts(Orientation orientation); - void identifyNonFloatItems(const QSet &visited, Orientation orientation); + void identifyFloatItems(const QSet &visited, Orientation orientation); void identifyNonFloatItems_helper(const AnchorData *ad, QSet *nonFloatingItemsIdentifiedSoFar); inline AnchorVertex *internalVertex(const QPair &itemEdge) const -- cgit v0.12 From dbf0d8c50fce24d36dd5e6eac853a1242ad89455 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 8 Oct 2009 17:46:48 +0200 Subject: Skip the crashing selftest on Mac The signal handler does seem to work on Mac for segfault Reviewed-by: Rohan McGovern --- tests/auto/selftests/tst_selftests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/selftests/tst_selftests.cpp b/tests/auto/selftests/tst_selftests.cpp index 1a2de65..579f4eb 100644 --- a/tests/auto/selftests/tst_selftests.cpp +++ b/tests/auto/selftests/tst_selftests.cpp @@ -299,7 +299,7 @@ void tst_Selftests::runSubTest() void tst_Selftests::initTestCase() { -#ifndef Q_OS_UNIX +#if !defined(Q_OS_UNIX) || defined(Q_WS_MAC) m_checkXMLBlacklist.append("crashes"); // This test crashes (XML valid on Unix only) #endif m_checkXMLBlacklist.append("waitwithoutgui"); // This test is not a QTestLib test. -- cgit v0.12 From f7e13aefc24b98299d8fd44cad60cc13b16e4114 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Thu, 8 Oct 2009 17:47:24 +0200 Subject: Fixed compile. --- tools/qdoc3/htmlgenerator.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index ed3a485..033c62c 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -698,7 +698,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, case Node::Typedef: sections[Typedef].appendMember((Node*)node); break; - case Node::Function: + case Node::Function: { const FunctionNode* fn = static_cast(node); if (fn->isMacro()) sections[Macro].appendMember((Node*)node); @@ -720,6 +720,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, sections[GlobalFunction].appendMember((Node*)node); } break; + } case Node::Property: sections[Property].appendMember((Node*)node); break; -- cgit v0.12 From e2282deeb67c22f42f1022be110a3e24723eb913 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 8 Oct 2009 18:30:39 +0200 Subject: Fixes XPASS on the QFileDialog test on Carbon Reviewed-by: alexis --- tests/auto/qfiledialog/tst_qfiledialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qfiledialog/tst_qfiledialog.cpp b/tests/auto/qfiledialog/tst_qfiledialog.cpp index f6b082f..dc2ca61 100644 --- a/tests/auto/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/qfiledialog/tst_qfiledialog.cpp @@ -944,7 +944,7 @@ void tst_QFiledialog::selectFiles() QVERIFY(listView); for (int i = 0; i < list.count(); ++i) { fd.selectFile(fd.directory().path() + "/" + list.at(i)); -#if defined(Q_WS_MAC) || defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN) +#if defined(QT_MAC_USE_COCOA) || defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN) QEXPECT_FAIL("", "This test does not work on Mac, Windows, or Symbian", Abort); #endif QTRY_VERIFY(!listView->selectionModel()->selectedRows().isEmpty()); -- cgit v0.12 From e738c8c90b21ca2c3d2c5d1271fd7a06a1a32c5f Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Thu, 8 Oct 2009 20:40:31 +0200 Subject: QS60Style: Re-enable color-from-skin-part extraction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After introducing native pixmap support, we had some crashes on certain setups (e.g. 3.2 Emulator) when accessing data that came from native pixmaps (FBServ). However, after fix 064674426ef0c446561b0c338441bb7d5ca091bf this is not reproducable, anymore. Therefore let's re-enable color extraction and enjoy better color palettes. Reviewed-By: Sami Merilä --- src/gui/styles/qs60style.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 6bdb79e..59787da 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -706,11 +706,10 @@ void QS60StylePrivate::setThemePalette(QPalette *palette) const palette->setColor(QPalette::AlternateBase, Qt::transparent); palette->setBrush(QPalette::Base, Qt::transparent); // set button and tooltipbase based on pixel colors -// After natitive pixmap support, colorFromFrameGraphics caused reproducable crashes on some setups. -// const QColor buttonColor = colorFromFrameGraphics(SF_ButtonNormal); -// palette->setColor(QPalette::Button, buttonColor); -// const QColor toolTipColor = colorFromFrameGraphics(SF_ToolTip); -// palette->setColor(QPalette::ToolTipBase, toolTipColor); + const QColor buttonColor = colorFromFrameGraphics(SF_ButtonNormal); + palette->setColor(QPalette::Button, buttonColor); + const QColor toolTipColor = colorFromFrameGraphics(SF_ToolTip); + palette->setColor(QPalette::ToolTipBase, toolTipColor); palette->setColor(QPalette::Light, palette->color(QPalette::Button).lighter()); palette->setColor(QPalette::Dark, palette->color(QPalette::Button).darker()); palette->setColor(QPalette::Midlight, palette->color(QPalette::Button).lighter(125)); -- cgit v0.12 From a2dcb039c336a4277949849cd1430812351da7ae Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Thu, 8 Oct 2009 20:45:16 +0200 Subject: Fix .ui of Styledemo (Layout tweaks) Let's make sure to have enough layout spacings around the widgets in order to see the focusrect. Also, the issue with the growing dialog is fixed. It was the spinbox and it's label which with the stylesheets set did not have enough horizontal space, and thus made the dialog grow on the following CSS change Reviewed-By: TrustMe --- demos/embedded/styledemo/stylewidget.ui | 333 ++++++++++++++------------------ 1 file changed, 149 insertions(+), 184 deletions(-) diff --git a/demos/embedded/styledemo/stylewidget.ui b/demos/embedded/styledemo/stylewidget.ui index a084dde..767f44a 100644 --- a/demos/embedded/styledemo/stylewidget.ui +++ b/demos/embedded/styledemo/stylewidget.ui @@ -6,28 +6,16 @@ 0 0 - 174 - 220 + 184 + 245 Form - - - 4 - - - 4 - - + + - - - 0 - 0 - - Styles @@ -141,7 +129,7 @@ - + Qt::Vertical @@ -154,156 +142,137 @@ - - + + + + 4 + + + + + + 0 + 0 + + + + Value: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Qt::WheelFocus + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + false + + + + + + + - + 0 0 - - QFrame::StyledPanel + + + 0 + 24 + - - QFrame::Raised + + Qt::TabFocus + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + 0 + 24 + + + + Qt::TabFocus + + + Qt::Horizontal - - - 0 - - - - - - - - 0 - 0 - - - - My Value is: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - false - - - - - - - - - 4 - - - - - - 0 - 0 - - - - - 0 - 24 - - - - Qt::Horizontal - - - - - - - - 0 - 0 - - - - Qt::StrongFocus - - - Show - - - true - - - true - - - false - - - - - - - - 0 - 24 - - - - Qt::Horizontal - - - - - - - - 0 - 0 - - - - Qt::StrongFocus - - - Enable - - - true - - - true - - - false - - - - - - - + + + + + 0 + 0 + + + + Qt::StrongFocus + + + Show + + + true + + + true + + + false + + + + + + + + 0 + 0 + + + + Qt::StrongFocus + + + Enable + + + true + + + true + + + false + + + + Qt::Vertical @@ -319,32 +288,28 @@ - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Qt::StrongFocus - - - Close - - - - + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::StrongFocus + + + Close + + -- cgit v0.12 From a35c52abe95f224af062550e4954f7cbefca1bd8 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Thu, 8 Oct 2009 21:20:22 +0200 Subject: Color role with higher contrast for focusrect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Low-risk, high value change. Beta worthy! As much as QPalette::Highlight sounds like a suitable color role for drawing a focus rect... It simply did not work well with a lot of S60 themes (e.g. the default N95 theme). QPalette::Text is a better candidate, since the S60 themes promise a good contrast of text on background graphics. Reviewed-By: Sami Merilä --- src/gui/styles/qs60style.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 59787da..4fa1d03 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -1864,7 +1864,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, painter->save(); painter->setRenderHint(QPainter::Antialiasing); painter->setOpacity(opacity); - painter->setPen(QPen(option->palette.color(QPalette::Highlight), penWidth)); + painter->setPen(QPen(option->palette.color(QPalette::Text), penWidth)); painter->drawRoundedRect(adjustedRect, roundRectRadius, roundRectRadius); painter->restore(); } -- cgit v0.12 From d2d8ccd4b1cb373499b036852850d439a025bbb1 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Fri, 9 Oct 2009 08:04:33 +1000 Subject: Don't print EGL buffer size if it isn't set. Reviewed-by: trustme --- src/gui/egl/qeglproperties.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/egl/qeglproperties.cpp b/src/gui/egl/qeglproperties.cpp index 02ae729..c61e1d3 100644 --- a/src/gui/egl/qeglproperties.cpp +++ b/src/gui/egl/qeglproperties.cpp @@ -313,7 +313,7 @@ QString QEglProperties::toString() const int alpha = value(EGL_ALPHA_SIZE); int bufferSize = value(EGL_BUFFER_SIZE); if (bufferSize == (red + green + blue + alpha)) - bufferSize = EGL_DONT_CARE; + bufferSize = 0; str += QLatin1String(" rgba="); str += QString::number(red); str += QLatin1Char(','); @@ -322,7 +322,7 @@ QString QEglProperties::toString() const str += QString::number(blue); str += QLatin1Char(','); str += QString::number(alpha); - if (bufferSize != EGL_DONT_CARE) { + if (bufferSize != 0) { // Only report buffer size if different than r+g+b+a. str += QLatin1String(" buffer-size="); str += QString::number(bufferSize); -- cgit v0.12 From 46843022acd7322c42a98858ec52b65ce7451d06 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Fri, 9 Oct 2009 08:44:12 +1000 Subject: Fix detection of pbuffers on OpenGL/ES systems The previous code was searching for an exact pbuffer format of RGBA = 1, 1, 1, 0, which of course is never going to happen. Instead, search for the best format. Reviewed-by: trustme --- src/opengl/qglpixelbuffer_egl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengl/qglpixelbuffer_egl.cpp b/src/opengl/qglpixelbuffer_egl.cpp index 4cba1bb..c2ba4a5 100644 --- a/src/opengl/qglpixelbuffer_egl.cpp +++ b/src/opengl/qglpixelbuffer_egl.cpp @@ -208,7 +208,7 @@ bool QGLPixelBuffer::hasOpenGLPbuffers() QEglProperties configProps; qt_egl_set_format(configProps, QInternal::Pbuffer, QGLFormat::defaultFormat()); configProps.setRenderableType(QEgl::OpenGL); - return ctx.chooseConfig(configProps); + return ctx.chooseConfig(configProps, QEgl::BestPixelFormat); } QT_END_NAMESPACE -- cgit v0.12 From ef8d9fa7091b0d45fe15aae43b8f1c47547cb16d Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Fri, 9 Oct 2009 08:56:45 +1000 Subject: Prevent double-destroy of a pbuffer's EGLSurface Fixing the surface memory leak in b125af1b for widgets caused this knock-on effect in pbuffers. Reviewed-by: trustme --- src/opengl/qglpixelbuffer_egl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengl/qglpixelbuffer_egl.cpp b/src/opengl/qglpixelbuffer_egl.cpp index c2ba4a5..2b5e2f5 100644 --- a/src/opengl/qglpixelbuffer_egl.cpp +++ b/src/opengl/qglpixelbuffer_egl.cpp @@ -151,7 +151,7 @@ bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidge bool QGLPixelBufferPrivate::cleanup() { - eglDestroySurface(QEglContext::defaultDisplay(0), pbuf); + // No need to destroy "pbuf" here - it is done in QGLContext::reset(). return true; } -- cgit v0.12 From 3d91051ce5ff92501b33580f1726f6726795c42d Mon Sep 17 00:00:00 2001 From: Sarah Smith Date: Fri, 9 Oct 2009 12:00:25 +1000 Subject: hellogl now runs on QT_OPENGL_ES_1 (ie N95). effort to have examples show portable GL code continues. One #ifdef in whole example and it now runs on N95 and desktop. Reviewed-by: Rhys Weatherley --- examples/opengl/hellogl/glwidget.cpp | 12 ++++++++---- examples/opengl/hellogl/main.cpp | 10 +++++++++- examples/opengl/hellogl/window.cpp | 8 ++++++++ examples/opengl/hellogl/window.h | 3 +++ examples/opengl/opengl.pro | 3 +++ examples/opengl/shared/qtlogo.cpp | 6 ++++++ examples/opengl/shared/qtlogo.h | 2 +- 7 files changed, 38 insertions(+), 6 deletions(-) diff --git a/examples/opengl/hellogl/glwidget.cpp b/examples/opengl/hellogl/glwidget.cpp index 282f21f..ffb3b15 100644 --- a/examples/opengl/hellogl/glwidget.cpp +++ b/examples/opengl/hellogl/glwidget.cpp @@ -150,10 +150,10 @@ void GLWidget::paintGL() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); - glTranslated(0.0, 0.0, -10.0); - glRotated(xRot / 16.0, 1.0, 0.0, 0.0); - glRotated(yRot / 16.0, 0.0, 1.0, 0.0); - glRotated(zRot / 16.0, 0.0, 0.0, 1.0); + glTranslatef(0.0, 0.0, -10.0); + glRotatef(xRot / 16.0, 1.0, 0.0, 0.0); + glRotatef(yRot / 16.0, 0.0, 1.0, 0.0); + glRotatef(zRot / 16.0, 0.0, 0.0, 1.0); logo->draw(); } //! [7] @@ -166,7 +166,11 @@ void GLWidget::resizeGL(int width, int height) glMatrixMode(GL_PROJECTION); glLoadIdentity(); +#ifdef QT_OPENGL_ES_1 + glOrthof(-0.5, +0.5, -0.5, +0.5, 4.0, 15.0); +#else glOrtho(-0.5, +0.5, -0.5, +0.5, 4.0, 15.0); +#endif glMatrixMode(GL_MODELVIEW); } //! [8] diff --git a/examples/opengl/hellogl/main.cpp b/examples/opengl/hellogl/main.cpp index e645dba..f610b3b 100644 --- a/examples/opengl/hellogl/main.cpp +++ b/examples/opengl/hellogl/main.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include +#include #include "window.h" @@ -47,6 +48,13 @@ int main(int argc, char *argv[]) { QApplication app(argc, argv); Window window; - window.show(); + window.resize(window.sizeHint()); + int desktopArea = QApplication::desktop()->width() * + QApplication::desktop()->height(); + int widgetArea = window.width() * window.height(); + if (((float)widgetArea / (float)desktopArea) < 0.75f) + window.show(); + else + window.showMaximized(); return app.exec(); } diff --git a/examples/opengl/hellogl/window.cpp b/examples/opengl/hellogl/window.cpp index 2b06b9c..19a8aac 100644 --- a/examples/opengl/hellogl/window.cpp +++ b/examples/opengl/hellogl/window.cpp @@ -88,3 +88,11 @@ QSlider *Window::createSlider() return slider; } //! [2] + +void Window::keyPressEvent(QKeyEvent *e) +{ + if (e->key() == Qt::Key_Escape) + close(); + else + QWidget::keyPressEvent(e); +} diff --git a/examples/opengl/hellogl/window.h b/examples/opengl/hellogl/window.h index 7269a05..4cfd31b 100644 --- a/examples/opengl/hellogl/window.h +++ b/examples/opengl/hellogl/window.h @@ -57,6 +57,9 @@ class Window : public QWidget public: Window(); +protected: + void keyPressEvent(QKeyEvent *event); + private: QSlider *createSlider(); diff --git a/examples/opengl/opengl.pro b/examples/opengl/opengl.pro index 2cb8227..eaac9b8 100644 --- a/examples/opengl/opengl.pro +++ b/examples/opengl/opengl.pro @@ -9,6 +9,9 @@ contains(QT_CONFIG, opengles1)|contains(QT_CONFIG, opengles1cl)|contains(QT_CONF !contains(QT_CONFIG, opengles1cl) { SUBDIRS += textures } + contains(QT_CONFIG, opengles1) { + SUBDIRS += hellogl + } } else { SUBDIRS = 2dpainting \ grabber \ diff --git a/examples/opengl/shared/qtlogo.cpp b/examples/opengl/shared/qtlogo.cpp index b32b416..bad83d1 100644 --- a/examples/opengl/shared/qtlogo.cpp +++ b/examples/opengl/shared/qtlogo.cpp @@ -39,6 +39,12 @@ ** ****************************************************************************/ +#include +#include +#include + +#include + #include "qtlogo.h" static const qreal tee_height = 0.311126; diff --git a/examples/opengl/shared/qtlogo.h b/examples/opengl/shared/qtlogo.h index 4f5c357..152958b 100644 --- a/examples/opengl/shared/qtlogo.h +++ b/examples/opengl/shared/qtlogo.h @@ -43,7 +43,7 @@ #define QTLOGO_H #include -#include +#include class Patch; struct Geometry; -- cgit v0.12 From 8ee6d090d45198fb2530849236c97f014666b7e4 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Fri, 9 Oct 2009 13:13:51 +1000 Subject: EGL_SAMPLES should be 1, not -1, to select number of samples Reviewed-by: trustme --- src/opengl/qgl_egl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp index fa876c7..fbf0349 100644 --- a/src/opengl/qgl_egl.cpp +++ b/src/opengl/qgl_egl.cpp @@ -75,7 +75,7 @@ void qt_egl_set_format(QEglProperties& props, int deviceType, const QGLFormat& f props.setValue(EGL_STENCIL_SIZE, f.stencilBufferSize() == -1 ? 1 : f.stencilBufferSize()); if (f.sampleBuffers()) { props.setValue(EGL_SAMPLE_BUFFERS, 1); - props.setValue(EGL_SAMPLES, f.samples()); + props.setValue(EGL_SAMPLES, f.samples() == -1 ? 1 : f.samples()); } else { props.setValue(EGL_SAMPLE_BUFFERS, 0); } -- cgit v0.12 From 73d9dced8298dfad7bc72607146e81e96fffb6d4 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Fri, 9 Oct 2009 13:19:36 +1000 Subject: Suppress unnecessary warning messages if pbuffers are not supported Reviewed-by: trustme --- src/opengl/qglpixelbuffer_egl.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/opengl/qglpixelbuffer_egl.cpp b/src/opengl/qglpixelbuffer_egl.cpp index 2b5e2f5..744fbd4 100644 --- a/src/opengl/qglpixelbuffer_egl.cpp +++ b/src/opengl/qglpixelbuffer_egl.cpp @@ -202,13 +202,20 @@ GLuint QGLPixelBuffer::generateDynamicTexture() const bool QGLPixelBuffer::hasOpenGLPbuffers() { // See if we have at least 1 configuration that matches the default format. - QEglContext ctx; - if (!ctx.openDisplay(0)) + EGLDisplay dpy = QEglContext::defaultDisplay(0); + if (dpy == EGL_NO_DISPLAY) return false; QEglProperties configProps; qt_egl_set_format(configProps, QInternal::Pbuffer, QGLFormat::defaultFormat()); configProps.setRenderableType(QEgl::OpenGL); - return ctx.chooseConfig(configProps, QEgl::BestPixelFormat); + do { + EGLConfig cfg = 0; + EGLint matching = 0; + if (eglChooseConfig(dpy, configProps.properties(), + &cfg, 1, &matching) && matching > 0) + return true; + } while (configProps.reduceConfiguration()); + return false; } QT_END_NAMESPACE -- cgit v0.12 From f370b5d986529155baf7d9dd95678854df4105e0 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Fri, 9 Oct 2009 14:57:00 +1000 Subject: Check the framebuffer format against a format, not a texture target The previous code was comparing QGLFramebufferObjectFormat::textureTarget() against GL_RGB to determine if alpha was present. This should be internalTextureFormat() instead. Reviewed-by: Sarah Smith --- src/opengl/qglframebufferobject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index 3e54b35..5585208 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -988,7 +988,7 @@ QImage QGLFramebufferObject::toImage() const bool wasBound = isBound(); if (!wasBound) const_cast(this)->bind(); - QImage image = qt_gl_read_framebuffer(d->size, format().textureTarget() != GL_RGB, true); + QImage image = qt_gl_read_framebuffer(d->size, format().internalTextureFormat() != GL_RGB, true); if (!wasBound) const_cast(this)->release(); -- cgit v0.12 From eb7daff1548510002031140ceb7fc601d064f670 Mon Sep 17 00:00:00 2001 From: Janne Anttila Date: Fri, 9 Oct 2009 10:26:28 +0300 Subject: Help Nokia X86 compiler to compiler qbuttongroup autotest. Reviewed-by: TrustMe --- tests/auto/qbuttongroup/tst_qbuttongroup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qbuttongroup/tst_qbuttongroup.cpp b/tests/auto/qbuttongroup/tst_qbuttongroup.cpp index 11c1f47..a19f865 100644 --- a/tests/auto/qbuttongroup/tst_qbuttongroup.cpp +++ b/tests/auto/qbuttongroup/tst_qbuttongroup.cpp @@ -406,7 +406,7 @@ void tst_QButtonGroup::task106609() QTestEventLoop::instance().enterLoop(1); QApplication::setActiveWindow(&dlg); - QTRY_COMPARE(QApplication::activeWindow(), &dlg); + QTRY_COMPARE(QApplication::activeWindow(), static_cast(&dlg)); //qDebug() << "int:" << spy2.count() << "QAbstractButton*:" << spy1.count(); QCOMPARE(spy2.count(), 2); -- cgit v0.12 From 52e22e7b9313233dd248753b25f56cd912382981 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 9 Oct 2009 09:49:59 +0200 Subject: Fix QHostInfo IP resolution when there's no reverse for the IP. If you try to resolve 10.3.4.6, you're probably going to get that it doesn't exist. On some systems, getnameinfo will return the IP address in string form (Linux, without NI_NAMEREQD). On some others, it will fail (Mac, Windows). So harmonise by gracefully handling the case in which getnameinfo fails. Possible behaviour change: we don't try the forward resolution any more, after completing the reverse one. Reviewed-by: Peter Hartmann --- src/network/kernel/qhostinfo_unix.cpp | 40 +++++++++++++---------------------- src/network/kernel/qhostinfo_win.cpp | 40 +++++++++++++---------------------- 2 files changed, 30 insertions(+), 50 deletions(-) diff --git a/src/network/kernel/qhostinfo_unix.cpp b/src/network/kernel/qhostinfo_unix.cpp index b4ac3d2..7e6e522 100644 --- a/src/network/kernel/qhostinfo_unix.cpp +++ b/src/network/kernel/qhostinfo_unix.cpp @@ -173,38 +173,28 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName) #endif char hbuf[NI_MAXHOST]; - if (!sa || getnameinfo(sa, saSize, hbuf, sizeof(hbuf), 0, 0, 0) != 0) { - results.setError(QHostInfo::HostNotFound); - results.setErrorString(tr("Host not found")); - return results; - } - results.setHostName(QString::fromLatin1(hbuf)); + if (sa && getnameinfo(sa, saSize, hbuf, sizeof(hbuf), 0, 0, 0) == 0) + results.setHostName(QString::fromLatin1(hbuf)); #else in_addr_t inetaddr = qt_safe_inet_addr(hostName.toLatin1().constData()); struct hostent *ent = gethostbyaddr((const char *)&inetaddr, sizeof(inetaddr), AF_INET); - if (!ent) { - results.setError(QHostInfo::HostNotFound); - results.setErrorString(tr("Host not found")); - return results; - } - results.setHostName(QString::fromLatin1(ent->h_name)); + if (ent) + results.setHostName(QString::fromLatin1(ent->h_name)); #endif + + if (results.hostName().isEmpty()) + results.setHostName(address.toString()); + results.setAddresses(QList() << address); + return results; } // IDN support - QByteArray aceHostname; - if (results.hostName().isEmpty()) { - // it's a hostname resolution - aceHostname = QUrl::toAce(hostName); - results.setHostName(hostName); - if (aceHostname.isEmpty()) { - results.setError(QHostInfo::HostNotFound); - results.setErrorString(hostName.isEmpty() ? QObject::tr("No host name given") : QObject::tr("Invalid hostname")); - return results; - } - } else { - // it's an IP reverse resolution - aceHostname = results.hostName().toLatin1(); + QByteArray aceHostname = QUrl::toAce(hostName); + results.setHostName(hostName); + if (aceHostname.isEmpty()) { + results.setError(QHostInfo::HostNotFound); + results.setErrorString(hostName.isEmpty() ? QObject::tr("No host name given") : QObject::tr("Invalid hostname")); + return results; } #if !defined (QT_NO_GETADDRINFO) diff --git a/src/network/kernel/qhostinfo_win.cpp b/src/network/kernel/qhostinfo_win.cpp index d9d7234..720aaa5 100644 --- a/src/network/kernel/qhostinfo_win.cpp +++ b/src/network/kernel/qhostinfo_win.cpp @@ -160,38 +160,28 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName) } char hbuf[NI_MAXHOST]; - if (local_getnameinfo(sa, saSize, hbuf, sizeof(hbuf), 0, 0, 0) != 0) { - results.setError(QHostInfo::HostNotFound); - results.setErrorString(tr("Host not found")); - return results; - } - results.setHostName(QString::fromLatin1(hbuf)); + if (local_getnameinfo(sa, saSize, hbuf, sizeof(hbuf), 0, 0, 0) == 0) + results.setHostName(QString::fromLatin1(hbuf)); } else { unsigned long addr = inet_addr(hostName.toLatin1().constData()); struct hostent *ent = gethostbyaddr((const char*)&addr, sizeof(addr), AF_INET); - if (!ent) { - results.setError(QHostInfo::HostNotFound); - results.setErrorString(tr("Host not found")); - return results; - } - results.setHostName(QString::fromLatin1(ent->h_name)); + if (ent) + results.setHostName(QString::fromLatin1(ent->h_name)); } + + if (results.hostName().isEmpty()) + results.setHostName(address.toString()); + results.setAddresses(QList() << address); + return results; } // IDN support - QByteArray aceHostname; - if (results.hostName().isEmpty()) { - // it's a hostname resolution - aceHostname = QUrl::toAce(hostName); - results.setHostName(hostName); - if (aceHostname.isEmpty()) { - results.setError(QHostInfo::HostNotFound); - results.setErrorString(hostName.isEmpty() ? tr("No host name given") : tr("Invalid hostname")); - return results; - } - } else { - // it's an IP reverse resolution - aceHostname = results.hostName().toLatin1(); + QByteArray aceHostname = QUrl::toAce(hostName); + results.setHostName(hostName); + if (aceHostname.isEmpty()) { + results.setError(QHostInfo::HostNotFound); + results.setErrorString(hostName.isEmpty() ? tr("No host name given") : tr("Invalid hostname")); + return results; } if (local_getaddrinfo && local_freeaddrinfo) { -- cgit v0.12 From 433430c4081c8992bc661d5481a2288eddf2037f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 9 Oct 2009 10:16:27 +0200 Subject: Doc: update the compiler notes about Sun CC's STL not being supported The default STL (Rogue Wave STL) is far too old for Qt. It doesn't meet the ISO C++ 98 specification. Using a more recent (and standards-compliant) STL like stlport4 enables Qt to build even QtWebKit on Solaris. Also change the note indicating we're using Sun Studio 12, not 8. --- doc/src/platforms/compiler-notes.qdoc | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/doc/src/platforms/compiler-notes.qdoc b/doc/src/platforms/compiler-notes.qdoc index 5b5240a..4577bf0 100644 --- a/doc/src/platforms/compiler-notes.qdoc +++ b/doc/src/platforms/compiler-notes.qdoc @@ -204,10 +204,22 @@ \section2 Sun Studio - Qt is tested using Sun Studio 8 (Sun CC 5.5). Go to + Qt is tested using Sun Studio 12 (Sun CC 5.9). Go to \l{Sun Studio Patches} page on Sun's Web site to download the latest patches for your Sun compiler. + Please note that Qt 4.6 is stricter in its STL requirements and + that the default STL implementation used by Sun CC does not pass + those requirements. This does not affect binary compatibility and + you can continue to use STL in your own code, but Qt's + STL-compatibility functions will be disabled. + + Sun CC ships with a secondary STL implementation (called stlport4) + which is standards-compliant and can be used by Qt. You can enable + it by passing the -library=stlport4 option to the compiler. Note + that this does not affect Qt's binary compatibility, but it may + affect that of other libraries and programs that use STL. + \section2 Sun WorkShop 5.0 Sun WorkShop 5.0 is not supported with Qt 4. -- cgit v0.12 From 95a06aa7e724309c3dcd714dbf8cf3743258592f Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 7 Oct 2009 13:53:42 +0200 Subject: Fixed doc for softkeys in the qwidget doc. Reviewed-by: David Boddie --- src/gui/kernel/qwidget.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 4cbf762..56602f7 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -901,9 +901,8 @@ void QWidget::setAutoFillBackground(bool enabled) \sa QEvent, QPainter, QGridLayout, QBoxLayout \section1 Softkeys - \since 4.6 - Softkeys are usually physical keys on a device that have a corresponding label or + Since Qt 4.6, Softkeys are usually physical keys on a device that have a corresponding label or other visual representation on the screen that is generally located next to its physical counterpart. They are most often found on mobile phone platforms. In modern touch based user interfaces it is also possible to have softkeys that do -- cgit v0.12 From afc718f1f21fd34a23e34af9b8a83eb55ae26f34 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 9 Oct 2009 11:06:21 +0200 Subject: Autotest: fix forward-declaration test. The problem was that we forward-declared as struct, but the function was implemented as class. It's different on MSVC. Reviewed-by: Trust Me --- tests/auto/qsharedpointer/tst_qsharedpointer.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index 58eaacb..46ec035 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -1701,7 +1701,7 @@ void tst_QSharedPointer::invalidConstructs() "struct DerivedData: public Data { int j; };\n" "\n" "extern int forwardDeclaredDestructorRunCount;\n" - "struct ForwardDeclared;\n" + "class ForwardDeclared;\n" "ForwardDeclared *forwardPointer();\n" ); @@ -1730,6 +1730,10 @@ void tst_QSharedPointer::invalidConstructs() bool result = (test.*testFunction)(body); if (qgetenv("QTEST_EXTERNAL_DEBUG").toInt() > 0) { qDebug("External test output:"); +#ifdef Q_CC_MSVC + // MSVC prints errors to stdout + printf("%s\n", test.standardOutput().constData()); +#endif printf("%s\n", test.standardError().constData()); } if (!result) { -- cgit v0.12 From 62e7e63779a8dbd5dec16e5eb938bf597bc22548 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 9 Oct 2009 11:18:22 +0200 Subject: Autotest: fix false positives with MSVC.NET 2003 This is definitely a compiler bug. The compiler forgets to adjust the value of the pointers inside the template operator== function. If you make the call outside the template function, it works as expected. Reviewed-by: Trust Me --- tests/auto/qsharedpointer/tst_qsharedpointer.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index 46ec035..ed9206c 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -812,8 +812,14 @@ void tst_QSharedPointer::differentPointers() QVERIFY(baseptr.data() == aData); QVERIFY(aData == baseptr.data()); - QVERIFY(bool(operator==(baseptr, aData))); + +#if defined(Q_CC_MSVC) && _MSC_VER < 1400 + QEXPECT_FAIL("", "Compiler bug", Continue); +#endif QVERIFY(baseptr == aData); +#if defined(Q_CC_MSVC) && _MSC_VER < 1400 + QEXPECT_FAIL("", "Compiler bug", Continue); +#endif QVERIFY(aData == baseptr); } check(); @@ -829,6 +835,9 @@ void tst_QSharedPointer::differentPointers() QVERIFY(ptr == baseptr); QVERIFY(ptr.data() == baseptr.data()); QVERIFY(ptr == aBase); +#if defined(Q_CC_MSVC) && _MSC_VER < 1400 + QEXPECT_FAIL("", "Compiler bug", Continue); +#endif QVERIFY(baseptr == aData); } check(); @@ -845,6 +854,9 @@ void tst_QSharedPointer::differentPointers() QVERIFY(ptr.data() == baseptr.data()); QVERIFY(ptr == aBase); QVERIFY(ptr == aData); +#if defined(Q_CC_MSVC) && _MSC_VER < 1400 + QEXPECT_FAIL("", "Compiler bug", Continue); +#endif QVERIFY(baseptr == aData); QVERIFY(baseptr == aBase); } @@ -865,6 +877,9 @@ void tst_QSharedPointer::virtualBaseDifferentPointers() QVERIFY(ptr.data() == baseptr.data()); QVERIFY(ptr == aBase); QVERIFY(ptr == aData); +#if defined(Q_CC_MSVC) && _MSC_VER < 1400 + QEXPECT_FAIL("", "Compiler bug", Continue); +#endif QVERIFY(baseptr == aData); QVERIFY(baseptr == aBase); } @@ -882,6 +897,9 @@ void tst_QSharedPointer::virtualBaseDifferentPointers() QVERIFY(ptr.data() == baseptr.data()); QVERIFY(ptr == aBase); QVERIFY(ptr == aData); +#if defined(Q_CC_MSVC) && _MSC_VER < 1400 + QEXPECT_FAIL("", "Compiler bug", Continue); +#endif QVERIFY(baseptr == aData); QVERIFY(baseptr == aBase); } -- cgit v0.12 From 606e1150e381e0d824e6850befb101a2ed8e0542 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 9 Oct 2009 12:03:42 +0200 Subject: Add a way to allow tracking the originating object with QNetworkRequest. Added setOriginatingObject() and originatingObject() to QNetworkRequest that internally tracks the QObject using a QWeakPointer. Reviewed-by: Lars Knoll Rubberstamped-by: Thiago --- src/network/access/qnetworkrequest.cpp | 30 ++++++++++++++++++++++ src/network/access/qnetworkrequest.h | 3 +++ src/network/access/qnetworkrequest_p.h | 2 ++ tests/auto/qnetworkrequest/tst_qnetworkrequest.cpp | 16 ++++++++++++ 4 files changed, 51 insertions(+) diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index cde9858..ca9e606 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -481,6 +481,36 @@ void QNetworkRequest::setSslConfiguration(const QSslConfiguration &config) } #endif +/*! + \since 4.6 + + Allows setting a reference to the object initiating + the request. + + For example QtWebKit sets the originating object to the + QWebFrame that initiated the request. + + \sa originatingObject() +*/ +void QNetworkRequest::setOriginatingObject(QObject *object) +{ + d->originatingObject = object; +} + +/*! + \since 4.6 + + Returns a reference to the object that initiated this + network request; returns 0 if not set or the object has + been destroyed. + + \sa setOriginatingObject() +*/ +QObject *QNetworkRequest::originatingObject() const +{ + return d->originatingObject.data(); +} + static QByteArray headerName(QNetworkRequest::KnownHeaders header) { switch (header) { diff --git a/src/network/access/qnetworkrequest.h b/src/network/access/qnetworkrequest.h index 7b15237..62c6dda 100644 --- a/src/network/access/qnetworkrequest.h +++ b/src/network/access/qnetworkrequest.h @@ -120,6 +120,9 @@ public: void setSslConfiguration(const QSslConfiguration &configuration); #endif + void setOriginatingObject(QObject *object); + QObject *originatingObject() const; + private: QSharedDataPointer d; friend class QNetworkRequestPrivate; diff --git a/src/network/access/qnetworkrequest_p.h b/src/network/access/qnetworkrequest_p.h index 22b239f..9b3632f 100644 --- a/src/network/access/qnetworkrequest_p.h +++ b/src/network/access/qnetworkrequest_p.h @@ -58,6 +58,7 @@ #include "QtCore/qlist.h" #include "QtCore/qhash.h" #include "QtCore/qshareddata.h" +#include "QtCore/qsharedpointer.h" QT_BEGIN_NAMESPACE @@ -73,6 +74,7 @@ public: RawHeadersList rawHeaders; CookedHeadersMap cookedHeaders; AttributesMap attributes; + QWeakPointer originatingObject; RawHeadersList::ConstIterator findRawHeader(const QByteArray &key) const; QList rawHeadersKeys() const; diff --git a/tests/auto/qnetworkrequest/tst_qnetworkrequest.cpp b/tests/auto/qnetworkrequest/tst_qnetworkrequest.cpp index 3f9632c..2e21087 100644 --- a/tests/auto/qnetworkrequest/tst_qnetworkrequest.cpp +++ b/tests/auto/qnetworkrequest/tst_qnetworkrequest.cpp @@ -66,6 +66,7 @@ private slots: void setHeader(); void rawHeaderParsing_data(); void rawHeaderParsing(); + void originatingObject(); void removeHeader(); }; @@ -476,5 +477,20 @@ void tst_QNetworkRequest::removeHeader() QVERIFY(request.hasRawHeader("bar")); } +void tst_QNetworkRequest::originatingObject() +{ + QNetworkRequest request; + + QVERIFY(!request.originatingObject()); + + { + QObject dummy; + request.setOriginatingObject(&dummy); + QCOMPARE(request.originatingObject(), &dummy); + } + + QVERIFY(!request.originatingObject()); +} + QTEST_MAIN(tst_QNetworkRequest) #include "tst_qnetworkrequest.moc" -- cgit v0.12 From 803bebe62face37310fd8d8b97ca7faa1d4284a8 Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Fri, 9 Oct 2009 12:10:42 +0200 Subject: Made QPen::setDashOffset() work with non-custom dashed lines. Task-number: QTBUG-2738 Reviewed-by: Trond --- src/gui/painting/qpen.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/gui/painting/qpen.cpp b/src/gui/painting/qpen.cpp index a050cb2..41efc80 100644 --- a/src/gui/painting/qpen.cpp +++ b/src/gui/painting/qpen.cpp @@ -411,6 +411,8 @@ Qt::PenStyle QPen::style() const pattern using the setDashPattern() function which implicitly converts the style of the pen to Qt::CustomDashLine. + \note This function resets the dash offset to zero. + \sa style(), {QPen#Pen Style}{Pen Style} */ @@ -420,7 +422,9 @@ void QPen::setStyle(Qt::PenStyle s) return; detach(); d->style = s; - static_cast(d)->dashPattern.clear(); + QPenData *dd = static_cast(d); + dd->dashPattern.clear(); + dd->dashOffset = 0; } /*! @@ -538,8 +542,12 @@ void QPen::setDashOffset(qreal offset) if (qFuzzyCompare(offset, static_cast(d)->dashOffset)) return; detach(); - static_cast(d)->dashOffset = offset; - d->style = Qt::CustomDashLine; + QPenData *dd = static_cast(d); + dd->dashOffset = offset; + if (d->style != Qt::CustomDashLine) { + dd->dashPattern = dashPattern(); + d->style = Qt::CustomDashLine; + } } /*! -- cgit v0.12 From f74570b72bd71f3747521a5f561971165f3297e5 Mon Sep 17 00:00:00 2001 From: Janne Anttila Date: Fri, 9 Oct 2009 13:58:08 +0300 Subject: Fix for tst_qfile::map auto test in Symbian OS 3.1. The map test case panic with E32User-Cbase 66 in N95 without this fix. This happens sisnce Open C bug where mmap may leave and trap handler is not inside OpenC. The workaround is to install the necessary TRAP handler in Qt, before calling mmap. AutoTests: tst_qfile::map passes Reviewed-by: Janne Koskinen --- src/corelib/io/qfsfileengine_unix.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 114da3b..b0cddaa 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -1255,8 +1255,19 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla int realOffset = offset / pagesSize; int extra = offset % pagesSize; - void *mapAddress = mmap((void*)0, (size_t)size + extra, - access, MAP_SHARED, nativeHandle(), realOffset * pagesSize); +#ifdef Q_OS_SYMBIAN + void *mapAddress; + TRAPD(err, mapAddress = mmap((void*)0, (size_t)size + extra, + access, MAP_SHARED, nativeHandle(), realOffset * pagesSize)); + if (err != KErrNone) { + qWarning("OpenC bug: leave from mmap %d", err); + mapAddress = MAP_FAILED; + errno = EINVAL; + } +#else + void *mapAddress = mmap((void*)0, (size_t)size + extra, + access, MAP_SHARED, nativeHandle(), realOffset * pagesSize); +#endif if (MAP_FAILED != mapAddress) { uchar *address = extra + static_cast(mapAddress); maps[address] = QPair(extra, size); -- cgit v0.12 From 05727386bec0142174c9cbaea6f2b3ca72a42b63 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 9 Oct 2009 13:18:40 +0200 Subject: Fix qdoc warning about undocumented parameter Reviewed-by: Trust me --- src/network/access/qnetworkrequest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index ca9e606..33bc57b 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -484,7 +484,7 @@ void QNetworkRequest::setSslConfiguration(const QSslConfiguration &config) /*! \since 4.6 - Allows setting a reference to the object initiating + Allows setting a reference to the \a object initiating the request. For example QtWebKit sets the originating object to the -- cgit v0.12 From f98f5c5432f13238fc640820cc222b671c1ee8df Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Fri, 9 Oct 2009 09:50:19 +0200 Subject: Fixed text positioning when printing in HighResolution on Mac OS X Reviewed-by: Richard --- src/gui/text/qfontengine_mac.mm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index 40db7b4..758d8af 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -138,9 +138,10 @@ QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const ATSFontFamilyRef &, con QCFString name; ATSFontGetName(atsFontRef, kATSOptionFlagsDefault, &name); - QCFType descriptor = CTFontDescriptorCreateWithNameAndSize(name, fontDef.pointSize); - QCFType baseFont = CTFontCreateWithFontDescriptor(descriptor, fontDef.pointSize, 0); - ctfont = CTFontCreateCopyWithSymbolicTraits(baseFont, fontDef.pointSize, 0, symbolicTraits, symbolicTraits); + + QCFType descriptor = CTFontDescriptorCreateWithNameAndSize(name, fontDef.pixelSize); + QCFType baseFont = CTFontCreateWithFontDescriptor(descriptor, fontDef.pixelSize, 0); + ctfont = CTFontCreateCopyWithSymbolicTraits(baseFont, fontDef.pixelSize, 0, symbolicTraits, symbolicTraits); // CTFontCreateCopyWithSymbolicTraits returns NULL if we ask for a trait that does // not exist for the given font. (for example italic) -- cgit v0.12 From 2caa16ff98348b043ecc3598e5b9af4a2e2ae3bc Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Thu, 8 Oct 2009 17:25:05 +0200 Subject: Fixed crash when printing to files under Cocoa When we select save as PDF in the print dialog, we get a new PMPrintSession in the printInfo object, while our stored one is deleted, so we update the pointer to be on the safe side Reviewed-by: msorvig --- src/gui/dialogs/qprintdialog_mac.mm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gui/dialogs/qprintdialog_mac.mm b/src/gui/dialogs/qprintdialog_mac.mm index a7587b1..667fc40 100644 --- a/src/gui/dialogs/qprintdialog_mac.mm +++ b/src/gui/dialogs/qprintdialog_mac.mm @@ -166,6 +166,12 @@ QT_USE_NAMESPACE } // Keep us in sync with file output PMDestinationType dest; + + // If the user selected print to file, the session has been + // changed behind our back and our d->ep->session object is a + // dangling pointer. Update it based on the "current" session + d->ep->session = static_cast([d->ep->printInfo PMPrintSession]); + PMSessionGetDestinationType(d->ep->session, d->ep->settings, &dest); if (dest == kPMDestinationFile) { QCFType file; -- cgit v0.12