From d1c2225c647e01f84c9aa80fc1d5d034754b94c5 Mon Sep 17 00:00:00 2001 From: "Eduardo M. Fleury" Date: Thu, 8 Oct 2009 10:44:08 -0300 Subject: QGraphicsAnchorLayout: Ensure spacing is not negative Currently we do not support negative-sized anchors in the graph, instead we invert such anchors and make their value positive. We consider changing this sometime in the future but until then, spacing must be non-negative at all times. Signed-off-by: Eduardo M. Fleury Reviewed-by: Caio Marcelo de Oliveira Filho --- src/gui/graphicsview/qgraphicsanchorlayout.cpp | 26 ++++++++++++++++++++++++ src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 7 +++++++ 2 files changed, 33 insertions(+) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.cpp b/src/gui/graphicsview/qgraphicsanchorlayout.cpp index ffbb67c..9f4a19b 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout.cpp @@ -306,6 +306,13 @@ void QGraphicsAnchorLayout::addAnchors(QGraphicsLayoutItem *firstItem, void QGraphicsAnchorLayout::setHorizontalSpacing(qreal spacing) { Q_D(QGraphicsAnchorLayout); + + // ### We don't support negative spacing yet + if (spacing < 0) { + spacing = 0; + qWarning() << "QGraphicsAnchorLayout does not support negative spacing."; + } + d->spacings[0] = spacing; invalidate(); } @@ -318,6 +325,13 @@ void QGraphicsAnchorLayout::setHorizontalSpacing(qreal spacing) void QGraphicsAnchorLayout::setVerticalSpacing(qreal spacing) { Q_D(QGraphicsAnchorLayout); + + // ### We don't support negative spacing yet + if (spacing < 0) { + spacing = 0; + qWarning() << "QGraphicsAnchorLayout does not support negative spacing."; + } + d->spacings[1] = spacing; invalidate(); } @@ -327,11 +341,23 @@ void QGraphicsAnchorLayout::setVerticalSpacing(qreal spacing) If an item is anchored with no spacing associated with the anchor, it will use the default spacing. + + Currently QGraphicsAnchorLayout does not support negative default spacings. + \sa setHorizontalSpacing(), setVerticalSpacing() */ void QGraphicsAnchorLayout::setSpacing(qreal spacing) { Q_D(QGraphicsAnchorLayout); + + // ### Currently we do not support negative anchors inside the graph. + // To avoid those being created by a negative spacing, we must + // make this test. + if (spacing < 0) { + spacing = 0; + qWarning() << "QGraphicsAnchorLayout does not support negative spacing."; + } + d->spacings[0] = d->spacings[1] = spacing; invalidate(); } diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index e3cd4f9..9524289 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -1550,6 +1550,13 @@ qreal QGraphicsAnchorLayoutPrivate::effectiveSpacing(Orientation orientation) co } } } + + // ### Currently we do not support negative anchors inside the graph. + // To avoid those being created by a negative style spacing, we must + // make this test. + if (s < 0) + s = 0; + return s; } -- cgit v0.12 From 6dc050639aeac0021bcb7864533779f2156e9d24 Mon Sep 17 00:00:00 2001 From: "Eduardo M. Fleury" Date: Thu, 8 Oct 2009 14:30:57 -0300 Subject: QGraphicsAnchorLayout: Add test for 'infinite' max size widgets With four items anchored side by side, each of them being allowed to grow to QWIDGETSIZE_MAX, we have a situation of fair distribution because the layout itself can grow only to QWIDGETSIZE_MAX (and not four times this amount). This test identified an error on the expanding distribution logic. Signed-off-by: Eduardo M. Fleury Reviewed-by: Caio Marcelo de Oliveira Filho --- .../tst_qgraphicsanchorlayout.cpp | 49 ++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index 286ea2d..cf4e9b8 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -73,6 +73,7 @@ private slots: void expandingSequenceFairDistribution(); void expandingParallel(); void floatConflict(); + void infiniteMaxSizes(); }; class RectWidget : public QGraphicsWidget @@ -1585,5 +1586,53 @@ void tst_QGraphicsAnchorLayout::floatConflict() delete p; } +void tst_QGraphicsAnchorLayout::infiniteMaxSizes() +{ + QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; + l->setContentsMargins(0, 0, 0, 0); + l->setSpacing(0); + + QSizeF min(10, 10); + QSizeF pref(50, 10); + QSizeF max(QWIDGETSIZE_MAX, 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"); + + // + 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); + + a->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + c->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + + QGraphicsWidget p; + p.setLayout(l); + + p.resize(200, 10); + QCOMPARE(a->geometry(), QRectF(0, 0, 50, 10)); + QCOMPARE(b->geometry(), QRectF(50, 0, 50, 10)); + QCOMPARE(c->geometry(), QRectF(100, 0, 50, 10)); + QCOMPARE(d->geometry(), QRectF(150, 0, 50, 10)); + + p.resize(1000, 10); + QCOMPARE(a->geometry(), QRectF(0, 0, 450, 10)); + QCOMPARE(b->geometry(), QRectF(450, 0, 50, 10)); + QCOMPARE(c->geometry(), QRectF(500, 0, 450, 10)); + QCOMPARE(d->geometry(), QRectF(950, 0, 50, 10)); + + qreal expMaxSize = (QWIDGETSIZE_MAX - 100.0) / 2; + p.resize(QWIDGETSIZE_MAX, 10); + QCOMPARE(a->geometry(), QRectF(0, 0, expMaxSize, 10)); + QCOMPARE(b->geometry(), QRectF(expMaxSize, 0, 50, 10)); + QCOMPARE(c->geometry(), QRectF(expMaxSize + 50, 0, expMaxSize, 10)); + QCOMPARE(d->geometry(), QRectF(QWIDGETSIZE_MAX - 50, 0, 50, 10)); +} + QTEST_MAIN(tst_QGraphicsAnchorLayout) #include "tst_qgraphicsanchorlayout.moc" -- cgit v0.12 From efb50541b57191e3fcfc8dac5a8e8a21658b75b1 Mon Sep 17 00:00:00 2001 From: "Eduardo M. Fleury" Date: Thu, 8 Oct 2009 15:47:42 -0300 Subject: QGraphicsAnchorLayout: Fix sequential anchor distribution w/ expanding sizes After the addition of expanding SizePolicy, the distribution of sequential anchors became wrong. We must now account for three intervals of distribution instead of only two. This commit also unifies the logic used by the sequential group anchor and the edge interpolator. Signed-off-by: Eduardo M. Fleury Reviewed-by: Caio Marcelo de Oliveira Filho --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 162 +++++++++++------------ 1 file changed, 76 insertions(+), 86 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 9524289..1935c27 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -250,44 +250,61 @@ void ParallelAnchorData::refreshSizeHints_helper(qreal effectiveSpacing, 0 is at Preferred 1 is at Maximum */ -static qreal getFactor(qreal value, qreal min, qreal pref, qreal max) -{ - // ### Maybe remove some of the assertions? (since outside is asserting us) - Q_ASSERT(value > min || qFuzzyCompare(value, min)); - Q_ASSERT(value < max || qFuzzyCompare(value, max)); - - if (qFuzzyCompare(value, min)) { - return -1.0; - } else if (qFuzzyCompare(value, pref)) { - return 0.0; - } else if (qFuzzyCompare(value, max)) { - return 1.0; - } else if (value < pref) { - // Since value < pref and value != pref and min <= value, - // we can assert that min < pref. - Q_ASSERT(min < pref); - return (value - min) / (pref - min) - 1; +static QPair getFactor(qreal value, qreal min, + qreal pref, qreal exp, + qreal max) +{ + QGraphicsAnchorLayoutPrivate::Interval interval; + qreal lower; + qreal upper; + + if (value < pref) { + interval = QGraphicsAnchorLayoutPrivate::MinToPreferred; + lower = min; + upper = pref; + } else if (value < exp) { + interval = QGraphicsAnchorLayoutPrivate::PreferredToExpanding; + lower = pref; + upper = exp; } else { - // Since value > pref and value != pref and max >= value, - // we can assert that max > pref. - Q_ASSERT(max > pref); - return (value - pref) / (max - pref); + interval = QGraphicsAnchorLayoutPrivate::ExpandingToMax; + lower = exp; + upper = max; } + + qreal progress; + if (upper == lower) { + progress = 0; + } else { + progress = (value - lower) / (upper - lower); + } + + return qMakePair(interval, progress); } -static qreal getExpandingFactor(qreal expSize, qreal sizeAtPreferred, - qreal sizeAtExpanding, qreal sizeAtMaximum) +static qreal interpolate(const QPair &factor, + qreal min, qreal pref, + qreal exp, qreal max) { - const qreal lower = qMin(sizeAtPreferred, sizeAtMaximum); - const qreal upper = qMax(sizeAtPreferred, sizeAtMaximum); - const qreal boundedExpSize = qBound(lower, expSize, upper); + qreal lower; + qreal upper; - const qreal bandSize = sizeAtMaximum - boundedExpSize; - if (bandSize == 0) { - return 0; - } else { - return (sizeAtExpanding - boundedExpSize) / bandSize; + switch (factor.first) { + case QGraphicsAnchorLayoutPrivate::MinToPreferred: + lower = min; + upper = pref; + break; + case QGraphicsAnchorLayoutPrivate::PreferredToExpanding: + lower = pref; + upper = exp; + break; + case QGraphicsAnchorLayoutPrivate::ExpandingToMax: + lower = exp; + upper = max; + break; } + + return lower + factor.second * (upper - lower); } void SequentialAnchorData::updateChildrenSizes() @@ -307,27 +324,22 @@ void SequentialAnchorData::updateChildrenSizes() // Band here refers if the value is in the Minimum To Preferred // band (the lower band) or the Preferred To Maximum (the upper band). - 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); + const QPair minFactor = + getFactor(sizeAtMinimum, minSize, prefSize, expSize, maxSize); + const QPair prefFactor = + getFactor(sizeAtPreferred, minSize, prefSize, expSize, maxSize); + const QPair expFactor = + getFactor(sizeAtExpanding, minSize, prefSize, expSize, maxSize); + const QPair maxFactor = + getFactor(sizeAtMaximum, minSize, prefSize, expSize, maxSize); for (int i = 0; i < m_edges.count(); ++i) { AnchorData *e = m_edges.at(i); - qreal bandSize = minFactor > 0 ? e->maxSize - e->prefSize : e->prefSize - e->minSize; - e->sizeAtMinimum = e->prefSize + bandSize * minFactor; - - bandSize = prefFactor > 0 ? e->maxSize - e->prefSize : e->prefSize - e->minSize; - e->sizeAtPreferred = e->prefSize + bandSize * prefFactor; - - bandSize = maxFactor > 0 ? e->maxSize - e->prefSize : e->prefSize - e->minSize; - e->sizeAtMaximum = e->prefSize + bandSize * maxFactor; - - 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->sizeAtMinimum = interpolate(minFactor, e->minSize, e->prefSize, e->expSize, e->maxSize); + e->sizeAtPreferred = interpolate(prefFactor, e->minSize, e->prefSize, e->expSize, e->maxSize); + e->sizeAtExpanding = interpolate(expFactor, e->minSize, e->prefSize, e->expSize, e->maxSize); + e->sizeAtMaximum = interpolate(maxFactor, e->minSize, e->prefSize, e->expSize, e->maxSize); e->updateChildrenSizes(); } @@ -2161,39 +2173,26 @@ void QGraphicsAnchorLayoutPrivate::calculateVertexPositions( \internal Calculate interpolation parameters based on current Layout Size. - Must once before calling "interpolateEdgeSize()" for each edge. + Must be called once before calling "interpolateEdgeSize()" for + the edges. */ void QGraphicsAnchorLayoutPrivate::setupEdgesInterpolation( Orientation orientation) { Q_Q(QGraphicsAnchorLayout); - qreal lower, upper, current; - if (orientation == Horizontal) { - current = q->contentsRect().width(); - } else { - current = q->contentsRect().height(); - } + qreal current; + current = (orientation == Horizontal) ? q->contentsRect().width() : q->contentsRect().height(); - if (current < sizeHints[orientation][Qt::PreferredSize]) { - interpolationInterval[orientation] = MinToPreferred; - lower = sizeHints[orientation][Qt::MinimumSize]; - upper = sizeHints[orientation][Qt::PreferredSize]; - } 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]; - } + QPair result; + result = getFactor(current, + sizeHints[orientation][Qt::MinimumSize], + sizeHints[orientation][Qt::PreferredSize], + sizeAtExpanding[orientation], + sizeHints[orientation][Qt::MaximumSize]); - if (upper == lower) { - interpolationProgress[orientation] = 0; - } else { - interpolationProgress[orientation] = (current - lower) / (upper - lower); - } + interpolationInterval[orientation] = result.first; + interpolationProgress[orientation] = result.second; } /*! @@ -2220,20 +2219,11 @@ void QGraphicsAnchorLayoutPrivate::interpolateEdge(AnchorVertex *base, AnchorData *edge, Orientation orientation) { - qreal lower, upper; - - if (interpolationInterval[orientation] == MinToPreferred) { - lower = edge->sizeAtMinimum; - upper = edge->sizeAtPreferred; - } else if (interpolationInterval[orientation] == PreferredToExpanding) { - lower = edge->sizeAtPreferred; - upper = edge->sizeAtExpanding; - } else { - lower = edge->sizeAtExpanding; - upper = edge->sizeAtMaximum; - } + const QPair factor(interpolationInterval[orientation], + interpolationProgress[orientation]); - qreal edgeDistance = (interpolationProgress[orientation] * (upper - lower)) + lower; + qreal edgeDistance = interpolate(factor, edge->sizeAtMinimum, edge->sizeAtPreferred, + edge->sizeAtExpanding, edge->sizeAtMaximum); Q_ASSERT(edge->from == base || edge->to == base); -- cgit v0.12 From cce279d015ccf19200153b43b7f378e25d0913d3 Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Wed, 7 Oct 2009 19:34:09 -0300 Subject: QGAL: improve dump graph and add helper code The graph dumper function take a name, and added debug code (that need to be enabled manually) to generate dumps from the graph before and after calculation. This is useful to debug simplification. Signed-off-by: Caio Marcelo de Oliveira Filho Reviewed-by: Artur Duque de Souza --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 14 ++++++++++++-- src/gui/graphicsview/qgraphicsanchorlayout_p.h | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 1935c27..c921b60 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -1584,9 +1584,19 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs() if (!calculateGraphCacheDirty) return; +#if defined(QT_DEBUG) && 0 + static int count = 0; + count++; + dumpGraph(QString::fromAscii("%1-before").arg(count)); +#endif + calculateGraphs(Horizontal); calculateGraphs(Vertical); +#if defined(QT_DEBUG) && 0 + dumpGraph(QString::fromAscii("%1-after").arg(count)); +#endif + calculateGraphCacheDirty = 0; } @@ -2558,9 +2568,9 @@ bool QGraphicsAnchorLayoutPrivate::hasConflicts() const } #ifdef QT_DEBUG -void QGraphicsAnchorLayoutPrivate::dumpGraph() +void QGraphicsAnchorLayoutPrivate::dumpGraph(const QString &name) { - QFile file(QString::fromAscii("anchorlayout.dot")); + QFile file(QString::fromAscii("anchorlayout.%1.dot").arg(name)); if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) qWarning("Could not write to %s", file.fileName().toLocal8Bit().constData()); diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 24b25de..ea19ecb 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -478,7 +478,7 @@ public: bool hasConflicts() const; #ifdef QT_DEBUG - void dumpGraph(); + void dumpGraph(const QString &name = QString()); #endif -- cgit v0.12 From b6be5eb62a79f7c0d3718a05b18dcf69d2c21550 Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Wed, 7 Oct 2009 19:41:32 -0300 Subject: QGAL: add a way to test whether simplex was used in a calculation This is one good way to track whether simplification is doing all its job or not. However it can only track cases where the graph simplify to only one anchor. For more complex cases the graph dumps are the way to go. Signed-off-by: Caio Marcelo de Oliveira Filho Reviewed-by: Artur Duque de Souza --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 8 ++++ src/gui/graphicsview/qgraphicsanchorlayout_p.h | 4 ++ .../tst_qgraphicsanchorlayout.cpp | 54 +++++++++++++++++++++- 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index c921b60..b92d1c3 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -1689,6 +1689,10 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( orientation == Horizontal ? "Horizontal" : "Vertical"); #endif +#ifdef QT_DEBUG + lastCalculationUsedSimplex[orientation] = true; +#endif + // Solve min and max size hints for trunk qreal min, max; feasible = solveMinMax(trunkConstraints, trunkPath, &min, &max); @@ -1738,6 +1742,10 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( orientation == Horizontal ? "Horizontal" : "Vertical"); #endif +#ifdef QT_DEBUG + lastCalculationUsedSimplex[orientation] = false; +#endif + // No Simplex is necessary because the path was simplified all the way to a single // anchor. Q_ASSERT(trunkPath.positives.count() == 1); diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index ea19ecb..7d38e40 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -513,6 +513,10 @@ public: bool graphHasConflicts[2]; QSet m_nonFloatItems[2]; +#ifdef QT_DEBUG + bool lastCalculationUsedSimplex[2]; +#endif + uint calculateGraphCacheDirty : 1; }; diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index cf4e9b8..cef56b9 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -153,6 +153,15 @@ static bool layoutHasConflict(QGraphicsAnchorLayout *l) return QGraphicsAnchorLayoutPrivate::get(l)->hasConflicts(); } +static bool usedSimplex(QGraphicsAnchorLayout *l, Qt::Orientation o) +{ + QGraphicsAnchorLayoutPrivate::Orientation oo = (o == Qt::Horizontal) ? + QGraphicsAnchorLayoutPrivate::Horizontal : + QGraphicsAnchorLayoutPrivate::Vertical; + + return QGraphicsAnchorLayoutPrivate::get(l)->lastCalculationUsedSimplex[oo]; +} + void tst_QGraphicsAnchorLayout::simple() { QGraphicsWidget *w1 = createItem(); @@ -170,10 +179,14 @@ void tst_QGraphicsAnchorLayout::simple() l->addAnchors(l, w1, Qt::Vertical); l->addAnchors(l, w2, Qt::Vertical); + QCOMPARE(l->count(), 2); + QGraphicsWidget p; p.setLayout(l); + p.adjustSize(); - QCOMPARE(l->count(), 2); + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); } void tst_QGraphicsAnchorLayout::simple_center() @@ -213,6 +226,9 @@ void tst_QGraphicsAnchorLayout::simple_center() QSizeF layoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize); QCOMPARE(layoutMaximumSize, QSizeF(200, 20)); + QVERIFY(usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); + delete p; } @@ -310,6 +326,9 @@ void tst_QGraphicsAnchorLayout::layoutDirection() QCOMPARE(checkReverseDirection(p), true); + QVERIFY(usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); + delete p; delete view; } @@ -398,6 +417,9 @@ void tst_QGraphicsAnchorLayout::diagonal() QCOMPARE(e->geometry(), QRectF(100.0, 200.0, 75.0, 100.0)); QCOMPARE(p.size(), testA); + QVERIFY(usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); + QCOMPARE(checkReverseDirection(&p), true); c->setMinimumWidth(300); @@ -494,6 +516,9 @@ void tst_QGraphicsAnchorLayout::parallel() QCOMPARE(e->geometry(), QRectF(375, 400, 175, 100)); QCOMPARE(f->geometry(), QRectF(550, 500, 200, 100)); QCOMPARE(p.size(), layoutMaximumSize); + + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); } void tst_QGraphicsAnchorLayout::parallel2() @@ -539,6 +564,9 @@ void tst_QGraphicsAnchorLayout::parallel2() p.resize(layoutMaximumSize); QCOMPARE(p.size(), layoutMaximumSize); + + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); } void tst_QGraphicsAnchorLayout::snake() @@ -749,6 +777,9 @@ void tst_QGraphicsAnchorLayout::fairDistribution() QCOMPARE(c->geometry(), QRectF(200.0, 200.0, 100.0, 100.0)); QCOMPARE(d->geometry(), QRectF(0.0, 300.0, 300.0, 100.0)); QCOMPARE(p.size(), layoutMaximumSize); + + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); } void tst_QGraphicsAnchorLayout::fairDistributionOppositeDirections() @@ -825,6 +856,9 @@ void tst_QGraphicsAnchorLayout::fairDistributionOppositeDirections() QCOMPARE(a->size(), d->size()); QCOMPARE(e->size().width(), 4 * a->size().width()); QCOMPARE(p.size(), layoutMaximumSize); + + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); } void tst_QGraphicsAnchorLayout::proportionalPreferred() @@ -887,6 +921,9 @@ void tst_QGraphicsAnchorLayout::proportionalPreferred() QCOMPARE(a->size().width(), 10 * factor); QCOMPARE(c->size().width(), 14 * factor); QCOMPARE(p.size(), QSizeF(12, 400)); + + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); } void tst_QGraphicsAnchorLayout::example() @@ -970,6 +1007,9 @@ void tst_QGraphicsAnchorLayout::example() QCOMPARE(a->size(), e->size()); QCOMPARE(b->size(), d->size()); QCOMPARE(f->size(), g->size()); + + QVERIFY(usedSimplex(l, Qt::Horizontal)); + QVERIFY(usedSimplex(l, Qt::Vertical)); } void tst_QGraphicsAnchorLayout::setSpacing() @@ -1291,6 +1331,9 @@ void tst_QGraphicsAnchorLayout::sizePolicy() QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(100, 100)); QCOMPARE(l->effectiveSizeHint(Qt::MaximumSize), QSizeF(100, 100)); + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); + delete p; delete view; } @@ -1381,6 +1424,9 @@ void tst_QGraphicsAnchorLayout::expandingSequence() QSizeF layoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize); QCOMPARE(layoutMaximumSize.width(), qreal(200)); + + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); } void tst_QGraphicsAnchorLayout::expandingSequenceFairDistribution() @@ -1442,6 +1488,9 @@ void tst_QGraphicsAnchorLayout::expandingSequenceFairDistribution() QSizeF layoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize); QCOMPARE(layoutMaximumSize.width(), qreal(400)); + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); + // 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. @@ -1464,6 +1513,9 @@ void tst_QGraphicsAnchorLayout::expandingSequenceFairDistribution() QCOMPARE(b->geometry().size(), pref + QSizeF(25, 0)); QCOMPARE(c->geometry().size(), pref); QCOMPARE(d->geometry().size(), pref + QSizeF(50, 0)); + + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); } void tst_QGraphicsAnchorLayout::expandingParallel() -- cgit v0.12 From bd47b9215a40ec4d9e290e18ac156f5e0cb5bbd2 Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Thu, 8 Oct 2009 15:52:11 -0300 Subject: QGAL: avoid having to re-calculate lists of variables Change the functions solvePreferred() and solveExpanding() to take a list of variables, so they don't need to calculate them based on the list of constraints. That way, the trunk variables are calculated only once. This commit also reduce the scope of 'sizeHintConstraints' variable instead of clearing and reusing it. Signed-off-by: Caio Marcelo de Oliveira Filho Reviewed-by: Artur Duque de Souza --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 50 +++++++++++------------- src/gui/graphicsview/qgraphicsanchorlayout_p.h | 8 ++-- 2 files changed, 27 insertions(+), 31 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index b92d1c3..fa53b66 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -1671,9 +1671,7 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( // of the "trunk" set of constraints and variables. // ### does trunk always exist? empty = trunk is the layout left->center->right QList trunkConstraints = parts[0]; - QList sizeHintConstraints; - sizeHintConstraints = constraintsFromSizeHints(getVariables(trunkConstraints)); - trunkConstraints += sizeHintConstraints; + QList trunkVariables = getVariables(trunkConstraints); // For minimum and maximum, use the path between the two layout sides as the // objective function. @@ -1695,26 +1693,24 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( // Solve min and max size hints for trunk qreal min, max; - feasible = solveMinMax(trunkConstraints, trunkPath, &min, &max); + + QList sizeHintConstraints = constraintsFromSizeHints(trunkVariables); + QList allTrunkConstraints = trunkConstraints + sizeHintConstraints; + + feasible = solveMinMax(allTrunkConstraints, trunkPath, &min, &max); 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]; + solvePreferred(allTrunkConstraints, trunkVariables); // Solve for expanding. The objective function and the constraints from items - // are calculated internally. - solveExpanding(trunkConstraints); + // are calculated internally. Note that we don't include the sizeHintConstraints, since + // they have a different logic for solveExpanding(). + solveExpanding(trunkConstraints, trunkVariables); // Propagate the new sizes down the simplified graph, ie. tell the // group anchors to set their children anchors sizes. - - // ### we calculated variables already a few times, can't we reuse that? - QList trunkVariables = getVariables(trunkConstraints); - for (int i = 0; i < trunkVariables.count(); ++i) trunkVariables.at(i)->updateChildrenSizes(); @@ -1736,6 +1732,9 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( sizeHints[orientation][Qt::MaximumSize] = max; sizeAtExpanding[orientation] = expanding; } + + qDeleteAll(sizeHintConstraints); + } else { #if 0 qDebug("Simplex NOT used for trunk of %s", @@ -1766,10 +1765,6 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( sizeAtExpanding[orientation] = ad->sizeAtExpanding; } - // Delete the constraints, we won't use them anymore. - qDeleteAll(sizeHintConstraints); - sizeHintConstraints.clear(); - // For the other parts that not the trunk, solve only for the preferred size // that is the size they will remain at, since they are not stretched by the // layout. @@ -1781,9 +1776,9 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( QList partVariables = getVariables(partConstraints); Q_ASSERT(!partVariables.isEmpty()); - sizeHintConstraints = constraintsFromSizeHints(partVariables); + QList sizeHintConstraints = constraintsFromSizeHints(partVariables); partConstraints += sizeHintConstraints; - feasible &= solvePreferred(partConstraints); + feasible &= solvePreferred(partConstraints, partVariables); if (!feasible) break; @@ -1800,7 +1795,6 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( // Delete the constraints, we won't use them anymore. qDeleteAll(sizeHintConstraints); - sizeHintConstraints.clear(); } } graphHasConflicts[orientation] = !feasible; @@ -2312,7 +2306,7 @@ void QGraphicsAnchorLayoutPrivate::interpolateSequentialEdges( interpolateEdge(prev, data->m_edges.last(), orientation); } -bool QGraphicsAnchorLayoutPrivate::solveMinMax(QList constraints, +bool QGraphicsAnchorLayoutPrivate::solveMinMax(const QList &constraints, GraphPath path, qreal *min, qreal *max) { QSimplex simplex; @@ -2353,9 +2347,9 @@ bool QGraphicsAnchorLayoutPrivate::solveMinMax(QList const return feasible; } -bool QGraphicsAnchorLayoutPrivate::solvePreferred(QList constraints) +bool QGraphicsAnchorLayoutPrivate::solvePreferred(const QList &constraints, + const QList &variables) { - QList variables = getVariables(constraints); QList preferredConstraints; QList preferredVariables; QSimplexConstraint objective; @@ -2378,7 +2372,7 @@ bool QGraphicsAnchorLayoutPrivate::solvePreferred(QList co // A + A_shrinker - A_grower = A_pref // for (int i = 0; i < variables.size(); ++i) { - AnchorData *ad = static_cast(variables[i]); + AnchorData *ad = variables[i]; if (ad->skipInPreferred) continue; @@ -2409,7 +2403,7 @@ bool QGraphicsAnchorLayoutPrivate::solvePreferred(QList co // Save sizeAtPreferred results for (int i = 0; i < variables.size(); ++i) { - AnchorData *ad = static_cast(variables[i]); + AnchorData *ad = variables[i]; ad->sizeAtPreferred = ad->result; } @@ -2470,9 +2464,9 @@ bool QGraphicsAnchorLayoutPrivate::solvePreferred(QList co 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) +void QGraphicsAnchorLayoutPrivate::solveExpanding(const QList &constraints, + const QList &variables) { - QList variables = getVariables(constraints); QList itemConstraints; QSimplexConstraint *objective = new QSimplexConstraint; bool hasExpanding = false; diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 7d38e40..474055a 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -471,10 +471,12 @@ public: Orientation orientation); // Linear Programming solver methods - bool solveMinMax(QList constraints, + bool solveMinMax(const QList &constraints, GraphPath path, qreal *min, qreal *max); - bool solvePreferred(QList constraints); - void solveExpanding(QList constraints); + bool solvePreferred(const QList &constraints, + const QList &variables); + void solveExpanding(const QList &constraints, + const QList &variables); bool hasConflicts() const; #ifdef QT_DEBUG -- cgit v0.12 From a9b1d44fdc9fac0be0016114afcad56e9d372c26 Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Thu, 8 Oct 2009 16:55:42 -0300 Subject: QGAL: update the sizes of all anchors instead of doing it separatedly After calculations, update the size of all anchors in the simplified graph. Those updates were happening locally after each calculation (trunk and semifloats), however some anchors that were not involved in simplex calculation were missing. One concrete consequence of the previous behaviour is that semifloat parts that were simplified into just one anchor, didn't have the chance to set their sizeAt* values. One consequence of the new behaviour is one more test passing. Signed-off-by: Caio Marcelo de Oliveira Filho Reviewed-by: Artur Duque de Souza --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 28 +++++++++++++++------- src/gui/graphicsview/qgraphicsanchorlayout_p.h | 1 + .../tst_qgraphicsanchorlayout1.cpp | 2 -- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index fa53b66..017ddbf 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -1709,11 +1709,6 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( // they have a different logic for solveExpanding(). solveExpanding(trunkConstraints, trunkVariables); - // Propagate the new sizes down the simplified graph, ie. tell the - // group anchors to set their children anchors sizes. - for (int i = 0; i < trunkVariables.count(); ++i) - trunkVariables.at(i)->updateChildrenSizes(); - // Calculate and set the preferred and expanding sizes for the layout, // from the edge sizes that were calculated above. qreal pref(0.0); @@ -1756,9 +1751,6 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( ad->sizeAtExpanding = ad->expSize; ad->sizeAtMaximum = ad->maxSize; - // Propagate - ad->updateChildrenSizes(); - sizeHints[orientation][Qt::MinimumSize] = ad->sizeAtMinimum; sizeHints[orientation][Qt::PreferredSize] = ad->sizeAtPreferred; sizeHints[orientation][Qt::MaximumSize] = ad->sizeAtMaximum; @@ -1790,13 +1782,17 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( ad->sizeAtMinimum = ad->sizeAtPreferred; ad->sizeAtExpanding = ad->sizeAtPreferred; ad->sizeAtMaximum = ad->sizeAtPreferred; - ad->updateChildrenSizes(); } // Delete the constraints, we won't use them anymore. qDeleteAll(sizeHintConstraints); } } + + // Propagate the new sizes down the simplified graph, ie. tell the + // group anchors to set their children anchors sizes. + updateAnchorSizes(orientation); + graphHasConflicts[orientation] = !feasible; // Clean up our data structures. They are not needed anymore since @@ -1907,6 +1903,20 @@ void QGraphicsAnchorLayoutPrivate::constraintsFromPaths(Orientation orientation) /*! \internal +*/ +void QGraphicsAnchorLayoutPrivate::updateAnchorSizes(Orientation orientation) +{ + Graph &g = graph[orientation]; + const QList > &vertices = g.connections(); + + for (int i = 0; i < vertices.count(); ++i) { + AnchorData *ad = g.edgeData(vertices.at(i).first, vertices.at(i).second); + ad->updateChildrenSizes(); + } +} + +/*! + \internal Create LP constraints for each anchor based on its minimum and maximum sizes, as specified in its size hints diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 474055a..940f143 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -441,6 +441,7 @@ public: void setAnchorSizeHintsFromItems(Orientation orientation); void findPaths(Orientation orientation); void constraintsFromPaths(Orientation orientation); + void updateAnchorSizes(Orientation orientation); QList constraintsFromSizeHints(const QList &anchors); QList > getGraphParts(Orientation orientation); void identifyNonFloatItems(QSet visited, Orientation orientation); diff --git a/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp b/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp index 148b2c8..755d866 100644 --- a/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp +++ b/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp @@ -1711,8 +1711,6 @@ void tst_QGraphicsAnchorLayout1::testBasicLayout() // Validate for (int i = 0; i < result.count(); ++i) { - if (i == 1) - QEXPECT_FAIL("Two, mixed", "Works with simplification disabled.", Continue); const BasicLayoutTestResult item = result[i]; QCOMPARE(widgets[item.index]->geometry(), item.rect); } -- cgit v0.12 From cebaf35e3d79a7cde84a9ef5b0023e841075d5c1 Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Thu, 8 Oct 2009 20:09:21 -0300 Subject: QGAL: refactor calculateGraphs() method Create calculateTrunk() and calculateNonTrunk() methods, that calculate sizes for anchors in different parts of the simplified graph (using simplex when needed). Also fixes a minor leak when the nontrunk part is non-feasible. The old code left the loop leaving the contents of 'sizeHintConstraints' not allocated. Signed-off-by: Caio Marcelo de Oliveira Filho Reviewed-by: Artur Duque de Souza --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 161 ++++++++++++----------- src/gui/graphicsview/qgraphicsanchorlayout_p.h | 7 + 2 files changed, 93 insertions(+), 75 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 017ddbf..1e9b579 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -1600,7 +1600,8 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs() calculateGraphCacheDirty = 0; } -// ### remove me: +// ### Maybe getGraphParts could return the variables when traversing, at least +// for trunk... QList getVariables(QList constraints) { QSet variableSet; @@ -1664,8 +1665,7 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( // 2) The floating or semi-floating anchors (items) that are those which // are connected to only one (or none) of the layout sides, thus are not // influenced by the layout size. - QList > parts; - parts = getGraphParts(orientation); + QList > parts = getGraphParts(orientation); // Now run the simplex solver to calculate Minimum, Preferred and Maximum sizes // of the "trunk" set of constraints and variables. @@ -1675,49 +1675,82 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( // For minimum and maximum, use the path between the two layout sides as the // objective function. - - // Retrieve that path AnchorVertex *v = internalVertex(q, pickEdge(Qt::AnchorRight, orientation)); GraphPath trunkPath = graphPaths[orientation].value(v); + bool feasible = calculateTrunk(orientation, trunkPath, trunkConstraints, trunkVariables); + + // For the other parts that not the trunk, solve only for the preferred size + // that is the size they will remain at, since they are not stretched by the + // layout. + + // Skipping the first (trunk) + for (int i = 1; i < parts.count(); ++i) { + if (!feasible) + break; + + QList partConstraints = parts[i]; + QList partVariables = getVariables(partConstraints); + Q_ASSERT(!partVariables.isEmpty()); + feasible &= calculateNonTrunk(partConstraints, partVariables); + } + + // Propagate the new sizes down the simplified graph, ie. tell the + // group anchors to set their children anchors sizes. + updateAnchorSizes(orientation); + + graphHasConflicts[orientation] = !feasible; + + // Clean up our data structures. They are not needed anymore since + // distribution uses just interpolation. + qDeleteAll(constraints[orientation]); + constraints[orientation].clear(); + graphPaths[orientation].clear(); // ### +} + +/*! + \internal + + Calculate the sizes for all anchors which are part of the trunk. This works + on top of a (possibly) simplified graph. +*/ +bool QGraphicsAnchorLayoutPrivate::calculateTrunk(Orientation orientation, const GraphPath &path, + const QList &constraints, + const QList &variables) +{ bool feasible = true; - if (!trunkConstraints.isEmpty()) { -#if 0 - qDebug("Simplex used for trunk of %s", - orientation == Horizontal ? "Horizontal" : "Vertical"); -#endif + bool needsSimplex = !constraints.isEmpty(); -#ifdef QT_DEBUG - lastCalculationUsedSimplex[orientation] = true; +#if 0 + qDebug("Simplex %s for trunk of %s", needsSimplex ? "used" : "NOT used", + orientation == Horizontal ? "Horizontal" : "Vertical"); #endif - // Solve min and max size hints for trunk - qreal min, max; + if (needsSimplex) { - QList sizeHintConstraints = constraintsFromSizeHints(trunkVariables); - QList allTrunkConstraints = trunkConstraints + sizeHintConstraints; + QList sizeHintConstraints = constraintsFromSizeHints(variables); + QList allConstraints = constraints + sizeHintConstraints; - feasible = solveMinMax(allTrunkConstraints, trunkPath, &min, &max); + // Solve min and max size hints + qreal min, max; + feasible = solveMinMax(allConstraints, path, &min, &max); if (feasible) { - // Solve for preferred. The objective function is calculated from the constraints - // and variables internally. - solvePreferred(allTrunkConstraints, trunkVariables); + solvePreferred(allConstraints, variables); - // Solve for expanding. The objective function and the constraints from items - // are calculated internally. Note that we don't include the sizeHintConstraints, since - // they have a different logic for solveExpanding(). - solveExpanding(trunkConstraints, trunkVariables); + // Note that we don't include the sizeHintConstraints, since they + // have a different logic for solveExpanding(). + solveExpanding(constraints, variables); // 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) { + foreach (const AnchorData *ad, path.positives) { pref += ad->sizeAtPreferred; expanding += ad->sizeAtExpanding; } - foreach (const AnchorData *ad, trunkPath.negatives) { + foreach (const AnchorData *ad, path.negatives) { pref -= ad->sizeAtPreferred; expanding -= ad->sizeAtExpanding; } @@ -1731,21 +1764,12 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( qDeleteAll(sizeHintConstraints); } else { -#if 0 - qDebug("Simplex NOT used for trunk of %s", - orientation == Horizontal ? "Horizontal" : "Vertical"); -#endif - -#ifdef QT_DEBUG - lastCalculationUsedSimplex[orientation] = false; -#endif - // No Simplex is necessary because the path was simplified all the way to a single // anchor. - Q_ASSERT(trunkPath.positives.count() == 1); - Q_ASSERT(trunkPath.negatives.count() == 0); + Q_ASSERT(path.positives.count() == 1); + Q_ASSERT(path.negatives.count() == 0); - AnchorData *ad = trunkPath.positives.toList()[0]; + AnchorData *ad = path.positives.toList()[0]; ad->sizeAtMinimum = ad->minSize; ad->sizeAtPreferred = ad->prefSize; ad->sizeAtExpanding = ad->expSize; @@ -1757,49 +1781,36 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( sizeAtExpanding[orientation] = ad->sizeAtExpanding; } - // For the other parts that not the trunk, solve only for the preferred size - // that is the size they will remain at, since they are not stretched by the - // layout. +#ifdef QT_DEBUG + lastCalculationUsedSimplex[orientation] = needsSimplex; +#endif - // Solve the other only for preferred, skip trunk - if (feasible) { - for (int i = 1; i < parts.count(); ++i) { - QList partConstraints = parts[i]; - QList partVariables = getVariables(partConstraints); - Q_ASSERT(!partVariables.isEmpty()); - - QList sizeHintConstraints = constraintsFromSizeHints(partVariables); - partConstraints += sizeHintConstraints; - feasible &= solvePreferred(partConstraints, partVariables); - if (!feasible) - break; + return feasible; +} - // Propagate size at preferred to other sizes. Semi-floats - // always will be in their sizeAtPreferred. - for (int j = 0; j < partVariables.count(); ++j) { - AnchorData *ad = partVariables[j]; - Q_ASSERT(ad); - ad->sizeAtMinimum = ad->sizeAtPreferred; - ad->sizeAtExpanding = ad->sizeAtPreferred; - ad->sizeAtMaximum = ad->sizeAtPreferred; - } +/*! + \internal +*/ +bool QGraphicsAnchorLayoutPrivate::calculateNonTrunk(const QList &constraints, + const QList &variables) +{ + QList sizeHintConstraints = constraintsFromSizeHints(variables); + bool feasible = solvePreferred(constraints + sizeHintConstraints, variables); - // Delete the constraints, we won't use them anymore. - qDeleteAll(sizeHintConstraints); + if (feasible) { + // Propagate size at preferred to other sizes. Semi-floats always will be + // in their sizeAtPreferred. + for (int j = 0; j < variables.count(); ++j) { + AnchorData *ad = variables[j]; + Q_ASSERT(ad); + ad->sizeAtMinimum = ad->sizeAtPreferred; + ad->sizeAtExpanding = ad->sizeAtPreferred; + ad->sizeAtMaximum = ad->sizeAtPreferred; } } - // Propagate the new sizes down the simplified graph, ie. tell the - // group anchors to set their children anchors sizes. - updateAnchorSizes(orientation); - - graphHasConflicts[orientation] = !feasible; - - // Clean up our data structures. They are not needed anymore since - // distribution uses just interpolation. - qDeleteAll(constraints[orientation]); - constraints[orientation].clear(); - graphPaths[orientation].clear(); // ### + qDeleteAll(sizeHintConstraints); + return feasible; } /*! diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 940f143..2ced72d 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -438,6 +438,13 @@ public: void calculateGraphs(); void calculateGraphs(Orientation orientation); + + bool calculateTrunk(Orientation orientation, const GraphPath &trunkPath, + const QList &constraints, + const QList &variables); + bool calculateNonTrunk(const QList &constraints, + const QList &variables); + void setAnchorSizeHintsFromItems(Orientation orientation); void findPaths(Orientation orientation); void constraintsFromPaths(Orientation orientation); -- cgit v0.12 From 9ea66fb4d1e1ad36bcd1a0e4b7e7de348273e8ff Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 15 Oct 2009 10:34:34 +0200 Subject: Spreadsheet demo: fix the footer color. One of the footer cell lost his gray color in commit 7c12258485db8d Task-number: QTBUG-4821 Reviewed-by: Jan-Arve --- demos/spreadsheet/spreadsheet.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/demos/spreadsheet/spreadsheet.cpp b/demos/spreadsheet/spreadsheet.cpp index 7f057a2..00045c6 100644 --- a/demos/spreadsheet/spreadsheet.cpp +++ b/demos/spreadsheet/spreadsheet.cpp @@ -523,6 +523,7 @@ void SpreadSheet::setupContents() table->setItem(8, 2, new SpreadSheetItem("1240")); table->setItem(9, 2, new SpreadSheetItem()); + table->item(9, 2)->setBackgroundColor(Qt::lightGray); // column 3 table->setItem(0, 3, new SpreadSheetItem("Currency")); -- cgit v0.12 From 2055fe9eb514b79a34a0c216164cd1a11561be4f Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 15 Oct 2009 11:44:01 +0200 Subject: Stabilize QLineEdit test on X11 --- tests/auto/qlineedit/tst_qlineedit.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/tests/auto/qlineedit/tst_qlineedit.cpp b/tests/auto/qlineedit/tst_qlineedit.cpp index 8368114..c676959 100644 --- a/tests/auto/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/qlineedit/tst_qlineedit.cpp @@ -3304,41 +3304,45 @@ void tst_QLineEdit::task174640_editingFinished() layout->addWidget(le2); mw.show(); - QTest::qWait(200); + QApplication::setActiveWindow(&mw); mw.activateWindow(); + QTest::qWaitForWindowShown(&mw); QSignalSpy editingFinishedSpy(le1, SIGNAL(editingFinished())); le1->setFocus(); - QTest::qWait(200); - QVERIFY(le1->hasFocus()); + QTest::qWait(20); + QTRY_VERIFY(le1->hasFocus()); QCOMPARE(editingFinishedSpy.count(), 0); le2->setFocus(); - QTest::qWait(200); - QVERIFY(le2->hasFocus()); + QTest::qWait(20); + QTRY_VERIFY(le2->hasFocus()); QCOMPARE(editingFinishedSpy.count(), 1); editingFinishedSpy.clear(); le1->setFocus(); - QTest::qWait(200); - QVERIFY(le1->hasFocus()); + QTest::qWait(20); + QTRY_VERIFY(le1->hasFocus()); QMenu *testMenu1 = new QMenu(le1); testMenu1->addAction("foo"); testMenu1->addAction("bar"); testMenu1->show(); - QTest::qWait(200); + QTest::qWaitForWindowShown(testMenu1); + QTest::qWait(20); mw.activateWindow(); + delete testMenu1; QCOMPARE(editingFinishedSpy.count(), 0); - QVERIFY(le1->hasFocus()); + QTRY_VERIFY(le1->hasFocus()); QMenu *testMenu2 = new QMenu(le2); testMenu2->addAction("foo2"); testMenu2->addAction("bar2"); testMenu2->show(); - QTest::qWait(200); + QTest::qWaitForWindowShown(testMenu2); + QTest::qWait(20); mw.activateWindow(); delete testMenu2; QCOMPARE(editingFinishedSpy.count(), 1); -- cgit v0.12 From d5be015ddf268f195568d313dc2c5491a6a2db93 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 15 Oct 2009 13:55:32 +0200 Subject: Stabilize test on x11 --- tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp | 7 ++++--- tests/auto/qwidget/tst_qwidget.cpp | 8 ++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp index 013a028..2426ce9 100644 --- a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp +++ b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp @@ -1287,6 +1287,7 @@ void tst_QGraphicsProxyWidget::paintEvent() QGraphicsView view(&scene); view.show(); QTest::qWaitForWindowShown(&view); + QTest::qWait(70); SubQGraphicsProxyWidget proxy; @@ -1297,14 +1298,14 @@ void tst_QGraphicsProxyWidget::paintEvent() w->show(); QTest::qWaitForWindowShown(w); QApplication::processEvents(); - QTest::qWait(50); + QTest::qWait(100); proxy.setWidget(w); scene.addItem(&proxy); //make sure we flush all the paint events QTest::qWait(70); QTRY_VERIFY(proxy.paintCount > 1); - QTest::qWait(70); + QTest::qWait(110); proxy.paintCount = 0; w->update(); @@ -2705,7 +2706,7 @@ void tst_QGraphicsProxyWidget::windowOpacity() view.show(); QTest::qWaitForWindowShown(&view); QApplication::sendPostedEvents(); - QTest::qWait(50); + QTest::qWait(150); qRegisterMetaType >("QList"); QSignalSpy signalSpy(&scene, SIGNAL(changed(const QList &))); diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index c000a12..daeee3d 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -7459,11 +7459,11 @@ void tst_QWidget::updateWhileMinimized() QTest::qWaitForWindowShown(&widget); QApplication::processEvents(); QTRY_VERIFY(widget.numPaintEvents > 0); - QTest::qWait(50); + QTest::qWait(150); // Minimize window. widget.showMinimized(); - QTest::qWait(70); + QTest::qWait(110); widget.reset(); @@ -8164,7 +8164,7 @@ public: static bool firstTime = true; if (firstTime) - QTimer::singleShot(150, this, SLOT(resizeMe())); + QTimer::singleShot(250, this, SLOT(resizeMe())); firstTime = false; } @@ -8181,7 +8181,7 @@ void tst_QWidget::moveInResizeEvent() testWidget.setGeometry(50, 50, 200, 200); testWidget.show(); QTest::qWaitForWindowShown(&testWidget); - QTest::qWait(160); + QTest::qWait(300); QRect expectedGeometry(100,100, 100, 100); QTRY_COMPARE(testWidget.geometry(), expectedGeometry); -- cgit v0.12 From 038434b66a473c08e78dc40376c5890dd1af938f Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Thu, 15 Oct 2009 14:14:19 +0200 Subject: Fixed updating problems QListView with IconMode The updated rectangle coordinates didn't use the viewport offsets. Reviewed-by: Olivier Task-number: QTBUG-4819 --- src/gui/itemviews/qlistview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp index 9b0b00f..243f542 100644 --- a/src/gui/itemviews/qlistview.cpp +++ b/src/gui/itemviews/qlistview.cpp @@ -2490,7 +2490,7 @@ bool QIconModeViewBase::filterDropEvent(QDropEvent *e) for (int i = 0; i < indexes.count(); ++i) { QModelIndex index = indexes.at(i); QRect rect = dd->rectForIndex(index); - viewport()->update(mapToViewport(rect)); + viewport()->update(dd->mapToViewport(rect, false)); QPoint dest = rect.topLeft() + delta; if (qq->isRightToLeft()) dest.setX(dd->flipX(dest.x()) - rect.width()); -- cgit v0.12 From 2eee73e843ba7b4c6e83bd6bfaa08994520c417d Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Thu, 15 Oct 2009 15:45:14 +0200 Subject: Compilation of the QGraphicsAnchorLayout test on 64bit + stabilize the linear layout test --- tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp | 2 +- tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp b/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp index 148b2c8..e69a718 100644 --- a/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp +++ b/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp @@ -435,7 +435,7 @@ void tst_QGraphicsAnchorLayout1::testAddAndRemoveAnchor() layout->removeAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft); QCOMPARE( layout->count(), 4 ); - QCOMPARE( (int)widget1->parentLayoutItem(), 0 ); + QVERIFY( !widget1->parentLayoutItem() ); // test that item is not removed from layout if other anchors remain set layout->setAnchor(widget2, Qt::AnchorLeft, widget3, Qt::AnchorRight, 10); diff --git a/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp b/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp index 4f28df4..8e7bb45 100644 --- a/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp +++ b/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp @@ -146,7 +146,7 @@ void tst_QGraphicsLinearLayout::initTestCase() // since the style will influence the results, we have to ensure // that the tests are run using the same style on all platforms #ifdef Q_WS_S60 - QApplication::setStyle(new QWindowsStyle); + QApplication::setStyle(new QWindowsStyle); #else QApplication::setStyle(new QPlastiqueStyle); #endif @@ -332,6 +332,7 @@ void tst_QGraphicsLinearLayout::alignment() widget->resize(newSize); view.show(); widget->show(); + QTest::qWaitForWindowShown(&view); QApplication::processEvents(); int x = 0; -- cgit v0.12 From f81a563c74eece173a0cf1d6c3243604c0db0a5b Mon Sep 17 00:00:00 2001 From: "Eduardo M. Fleury" Date: Thu, 8 Oct 2009 10:44:08 -0300 Subject: QGraphicsAnchorLayout: Ensure spacing is not negative Currently we do not support negative-sized anchors in the graph, instead we invert such anchors and make their value positive. We consider changing this sometime in the future but until then, spacing must be non-negative at all times. Signed-off-by: Eduardo M. Fleury Reviewed-by: Caio Marcelo de Oliveira Filho --- src/gui/graphicsview/qgraphicsanchorlayout.cpp | 26 ++++++++++++++++++++++++ src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 7 +++++++ 2 files changed, 33 insertions(+) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.cpp b/src/gui/graphicsview/qgraphicsanchorlayout.cpp index ffbb67c..9f4a19b 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout.cpp @@ -306,6 +306,13 @@ void QGraphicsAnchorLayout::addAnchors(QGraphicsLayoutItem *firstItem, void QGraphicsAnchorLayout::setHorizontalSpacing(qreal spacing) { Q_D(QGraphicsAnchorLayout); + + // ### We don't support negative spacing yet + if (spacing < 0) { + spacing = 0; + qWarning() << "QGraphicsAnchorLayout does not support negative spacing."; + } + d->spacings[0] = spacing; invalidate(); } @@ -318,6 +325,13 @@ void QGraphicsAnchorLayout::setHorizontalSpacing(qreal spacing) void QGraphicsAnchorLayout::setVerticalSpacing(qreal spacing) { Q_D(QGraphicsAnchorLayout); + + // ### We don't support negative spacing yet + if (spacing < 0) { + spacing = 0; + qWarning() << "QGraphicsAnchorLayout does not support negative spacing."; + } + d->spacings[1] = spacing; invalidate(); } @@ -327,11 +341,23 @@ void QGraphicsAnchorLayout::setVerticalSpacing(qreal spacing) If an item is anchored with no spacing associated with the anchor, it will use the default spacing. + + Currently QGraphicsAnchorLayout does not support negative default spacings. + \sa setHorizontalSpacing(), setVerticalSpacing() */ void QGraphicsAnchorLayout::setSpacing(qreal spacing) { Q_D(QGraphicsAnchorLayout); + + // ### Currently we do not support negative anchors inside the graph. + // To avoid those being created by a negative spacing, we must + // make this test. + if (spacing < 0) { + spacing = 0; + qWarning() << "QGraphicsAnchorLayout does not support negative spacing."; + } + d->spacings[0] = d->spacings[1] = spacing; invalidate(); } diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index f9b5c8c..1cbea8e 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -1550,6 +1550,13 @@ qreal QGraphicsAnchorLayoutPrivate::effectiveSpacing(Orientation orientation) co } } } + + // ### Currently we do not support negative anchors inside the graph. + // To avoid those being created by a negative style spacing, we must + // make this test. + if (s < 0) + s = 0; + return s; } -- cgit v0.12 From 80ffc2fa1766aa8009a30de495fc11ab6690bd87 Mon Sep 17 00:00:00 2001 From: "Eduardo M. Fleury" Date: Thu, 8 Oct 2009 14:30:57 -0300 Subject: QGraphicsAnchorLayout: Add test for 'infinite' max size widgets With four items anchored side by side, each of them being allowed to grow to QWIDGETSIZE_MAX, we have a situation of fair distribution because the layout itself can grow only to QWIDGETSIZE_MAX (and not four times this amount). This test identified an error on the expanding distribution logic. Signed-off-by: Eduardo M. Fleury Reviewed-by: Caio Marcelo de Oliveira Filho --- .../tst_qgraphicsanchorlayout.cpp | 49 ++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index 286ea2d..cf4e9b8 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -73,6 +73,7 @@ private slots: void expandingSequenceFairDistribution(); void expandingParallel(); void floatConflict(); + void infiniteMaxSizes(); }; class RectWidget : public QGraphicsWidget @@ -1585,5 +1586,53 @@ void tst_QGraphicsAnchorLayout::floatConflict() delete p; } +void tst_QGraphicsAnchorLayout::infiniteMaxSizes() +{ + QGraphicsAnchorLayout *l = new QGraphicsAnchorLayout; + l->setContentsMargins(0, 0, 0, 0); + l->setSpacing(0); + + QSizeF min(10, 10); + QSizeF pref(50, 10); + QSizeF max(QWIDGETSIZE_MAX, 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"); + + // + 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); + + a->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + c->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + + QGraphicsWidget p; + p.setLayout(l); + + p.resize(200, 10); + QCOMPARE(a->geometry(), QRectF(0, 0, 50, 10)); + QCOMPARE(b->geometry(), QRectF(50, 0, 50, 10)); + QCOMPARE(c->geometry(), QRectF(100, 0, 50, 10)); + QCOMPARE(d->geometry(), QRectF(150, 0, 50, 10)); + + p.resize(1000, 10); + QCOMPARE(a->geometry(), QRectF(0, 0, 450, 10)); + QCOMPARE(b->geometry(), QRectF(450, 0, 50, 10)); + QCOMPARE(c->geometry(), QRectF(500, 0, 450, 10)); + QCOMPARE(d->geometry(), QRectF(950, 0, 50, 10)); + + qreal expMaxSize = (QWIDGETSIZE_MAX - 100.0) / 2; + p.resize(QWIDGETSIZE_MAX, 10); + QCOMPARE(a->geometry(), QRectF(0, 0, expMaxSize, 10)); + QCOMPARE(b->geometry(), QRectF(expMaxSize, 0, 50, 10)); + QCOMPARE(c->geometry(), QRectF(expMaxSize + 50, 0, expMaxSize, 10)); + QCOMPARE(d->geometry(), QRectF(QWIDGETSIZE_MAX - 50, 0, 50, 10)); +} + QTEST_MAIN(tst_QGraphicsAnchorLayout) #include "tst_qgraphicsanchorlayout.moc" -- cgit v0.12 From 70bfdcee2e09cb491a5dbcc37caaf17076893339 Mon Sep 17 00:00:00 2001 From: "Eduardo M. Fleury" Date: Thu, 8 Oct 2009 15:47:42 -0300 Subject: QGraphicsAnchorLayout: Fix sequential anchor distribution w/ expanding sizes After the addition of expanding SizePolicy, the distribution of sequential anchors became wrong. We must now account for three intervals of distribution instead of only two. This commit also unifies the logic used by the sequential group anchor and the edge interpolator. Signed-off-by: Eduardo M. Fleury Reviewed-by: Caio Marcelo de Oliveira Filho --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 162 +++++++++++------------ 1 file changed, 76 insertions(+), 86 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 1cbea8e..ff42cb5 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -250,44 +250,61 @@ void ParallelAnchorData::refreshSizeHints_helper(qreal effectiveSpacing, 0 is at Preferred 1 is at Maximum */ -static qreal getFactor(qreal value, qreal min, qreal pref, qreal max) -{ - // ### Maybe remove some of the assertions? (since outside is asserting us) - Q_ASSERT(value > min || qFuzzyCompare(value, min)); - Q_ASSERT(value < max || qFuzzyCompare(value, max)); - - if (qFuzzyCompare(value, min)) { - return -1.0; - } else if (qFuzzyCompare(value, pref)) { - return 0.0; - } else if (qFuzzyCompare(value, max)) { - return 1.0; - } else if (value < pref) { - // Since value < pref and value != pref and min <= value, - // we can assert that min < pref. - Q_ASSERT(min < pref); - return (value - min) / (pref - min) - 1; +static QPair getFactor(qreal value, qreal min, + qreal pref, qreal exp, + qreal max) +{ + QGraphicsAnchorLayoutPrivate::Interval interval; + qreal lower; + qreal upper; + + if (value < pref) { + interval = QGraphicsAnchorLayoutPrivate::MinToPreferred; + lower = min; + upper = pref; + } else if (value < exp) { + interval = QGraphicsAnchorLayoutPrivate::PreferredToExpanding; + lower = pref; + upper = exp; } else { - // Since value > pref and value != pref and max >= value, - // we can assert that max > pref. - Q_ASSERT(max > pref); - return (value - pref) / (max - pref); + interval = QGraphicsAnchorLayoutPrivate::ExpandingToMax; + lower = exp; + upper = max; } + + qreal progress; + if (upper == lower) { + progress = 0; + } else { + progress = (value - lower) / (upper - lower); + } + + return qMakePair(interval, progress); } -static qreal getExpandingFactor(const qreal &expSize, const qreal &sizeAtPreferred, - const qreal &sizeAtExpanding, const qreal &sizeAtMaximum) +static qreal interpolate(const QPair &factor, + qreal min, qreal pref, + qreal exp, qreal max) { - const qreal lower = qMin(sizeAtPreferred, sizeAtMaximum); - const qreal upper = qMax(sizeAtPreferred, sizeAtMaximum); - const qreal boundedExpSize = qBound(lower, expSize, upper); + qreal lower; + qreal upper; - const qreal bandSize = sizeAtMaximum - boundedExpSize; - if (bandSize == 0) { - return 0; - } else { - return (sizeAtExpanding - boundedExpSize) / bandSize; + switch (factor.first) { + case QGraphicsAnchorLayoutPrivate::MinToPreferred: + lower = min; + upper = pref; + break; + case QGraphicsAnchorLayoutPrivate::PreferredToExpanding: + lower = pref; + upper = exp; + break; + case QGraphicsAnchorLayoutPrivate::ExpandingToMax: + lower = exp; + upper = max; + break; } + + return lower + factor.second * (upper - lower); } void SequentialAnchorData::updateChildrenSizes() @@ -307,27 +324,22 @@ void SequentialAnchorData::updateChildrenSizes() // Band here refers if the value is in the Minimum To Preferred // band (the lower band) or the Preferred To Maximum (the upper band). - 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); + const QPair minFactor = + getFactor(sizeAtMinimum, minSize, prefSize, expSize, maxSize); + const QPair prefFactor = + getFactor(sizeAtPreferred, minSize, prefSize, expSize, maxSize); + const QPair expFactor = + getFactor(sizeAtExpanding, minSize, prefSize, expSize, maxSize); + const QPair maxFactor = + getFactor(sizeAtMaximum, minSize, prefSize, expSize, maxSize); for (int i = 0; i < m_edges.count(); ++i) { AnchorData *e = m_edges.at(i); - qreal bandSize = minFactor > 0 ? e->maxSize - e->prefSize : e->prefSize - e->minSize; - e->sizeAtMinimum = e->prefSize + bandSize * minFactor; - - bandSize = prefFactor > 0 ? e->maxSize - e->prefSize : e->prefSize - e->minSize; - e->sizeAtPreferred = e->prefSize + bandSize * prefFactor; - - bandSize = maxFactor > 0 ? e->maxSize - e->prefSize : e->prefSize - e->minSize; - e->sizeAtMaximum = e->prefSize + bandSize * maxFactor; - - 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->sizeAtMinimum = interpolate(minFactor, e->minSize, e->prefSize, e->expSize, e->maxSize); + e->sizeAtPreferred = interpolate(prefFactor, e->minSize, e->prefSize, e->expSize, e->maxSize); + e->sizeAtExpanding = interpolate(expFactor, e->minSize, e->prefSize, e->expSize, e->maxSize); + e->sizeAtMaximum = interpolate(maxFactor, e->minSize, e->prefSize, e->expSize, e->maxSize); e->updateChildrenSizes(); } @@ -2167,39 +2179,26 @@ void QGraphicsAnchorLayoutPrivate::calculateVertexPositions( \internal Calculate interpolation parameters based on current Layout Size. - Must once before calling "interpolateEdgeSize()" for each edge. + Must be called once before calling "interpolateEdgeSize()" for + the edges. */ void QGraphicsAnchorLayoutPrivate::setupEdgesInterpolation( Orientation orientation) { Q_Q(QGraphicsAnchorLayout); - qreal lower, upper, current; - if (orientation == Horizontal) { - current = q->contentsRect().width(); - } else { - current = q->contentsRect().height(); - } + qreal current; + current = (orientation == Horizontal) ? q->contentsRect().width() : q->contentsRect().height(); - if (current < sizeHints[orientation][Qt::PreferredSize]) { - interpolationInterval[orientation] = MinToPreferred; - lower = sizeHints[orientation][Qt::MinimumSize]; - upper = sizeHints[orientation][Qt::PreferredSize]; - } 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]; - } + QPair result; + result = getFactor(current, + sizeHints[orientation][Qt::MinimumSize], + sizeHints[orientation][Qt::PreferredSize], + sizeAtExpanding[orientation], + sizeHints[orientation][Qt::MaximumSize]); - if (upper == lower) { - interpolationProgress[orientation] = 0; - } else { - interpolationProgress[orientation] = (current - lower) / (upper - lower); - } + interpolationInterval[orientation] = result.first; + interpolationProgress[orientation] = result.second; } /*! @@ -2226,20 +2225,11 @@ void QGraphicsAnchorLayoutPrivate::interpolateEdge(AnchorVertex *base, AnchorData *edge, Orientation orientation) { - qreal lower, upper; - - if (interpolationInterval[orientation] == MinToPreferred) { - lower = edge->sizeAtMinimum; - upper = edge->sizeAtPreferred; - } else if (interpolationInterval[orientation] == PreferredToExpanding) { - lower = edge->sizeAtPreferred; - upper = edge->sizeAtExpanding; - } else { - lower = edge->sizeAtExpanding; - upper = edge->sizeAtMaximum; - } + const QPair factor(interpolationInterval[orientation], + interpolationProgress[orientation]); - qreal edgeDistance = (interpolationProgress[orientation] * (upper - lower)) + lower; + qreal edgeDistance = interpolate(factor, edge->sizeAtMinimum, edge->sizeAtPreferred, + edge->sizeAtExpanding, edge->sizeAtMaximum); Q_ASSERT(edge->from == base || edge->to == base); -- cgit v0.12 From a0b0e6b086b493aa833596a7d228ca7eb27be47e Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Wed, 7 Oct 2009 19:34:09 -0300 Subject: QGAL: improve dump graph and add helper code The graph dumper function take a name, and added debug code (that need to be enabled manually) to generate dumps from the graph before and after calculation. This is useful to debug simplification. Signed-off-by: Caio Marcelo de Oliveira Filho Reviewed-by: Artur Duque de Souza --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 14 ++++++++++++-- src/gui/graphicsview/qgraphicsanchorlayout_p.h | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index ff42cb5..f090aa3 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -1584,9 +1584,19 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs() if (!calculateGraphCacheDirty) return; +#if defined(QT_DEBUG) && 0 + static int count = 0; + count++; + dumpGraph(QString::fromAscii("%1-before").arg(count)); +#endif + calculateGraphs(Horizontal); calculateGraphs(Vertical); +#if defined(QT_DEBUG) && 0 + dumpGraph(QString::fromAscii("%1-after").arg(count)); +#endif + calculateGraphCacheDirty = 0; } @@ -2563,9 +2573,9 @@ bool QGraphicsAnchorLayoutPrivate::hasConflicts() const } #ifdef QT_DEBUG -void QGraphicsAnchorLayoutPrivate::dumpGraph() +void QGraphicsAnchorLayoutPrivate::dumpGraph(const QString &name) { - QFile file(QString::fromAscii("anchorlayout.dot")); + QFile file(QString::fromAscii("anchorlayout.%1.dot").arg(name)); if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) qWarning("Could not write to %s", file.fileName().toLocal8Bit().constData()); diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 9ac0e19..9b50661 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -478,7 +478,7 @@ public: bool hasConflicts() const; #ifdef QT_DEBUG - void dumpGraph(); + void dumpGraph(const QString &name = QString()); #endif -- cgit v0.12 From 1501429a78d647f922dfdb4432fbfac333143c91 Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Wed, 7 Oct 2009 19:41:32 -0300 Subject: QGAL: add a way to test whether simplex was used in a calculation This is one good way to track whether simplification is doing all its job or not. However it can only track cases where the graph simplify to only one anchor. For more complex cases the graph dumps are the way to go. Signed-off-by: Caio Marcelo de Oliveira Filho Reviewed-by: Artur Duque de Souza --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 8 ++++ src/gui/graphicsview/qgraphicsanchorlayout_p.h | 4 ++ .../tst_qgraphicsanchorlayout.cpp | 54 +++++++++++++++++++++- 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index f090aa3..b61405f 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -1689,6 +1689,10 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( orientation == Horizontal ? "Horizontal" : "Vertical"); #endif +#ifdef QT_DEBUG + lastCalculationUsedSimplex[orientation] = true; +#endif + // Solve min and max size hints for trunk qreal min, max; feasible = solveMinMax(trunkConstraints, trunkPath, &min, &max); @@ -1738,6 +1742,10 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( orientation == Horizontal ? "Horizontal" : "Vertical"); #endif +#ifdef QT_DEBUG + lastCalculationUsedSimplex[orientation] = false; +#endif + // No Simplex is necessary because the path was simplified all the way to a single // anchor. Q_ASSERT(trunkPath.positives.count() == 1); diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 9b50661..b14bc62 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -513,6 +513,10 @@ public: bool graphHasConflicts[2]; QSet m_floatItems[2]; +#ifdef QT_DEBUG + bool lastCalculationUsedSimplex[2]; +#endif + uint calculateGraphCacheDirty : 1; }; diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index cf4e9b8..cef56b9 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -153,6 +153,15 @@ static bool layoutHasConflict(QGraphicsAnchorLayout *l) return QGraphicsAnchorLayoutPrivate::get(l)->hasConflicts(); } +static bool usedSimplex(QGraphicsAnchorLayout *l, Qt::Orientation o) +{ + QGraphicsAnchorLayoutPrivate::Orientation oo = (o == Qt::Horizontal) ? + QGraphicsAnchorLayoutPrivate::Horizontal : + QGraphicsAnchorLayoutPrivate::Vertical; + + return QGraphicsAnchorLayoutPrivate::get(l)->lastCalculationUsedSimplex[oo]; +} + void tst_QGraphicsAnchorLayout::simple() { QGraphicsWidget *w1 = createItem(); @@ -170,10 +179,14 @@ void tst_QGraphicsAnchorLayout::simple() l->addAnchors(l, w1, Qt::Vertical); l->addAnchors(l, w2, Qt::Vertical); + QCOMPARE(l->count(), 2); + QGraphicsWidget p; p.setLayout(l); + p.adjustSize(); - QCOMPARE(l->count(), 2); + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); } void tst_QGraphicsAnchorLayout::simple_center() @@ -213,6 +226,9 @@ void tst_QGraphicsAnchorLayout::simple_center() QSizeF layoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize); QCOMPARE(layoutMaximumSize, QSizeF(200, 20)); + QVERIFY(usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); + delete p; } @@ -310,6 +326,9 @@ void tst_QGraphicsAnchorLayout::layoutDirection() QCOMPARE(checkReverseDirection(p), true); + QVERIFY(usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); + delete p; delete view; } @@ -398,6 +417,9 @@ void tst_QGraphicsAnchorLayout::diagonal() QCOMPARE(e->geometry(), QRectF(100.0, 200.0, 75.0, 100.0)); QCOMPARE(p.size(), testA); + QVERIFY(usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); + QCOMPARE(checkReverseDirection(&p), true); c->setMinimumWidth(300); @@ -494,6 +516,9 @@ void tst_QGraphicsAnchorLayout::parallel() QCOMPARE(e->geometry(), QRectF(375, 400, 175, 100)); QCOMPARE(f->geometry(), QRectF(550, 500, 200, 100)); QCOMPARE(p.size(), layoutMaximumSize); + + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); } void tst_QGraphicsAnchorLayout::parallel2() @@ -539,6 +564,9 @@ void tst_QGraphicsAnchorLayout::parallel2() p.resize(layoutMaximumSize); QCOMPARE(p.size(), layoutMaximumSize); + + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); } void tst_QGraphicsAnchorLayout::snake() @@ -749,6 +777,9 @@ void tst_QGraphicsAnchorLayout::fairDistribution() QCOMPARE(c->geometry(), QRectF(200.0, 200.0, 100.0, 100.0)); QCOMPARE(d->geometry(), QRectF(0.0, 300.0, 300.0, 100.0)); QCOMPARE(p.size(), layoutMaximumSize); + + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); } void tst_QGraphicsAnchorLayout::fairDistributionOppositeDirections() @@ -825,6 +856,9 @@ void tst_QGraphicsAnchorLayout::fairDistributionOppositeDirections() QCOMPARE(a->size(), d->size()); QCOMPARE(e->size().width(), 4 * a->size().width()); QCOMPARE(p.size(), layoutMaximumSize); + + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); } void tst_QGraphicsAnchorLayout::proportionalPreferred() @@ -887,6 +921,9 @@ void tst_QGraphicsAnchorLayout::proportionalPreferred() QCOMPARE(a->size().width(), 10 * factor); QCOMPARE(c->size().width(), 14 * factor); QCOMPARE(p.size(), QSizeF(12, 400)); + + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); } void tst_QGraphicsAnchorLayout::example() @@ -970,6 +1007,9 @@ void tst_QGraphicsAnchorLayout::example() QCOMPARE(a->size(), e->size()); QCOMPARE(b->size(), d->size()); QCOMPARE(f->size(), g->size()); + + QVERIFY(usedSimplex(l, Qt::Horizontal)); + QVERIFY(usedSimplex(l, Qt::Vertical)); } void tst_QGraphicsAnchorLayout::setSpacing() @@ -1291,6 +1331,9 @@ void tst_QGraphicsAnchorLayout::sizePolicy() QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(100, 100)); QCOMPARE(l->effectiveSizeHint(Qt::MaximumSize), QSizeF(100, 100)); + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); + delete p; delete view; } @@ -1381,6 +1424,9 @@ void tst_QGraphicsAnchorLayout::expandingSequence() QSizeF layoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize); QCOMPARE(layoutMaximumSize.width(), qreal(200)); + + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); } void tst_QGraphicsAnchorLayout::expandingSequenceFairDistribution() @@ -1442,6 +1488,9 @@ void tst_QGraphicsAnchorLayout::expandingSequenceFairDistribution() QSizeF layoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize); QCOMPARE(layoutMaximumSize.width(), qreal(400)); + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); + // 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. @@ -1464,6 +1513,9 @@ void tst_QGraphicsAnchorLayout::expandingSequenceFairDistribution() QCOMPARE(b->geometry().size(), pref + QSizeF(25, 0)); QCOMPARE(c->geometry().size(), pref); QCOMPARE(d->geometry().size(), pref + QSizeF(50, 0)); + + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); } void tst_QGraphicsAnchorLayout::expandingParallel() -- cgit v0.12 From eb2717ccbb20334b52aea269303258fe6236c117 Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Thu, 8 Oct 2009 15:52:11 -0300 Subject: QGAL: avoid having to re-calculate lists of variables Change the functions solvePreferred() and solveExpanding() to take a list of variables, so they don't need to calculate them based on the list of constraints. That way, the trunk variables are calculated only once. This commit also reduce the scope of 'sizeHintConstraints' variable instead of clearing and reusing it. Signed-off-by: Caio Marcelo de Oliveira Filho Reviewed-by: Artur Duque de Souza --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 50 +++++++++++------------- src/gui/graphicsview/qgraphicsanchorlayout_p.h | 8 ++-- 2 files changed, 27 insertions(+), 31 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index b61405f..485743e 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -1671,9 +1671,7 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( // of the "trunk" set of constraints and variables. // ### does trunk always exist? empty = trunk is the layout left->center->right QList trunkConstraints = parts[0]; - QList sizeHintConstraints; - sizeHintConstraints = constraintsFromSizeHints(getVariables(trunkConstraints)); - trunkConstraints += sizeHintConstraints; + QList trunkVariables = getVariables(trunkConstraints); // For minimum and maximum, use the path between the two layout sides as the // objective function. @@ -1695,26 +1693,24 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( // Solve min and max size hints for trunk qreal min, max; - feasible = solveMinMax(trunkConstraints, trunkPath, &min, &max); + + QList sizeHintConstraints = constraintsFromSizeHints(trunkVariables); + QList allTrunkConstraints = trunkConstraints + sizeHintConstraints; + + feasible = solveMinMax(allTrunkConstraints, trunkPath, &min, &max); 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]; + solvePreferred(allTrunkConstraints, trunkVariables); // Solve for expanding. The objective function and the constraints from items - // are calculated internally. - solveExpanding(trunkConstraints); + // are calculated internally. Note that we don't include the sizeHintConstraints, since + // they have a different logic for solveExpanding(). + solveExpanding(trunkConstraints, trunkVariables); // Propagate the new sizes down the simplified graph, ie. tell the // group anchors to set their children anchors sizes. - - // ### we calculated variables already a few times, can't we reuse that? - QList trunkVariables = getVariables(trunkConstraints); - for (int i = 0; i < trunkVariables.count(); ++i) trunkVariables.at(i)->updateChildrenSizes(); @@ -1736,6 +1732,9 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( sizeHints[orientation][Qt::MaximumSize] = max; sizeAtExpanding[orientation] = expanding; } + + qDeleteAll(sizeHintConstraints); + } else { #if 0 qDebug("Simplex NOT used for trunk of %s", @@ -1766,10 +1765,6 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( sizeAtExpanding[orientation] = ad->sizeAtExpanding; } - // Delete the constraints, we won't use them anymore. - qDeleteAll(sizeHintConstraints); - sizeHintConstraints.clear(); - // For the other parts that not the trunk, solve only for the preferred size // that is the size they will remain at, since they are not stretched by the // layout. @@ -1781,9 +1776,9 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( QList partVariables = getVariables(partConstraints); Q_ASSERT(!partVariables.isEmpty()); - sizeHintConstraints = constraintsFromSizeHints(partVariables); + QList sizeHintConstraints = constraintsFromSizeHints(partVariables); partConstraints += sizeHintConstraints; - feasible &= solvePreferred(partConstraints); + feasible &= solvePreferred(partConstraints, partVariables); if (!feasible) break; @@ -1800,7 +1795,6 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( // Delete the constraints, we won't use them anymore. qDeleteAll(sizeHintConstraints); - sizeHintConstraints.clear(); } } graphHasConflicts[orientation] = !feasible; @@ -2318,7 +2312,7 @@ void QGraphicsAnchorLayoutPrivate::interpolateSequentialEdges( interpolateEdge(prev, data->m_edges.last(), orientation); } -bool QGraphicsAnchorLayoutPrivate::solveMinMax(QList constraints, +bool QGraphicsAnchorLayoutPrivate::solveMinMax(const QList &constraints, GraphPath path, qreal *min, qreal *max) { QSimplex simplex; @@ -2359,9 +2353,9 @@ bool QGraphicsAnchorLayoutPrivate::solveMinMax(QList const return feasible; } -bool QGraphicsAnchorLayoutPrivate::solvePreferred(QList constraints) +bool QGraphicsAnchorLayoutPrivate::solvePreferred(const QList &constraints, + const QList &variables) { - QList variables = getVariables(constraints); QList preferredConstraints; QList preferredVariables; QSimplexConstraint objective; @@ -2384,7 +2378,7 @@ bool QGraphicsAnchorLayoutPrivate::solvePreferred(QList co // A + A_shrinker - A_grower = A_pref // for (int i = 0; i < variables.size(); ++i) { - AnchorData *ad = static_cast(variables[i]); + AnchorData *ad = variables[i]; if (ad->skipInPreferred) continue; @@ -2415,7 +2409,7 @@ bool QGraphicsAnchorLayoutPrivate::solvePreferred(QList co // Save sizeAtPreferred results for (int i = 0; i < variables.size(); ++i) { - AnchorData *ad = static_cast(variables[i]); + AnchorData *ad = variables[i]; ad->sizeAtPreferred = ad->result; } @@ -2476,9 +2470,9 @@ bool QGraphicsAnchorLayoutPrivate::solvePreferred(QList co 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) +void QGraphicsAnchorLayoutPrivate::solveExpanding(const QList &constraints, + const QList &variables) { - QList variables = getVariables(constraints); QList itemConstraints; QSimplexConstraint *objective = new QSimplexConstraint; bool hasExpanding = false; diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index b14bc62..1d7b758 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -471,10 +471,12 @@ public: Orientation orientation); // Linear Programming solver methods - bool solveMinMax(QList constraints, + bool solveMinMax(const QList &constraints, GraphPath path, qreal *min, qreal *max); - bool solvePreferred(QList constraints); - void solveExpanding(QList constraints); + bool solvePreferred(const QList &constraints, + const QList &variables); + void solveExpanding(const QList &constraints, + const QList &variables); bool hasConflicts() const; #ifdef QT_DEBUG -- cgit v0.12 From e7e67b26fcd6c53dd822b1ae36074d418d432b4a Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Thu, 8 Oct 2009 16:55:42 -0300 Subject: QGAL: update the sizes of all anchors instead of doing it separatedly After calculations, update the size of all anchors in the simplified graph. Those updates were happening locally after each calculation (trunk and semifloats), however some anchors that were not involved in simplex calculation were missing. One concrete consequence of the previous behaviour is that semifloat parts that were simplified into just one anchor, didn't have the chance to set their sizeAt* values. One consequence of the new behaviour is one more test passing. Signed-off-by: Caio Marcelo de Oliveira Filho Reviewed-by: Artur Duque de Souza --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 28 +++++++++++++++------- src/gui/graphicsview/qgraphicsanchorlayout_p.h | 1 + .../tst_qgraphicsanchorlayout1.cpp | 2 -- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 485743e..260e8dc 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -1709,11 +1709,6 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( // they have a different logic for solveExpanding(). solveExpanding(trunkConstraints, trunkVariables); - // Propagate the new sizes down the simplified graph, ie. tell the - // group anchors to set their children anchors sizes. - for (int i = 0; i < trunkVariables.count(); ++i) - trunkVariables.at(i)->updateChildrenSizes(); - // Calculate and set the preferred and expanding sizes for the layout, // from the edge sizes that were calculated above. qreal pref(0.0); @@ -1756,9 +1751,6 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( ad->sizeAtExpanding = ad->expSize; ad->sizeAtMaximum = ad->maxSize; - // Propagate - ad->updateChildrenSizes(); - sizeHints[orientation][Qt::MinimumSize] = ad->sizeAtMinimum; sizeHints[orientation][Qt::PreferredSize] = ad->sizeAtPreferred; sizeHints[orientation][Qt::MaximumSize] = ad->sizeAtMaximum; @@ -1790,13 +1782,17 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( ad->sizeAtMinimum = ad->sizeAtPreferred; ad->sizeAtExpanding = ad->sizeAtPreferred; ad->sizeAtMaximum = ad->sizeAtPreferred; - ad->updateChildrenSizes(); } // Delete the constraints, we won't use them anymore. qDeleteAll(sizeHintConstraints); } } + + // Propagate the new sizes down the simplified graph, ie. tell the + // group anchors to set their children anchors sizes. + updateAnchorSizes(orientation); + graphHasConflicts[orientation] = !feasible; // Clean up our data structures. They are not needed anymore since @@ -1907,6 +1903,20 @@ void QGraphicsAnchorLayoutPrivate::constraintsFromPaths(Orientation orientation) /*! \internal +*/ +void QGraphicsAnchorLayoutPrivate::updateAnchorSizes(Orientation orientation) +{ + Graph &g = graph[orientation]; + const QList > &vertices = g.connections(); + + for (int i = 0; i < vertices.count(); ++i) { + AnchorData *ad = g.edgeData(vertices.at(i).first, vertices.at(i).second); + ad->updateChildrenSizes(); + } +} + +/*! + \internal Create LP constraints for each anchor based on its minimum and maximum sizes, as specified in its size hints diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 1d7b758..e045fbd 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -441,6 +441,7 @@ public: void setAnchorSizeHintsFromItems(Orientation orientation); void findPaths(Orientation orientation); void constraintsFromPaths(Orientation orientation); + void updateAnchorSizes(Orientation orientation); QList constraintsFromSizeHints(const QList &anchors); QList > getGraphParts(Orientation orientation); void identifyFloatItems(const QSet &visited, Orientation orientation); diff --git a/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp b/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp index 148b2c8..755d866 100644 --- a/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp +++ b/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp @@ -1711,8 +1711,6 @@ void tst_QGraphicsAnchorLayout1::testBasicLayout() // Validate for (int i = 0; i < result.count(); ++i) { - if (i == 1) - QEXPECT_FAIL("Two, mixed", "Works with simplification disabled.", Continue); const BasicLayoutTestResult item = result[i]; QCOMPARE(widgets[item.index]->geometry(), item.rect); } -- cgit v0.12 From aff8e7a24e5e8cc1f330a1b3c2947ba4d07d51ed Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Thu, 8 Oct 2009 20:09:21 -0300 Subject: QGAL: refactor calculateGraphs() method Create calculateTrunk() and calculateNonTrunk() methods, that calculate sizes for anchors in different parts of the simplified graph (using simplex when needed). Also fixes a minor leak when the nontrunk part is non-feasible. The old code left the loop leaving the contents of 'sizeHintConstraints' not allocated. Signed-off-by: Caio Marcelo de Oliveira Filho Reviewed-by: Artur Duque de Souza --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 161 ++++++++++++----------- src/gui/graphicsview/qgraphicsanchorlayout_p.h | 7 + 2 files changed, 93 insertions(+), 75 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 260e8dc..c9821ae 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -1600,7 +1600,8 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs() calculateGraphCacheDirty = 0; } -// ### remove me: +// ### Maybe getGraphParts could return the variables when traversing, at least +// for trunk... QList getVariables(QList constraints) { QSet variableSet; @@ -1664,8 +1665,7 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( // 2) The floating or semi-floating anchors (items) that are those which // are connected to only one (or none) of the layout sides, thus are not // influenced by the layout size. - QList > parts; - parts = getGraphParts(orientation); + QList > parts = getGraphParts(orientation); // Now run the simplex solver to calculate Minimum, Preferred and Maximum sizes // of the "trunk" set of constraints and variables. @@ -1675,49 +1675,82 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( // For minimum and maximum, use the path between the two layout sides as the // objective function. - - // Retrieve that path AnchorVertex *v = internalVertex(q, pickEdge(Qt::AnchorRight, orientation)); GraphPath trunkPath = graphPaths[orientation].value(v); + bool feasible = calculateTrunk(orientation, trunkPath, trunkConstraints, trunkVariables); + + // For the other parts that not the trunk, solve only for the preferred size + // that is the size they will remain at, since they are not stretched by the + // layout. + + // Skipping the first (trunk) + for (int i = 1; i < parts.count(); ++i) { + if (!feasible) + break; + + QList partConstraints = parts[i]; + QList partVariables = getVariables(partConstraints); + Q_ASSERT(!partVariables.isEmpty()); + feasible &= calculateNonTrunk(partConstraints, partVariables); + } + + // Propagate the new sizes down the simplified graph, ie. tell the + // group anchors to set their children anchors sizes. + updateAnchorSizes(orientation); + + graphHasConflicts[orientation] = !feasible; + + // Clean up our data structures. They are not needed anymore since + // distribution uses just interpolation. + qDeleteAll(constraints[orientation]); + constraints[orientation].clear(); + graphPaths[orientation].clear(); // ### +} + +/*! + \internal + + Calculate the sizes for all anchors which are part of the trunk. This works + on top of a (possibly) simplified graph. +*/ +bool QGraphicsAnchorLayoutPrivate::calculateTrunk(Orientation orientation, const GraphPath &path, + const QList &constraints, + const QList &variables) +{ bool feasible = true; - if (!trunkConstraints.isEmpty()) { -#if 0 - qDebug("Simplex used for trunk of %s", - orientation == Horizontal ? "Horizontal" : "Vertical"); -#endif + bool needsSimplex = !constraints.isEmpty(); -#ifdef QT_DEBUG - lastCalculationUsedSimplex[orientation] = true; +#if 0 + qDebug("Simplex %s for trunk of %s", needsSimplex ? "used" : "NOT used", + orientation == Horizontal ? "Horizontal" : "Vertical"); #endif - // Solve min and max size hints for trunk - qreal min, max; + if (needsSimplex) { - QList sizeHintConstraints = constraintsFromSizeHints(trunkVariables); - QList allTrunkConstraints = trunkConstraints + sizeHintConstraints; + QList sizeHintConstraints = constraintsFromSizeHints(variables); + QList allConstraints = constraints + sizeHintConstraints; - feasible = solveMinMax(allTrunkConstraints, trunkPath, &min, &max); + // Solve min and max size hints + qreal min, max; + feasible = solveMinMax(allConstraints, path, &min, &max); if (feasible) { - // Solve for preferred. The objective function is calculated from the constraints - // and variables internally. - solvePreferred(allTrunkConstraints, trunkVariables); + solvePreferred(allConstraints, variables); - // Solve for expanding. The objective function and the constraints from items - // are calculated internally. Note that we don't include the sizeHintConstraints, since - // they have a different logic for solveExpanding(). - solveExpanding(trunkConstraints, trunkVariables); + // Note that we don't include the sizeHintConstraints, since they + // have a different logic for solveExpanding(). + solveExpanding(constraints, variables); // 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) { + foreach (const AnchorData *ad, path.positives) { pref += ad->sizeAtPreferred; expanding += ad->sizeAtExpanding; } - foreach (const AnchorData *ad, trunkPath.negatives) { + foreach (const AnchorData *ad, path.negatives) { pref -= ad->sizeAtPreferred; expanding -= ad->sizeAtExpanding; } @@ -1731,21 +1764,12 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( qDeleteAll(sizeHintConstraints); } else { -#if 0 - qDebug("Simplex NOT used for trunk of %s", - orientation == Horizontal ? "Horizontal" : "Vertical"); -#endif - -#ifdef QT_DEBUG - lastCalculationUsedSimplex[orientation] = false; -#endif - // No Simplex is necessary because the path was simplified all the way to a single // anchor. - Q_ASSERT(trunkPath.positives.count() == 1); - Q_ASSERT(trunkPath.negatives.count() == 0); + Q_ASSERT(path.positives.count() == 1); + Q_ASSERT(path.negatives.count() == 0); - AnchorData *ad = trunkPath.positives.toList()[0]; + AnchorData *ad = path.positives.toList()[0]; ad->sizeAtMinimum = ad->minSize; ad->sizeAtPreferred = ad->prefSize; ad->sizeAtExpanding = ad->expSize; @@ -1757,49 +1781,36 @@ void QGraphicsAnchorLayoutPrivate::calculateGraphs( sizeAtExpanding[orientation] = ad->sizeAtExpanding; } - // For the other parts that not the trunk, solve only for the preferred size - // that is the size they will remain at, since they are not stretched by the - // layout. +#ifdef QT_DEBUG + lastCalculationUsedSimplex[orientation] = needsSimplex; +#endif - // Solve the other only for preferred, skip trunk - if (feasible) { - for (int i = 1; i < parts.count(); ++i) { - QList partConstraints = parts[i]; - QList partVariables = getVariables(partConstraints); - Q_ASSERT(!partVariables.isEmpty()); - - QList sizeHintConstraints = constraintsFromSizeHints(partVariables); - partConstraints += sizeHintConstraints; - feasible &= solvePreferred(partConstraints, partVariables); - if (!feasible) - break; + return feasible; +} - // Propagate size at preferred to other sizes. Semi-floats - // always will be in their sizeAtPreferred. - for (int j = 0; j < partVariables.count(); ++j) { - AnchorData *ad = partVariables[j]; - Q_ASSERT(ad); - ad->sizeAtMinimum = ad->sizeAtPreferred; - ad->sizeAtExpanding = ad->sizeAtPreferred; - ad->sizeAtMaximum = ad->sizeAtPreferred; - } +/*! + \internal +*/ +bool QGraphicsAnchorLayoutPrivate::calculateNonTrunk(const QList &constraints, + const QList &variables) +{ + QList sizeHintConstraints = constraintsFromSizeHints(variables); + bool feasible = solvePreferred(constraints + sizeHintConstraints, variables); - // Delete the constraints, we won't use them anymore. - qDeleteAll(sizeHintConstraints); + if (feasible) { + // Propagate size at preferred to other sizes. Semi-floats always will be + // in their sizeAtPreferred. + for (int j = 0; j < variables.count(); ++j) { + AnchorData *ad = variables[j]; + Q_ASSERT(ad); + ad->sizeAtMinimum = ad->sizeAtPreferred; + ad->sizeAtExpanding = ad->sizeAtPreferred; + ad->sizeAtMaximum = ad->sizeAtPreferred; } } - // Propagate the new sizes down the simplified graph, ie. tell the - // group anchors to set their children anchors sizes. - updateAnchorSizes(orientation); - - graphHasConflicts[orientation] = !feasible; - - // Clean up our data structures. They are not needed anymore since - // distribution uses just interpolation. - qDeleteAll(constraints[orientation]); - constraints[orientation].clear(); - graphPaths[orientation].clear(); // ### + qDeleteAll(sizeHintConstraints); + return feasible; } /*! diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index e045fbd..d96a035 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -438,6 +438,13 @@ public: void calculateGraphs(); void calculateGraphs(Orientation orientation); + + bool calculateTrunk(Orientation orientation, const GraphPath &trunkPath, + const QList &constraints, + const QList &variables); + bool calculateNonTrunk(const QList &constraints, + const QList &variables); + void setAnchorSizeHintsFromItems(Orientation orientation); void findPaths(Orientation orientation); void constraintsFromPaths(Orientation orientation); -- cgit v0.12 From 6a4d30b12baa85a223116d6629fa1e08e922d659 Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Tue, 13 Oct 2009 16:10:10 -0300 Subject: QGAL: refactor and document the simplification algorithm Refactor the simplifyGraphIteration() function. The aim was to make it more clear without changing too much the way it does stuff. Before it collected a list of candidates and then filtered that into sublists of same order, and after that removed the center edges from the borders. It also reversed the list if the direction wasn't forward, to pass it in forward order to simplifySequentialChunk() helper function. The refactored version - take in account the order when building the candidates, this avoids index manipulation; - try to calculate 'beforeSequence' and 'afterSequence' as it builds the candidates list; - make simplifySequentialChunk() aware of directions, now it deals internally with reversed direction sequences. This commits also adds explanations to trickier parts of the code. Signed-off-by: Caio Marcelo de Oliveira Filho Reviewed-by: Artur Duque de Souza Reviewed-by: Eduardo M. Fleury --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 324 ++++++++++++----------- 1 file changed, 165 insertions(+), 159 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index c9821ae..937ccfa 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -506,36 +506,46 @@ static bool simplifySequentialChunk(Graph *graph, const QVector &vertices, AnchorVertex *after) { - int i; + AnchorData *data = graph->edgeData(before, vertices.first()); + Q_ASSERT(data); + + const bool forward = (before == data->from); + QVector orderedVertices; + + if (forward) { + orderedVertices = vertices; + } else { + qSwap(before, after); + for (int i = vertices.count() - 1; i >= 0; --i) + orderedVertices.append(vertices.at(i)); + } + #if defined(QT_DEBUG) && 0 QString strVertices; - for (i = 0; i < vertices.count(); ++i) - strVertices += QString::fromAscii("%1 - ").arg(vertices.at(i)->toString()); + for (int i = 0; i < orderedVertices.count(); ++i) { + strVertices += QString::fromAscii("%1 - ").arg(orderedVertices.at(i)->toString()); + } QString strPath = QString::fromAscii("%1 - %2%3").arg(before->toString(), strVertices, after->toString()); qDebug("simplifying [%s] to [%s - %s]", qPrintable(strPath), qPrintable(before->toString()), qPrintable(after->toString())); #endif 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); - sequence->m_edges.append(data); + + for (int i = 0; i <= orderedVertices.count(); ++i) { + AnchorVertex *next = (i < orderedVertices.count()) ? orderedVertices.at(i) : after; + AnchorData *ad = graph->takeEdge(prev, next); + Q_ASSERT(ad); + sequence->m_edges.append(ad); prev = next; } - sequence->setVertices(vertices); + + sequence->setVertices(orderedVertices); 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 - if (data->from != vertices.last()) - qSwap(sequence->from, sequence->to); - // Note that since layout 'edges' can't be simplified away from // the graph, it's safe to assume that if there's a layout // 'edge', it'll be in the boundaries of the sequence. @@ -590,15 +600,6 @@ static bool simplifySequentialChunk(Graph *graph, 2. Go to (1) 3. Done - - * Gathering sequential anchors * - The algorithm walks the graph in depth-first order, and only collects vertices that has two - edges connected to it. If the vertex does not have two edges or if it is a layout edge, - it will take all the previously collected vertices and try to create a simplified sequential - anchor representing all the previously collected vertices. - Once the simplified anchor is inserted, the collected list is cleared in order to find the next - sequence to simplify. - Note that there are some catches to this that are not covered by the above explanation. */ void QGraphicsAnchorLayoutPrivate::simplifyGraph(Orientation orientation) { @@ -615,9 +616,7 @@ void QGraphicsAnchorLayoutPrivate::simplifyGraph(Orientation orientation) orientation == Horizontal ? "Horizontal" : "Vertical"); #endif - AnchorVertex *rootVertex = graph[orientation].rootVertex(); - - if (!rootVertex) + if (!graph[orientation].rootVertex()) return; bool dirty; @@ -626,164 +625,171 @@ void QGraphicsAnchorLayoutPrivate::simplifyGraph(Orientation orientation) } while (dirty); } +/*! + \internal + + One iteration of the simplification algorithm. Returns true if another iteration is needed. + + The algorithm walks the graph in depth-first order, and only collects vertices that has two + edges connected to it. If the vertex does not have two edges or if it is a layout edge, it + will take all the previously collected vertices and try to create a simplified sequential + anchor representing all the previously collected vertices. Once the simplified anchor is + inserted, the collected list is cleared in order to find the next sequence to simplify. + + Note that there are some catches to this that are not covered by the above explanation, see + the function comments for more details. +*/ bool QGraphicsAnchorLayoutPrivate::simplifyGraphIteration(QGraphicsAnchorLayoutPrivate::Orientation orientation) { Q_Q(QGraphicsAnchorLayout); Graph &g = graph[orientation]; - AnchorVertex *v = g.rootVertex(); QSet visited; - QStack stack; - stack.push(v); + QStack > stack; + stack.push(qMakePair(static_cast(0), g.rootVertex())); QVector candidates; + bool candidatesForward; const Qt::AnchorPoint centerEdge = pickEdge(Qt::AnchorHorizontalCenter, orientation); - const Qt::AnchorPoint layoutEdge = oppositeEdge(v->m_edge); - bool dirty = false; - - // walk depth-first. + // Walk depth-first, in the stack we store start of the candidate sequence (beforeSequence) + // and the vertex to be visited. while (!stack.isEmpty()) { - v = stack.pop(); - QList vertices = g.adjacentVertices(v); - const int count = vertices.count(); - bool endOfSequence = (v->m_item == q && v->m_edge == layoutEdge) || count != 2; - if (count == 2 && v->m_item != q) { - candidates.append(v); - if (visited.contains(vertices.first()) && visited.contains(vertices.last())) { - // in case of a cycle - endOfSequence = true; + QPair pair = stack.pop(); + AnchorVertex *beforeSequence = pair.first; + AnchorVertex *v = pair.second; + + // The basic idea is to determine whether we found an end of sequence, + // if that's the case, we stop adding vertices to the candidate list + // and do a simplification step. + // + // A vertex can trigger an end of sequence if + // (a) it is a layout vertex, we don't simplify away the layout vertices; + // (b) it does not have exactly 2 adjacents; + // (c) it will change the direction of the sequence; + // (d) its next adjacent is already visited (a cycle in the graph). + + const QList &adjacents = g.adjacentVertices(v); + const bool isLayoutVertex = v->m_item == q; + AnchorVertex *afterSequence = v; + bool endOfSequence = false; + + // + // Identify the end cases. + // + + // Identifies cases (a) and (b) + endOfSequence = isLayoutVertex || adjacents.count() != 2; + + if (!endOfSequence) { + // If this is the first vertice, determine what is the direction to use for this + // sequence. + if (candidates.isEmpty()) { + const AnchorData *data = g.edgeData(beforeSequence, v); + Q_ASSERT(data); + candidatesForward = (beforeSequence == data->from); } - } - if (endOfSequence && candidates.count() >= 1) { - int i; - AnchorVertex *afterSequence= 0; - AnchorVertex *beforeSequence = 0; - // find the items before and after the valid sequence - if (candidates.count() == 1) { - QList beforeAndAfterVertices = g.adjacentVertices(candidates.at(0)); - Q_ASSERT(beforeAndAfterVertices.count() == 2); - // Since we only have one vertex, we can pick - // any of the two vertices to become before/after. - afterSequence = beforeAndAfterVertices.last(); - beforeSequence = beforeAndAfterVertices.first(); - } else { - QList adjacentOfSecondLastVertex = g.adjacentVertices(candidates.last()); - Q_ASSERT(adjacentOfSecondLastVertex.count() == 2); - if (adjacentOfSecondLastVertex.first() == candidates.at(candidates.count() - 2)) - afterSequence = adjacentOfSecondLastVertex.last(); - else - afterSequence = adjacentOfSecondLastVertex.first(); - QList adjacentOfSecondVertex = g.adjacentVertices(candidates.first()); - Q_ASSERT(adjacentOfSecondVertex.count() == 2); - if (adjacentOfSecondVertex.first() == candidates.at(1)) - beforeSequence = adjacentOfSecondVertex.last(); - else - beforeSequence = adjacentOfSecondVertex.first(); + // This is a tricky part. We peek at the next vertex to find out + // + // - whether the edge from this vertex to the next vertex has the same direction; + // - whether we already visited the next vertex. + // + // Those are needed to identify (c) and (d). Note that unlike (a) and (b), we preempt + // the end of sequence by looking into the next vertex. + + // Peek at the next vertex + AnchorVertex *after; + if (candidates.isEmpty()) + after = (beforeSequence == adjacents.last() ? adjacents.first() : adjacents.last()); + else + after = (candidates.last() == adjacents.last() ? adjacents.first() : adjacents.last()); + + // ### At this point we assumed that candidates will not contain 'after', this may not hold + // when simplifying FLOATing anchors. + Q_ASSERT(!candidates.contains(after)); + + const AnchorData *data = g.edgeData(v, after); + Q_ASSERT(data); + const bool willChangeDirection = (candidatesForward != (v == data->from)); + const bool cycleFound = visited.contains(after); + + // Now cases (c) and (d)... + endOfSequence = willChangeDirection || cycleFound; + + if (endOfSequence) { + if (!willChangeDirection) { + // If the direction will not change, we can add the current vertex to the + // candidates list and we know that 'after' can be used as afterSequence. + candidates.append(v); + afterSequence = after; + } + } else { + // If it's not an end of sequence, then the vertex didn't trigger neither of the + // previously four cases, so it can be added to the candidates list. + candidates.append(v); } - // The complete path of the sequence to simplify is: beforeSequence, , afterSequence - // where beforeSequence and afterSequence are the endpoints where the anchor is inserted - // between. -#if defined(QT_DEBUG) && 0 - // ### DEBUG - QString strCandidates; - for (i = 0; i < candidates.count(); ++i) - strCandidates += QString::fromAscii("%1 - ").arg(candidates.at(i)->toString()); - QString strPath = QString::fromAscii("%1 - %2%3").arg(beforeSequence->toString(), strCandidates, afterSequence->toString()); - qDebug("candidate list for sequential simplification:\n[%s]", qPrintable(strPath)); -#endif + } - bool forward = true; - AnchorVertex *prev = beforeSequence; - int intervalFrom = 0; + // + // Add next non-visited vertices to the stack. + // + for (int i = 0; i < adjacents.count(); ++i) { + AnchorVertex *next = adjacents.at(i); + if (visited.contains(next)) + continue; - // Check for directionality (from). We don't want to destroy that information, - // thus we only combine anchors with the same direction. + // If current vertex is an end of sequence, and it'll reset the candidates list. So + // the next vertices will build candidates lists with the current vertex as 'before' + // vertex. If it's not an end of sequence, we keep the original 'before' vertex, + // since we are keeping the candidates list. + if (endOfSequence) + stack.push(qMakePair(v, next)); + else + stack.push(qMakePair(beforeSequence, next)); + } - // "i" is the index *including* the beforeSequence and afterSequence vertices. - for (i = 1; i <= candidates.count() + 1; ++i) { - bool atVertexAfter = i > candidates.count(); - AnchorVertex *v1 = atVertexAfter ? afterSequence : candidates.at(i - 1); - AnchorData *data = g.edgeData(prev, v1); - Q_ASSERT(data); - if (i == 1) { - forward = (prev == data->from ? true : false); - } else if (forward != (prev == data->from) || atVertexAfter) { - int intervalTo = i; - if (forward != (prev == data->from)) - --intervalTo; - - // intervalFrom and intervalTo should now be indices to the vertex before and - // after the sequential anchor. - if (intervalTo - intervalFrom >= 2) { - // simplify in the range [intervalFrom, intervalTo] - - // Trim off internal center anchors (Left-Center/Center-Right) from the - // start and the end of the sequence. We never want to simplify internal - // center anchors where there is an external anchor connected to the center. - AnchorVertex *intervalVertexFrom = intervalFrom == 0 ? beforeSequence : candidates.at(intervalFrom - 1); - int effectiveIntervalFrom = intervalFrom; - if (intervalVertexFrom->m_edge == centerEdge - && intervalVertexFrom->m_item == candidates.at(effectiveIntervalFrom)->m_item) { - ++effectiveIntervalFrom; - intervalVertexFrom = candidates.at(effectiveIntervalFrom - 1); - } - AnchorVertex *intervalVertexTo = intervalTo <= candidates.count() ? candidates.at(intervalTo - 1) : afterSequence; - int effectiveIntervalTo = intervalTo; - if (intervalVertexTo->m_edge == centerEdge - && intervalVertexTo->m_item == candidates.at(effectiveIntervalTo - 2)->m_item) { - --effectiveIntervalTo; - intervalVertexTo = candidates.at(effectiveIntervalTo - 1); - } - if (effectiveIntervalTo - effectiveIntervalFrom >= 2) { - QVector subCandidates; - if (forward) { - subCandidates = candidates.mid(effectiveIntervalFrom, effectiveIntervalTo - effectiveIntervalFrom - 1); - } else { - // reverse the order of the candidates. - qSwap(intervalVertexFrom, intervalVertexTo); - do { - ++effectiveIntervalFrom; - subCandidates.prepend(candidates.at(effectiveIntervalFrom - 1)); - } while (effectiveIntervalFrom < effectiveIntervalTo - 1); - } - if (simplifySequentialChunk(&g, intervalVertexFrom, subCandidates, intervalVertexTo)) { - dirty = true; - break; - } - // finished simplification of chunk with same direction - } - } - if (forward == (prev == data->from)) - --intervalTo; - intervalFrom = intervalTo; - - forward = !forward; - } - prev = v1; - } + visited.insert(v); - if (dirty) - break; - } + if (!endOfSequence || candidates.isEmpty()) + continue; + + // + // Create a sequence for (beforeSequence, candidates, afterSequence). + // - if (endOfSequence) - candidates.clear(); + // One restriction we have is to not simplify half of an anchor and let the other half + // unsimplified. So we remove center edges before and after the sequence. + if (beforeSequence->m_edge == centerEdge && beforeSequence->m_item == candidates.first()->m_item) { + beforeSequence = candidates.first(); + candidates.remove(0); - for (int i = 0; i < count; ++i) { - AnchorVertex *next = vertices.at(i); - if (next->m_item == q && next->m_edge == centerEdge) + // If there's not candidates to be simplified, leave. + if (candidates.isEmpty()) continue; - if (visited.contains(next)) + } + + if (afterSequence->m_edge == centerEdge && afterSequence->m_item == candidates.last()->m_item) { + afterSequence = candidates.last(); + candidates.remove(candidates.count() - 1); + + if (candidates.isEmpty()) continue; - stack.push(next); } - visited.insert(v); + // This function will remove the candidates from the graph and create one edge between + // beforeSequence and afterSequence. This function returns true if the sequential + // simplification also caused a parallel simplification to be created. In this case we end + // the iteration and start again (since all the visited state we have may be outdated). + if (simplifySequentialChunk(&g, beforeSequence, candidates, afterSequence)) + return true; + + // If there was no parallel simplification, we'll keep walking the graph. So we clear the + // candidates list to start again. + candidates.clear(); } - return dirty; + return false; } static void restoreSimplifiedAnchor(Graph &g, -- cgit v0.12 From 8ef83e60df0291ba2a36cc744e1f0c11f465f1e2 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Thu, 15 Oct 2009 18:45:13 +0200 Subject: Fixed a rare crash in qt_x11_enforce_cursor A QPointer was set to point to a QWidget by one of its children, during its deletion. This happens during the child deletion, and after the call to QObject::clearGuards(), which means that the QPointer becomes a dangling one. The fix ensures that qt_x11_enforce_cursor will not be called with a being-deleted QWidget. The included auto-test doesn't test anything, except that it doesn't crash. Reviewed-by: Olivier --- src/gui/kernel/qapplication.cpp | 5 ++++- tests/auto/qwidget/tst_qwidget.cpp | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index b990fe2..5476e36 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -2662,7 +2662,10 @@ void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave) { if (!isAlien(w)) break; if (w->testAttribute(Qt::WA_SetCursor)) { - parentOfLeavingCursor = w->parentWidget(); + QWidget *parent = w->parentWidget(); + while (parent && parent->d_func()->data.in_destructor) + parent = parent->parentWidget(); + parentOfLeavingCursor = parent; //continue looping, we need to find the downest alien widget with a cursor. // (downest on the screen) } diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index daeee3d..4cb9f72 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -69,6 +69,9 @@ #include #include +#include +#include + #include "../../shared/util.h" @@ -285,6 +288,7 @@ private slots: #ifdef Q_WS_X11 void minAndMaxSizeWithX11BypassWindowManagerHint(); void showHideShow(); + void clean_qt_x11_enforce_cursor(); #endif void compatibilityChildInsertedEvents(); @@ -6048,6 +6052,35 @@ void tst_QWidget::showHideShow() QVERIFY(w.gotExpectedMapNotify); } + +void tst_QWidget::clean_qt_x11_enforce_cursor() +{ + { + QWidget window; + QWidget *w = new QWidget(&window); + QWidget *child = new QWidget(w); + child->setAttribute(Qt::WA_SetCursor, true); + + window.show(); + QApplication::setActiveWindow(&window); + QTest::qWaitForWindowShown(&window); + QTest::qWait(100); + QCursor::setPos(window.geometry().center()); + QTest::qWait(100); + + child->setFocus(); + QApplication::processEvents(); + QTest::qWait(100); + + delete w; + } + + QGraphicsScene scene; + QLineEdit *edit = new QLineEdit; + scene.addWidget(edit); + + // If the test didn't crash, then it passed. +} #endif class EventRecorder : public QObject -- cgit v0.12 From db795de8e92da117070c45fb963273a6fa61c688 Mon Sep 17 00:00:00 2001 From: "Eduardo M. Fleury" Date: Thu, 15 Oct 2009 11:16:32 -0300 Subject: QGraphicsAnchorLayout: Mark expected failures in tests w/o simplification Some tests are expected to fail when run without simplification, ie. by setting the environment var QT_ANCHORLAYOUT_NO_SIMPLIFICATION. This commit adds QEXPECT_FAIL before those tests. In some cases the failures are random therefore we must disable the test instead. Signed-off-by: Eduardo M. Fleury Reviewed-by: Caio Marcelo de Oliveira Filho --- .../tst_qgraphicsanchorlayout.cpp | 91 ++++++++++++++++------ 1 file changed, 67 insertions(+), 24 deletions(-) diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index cef56b9..a51d2ab 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -49,6 +49,14 @@ class tst_QGraphicsAnchorLayout : public QObject { Q_OBJECT; +public: + tst_QGraphicsAnchorLayout() : QObject() { + hasSimplification = qgetenv("QT_ANCHORLAYOUT_NO_SIMPLIFICATION").isEmpty(); + } + +private: + bool hasSimplification; + private slots: void simple(); void simple_center(); @@ -185,8 +193,10 @@ void tst_QGraphicsAnchorLayout::simple() p.setLayout(l); p.adjustSize(); - QVERIFY(!usedSimplex(l, Qt::Horizontal)); - QVERIFY(!usedSimplex(l, Qt::Vertical)); + if (hasSimplification) { + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); + } } void tst_QGraphicsAnchorLayout::simple_center() @@ -226,8 +236,10 @@ void tst_QGraphicsAnchorLayout::simple_center() QSizeF layoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize); QCOMPARE(layoutMaximumSize, QSizeF(200, 20)); - QVERIFY(usedSimplex(l, Qt::Horizontal)); - QVERIFY(!usedSimplex(l, Qt::Vertical)); + if (hasSimplification) { + QVERIFY(usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); + } delete p; } @@ -326,8 +338,10 @@ void tst_QGraphicsAnchorLayout::layoutDirection() QCOMPARE(checkReverseDirection(p), true); - QVERIFY(usedSimplex(l, Qt::Horizontal)); - QVERIFY(!usedSimplex(l, Qt::Vertical)); + if (hasSimplification) { + QVERIFY(usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); + } delete p; delete view; @@ -417,8 +431,10 @@ void tst_QGraphicsAnchorLayout::diagonal() QCOMPARE(e->geometry(), QRectF(100.0, 200.0, 75.0, 100.0)); QCOMPARE(p.size(), testA); - QVERIFY(usedSimplex(l, Qt::Horizontal)); - QVERIFY(!usedSimplex(l, Qt::Vertical)); + if (hasSimplification) { + QVERIFY(usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); + } QCOMPARE(checkReverseDirection(&p), true); @@ -496,6 +512,9 @@ void tst_QGraphicsAnchorLayout::parallel() QCOMPARE(f->geometry(), QRectF(350, 500, 100, 100)); QCOMPARE(p.size(), layoutMinimumSize); + if (!hasSimplification) + return; + p.resize(layoutPreferredSize); QCOMPARE(a->geometry(), QRectF(0, 0, 150, 100)); QCOMPARE(b->geometry(), QRectF(150, 100, 150, 100)); @@ -565,8 +584,10 @@ void tst_QGraphicsAnchorLayout::parallel2() p.resize(layoutMaximumSize); QCOMPARE(p.size(), layoutMaximumSize); - QVERIFY(!usedSimplex(l, Qt::Horizontal)); - QVERIFY(!usedSimplex(l, Qt::Vertical)); + if (hasSimplification) { + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); + } } void tst_QGraphicsAnchorLayout::snake() @@ -758,6 +779,8 @@ void tst_QGraphicsAnchorLayout::fairDistribution() QCOMPARE(layoutMaximumSize, QSizeF(300.0, 400.0)); p.resize(layoutMinimumSize); + if (!hasSimplification) + QEXPECT_FAIL("", "Without simplification there is no fair distribution.", Abort); QCOMPARE(a->geometry(), QRectF(0.0, 0.0, 20.0, 100.0)); QCOMPARE(b->geometry(), QRectF(20.0, 100.0, 20.0, 100.0)); QCOMPARE(c->geometry(), QRectF(40.0, 200.0, 20.0, 100.0)); @@ -778,8 +801,10 @@ void tst_QGraphicsAnchorLayout::fairDistribution() QCOMPARE(d->geometry(), QRectF(0.0, 300.0, 300.0, 100.0)); QCOMPARE(p.size(), layoutMaximumSize); - QVERIFY(!usedSimplex(l, Qt::Horizontal)); - QVERIFY(!usedSimplex(l, Qt::Vertical)); + if (hasSimplification) { + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); + } } void tst_QGraphicsAnchorLayout::fairDistributionOppositeDirections() @@ -836,6 +861,9 @@ void tst_QGraphicsAnchorLayout::fairDistributionOppositeDirections() QCOMPARE(layoutPreferredSize, QSizeF(220.0, 500.0)); QCOMPARE(layoutMaximumSize, QSizeF(400.0, 500.0)); + if (!hasSimplification) + return; + p.resize(layoutMinimumSize); QCOMPARE(a->size(), b->size()); QCOMPARE(a->size(), c->size()); @@ -922,8 +950,10 @@ void tst_QGraphicsAnchorLayout::proportionalPreferred() QCOMPARE(c->size().width(), 14 * factor); QCOMPARE(p.size(), QSizeF(12, 400)); - QVERIFY(!usedSimplex(l, Qt::Horizontal)); - QVERIFY(!usedSimplex(l, Qt::Vertical)); + if (hasSimplification) { + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); + } } void tst_QGraphicsAnchorLayout::example() @@ -1008,8 +1038,10 @@ void tst_QGraphicsAnchorLayout::example() QCOMPARE(b->size(), d->size()); QCOMPARE(f->size(), g->size()); - QVERIFY(usedSimplex(l, Qt::Horizontal)); - QVERIFY(usedSimplex(l, Qt::Vertical)); + if (hasSimplification) { + QVERIFY(usedSimplex(l, Qt::Horizontal)); + QVERIFY(usedSimplex(l, Qt::Vertical)); + } } void tst_QGraphicsAnchorLayout::setSpacing() @@ -1331,8 +1363,10 @@ void tst_QGraphicsAnchorLayout::sizePolicy() QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(100, 100)); QCOMPARE(l->effectiveSizeHint(Qt::MaximumSize), QSizeF(100, 100)); - QVERIFY(!usedSimplex(l, Qt::Horizontal)); - QVERIFY(!usedSimplex(l, Qt::Vertical)); + if (hasSimplification) { + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); + } delete p; delete view; @@ -1425,8 +1459,10 @@ void tst_QGraphicsAnchorLayout::expandingSequence() QSizeF layoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize); QCOMPARE(layoutMaximumSize.width(), qreal(200)); - QVERIFY(!usedSimplex(l, Qt::Horizontal)); - QVERIFY(!usedSimplex(l, Qt::Vertical)); + if (hasSimplification) { + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); + } } void tst_QGraphicsAnchorLayout::expandingSequenceFairDistribution() @@ -1488,8 +1524,10 @@ void tst_QGraphicsAnchorLayout::expandingSequenceFairDistribution() QSizeF layoutMaximumSize = l->effectiveSizeHint(Qt::MaximumSize); QCOMPARE(layoutMaximumSize.width(), qreal(400)); - QVERIFY(!usedSimplex(l, Qt::Horizontal)); - QVERIFY(!usedSimplex(l, Qt::Vertical)); + if (hasSimplification) { + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); + } // 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 @@ -1514,8 +1552,10 @@ void tst_QGraphicsAnchorLayout::expandingSequenceFairDistribution() QCOMPARE(c->geometry().size(), pref); QCOMPARE(d->geometry().size(), pref + QSizeF(50, 0)); - QVERIFY(!usedSimplex(l, Qt::Horizontal)); - QVERIFY(!usedSimplex(l, Qt::Vertical)); + if (hasSimplification) { + QVERIFY(!usedSimplex(l, Qt::Horizontal)); + QVERIFY(!usedSimplex(l, Qt::Vertical)); + } } void tst_QGraphicsAnchorLayout::expandingParallel() @@ -1672,6 +1712,9 @@ void tst_QGraphicsAnchorLayout::infiniteMaxSizes() QCOMPARE(c->geometry(), QRectF(100, 0, 50, 10)); QCOMPARE(d->geometry(), QRectF(150, 0, 50, 10)); + if (!hasSimplification) + QEXPECT_FAIL("", "Without simplification there is no fair distribution.", Abort); + p.resize(1000, 10); QCOMPARE(a->geometry(), QRectF(0, 0, 450, 10)); QCOMPARE(b->geometry(), QRectF(450, 0, 50, 10)); -- cgit v0.12 From c5609a9247b965ea57db98607ad498a216e179d6 Mon Sep 17 00:00:00 2001 From: "Eduardo M. Fleury" Date: Thu, 15 Oct 2009 15:25:03 -0300 Subject: QGAL: Add anchor layout vs nested linear layouts benchmark Adding a benchmark to compare the use of three nested linear layouts versus the use of a single anchor layout. We also test two different anchor layout setups to achieve the same visual result. In the first one we use the addCornerAnchors API that, in the way it was used, adds reduntant anchors. The second uses the basic addAnchor API to create only the essential anchors. Currently the first setup is way slower than the second. That happens because the redundant anchors create "zero-sized knots" in the graph, that are not eaten by the simplification algorithm, thus requiring the usage of the simplex solver. Zero-sized knots are groups of three or more vertices that are linked together by zero-sized anchors. In pratice, these vertices represent the same place in the graph (remember, the distance between them is zero), but to the simplification mechanism, they look like three distinct ones. Signed-off-by: Eduardo M. Fleury Reviewed-by: Caio Marcelo de Oliveira Filho --- .../tst_qgraphicsanchorlayout.cpp | 111 +++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/tests/benchmarks/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/benchmarks/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index 000ab6e..43dff93 100644 --- a/tests/benchmarks/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/benchmarks/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -41,6 +41,7 @@ #include #include +#include #include #include @@ -54,6 +55,9 @@ public: private slots: void s60_hard_complex_data(); void s60_hard_complex(); + void linearVsAnchorNested_data(); + void linearVsAnchorNested(); + }; @@ -192,6 +196,113 @@ void tst_QGraphicsAnchorLayout::s60_hard_complex() } } +void tst_QGraphicsAnchorLayout::linearVsAnchorNested_data() +{ + QTest::addColumn("whichLayout"); + QTest::newRow("LinearLayout") + << 0; + QTest::newRow("AnchorLayout setup with null-anchors knot") + << 1; + QTest::newRow("AnchorLayout setup easy to simplificate") + << 2; +} + +void tst_QGraphicsAnchorLayout::linearVsAnchorNested() +{ + QFETCH(int, whichLayout); + + QSizeF min(10, 10); + QSizeF pref(80, 80); + QSizeF max(150, 150); + + 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"); + + QGraphicsLayout *layout; + + if (whichLayout == 0) { + QGraphicsLinearLayout *linear1 = new QGraphicsLinearLayout; + QGraphicsLinearLayout *linear2 = new QGraphicsLinearLayout(Qt::Vertical); + QGraphicsLinearLayout *linear3 = new QGraphicsLinearLayout; + + linear1->addItem(a); + linear1->addItem(linear2); + linear2->addItem(b); + linear2->addItem(linear3); + linear3->addItem(c); + linear3->addItem(d); + + layout = linear1; + } else if (whichLayout == 1) { + QGraphicsAnchorLayout *anchor = new QGraphicsAnchorLayout; + + // A + anchor->addCornerAnchors(a, Qt::TopLeftCorner, anchor, Qt::TopLeftCorner); + anchor->addCornerAnchors(a, Qt::TopRightCorner, b, Qt::TopLeftCorner); + anchor->addCornerAnchors(a, Qt::BottomLeftCorner, anchor, Qt::BottomLeftCorner); + anchor->addCornerAnchors(a, Qt::BottomRightCorner, c, Qt::BottomLeftCorner); + + // B + anchor->addCornerAnchors(b, Qt::TopRightCorner, anchor, Qt::TopRightCorner); + anchor->addCornerAnchors(b, Qt::BottomLeftCorner, c, Qt::TopLeftCorner); + anchor->addCornerAnchors(b, Qt::BottomRightCorner, d, Qt::TopRightCorner); + + // C + anchor->addCornerAnchors(c, Qt::TopRightCorner, d, Qt::TopLeftCorner); + anchor->addCornerAnchors(c, Qt::BottomRightCorner, d, Qt::BottomLeftCorner); + + // D + anchor->addCornerAnchors(d, Qt::BottomRightCorner, anchor, Qt::BottomRightCorner); + + layout = anchor; + } else { + QGraphicsAnchorLayout *anchor = new QGraphicsAnchorLayout; + + // A + anchor->addAnchor(a, Qt::AnchorLeft, anchor, Qt::AnchorLeft); + anchor->addAnchors(a, anchor, Qt::Vertical); + anchor->addAnchor(a, Qt::AnchorRight, b, Qt::AnchorLeft); + anchor->addAnchor(a, Qt::AnchorRight, c, Qt::AnchorLeft); + + // B + anchor->addAnchor(b, Qt::AnchorTop, anchor, Qt::AnchorTop); + anchor->addAnchor(b, Qt::AnchorRight, anchor, Qt::AnchorRight); + anchor->addAnchor(b, Qt::AnchorBottom, c, Qt::AnchorTop); + anchor->addAnchor(b, Qt::AnchorBottom, d, Qt::AnchorTop); + + // C + anchor->addAnchor(c, Qt::AnchorRight, d, Qt::AnchorLeft); + anchor->addAnchor(c, Qt::AnchorBottom, anchor, Qt::AnchorBottom); + + // D + anchor->addAnchor(d, Qt::AnchorRight, anchor, Qt::AnchorRight); + anchor->addAnchor(d, Qt::AnchorBottom, anchor, Qt::AnchorBottom); + + layout = anchor; + } + + QSizeF sizeHint; + // warm up instruction cache + layout->invalidate(); + sizeHint = layout->effectiveSizeHint(Qt::PreferredSize); + + // ...then measure... + QBENCHMARK { + // To ensure that all sizeHints caches are invalidated in + // the LinearLayout setup, we must call updateGeometry on the + // children. If we didn't, only the top level layout would be + // re-calculated. + static_cast(a)->updateGeometry(); + static_cast(b)->updateGeometry(); + static_cast(c)->updateGeometry(); + static_cast(d)->updateGeometry(); + layout->invalidate(); + sizeHint = layout->effectiveSizeHint(Qt::PreferredSize); + } +} + QTEST_MAIN(tst_QGraphicsAnchorLayout) #include "tst_qgraphicsanchorlayout.moc" -- cgit v0.12 From ea52aef43acf862a51ea5b2eb65fa2ad60e5590f Mon Sep 17 00:00:00 2001 From: Jesus Sanchez-Palencia Date: Wed, 14 Oct 2009 16:56:54 -0300 Subject: QGraphicsAnchorLayout: Adding two benchmarks on LinearLayout vs AnchorLayout cases Signed-off-by: Jesus Sanchez-Palencia Reviewed-by: Eduardo M. Fleury --- .../tst_qgraphicsanchorlayout.cpp | 127 ++++++++++++++++++++- 1 file changed, 126 insertions(+), 1 deletion(-) diff --git a/tests/benchmarks/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/benchmarks/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index 43dff93..81064d7 100644 --- a/tests/benchmarks/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/benchmarks/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -55,9 +55,12 @@ public: private slots: void s60_hard_complex_data(); void s60_hard_complex(); + void linearVsAnchorSizeHints_data(); + void linearVsAnchorSizeHints(); + void linearVsAnchorSetGeometry_data(); + void linearVsAnchorSetGeometry(); void linearVsAnchorNested_data(); void linearVsAnchorNested(); - }; @@ -196,6 +199,128 @@ void tst_QGraphicsAnchorLayout::s60_hard_complex() } } +static QGraphicsLayout* createLayouts(int whichLayout) +{ + QSizeF min(0, 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"); + + QGraphicsLayout *l; + if (whichLayout == 0) { + l = new QGraphicsLinearLayout; + QGraphicsLinearLayout *linear = static_cast(l); + linear->setContentsMargins(0, 0, 0, 0); + + linear->addItem(a); + linear->addItem(b); + linear->addItem(c); + linear->addItem(d); + } else { + l = new QGraphicsAnchorLayout; + QGraphicsAnchorLayout *anchor = static_cast(l); + anchor->setContentsMargins(0, 0, 0, 0); + + // Horizontal + setAnchor(anchor, anchor, Qt::AnchorLeft, a, Qt::AnchorLeft, 0); + setAnchor(anchor, a, Qt::AnchorRight, b, Qt::AnchorLeft, 0); + setAnchor(anchor, b, Qt::AnchorRight, c, Qt::AnchorLeft, 0); + setAnchor(anchor, c, Qt::AnchorRight, d, Qt::AnchorLeft, 0); + setAnchor(anchor, d, Qt::AnchorRight, anchor, Qt::AnchorRight, 0); + + // Vertical + anchor->addAnchors(anchor, a, Qt::Vertical); + anchor->addAnchors(anchor, b, Qt::Vertical); + anchor->addAnchors(anchor, c, Qt::Vertical); + anchor->addAnchors(anchor, d, Qt::Vertical); + } + + return l; +} + +void tst_QGraphicsAnchorLayout::linearVsAnchorSizeHints_data() +{ + QTest::addColumn("whichLayout"); + QTest::addColumn("whichSizeHint"); + + QTest::newRow("QGraphicsLinearLayout::minimum") + << 0 << int(Qt::MinimumSize); + QTest::newRow("QGraphicsLinearLayout::preferred") + << 0 << int(Qt::PreferredSize); + QTest::newRow("QGraphicsLinearLayout::maximum") + << 0 << int(Qt::MaximumSize); + QTest::newRow("QGraphicsLinearLayout::noSizeHint") + << 0 << -1; + + QTest::newRow("QGraphicsAnchorLayout::minimum") + << 1 << int(Qt::MinimumSize); + QTest::newRow("QGraphicsAnchorLayout::preferred") + << 1 << int(Qt::PreferredSize); + QTest::newRow("QGraphicsAnchorLayout::maximum") + << 1 << int(Qt::MaximumSize); + QTest::newRow("QGraphicsAnchorLayout::noSizeHint") + << 1 << -1; +} + +void tst_QGraphicsAnchorLayout::linearVsAnchorSizeHints() +{ + QFETCH(int, whichSizeHint); + QFETCH(int, whichLayout); + + QGraphicsLayout *l = createLayouts(whichLayout); + + QSizeF sizeHint; + // warm up instruction cache + l->invalidate(); + sizeHint = l->effectiveSizeHint((Qt::SizeHint)whichSizeHint); + // ...then measure... + + QBENCHMARK { + l->invalidate(); + sizeHint = l->effectiveSizeHint((Qt::SizeHint)whichSizeHint); + } +} + +void tst_QGraphicsAnchorLayout::linearVsAnchorSetGeometry_data() +{ + QTest::addColumn("whichLayout"); + + QTest::newRow("QGraphicsLinearLayout") + << 0; + QTest::newRow("QGraphicsAnchorLayout") + << 1; +} + +void tst_QGraphicsAnchorLayout::linearVsAnchorSetGeometry() +{ + QFETCH(int, whichLayout); + + QGraphicsLayout *l = createLayouts(whichLayout); + + QRectF sizeHint; + qreal maxWidth; + qreal increment; + // warm up instruction cache + l->invalidate(); + sizeHint.setSize(l->effectiveSizeHint(Qt::MinimumSize)); + maxWidth = l->effectiveSizeHint(Qt::MaximumSize).width(); + increment = (maxWidth - sizeHint.width()) / 100; + l->setGeometry(sizeHint); + // ...then measure... + + QBENCHMARK { + l->invalidate(); + for (qreal width = sizeHint.width(); width <= maxWidth; width += increment) { + sizeHint.setWidth(width); + l->setGeometry(sizeHint); + } + } +} + void tst_QGraphicsAnchorLayout::linearVsAnchorNested_data() { QTest::addColumn("whichLayout"); -- cgit v0.12 From 7644b352297e9fd1ee271421e9ce8b7256946b12 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 16 Oct 2009 09:34:38 +0200 Subject: Fixed typo in qtableview.cpp. Auto-test included. Will timeout on fail. Reviewed-by: Alexis --- src/gui/itemviews/qtableview.cpp | 2 +- tests/auto/qtableview/tst_qtableview.cpp | 35 +++++++++++++++++++++++++++----- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp index a610b73..2a937f1 100644 --- a/src/gui/itemviews/qtableview.cpp +++ b/src/gui/itemviews/qtableview.cpp @@ -1599,7 +1599,7 @@ QModelIndex QTableView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifi break; visualColumn = right + 1; if (visualRow == 0) { - wrapped == true; + wrapped = true; visualRow = bottom; } else { --visualRow; diff --git a/tests/auto/qtableview/tst_qtableview.cpp b/tests/auto/qtableview/tst_qtableview.cpp index d75cfa7..d8110e1 100644 --- a/tests/auto/qtableview/tst_qtableview.cpp +++ b/tests/auto/qtableview/tst_qtableview.cpp @@ -1195,6 +1195,13 @@ void tst_QTableView::moveCursorStrikesBack_data() << 0 << 5 << (IntList() << int(QtTestTableView::MoveNext)) << 1 << 0; + QTest::newRow("Last column disabled. Task QTBUG-3878") << -1 << -1 + << IntList() + << (IntList() << 6) + << QRect() + << 1 << 0 << (IntList() << int(QtTestTableView::MovePrevious)) + << 0 << 5; + QTest::newRow("Span, anchor column hidden") << -1 << 1 << IntList() << IntList() @@ -1250,6 +1257,24 @@ void tst_QTableView::moveCursorStrikesBack_data() << QRect(1, 2, 2, 3) << 5 << 2 << (IntList() << int(QtTestTableView::MoveUp) << int(QtTestTableView::MoveUp)) << 1 << 2; + + IntList fullList; + for (int i = 0; i < 7; ++i) + fullList << i; + + QTest::newRow("All disabled, wrap forward. Timeout => FAIL") << -1 << -1 + << fullList + << fullList + << QRect() + << 1 << 0 << (IntList() << int(QtTestTableView::MoveNext)) + << 1 << 0; + + QTest::newRow("All disabled, wrap backwards. Timeout => FAIL") << -1 << -1 + << fullList + << fullList + << QRect() + << 1 << 0 << (IntList() << int(QtTestTableView::MovePrevious)) + << 1 << 0; } void tst_QTableView::moveCursorStrikesBack() @@ -1272,11 +1297,6 @@ void tst_QTableView::moveCursorStrikesBack() view.hideRow(hideRow); view.hideColumn(hideColumn); - foreach (int row, disableRows) - model.disableRow(row); - foreach (int column, disableColumns) - model.disableColumn(column); - if (span.height() && span.width()) view.setSpan(span.top(), span.left(), span.height(), span.width()); view.show(); @@ -1284,6 +1304,11 @@ void tst_QTableView::moveCursorStrikesBack() QModelIndex index = model.index(startRow, startColumn); view.setCurrentIndex(index); + foreach (int row, disableRows) + model.disableRow(row); + foreach (int column, disableColumns) + model.disableColumn(column); + int newRow = -1; int newColumn = -1; foreach (int cursorMoveAction, cursorMoveActions) { -- cgit v0.12 From 7e5724b7d4632899af2e84856dd7d6f2a1771ee0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Fri, 16 Oct 2009 11:56:08 +0200 Subject: Make sure that the anchor layout autotests pass in release configuration The problem was that lastCalculationUsedSimplex was only compiled in debug mode. The autotests run in release, so it did not compile. Reviewed-by: alexis --- src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 2 +- src/gui/graphicsview/qgraphicsanchorlayout_p.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index c9821ae..5a531f5 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -1781,7 +1781,7 @@ bool QGraphicsAnchorLayoutPrivate::calculateTrunk(Orientation orientation, const sizeAtExpanding[orientation] = ad->sizeAtExpanding; } -#ifdef QT_DEBUG +#if defined(QT_DEBUG) || defined(Q_AUTOTEST_EXPORT) lastCalculationUsedSimplex[orientation] = needsSimplex; #endif diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index d96a035..3a23677 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -523,7 +523,7 @@ public: bool graphHasConflicts[2]; QSet m_floatItems[2]; -#ifdef QT_DEBUG +#if defined(QT_DEBUG) || defined(Q_AUTOTEST_EXPORT) bool lastCalculationUsedSimplex[2]; #endif -- cgit v0.12 From 6018d7a21a1ba336a59e3cda161b7cfeb144b4b5 Mon Sep 17 00:00:00 2001 From: Frans Englich Date: Fri, 16 Oct 2009 16:31:27 +0200 Subject: Kill warning, simplify code. Reviewed-by: TrustMe --- src/3rdparty/phonon/mmf/audiooutput.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/3rdparty/phonon/mmf/audiooutput.cpp b/src/3rdparty/phonon/mmf/audiooutput.cpp index 5a00f60..bb0e5bc 100644 --- a/src/3rdparty/phonon/mmf/audiooutput.cpp +++ b/src/3rdparty/phonon/mmf/audiooutput.cpp @@ -102,15 +102,17 @@ bool MMF::AudioOutput::activateOnMediaObject(MediaObject *mo) QHash MMF::AudioOutput::audioOutputDescription(int index) { + QHash retval; + if (index == AudioOutputDeviceID) { QHash retval; retval.insert("name", QCoreApplication::translate("Phonon::MMF", "Audio Output")); retval.insert("description", QCoreApplication::translate("Phonon::MMF", "The audio output device")); retval.insert("available", true); - - return retval; } + + return retval; } QT_END_NAMESPACE -- cgit v0.12 From 299fd2c5d3c901890c0bc2c36c4b5f48d46859dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Fri, 16 Oct 2009 17:31:10 +0200 Subject: API addition: Make it possible to set the size policy of an anchor. After this commit, when you modify the spacing of an anchor you are effectively modifying the preferred size of the anchor, since all anchors (except internal ones) have their minimumSizeHint to 0 and maximumSizeHint to QWIDGETSIZE_MAX. I also changed the sizeHintsFromItem to be more generic so that I could use it for anchors. (Thus, it was renamed to "internalSizeHints"). It now only takes care of setting the min/pref/exp/maxSize of AnchorData based on the anchor/item size hint and their size policies. As a consequence of all of this, setFixedSize changed behaviour and became setPreferredSize (since setSpacing is basically setPreferredSize). The implementation of that now only sets the prefSize. The patch also has an unrelated fix for IgnoreFlag, where it will (again) return the minimumSize for sizeHint(Qt::PreferredSize) instead of the maximumSize. This was to be more consistent with qgridlayoutengine.cpp. The docs are not very clear on this behaviour unfortunately. This API change has been discussed. Reviewed-by: alexis --- src/gui/graphicsview/qgraphicsanchorlayout.cpp | 17 ++++ src/gui/graphicsview/qgraphicsanchorlayout.h | 2 + src/gui/graphicsview/qgraphicsanchorlayout_p.cpp | 109 ++++++++++++--------- src/gui/graphicsview/qgraphicsanchorlayout_p.h | 14 ++- .../tst_qgraphicsanchorlayout.cpp | 56 ++++++++--- 5 files changed, 130 insertions(+), 68 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.cpp b/src/gui/graphicsview/qgraphicsanchorlayout.cpp index 9f4a19b..c39e8a6 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout.cpp @@ -118,6 +118,23 @@ QGraphicsAnchor::~QGraphicsAnchor() } /*! + Sets the size policy of the anchor to \a policy. +*/ +void QGraphicsAnchor::setSizePolicy(QSizePolicy::Policy policy) +{ + Q_D(QGraphicsAnchor); + d->setSizePolicy(policy); +} +/*! + Returns the size policy of the anchor. The default size policy is QSizePolicy::Fixed +*/ +QSizePolicy::Policy QGraphicsAnchor::sizePolicy() const +{ + Q_D(const QGraphicsAnchor); + return d->sizePolicy; +} + +/*! \property QGraphicsAnchor::spacing \brief the space between items in the QGraphicsAnchorLayout. diff --git a/src/gui/graphicsview/qgraphicsanchorlayout.h b/src/gui/graphicsview/qgraphicsanchorlayout.h index 99dbf92..f09ac43 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout.h @@ -65,6 +65,8 @@ class Q_GUI_EXPORT QGraphicsAnchor : public QObject public: void setSpacing(qreal spacing); void unsetSpacing(); + void setSizePolicy(QSizePolicy::Policy policy); + QSizePolicy::Policy sizePolicy() const; qreal spacing() const; ~QGraphicsAnchor(); private: diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index e1db939..8c8c303 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -53,7 +53,8 @@ QT_BEGIN_NAMESPACE QGraphicsAnchorPrivate::QGraphicsAnchorPrivate(int version) - : QObjectPrivate(version), layoutPrivate(0), data(0) + : QObjectPrivate(version), layoutPrivate(0), data(0), + sizePolicy(QSizePolicy::Fixed) { } @@ -62,6 +63,14 @@ QGraphicsAnchorPrivate::~QGraphicsAnchorPrivate() layoutPrivate->removeAnchor(data->from, data->to); } +void QGraphicsAnchorPrivate::setSizePolicy(QSizePolicy::Policy policy) +{ + if (sizePolicy != policy) { + sizePolicy = policy; + layoutPrivate->q_func()->invalidate(); + } +} + void QGraphicsAnchorPrivate::setSpacing(qreal value) { if (data) { @@ -92,28 +101,11 @@ qreal QGraphicsAnchorPrivate::spacing() const } -static void sizeHintsFromItem(QGraphicsLayoutItem *item, - const QGraphicsAnchorLayoutPrivate::Orientation orient, - qreal *minSize, qreal *prefSize, - qreal *expSize, qreal *maxSize) +static void internalSizeHints(QSizePolicy::Policy policy, + qreal minSizeHint, qreal prefSizeHint, qreal maxSizeHint, + 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. // @@ -139,7 +131,7 @@ static void sizeHintsFromItem(QGraphicsLayoutItem *item, // Note that these two initializations are affected by the previous flags if (policy & QSizePolicy::IgnoreFlag) - *prefSize = *maxSize; + *prefSize = *minSize; else *prefSize = prefSizeHint; @@ -153,38 +145,63 @@ void AnchorData::refreshSizeHints(qreal effectiveSpacing) { const bool isInternalAnchor = from->m_item == to->m_item; + QSizePolicy::Policy policy; + qreal minSizeHint; + qreal prefSizeHint; + qreal maxSizeHint; + if (isInternalAnchor) { const QGraphicsAnchorLayoutPrivate::Orientation orient = QGraphicsAnchorLayoutPrivate::edgeOrientation(from->m_edge); + const Qt::AnchorPoint centerEdge = + QGraphicsAnchorLayoutPrivate::pickEdge(Qt::AnchorHorizontalCenter, orient); + bool hasCenter = (from->m_edge == centerEdge || to->m_edge == centerEdge); if (isLayoutAnchor) { minSize = 0; prefSize = 0; expSize = 0; maxSize = QWIDGETSIZE_MAX; + if (hasCenter) + maxSize /= 2; + return; } else { - QGraphicsLayoutItem *item = from->m_item; - sizeHintsFromItem(item, orient, &minSize, &prefSize, &expSize, &maxSize); - } - const Qt::AnchorPoint centerEdge = - QGraphicsAnchorLayoutPrivate::pickEdge(Qt::AnchorHorizontalCenter, orient); - bool hasCenter = (from->m_edge == centerEdge || to->m_edge == centerEdge); + QGraphicsLayoutItem *item = from->m_item; + 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(); + } - if (hasCenter) { - minSize /= 2; - prefSize /= 2; - expSize /= 2; - maxSize /= 2; + if (hasCenter) { + minSizeHint /= 2; + prefSizeHint /= 2; + maxSizeHint /= 2; + } } - - } else if (!hasSize) { - // Anchor has no size defined, use given default information - minSize = effectiveSpacing; - prefSize = effectiveSpacing; - expSize = effectiveSpacing; - maxSize = effectiveSpacing; + } else { + Q_ASSERT(graphicsAnchor); + policy = graphicsAnchor->sizePolicy(); + minSizeHint = 0; + if (hasSize) { + // One can only configure the preferred size of a normal anchor. Their minimum and + // maximum "size hints" are always 0 and QWIDGETSIZE_MAX, correspondingly. However, + // their effective size hints might be narrowed down due to their size policies. + prefSizeHint = prefSize; + } else { + prefSizeHint = effectiveSpacing; + } + maxSizeHint = QWIDGETSIZE_MAX; } + internalSizeHints(policy, minSizeHint, prefSizeHint, maxSizeHint, + &minSize, &prefSize, &expSize, &maxSize); // Set the anchor effective sizes to preferred. // @@ -1191,18 +1208,18 @@ QGraphicsAnchor *QGraphicsAnchorLayoutPrivate::addAnchor(QGraphicsLayoutItem *fi || secondItem == q || pickEdge(firstEdge, Horizontal) == Qt::AnchorHorizontalCenter || oppositeEdge(firstEdge) != secondEdge) { - data->setFixedSize(0); + data->setPreferredSize(0); } else { data->unsetSize(); } addAnchor_helper(firstItem, firstEdge, secondItem, secondEdge, data); } else if (*spacing >= 0) { - data->setFixedSize(*spacing); + data->setPreferredSize(*spacing); addAnchor_helper(firstItem, firstEdge, secondItem, secondEdge, data); } else { - data->setFixedSize(-*spacing); + data->setPreferredSize(-*spacing); addAnchor_helper(secondItem, secondEdge, firstItem, firstEdge, data); } @@ -1389,9 +1406,9 @@ void QGraphicsAnchorLayoutPrivate::setAnchorSize(AnchorData *data, const qreal * // positive by definition. // "negative spacing" is handled by inverting the standard item order. if (*anchorSize >= 0) { - data->setFixedSize(*anchorSize); + data->setPreferredSize(*anchorSize); } else { - data->setFixedSize(-*anchorSize); + data->setPreferredSize(-*anchorSize); qSwap(data->from, data->to); } } else { diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.h b/src/gui/graphicsview/qgraphicsanchorlayout_p.h index 3a23677..d45c004 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.h +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.h @@ -169,16 +169,9 @@ struct AnchorData : public QSimplexVariable { QString name; #endif - inline void setFixedSize(qreal size) + inline void setPreferredSize(qreal size) { - minSize = size; prefSize = size; - expSize = size; - maxSize = size; - sizeAtMinimum = size; - sizeAtPreferred = size; - sizeAtExpanding = size; - sizeAtMaximum = size; hasSize = true; } @@ -316,8 +309,11 @@ public: void unsetSpacing(); qreal spacing() const; + void setSizePolicy(QSizePolicy::Policy policy); + QGraphicsAnchorLayoutPrivate *layoutPrivate; AnchorData *data; + QSizePolicy::Policy sizePolicy; }; @@ -528,6 +524,8 @@ public: #endif uint calculateGraphCacheDirty : 1; + + friend class QGraphicsAnchorPrivate; }; QT_END_NAMESPACE diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index cce7b4c..7b87969 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -1296,19 +1296,8 @@ void tst_QGraphicsAnchorLayout::sizePolicy() l->setSpacing(0); l->setContentsMargins(0, 0, 0, 0); - // horizontal - QGraphicsAnchor *anchor = l->addAnchor(l, Qt::AnchorLeft, w1, Qt::AnchorLeft); - anchor->setSpacing(0); - - anchor = l->addAnchor(w1, Qt::AnchorRight, l, Qt::AnchorRight); - anchor->setSpacing(0); - - // vertical - anchor = l->addAnchor(l, Qt::AnchorTop, w1, Qt::AnchorTop); - anchor->setSpacing(0); - - anchor = l->addAnchor(w1, Qt::AnchorBottom, l, Qt::AnchorBottom); - anchor->setSpacing(0); + // horizontal and vertical + l->addAnchors(l, w1); QGraphicsWidget *p = new QGraphicsWidget; p->setLayout(l); @@ -1358,9 +1347,48 @@ void tst_QGraphicsAnchorLayout::sizePolicy() w1->adjustSize(); QCOMPARE(l->effectiveSizeHint(Qt::MinimumSize), QSizeF(0, 0)); - QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(100, 100)); + QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(0, 0)); QCOMPARE(l->effectiveSizeHint(Qt::MaximumSize), QSizeF(100, 100)); + // Anchor size policies + w1->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + QGraphicsAnchor *anchor = l->anchor(l, Qt::AnchorLeft, w1, Qt::AnchorLeft); + anchor->setSpacing(10); + + // QSizePolicy::Minimum + anchor->setSizePolicy(QSizePolicy::Minimum); + QApplication::processEvents(); + + QCOMPARE(l->effectiveSizeHint(Qt::MinimumSize), QSizeF(60, 50)); + QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(60, 50)); + // The layout has a maximum size of QWIDGETSIZE_MAX, so the result won't exceed that value. + QCOMPARE(l->effectiveSizeHint(Qt::MaximumSize), QSizeF(QWIDGETSIZE_MAX, 50)); + + // QSizePolicy::Preferred + anchor->setSizePolicy(QSizePolicy::Preferred); + QApplication::processEvents(); + + QCOMPARE(l->effectiveSizeHint(Qt::MinimumSize), QSizeF(50, 50)); + QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(60, 50)); + // The layout has a maximum size of QWIDGETSIZE_MAX, so the result won't exceed that value. + QCOMPARE(l->effectiveSizeHint(Qt::MaximumSize), QSizeF(QWIDGETSIZE_MAX, 50)); + + // QSizePolicy::Maximum + anchor->setSizePolicy(QSizePolicy::Maximum); + QApplication::processEvents(); + + QCOMPARE(l->effectiveSizeHint(Qt::MinimumSize), QSizeF(50, 50)); + QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(60, 50)); + QCOMPARE(l->effectiveSizeHint(Qt::MaximumSize), QSizeF(60, 50)); + + // QSizePolicy::Ignored + anchor->setSizePolicy(QSizePolicy::Ignored); + QApplication::processEvents(); + + QCOMPARE(l->effectiveSizeHint(Qt::MinimumSize), QSizeF(50, 50)); + QCOMPARE(l->effectiveSizeHint(Qt::PreferredSize), QSizeF(50, 50)); + QCOMPARE(l->effectiveSizeHint(Qt::MaximumSize), QSizeF(QWIDGETSIZE_MAX, 50)); + if (hasSimplification) { QVERIFY(!usedSimplex(l, Qt::Horizontal)); QVERIFY(!usedSimplex(l, Qt::Vertical)); -- cgit v0.12 From 6f20e48d946fa3c90215f6affe5aa490559a6971 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Mon, 19 Oct 2009 09:25:12 +0200 Subject: Whitespace cleanup. --- src/gui/graphicsview/qgraphicsgridlayout.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsgridlayout.cpp b/src/gui/graphicsview/qgraphicsgridlayout.cpp index d1d91db..eef4e45 100644 --- a/src/gui/graphicsview/qgraphicsgridlayout.cpp +++ b/src/gui/graphicsview/qgraphicsgridlayout.cpp @@ -63,7 +63,7 @@ You can access each item in the layout by calling count() and itemAt(). Calling removeAt() will remove an item from the layout, without destroying it. - + \sa QGraphicsLinearLayout, QGraphicsWidget */ @@ -89,7 +89,7 @@ public: QLayoutStyleInfo styleInfo() const; QGridLayoutEngine engine; -#ifdef QT_DEBUG +#ifdef QT_DEBUG void dump(int indent) const; #endif }; @@ -121,7 +121,7 @@ QGraphicsGridLayout::~QGraphicsGridLayout() for (int i = count() - 1; i >= 0; --i) { QGraphicsLayoutItem *item = itemAt(i); // The following lines can be removed, but this removes the item - // from the layout more efficiently than the implementation of + // from the layout more efficiently than the implementation of // ~QGraphicsLayoutItem. removeAt(i); if (item) { @@ -141,18 +141,18 @@ void QGraphicsGridLayout::addItem(QGraphicsLayoutItem *item, int row, int column { Q_D(QGraphicsGridLayout); if (row < 0 || column < 0) { - qWarning("QGraphicsGridLayout::addItem: invalid row/column: %d", - row < 0 ? row : column); - return; + qWarning("QGraphicsGridLayout::addItem: invalid row/column: %d", + row < 0 ? row : column); + return; } if (columnSpan < 1 || rowSpan < 1) { - qWarning("QGraphicsGridLayout::addItem: invalid row span/column span: %d", - rowSpan < 1 ? rowSpan : columnSpan); - return; + qWarning("QGraphicsGridLayout::addItem: invalid row span/column span: %d", + rowSpan < 1 ? rowSpan : columnSpan); + return; } if (!item) { - qWarning("QGraphicsGridLayout::addItem: cannot add null item"); - return; + qWarning("QGraphicsGridLayout::addItem: cannot add null item"); + return; } d->addChildLayoutItem(item); @@ -647,5 +647,5 @@ QSizePolicy::ControlTypes QGraphicsGridLayout::controlTypes(LayoutSide side) con #endif QT_END_NAMESPACE - -#endif //QT_NO_GRAPHICSVIEW + +#endif //QT_NO_GRAPHICSVIEW -- cgit v0.12 From 856efef9bf87e0b7e5ed6ad2ccb225e294321888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Mon, 19 Oct 2009 09:39:30 +0200 Subject: Do not loop forever if we are adding the layout itself to the layout. Reviewed-by: alexis --- src/gui/graphicsview/qgraphicsgridlayout.cpp | 4 ++++ src/gui/graphicsview/qgraphicslinearlayout.cpp | 4 ++++ tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp | 11 +++++++++++ .../auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp | 11 +++++++++++ 4 files changed, 30 insertions(+) diff --git a/src/gui/graphicsview/qgraphicsgridlayout.cpp b/src/gui/graphicsview/qgraphicsgridlayout.cpp index eef4e45..9a8dba0 100644 --- a/src/gui/graphicsview/qgraphicsgridlayout.cpp +++ b/src/gui/graphicsview/qgraphicsgridlayout.cpp @@ -154,6 +154,10 @@ void QGraphicsGridLayout::addItem(QGraphicsLayoutItem *item, int row, int column qWarning("QGraphicsGridLayout::addItem: cannot add null item"); return; } + if (item == this) { + qWarning("QGraphicsGridLayout::addItem: cannot insert itself"); + return; + } d->addChildLayoutItem(item); diff --git a/src/gui/graphicsview/qgraphicslinearlayout.cpp b/src/gui/graphicsview/qgraphicslinearlayout.cpp index 0aa68df..7ff7c9b 100644 --- a/src/gui/graphicsview/qgraphicslinearlayout.cpp +++ b/src/gui/graphicsview/qgraphicslinearlayout.cpp @@ -272,6 +272,10 @@ void QGraphicsLinearLayout::insertItem(int index, QGraphicsLayoutItem *item) qWarning("QGraphicsLinearLayout::insertItem: cannot insert null item"); return; } + if (item == this) { + qWarning("QGraphicsLinearLayout::insertItem: cannot insert itself"); + return; + } d->addChildLayoutItem(item); Q_ASSERT(item); diff --git a/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp b/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp index 554292f..e33c7b6 100644 --- a/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp +++ b/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp @@ -104,6 +104,7 @@ private slots: void defaultStretchFactors(); void geometries_data(); void geometries(); + void avoidRecursionInInsertItem(); void task236367_maxSizeHint(); }; @@ -2081,6 +2082,16 @@ void tst_QGraphicsGridLayout::geometries() delete widget; } +void tst_QGraphicsGridLayout::avoidRecursionInInsertItem() +{ + QGraphicsWidget window(0, Qt::Window); + QGraphicsGridLayout *layout = new QGraphicsGridLayout(&window); + QCOMPARE(layout->count(), 0); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsGridLayout::addItem: cannot insert itself"); + layout->addItem(layout, 0, 0); + QCOMPARE(layout->count(), 0); +} + void tst_QGraphicsGridLayout::task236367_maxSizeHint() { QGraphicsWidget *widget = new QGraphicsWidget; diff --git a/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp b/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp index 8e7bb45..546f92d 100644 --- a/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp +++ b/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp @@ -101,6 +101,7 @@ private slots: void updateGeometry(); void layoutDirection(); void removeLayout(); + void avoidRecursionInInsertItem(); // Task specific tests void task218400_insertStretchCrash(); @@ -1432,6 +1433,16 @@ void tst_QGraphicsLinearLayout::removeLayout() QCOMPARE(pushButton->geometry(), r2); } +void tst_QGraphicsLinearLayout::avoidRecursionInInsertItem() +{ + QGraphicsWidget window(0, Qt::Window); + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(&window); + QCOMPARE(layout->count(), 0); + QTest::ignoreMessage(QtWarningMsg, "QGraphicsLinearLayout::insertItem: cannot insert itself"); + layout->insertItem(0, layout); + QCOMPARE(layout->count(), 0); +} + void tst_QGraphicsLinearLayout::task218400_insertStretchCrash() { QGraphicsScene *scene = new QGraphicsScene; -- cgit v0.12 From f9d36789b4f2565f342f22d62a5106e5d5ca3389 Mon Sep 17 00:00:00 2001 From: Frans Englich Date: Mon, 19 Oct 2009 12:04:57 +0200 Subject: Does not disable full screen when end of video playlist is reached. Tested on Symbian and Windows(DS9). Task-number: QTBUG-4869 Reviewed-by: Gareth Stockwell --- demos/qmediaplayer/mediaplayer.cpp | 3 +++ src/3rdparty/phonon/mmf/mmf_videoplayer.cpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/demos/qmediaplayer/mediaplayer.cpp b/demos/qmediaplayer/mediaplayer.cpp index baac236..e1ceb0e 100644 --- a/demos/qmediaplayer/mediaplayer.cpp +++ b/demos/qmediaplayer/mediaplayer.cpp @@ -367,6 +367,9 @@ void MediaPlayer::stateChanged(Phonon::State newstate, Phonon::State oldstate) case Phonon::PausedState: case Phonon::StoppedState: playButton->setIcon(playIcon); + + m_videoWidget->setFullScreen(false); + if (m_MediaObject.currentSource().type() != Phonon::MediaSource::Invalid){ playButton->setEnabled(true); rewindButton->setEnabled(true); diff --git a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp index a93aca0..d1d2337 100644 --- a/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp +++ b/src/3rdparty/phonon/mmf/mmf_videoplayer.cpp @@ -300,8 +300,8 @@ void MMF::VideoPlayer::MvpuoPlayComplete(TInt aError) TRACE_CONTEXT(VideoPlayer::MvpuoPlayComplete, EVideoApi) TRACE_ENTRY("state %d error %d", state(), aError); - // TODO Q_UNUSED(aError); // suppress warnings in release builds + changeState(StoppedState); TRACE_EXIT_0(); } -- cgit v0.12 From 2633931653757decd93dd3939c09f5e07203da1c Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Mon, 19 Oct 2009 11:59:20 +0200 Subject: Fix a bug affecting keyboard navigation in the table view Reviewed-by: thierry Reviewed-by: pierre --- src/gui/itemviews/qlistview.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp index 243f542..1d9b6e0 100644 --- a/src/gui/itemviews/qlistview.cpp +++ b/src/gui/itemviews/qlistview.cpp @@ -1105,13 +1105,13 @@ QModelIndex QListView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie ++row; if (row >= rowCount) return QModelIndex(); - return d->model->index(row, 0, d->root); + return d->model->index(row, d->column, d->root); } const QRect initialRect = rectForIndex(current); QRect rect = initialRect; if (rect.isEmpty()) { - return d->model->index(0, 0, d->root); + return d->model->index(0, d->column, d->root); } if (d->gridSize().isValid()) rect.setSize(d->gridSize()); -- cgit v0.12 From 93550050f4fe4f411bfbd80d7b30ff5bc8a20df7 Mon Sep 17 00:00:00 2001 From: Pierre Rossi Date: Mon, 19 Oct 2009 21:37:45 +0200 Subject: add the autotest for the QListView::setModelColumn bug sha1 of the fix: 2633931653757decd93dd3939c09f5e07203da1c --- tests/auto/qlistview/tst_qlistview.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/auto/qlistview/tst_qlistview.cpp b/tests/auto/qlistview/tst_qlistview.cpp index 7599ce6a06..3ee6889 100644 --- a/tests/auto/qlistview/tst_qlistview.cpp +++ b/tests/auto/qlistview/tst_qlistview.cpp @@ -116,6 +116,7 @@ private slots: void keyboardSearch(); void shiftSelectionWithNonUniformItemSizes(); void clickOnViewportClearsSelection(); + void task262152_setModelColumnNavigate(); }; // Testing get/set functions @@ -1767,6 +1768,29 @@ void tst_QListView::clickOnViewportClearsSelection() } +void tst_QListView::task262152_setModelColumnNavigate() +{ + QListView view; + QStandardItemModel model(3,2); + model.setItem(0,1,new QStandardItem("[0,1]")); + model.setItem(1,1,new QStandardItem("[1,1]")); + model.setItem(2,1,new QStandardItem("[2,1]")); + + view.setModel(&model); + view.setModelColumn(1); + + view.show(); + QTest::qWait(30); + QTest::keyClick(&view, Qt::Key_Down); + QTest::qWait(10); + QCOMPARE(view.currentIndex(), model.index(1,1)); + QTest::keyClick(&view, Qt::Key_Down); + QTest::qWait(10); + QCOMPARE(view.currentIndex(), model.index(2,1)); + +} + + QTEST_MAIN(tst_QListView) #include "tst_qlistview.moc" -- cgit v0.12 From 420be4ee3d98c093c71cc840192138da6b5e61d2 Mon Sep 17 00:00:00 2001 From: Sarah Smith Date: Tue, 20 Oct 2009 11:53:30 +1000 Subject: Fix bug QTBUG-4848 Make the shapeText function return numGlyphs properly - its not always the same as length of string. Task-number: QTBUG-4848 Reviewed-by: Rhys Weatherley --- src/gui/text/qfontengine_mac.mm | 14 +++++++--- src/gui/text/qtextengine_mac.cpp | 9 +++---- tests/auto/qlabel/qlabel.pro | 21 +++++---------- tests/auto/qlabel/tst_qlabel.cpp | 58 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 78 insertions(+), 24 deletions(-) diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index d11083f..8ce437d 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -830,7 +830,6 @@ static OSStatus atsuPostLayoutCallback(ATSULayoutOperationSelector selector, ATS surrogates += (str[i].unicode() >= 0xd800 && str[i].unicode() < 0xdc00 && str[i+1].unicode() >= 0xdc00 && str[i+1].unicode() < 0xe000); } - Q_ASSERT(*nfo->numGlyphs == item->length - surrogates); #endif for (nextCharStop = item->from; nextCharStop < item->from + item->length; ++nextCharStop) if (item->charAttributes[nextCharStop].charStop) @@ -856,10 +855,13 @@ static OSStatus atsuPostLayoutCallback(ATSULayoutOperationSelector selector, ATS QFixed xAdvance = FixedToQFixed(layoutData[glyphIdx + 1].realPos - layoutData[glyphIdx].realPos); if (glyphId != 0xffff || i == 0) { - nfo->glyphs->glyphs[i] = (glyphId & 0x00ffffff) | (fontIdx << 24); + if (i < nfo->glyphs->numGlyphs) + { + nfo->glyphs->glyphs[i] = (glyphId & 0x00ffffff) | (fontIdx << 24); - nfo->glyphs->advances_y[i] = yAdvance; - nfo->glyphs->advances_x[i] = xAdvance; + nfo->glyphs->advances_y[i] = yAdvance; + nfo->glyphs->advances_x[i] = xAdvance; + } } else { // ATSUI gives us 0xffff as glyph id at the index in the glyph array for // a character position that maps to a ligtature. Such a glyph id does not @@ -1029,6 +1031,8 @@ bool QFontEngineMacMulti::stringToCMapInternal(const QChar *str, int len, QGlyph nfo.flags = flags; nfo.shaperItem = shaperItem; + int prevNumGlyphs = *nglyphs; + QVarLengthArray mappedFonts(len); for (int i = 0; i < len; ++i) mappedFonts[i] = 0; @@ -1140,6 +1144,8 @@ bool QFontEngineMacMulti::stringToCMapInternal(const QChar *str, int len, QGlyph } ATSUClearLayoutCache(textLayout, kATSUFromTextBeginning); + if (prevNumGlyphs < *nfo.numGlyphs) + return false; return true; } diff --git a/src/gui/text/qtextengine_mac.cpp b/src/gui/text/qtextengine_mac.cpp index 4f20094..e101830 100644 --- a/src/gui/text/qtextengine_mac.cpp +++ b/src/gui/text/qtextengine_mac.cpp @@ -50,7 +50,6 @@ static void heuristicSetGlyphAttributes(const QChar *uc, int length, QGlyphLayou { // ### zeroWidth and justification are missing here!!!!! - Q_ASSERT(num_glyphs <= length); Q_UNUSED(num_glyphs); // qDebug("QScriptEngine::heuristicSetGlyphAttributes, num_glyphs=%d", item->num_glyphs); @@ -596,7 +595,7 @@ void QTextEngine::shapeTextMac(int item) const } while (true) { - ensureSpace(num_glyphs); + ensureSpace(num_glyphs); num_glyphs = layoutData->glyphLayout.numGlyphs - layoutData->used; QGlyphLayout g = availableGlyphs(&si); @@ -611,9 +610,9 @@ void QTextEngine::shapeTextMac(int item) const log_clusters, attributes())) { - heuristicSetGlyphAttributes(str, len, &g, log_clusters, num_glyphs); - break; - } + heuristicSetGlyphAttributes(str, len, &g, log_clusters, num_glyphs); + break; + } } si.num_glyphs = num_glyphs; diff --git a/tests/auto/qlabel/qlabel.pro b/tests/auto/qlabel/qlabel.pro index 6d55c13..297f868 100644 --- a/tests/auto/qlabel/qlabel.pro +++ b/tests/auto/qlabel/qlabel.pro @@ -1,19 +1,10 @@ load(qttest_p4) -SOURCES += tst_qlabel.cpp - -wince*:{ - DEFINES += SRCDIR=\\\"\\\" -} else:!symbian { - DEFINES += SRCDIR=\\\"$$PWD/\\\" -} - -wince*|symbian { - addFiles.sources = *.png testdata +SOURCES += tst_qlabel.cpp +wince*::DEFINES += SRCDIR=\\\"\\\" +else:!symbian:DEFINES += SRCDIR=\\\"$$PWD/\\\" +wince*|symbian { + addFiles.sources = *.png \ + testdata addFiles.path = . DEPLOYMENT += addFiles } - - - - - diff --git a/tests/auto/qlabel/tst_qlabel.cpp b/tests/auto/qlabel/tst_qlabel.cpp index dd03ef3..9eae9c9 100644 --- a/tests/auto/qlabel/tst_qlabel.cpp +++ b/tests/auto/qlabel/tst_qlabel.cpp @@ -50,6 +50,7 @@ #include #include #include +#include //TESTED_CLASS= //TESTED_FILES= @@ -112,6 +113,9 @@ private slots: void task226479_movieResize(); void emptyPixmap(); + void unicodeText_data(); + void unicodeText(); + private: QLabel *testWidget; QPointer test_box; @@ -451,5 +455,59 @@ void tst_QLabel::emptyPixmap() QCOMPARE(label1.sizeHint(), label4.sizeHint()); } +/** + Test for QTBUG-4848 - unicode data corrupting QLabel display +*/ +void tst_QLabel::unicodeText_data() +{ + QTest::addColumn("text"); + QTest::addColumn("languageName"); + + /* + The "glass" phrase in Thai was the initial report for bug QTBUG-4848, was + originally found on http://www.columbia.edu/kermit/utf8.html. + + The phrase is from an internet tradition regarding a striking phrase + that is translated into many different languages. The utf8 strings + below were generated by using http://translate.google.com. + + The glass phrase in Thai contains the ้ว character which manifests bug + QTBUG-4848 + + The last long phrase is an excerpt from Churchills "on the beaches" + speech, also translated using http://translate.google.com. + */ + + QTest::newRow("english") << QString::fromUtf8("I can eat glass and it doesn't hurt me.") << QString("english"); + QTest::newRow("thai") << QString::fromUtf8("ฉันจะกินแก้วและไม่เจ็บฉัน") << QString("thai"); + QTest::newRow("chinese") << QString::fromUtf8("我可以吃玻璃,并没有伤害我。") << QString("chinese"); + QTest::newRow("arabic") << QString::fromUtf8("أستطيع أكل الزجاج ، وأنه لا يؤذيني.") << QString("arabic"); + QTest::newRow("russian") << QString::fromUtf8("Я могу есть стекло, и не больно.") << QString("russian"); + QTest::newRow("korean") << QString::fromUtf8("유리를 먹을 수있는, 그리고 그게 날 다치게하지 않습니다.") << QString("korean"); + QTest::newRow("greek") << QString::fromUtf8("Μπορώ να φάτε γυαλί και δεν μου κάνει κακό.") << QString("greek"); + QTest::newRow("german") << QString::fromUtf8("Ich kann Glas essen und es macht mich nicht heiß.") << QString("german"); + + QTest::newRow("thai_long") << QString::fromUtf8("เราจะต่อสู้ในทะเลและมหาสมุทร. เราจะต่อสู้ด้วยความมั่นใจเติบโตและความเจริญเติบโตในอากาศเราจะปกป้องเกาะของเราค่าใช้จ่ายใดๆอาจ." + "เราจะต่อสู้บนชายหาดเราจะต่อสู้ในบริเวณเชื่อมโยงไปถึงเราจะต่อสู้ในช่องและในถนนที่เราจะต่อสู้ในภูเขานั้นเราจะไม่ยอม.") + << QString("thai_long"); +} + +void tst_QLabel::unicodeText() +{ + const QString testDataPath("testdata/unicodeText"); + QFETCH(QString, text); + QFETCH(QString, languageName); + QFrame frame; + QVBoxLayout *layout = new QVBoxLayout(); + QLabel *label = new QLabel(text, &frame); + layout->addWidget(label); + layout->setMargin(8); + frame.setLayout(layout); + frame.show(); + QTest::qWaitForWindowShown(&frame); + QVERIFY(frame.isVisible()); // was successfully sized and shown + testWidget->show(); +} + QTEST_MAIN(tst_QLabel) #include "tst_qlabel.moc" -- cgit v0.12 From 31fefc7cc9dc01be244b362ada1c1b2f8aad7c47 Mon Sep 17 00:00:00 2001 From: Julian de Bhal Date: Tue, 20 Oct 2009 12:32:19 +1000 Subject: Fix dangling shader manager pointers The QGLEngineShaderManager pointers in QGLCustomShaderStagePrivate have been changed to QPointers to prevent the QGLPixmapFilters in QGL2PaintEngineEx from dereferencing the QGLEngineShaderManager after it is destroyed. Reviewed-by: Rhys Weatherley --- src/opengl/gl2paintengineex/qglcustomshaderstage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengl/gl2paintengineex/qglcustomshaderstage.cpp b/src/opengl/gl2paintengineex/qglcustomshaderstage.cpp index 24606bc..ab2026c 100644 --- a/src/opengl/gl2paintengineex/qglcustomshaderstage.cpp +++ b/src/opengl/gl2paintengineex/qglcustomshaderstage.cpp @@ -52,7 +52,7 @@ public: QGLCustomShaderStagePrivate() : m_manager(0) {} - QGLEngineShaderManager* m_manager; + QPointer m_manager; QByteArray m_source; }; -- cgit v0.12 From f38eb1b6edf8f6d758899c8ca4a4bae2d7eb4b92 Mon Sep 17 00:00:00 2001 From: Bill King Date: Tue, 20 Oct 2009 13:51:06 +1000 Subject: Fix now invalid ExpectFail. The bug causing this fail is now fixed, so remove the expectfails. --- tests/auto/qsqlquery/tst_qsqlquery.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/auto/qsqlquery/tst_qsqlquery.cpp b/tests/auto/qsqlquery/tst_qsqlquery.cpp index 546c105..98030d1 100644 --- a/tests/auto/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/qsqlquery/tst_qsqlquery.cpp @@ -194,7 +194,6 @@ private slots: void sqlServerReturn0_data() { generic_data(); } void sqlServerReturn0(); - private: // returns all database connections void generic_data(const QString &engine=QString()); @@ -510,9 +509,7 @@ void tst_QSqlQuery::mysqlOutValues() QVERIFY_SQL( q, exec( "create procedure " + qTableName( "qtestproc" ) + " () " "BEGIN select * from " + qTableName( "qtest" ) + " order by id; END" ) ); QVERIFY_SQL( q, exec( "call " + qTableName( "qtestproc" ) + "()" ) ); - QEXPECT_FAIL("", "There's a mysql bug that means only selects think they return data when running in prepared mode", Continue); QVERIFY_SQL( q, next() ); - QEXPECT_FAIL("", "There's a mysql bug that means only selects think they return data when running in prepared mode", Continue); QCOMPARE( q.value( 1 ).toString(), QString( "VarChar1" ) ); QVERIFY_SQL( q, exec( "drop procedure " + qTableName( "qtestproc" ) ) ); -- cgit v0.12 From 04648b44f0784223122a782320d0b09b5c1e9497 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Tue, 20 Oct 2009 16:46:46 +1000 Subject: Remove unnecessary PowerVR helper functions The cross-process memory sharing code never really worked in the way we needed it to - so remove it until something better comes along. Reviewed-by: trustme --- .../gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.c | 60 ---------------------- .../gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.h | 15 ------ 2 files changed, 75 deletions(-) diff --git a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.c b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.c index c1b655a..17345a9 100644 --- a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.c +++ b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.c @@ -828,63 +828,3 @@ void pvrQwsSetSwapFunction drawable->swapFunction = func; drawable->userData = userData; } - -unsigned long pvrQwsGetMemoryId(PvrQwsDrawable *drawable) -{ - unsigned long addr; - unsigned long start; - unsigned long end; - unsigned long off; - unsigned long offset; - FILE *file; - char buffer[BUFSIZ]; - char flags[16]; - - if (!drawable->backBuffersValid) - return 0; - addr = (unsigned long) - (drawable->backBuffers[drawable->currentBackBuffer]->pBase); - - /* Search /proc/self/maps for the memory region that contains "addr". - The file offset for that memory region is the identifier we need */ - file = fopen("/proc/self/maps", "r"); - if (!file) { - perror("/proc/self/maps"); - return 0; - } - offset = 0; - while (fgets(buffer, sizeof(buffer), file)) { - if (sscanf(buffer, "%lx-%lx %s %lx", - &start, &end, flags, &off) < 4) - continue; - if (start <= addr && addr < end) { - offset = off; - break; - } - } - fclose(file); - return offset; -} - -void *pvrQwsMapMemory(unsigned long id, int size) -{ - void *addr; - int fd = open("/dev/pvrsrv", O_RDWR, 0); - if (fd < 0) { - perror("/dev/pvrsrv"); - return 0; - } - addr = mmap(0, (size_t)size, PROT_READ | PROT_WRITE, - MAP_SHARED, fd, (off_t)id); - if (addr == (void *)(-1)) { - perror("mmap pvr memory region"); - addr = 0; - } - close(fd); - return addr; -} - -void pvrQwsUnmapMemory(void *addr, int size) -{ - munmap(addr, size); -} diff --git a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.h b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.h index b9e035f..55e0310 100644 --- a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.h +++ b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.h @@ -162,21 +162,6 @@ int pvrQwsSwapBuffers(PvrQwsDrawable *drawable, int repaintOnly); void pvrQwsSetSwapFunction (PvrQwsDrawable *drawable, PvrQwsSwapFunction func, void *userData); -/* Get a memory identifier for the indicated drawable's buffer. - The identifier can be passed to another process and then - passed to pvrQwsMapMemory() to map the drawable's buffer into - the other process's address space. Returns zero if the - memory identifier could not be determined. This should only - be used for pixmap drawables */ -unsigned long pvrQwsGetMemoryId(PvrQwsDrawable *drawable); - -/* Map the memory buffer of a foreign application's drawable, as - indicated by "id" and "size". Returns null if the map failed */ -void *pvrQwsMapMemory(unsigned long id, int size); - -/* Unmap the memory obtained from pvrQwsMapMemory() */ -void pvrQwsUnmapMemory(void *addr, int size); - #ifdef __cplusplus }; #endif -- cgit v0.12 From 5b82db6e59aee775a5acc477d6e9dac9c453876d Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Sun, 18 Oct 2009 18:02:00 +0200 Subject: Cocoa: modal window reappears on screen after reactivating app If you close a modal window, then activate different app, then activate app again, the window will pop non-modal in front. This patch makes sure that when we hide a window, we point to the next window to receive keyboard focus. Rev-By: MortenS --- src/gui/kernel/qwidget_mac.mm | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index c966aa3..05c6a5b 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -305,6 +305,8 @@ bool qt_mac_insideKeyWindow(const QWidget *w) { #ifdef QT_MAC_USE_COCOA return [[reinterpret_cast(w->winId()) window] isKeyWindow]; +#else + Q_UNUSED(w); #endif return false; } @@ -3301,7 +3303,11 @@ void QWidgetPrivate::show_sys() [window miniaturize:window]; #endif } else if (!q->testAttribute(Qt::WA_ShowWithoutActivating)) { +#ifndef QT_MAC_USE_COCOA qt_event_request_activate(q); +#else + [qt_mac_window_for(q) makeKeyWindow]; +#endif } } else if(topData()->embedded || !q->parentWidget() || q->parentWidget()->isVisible()) { #ifndef QT_MAC_USE_COCOA @@ -3404,8 +3410,13 @@ void QWidgetPrivate::hide_sys() } #endif } - if(w && w->isVisible() && !w->isMinimized()) - qt_event_request_activate(w); + if(w && w->isVisible() && !w->isMinimized()) { +#ifndef QT_MAC_USE_COCOA + qt_event_request_activate(w); +#else + [qt_mac_window_for(w) makeKeyWindow]; +#endif + } } } else { invalidateBuffer(q->rect()); -- cgit v0.12 From 4ae09215de36fcfd17dc6875aca102d784d65012 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Tue, 20 Oct 2009 16:55:06 +1000 Subject: The shipped pvr2d.h/wsegl.h for PowerVR do not work with MBX Reviewed-by: trustme --- src/plugins/gfxdrivers/powervr/README | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/plugins/gfxdrivers/powervr/README b/src/plugins/gfxdrivers/powervr/README index 322a6b2..513e7f5 100644 --- a/src/plugins/gfxdrivers/powervr/README +++ b/src/plugins/gfxdrivers/powervr/README @@ -31,9 +31,10 @@ strictly Unix-style markers. * IMPORTANT: To build the QScreen plugin and the WSEGL library it depends * * on, the pvr2d.h, wsegl.h headers for your platform are required. You * * can find a copy of these headers in src/3rdparty/powervr for SGX based * -* platforms like the TI OMAP3xxx. They may also work on MBX platforms too * -* depending on how old your libEGL is. You can tell Qt where to find * -* these headers by setting QMAKE_INCDIR_POWERVR in the mkspec. * +* platforms like the TI OMAP3xxx. They probably will not work on MBX * +* because of differences in the layout of certain PVR2D structures. * +* You can tell Qt where to find the actual headers for your system by * +* setting QMAKE_INCDIR_POWERVR in the mkspec. * *************************************************************************** When you start a Qt/Embedded application, you should modify the QWS_DISPLAY -- cgit v0.12 From 3d4804a229e6cb869aa03481dd871e756ffa35ae Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Tue, 20 Oct 2009 11:08:04 +0200 Subject: Revert "Change the way we handle KeyboardUIMode on Mac" This will be handled differently (QTBUG-4751) This reverts commit b12fb5861ce09539c04cd51db12a9bfbe32a4774. --- src/corelib/global/qnamespace.qdoc | 4 +++- src/gui/kernel/qapplication.cpp | 20 ++++---------------- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index ba05b00..e8d6df0 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -1827,7 +1827,9 @@ \value TabFocus the widget accepts focus by tabbing. \value ClickFocus the widget accepts focus by clicking. \value StrongFocus the widget accepts focus by both tabbing - and clicking. + and clicking. On Mac OS X this will also + be indicate that the widget accepts tab focus + when in 'Text/List focus mode'. \value WheelFocus like Qt::StrongFocus plus the widget accepts focus by using the mouse wheel. \value NoFocus the widget does not accept focus. diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 41d8098..f48c551 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -68,9 +68,6 @@ #include "private/qstylesheetstyle_p.h" #include "private/qstyle_p.h" #include "qmessagebox.h" -#include "qlineedit.h" -#include "qlistview.h" -#include "qtextedit.h" #include #include "qinputcontext.h" @@ -2501,6 +2498,8 @@ void QApplication::setActiveWindow(QWidget* act) */ QWidget *QApplicationPrivate::focusNextPrevChild_helper(QWidget *toplevel, bool next) { + uint focus_flag = qt_tab_all_widgets ? Qt::TabFocus : Qt::StrongFocus; + QWidget *f = toplevel->focusWidget(); if (!f) f = toplevel; @@ -2508,22 +2507,11 @@ QWidget *QApplicationPrivate::focusNextPrevChild_helper(QWidget *toplevel, bool QWidget *w = f; QWidget *test = f->d_func()->focus_next; while (test && test != f) { - if ((test->focusPolicy() & Qt::TabFocus) + if ((test->focusPolicy() & focus_flag) == focus_flag && !(test->d_func()->extra && test->d_func()->extra->focus_proxy) && test->isVisibleTo(toplevel) && test->isEnabled() && !(w->windowType() == Qt::SubWindow && !w->isAncestorOf(test)) - && (toplevel->windowType() != Qt::SubWindow || toplevel->isAncestorOf(test)) - && (qt_tab_all_widgets -#ifndef QT_NO_LINEEDIT - || qobject_cast(test) -#endif -#ifndef QT_NO_TEXTEDIT - || qobject_cast(test) -#endif -#ifndef QT_NO_ITEMVIEWS - || qobject_cast(test) -#endif - )) { + && (toplevel->windowType() != Qt::SubWindow || toplevel->isAncestorOf(test))) { w = test; if (next) break; -- cgit v0.12 From b2c51304a238845da35f20953ace0f4a291ceabc Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 20 Oct 2009 11:36:01 +0200 Subject: i18n: Complete German translations for 4.6.0 (XmlPatterns) --- translations/qt_de.ts | 643 +++++++++++++++++++++++++------------------------- 1 file changed, 326 insertions(+), 317 deletions(-) diff --git a/translations/qt_de.ts b/translations/qt_de.ts index c09daa9..0d329e5 100644 --- a/translations/qt_de.ts +++ b/translations/qt_de.ts @@ -140,9 +140,22 @@ Bitte prüfen Sie die Gstreamer-Installation und stellen Sie sicher, dass das Pa + Phonon::MMF + + + Audio Output + Audio-Ausgabe + + + + The audio output device + Audio-Ausgabegerät + + + Phonon::MMF::AudioEqualizer - + Frequency band, %1 Hz Frequenzband, %1 Hz @@ -917,7 +930,7 @@ nach Diese Socket-Operation wird nicht unterstützt - + Socket operation timed out Das Zeitlimit für die Operation wurde überschritten @@ -953,7 +966,7 @@ nach QApplication - + QT_LAYOUT_DIRECTION Translate this string to the string 'LTR' in left-to-right languages or to 'RTL' in right-to-left languages (such as Hebrew and Arabic) to get proper widget layout. LTR @@ -1023,7 +1036,7 @@ nach QColorDialog - + Hu&e: Farb&ton: @@ -1063,7 +1076,7 @@ nach Farbauswahl - + &Basic colors Grundfar&ben @@ -1263,7 +1276,7 @@ nach - + OK OK @@ -1447,7 +1460,7 @@ nach QErrorMessage - + &Show this message again Diese Meldung wieder an&zeigen @@ -1457,7 +1470,7 @@ nach &OK - + Debug Message: Debug-Ausgabe: @@ -1538,7 +1551,7 @@ nach Details - + File Datei @@ -1567,12 +1580,12 @@ nach S&peichern - + Recent Places Zuletzt besucht - + &Rename &Umbenennen @@ -1836,50 +1849,50 @@ Möchten Sie die Datei trotzdem löschen? QFontDatabase - + Normal Normal - + - + Bold Fett - - + + Demi Bold Halbfett - + - + Black Schwarz - + Demi Semi - + Light Leicht - - + + Italic Kursiv - - + + Oblique Schräggestellt @@ -2255,13 +2268,9 @@ Möchten Sie die Datei trotzdem löschen? QHostInfoAgent - - - + - - - + Host not found Rechner konnte nicht gefunden werden @@ -2282,7 +2291,7 @@ Möchten Sie die Datei trotzdem löschen? Unbekannter Fehler - + No host name given Es wurde kein Hostname angegeben @@ -2612,7 +2621,7 @@ Möchten Sie die Datei trotzdem löschen? QIODevice - + Permission denied Zugriff verweigert @@ -3092,7 +3101,7 @@ Möchten Sie die Datei trotzdem löschen? QMenuBar - + Actions Optionen @@ -3556,7 +3565,7 @@ Möchten Sie die Datei trotzdem löschen? QObject - + Invalid hostname Ungültiger Rechnername @@ -3782,7 +3791,7 @@ Möchten Sie die Datei trotzdem löschen? unbekannt - + OK OK @@ -4492,7 +4501,7 @@ Bitte wählen Sie einen anderen Dateinamen. Zeitüberschreitung - + @@ -5834,7 +5843,7 @@ Bitte wählen Sie einen anderen Dateinamen. Abbrechen - + Exit Beenden @@ -6058,7 +6067,7 @@ Bitte wählen Sie einen anderen Dateinamen. QTextControl - + &Undo &Rückgängig @@ -6216,7 +6225,7 @@ Bitte wählen Sie einen anderen Dateinamen. QWebFrame - + Request cancelled Anfrage wurde abgebrochen @@ -6861,17 +6870,17 @@ Bitte wählen Sie einen anderen Dateinamen. - + JavaScript Alert - %1 JavaScript-Hinweis - %1 - + JavaScript Confirm - %1 JavaScript-Bestätigung - %1 - + JavaScript Prompt - %1 JavaScript-Eingabeaufforderung - %1 @@ -6886,7 +6895,7 @@ Bitte wählen Sie einen anderen Dateinamen. Das Skript dieser Webseite ist fehlerhaft. Möchten Sie es anhalten? - + Move the cursor to the next character Positionsmarke auf folgendes Zeichen setzen @@ -7107,7 +7116,7 @@ Bitte wählen Sie einen anderen Dateinamen. QWidget - + * * @@ -8098,7 +8107,7 @@ Bitte wählen Sie einen anderen Dateinamen. In an XSL-T pattern, only function %1 and %2, not %3, can be used for matching. - Bei einem XSL-T-Suchmuster dürfen nur die Funktionen %1 und %2, nicht jedoch %3 zur Suche verwendet werden. + Bei einem XSL-T-Suchmuster dürfen nur die Funktionen %1 und %2, nicht jedoch %3 zur Suche verwendet werden. @@ -8138,17 +8147,17 @@ Bitte wählen Sie einen anderen Dateinamen. W3C XML Schema identity constraint selector - + W3C XML Schema identity constraint selector W3C XML Schema identity constraint field - + W3C XML Schema identity constraint field A construct was encountered which is disallowed in the current language(%1). - + Es wurde ein Sprachkonstrukt angetroffen, was in der aktuellen Sprache (%1) nicht erlaubt ist. @@ -8491,206 +8500,206 @@ Bitte wählen Sie einen anderen Dateinamen. %1 has inheritance loop in its base type %2. - + %1 hat eine zirkuläre Vererbung im Basistyp %2. Circular inheritance of base type %1. - + Zirkuläre Vererbung im Basistyp %1. Circular inheritance of union %1. - + Zirkuläre Vererbung bei der Vereinigung %1. %1 is not allowed to derive from %2 by restriction as the latter defines it as final. - + %1 darf nicht durch Einschränkung von %2 abgeleitet werden, da letzterer sie als final deklariert. %1 is not allowed to derive from %2 by extension as the latter defines it as final. - + %1 darf nicht durch Erweiterung von %2 abgeleitet werden, da letzterer sie als final deklariert. Base type of simple type %1 cannot be complex type %2. - + Der komplexe Typ %2 kann nicht Basisklasse des einfachen Typs %1 sein. Simple type %1 cannot have direct base type %2. - + Der einfache Typ %1 kann nicht den unmittelbaren Basistyp %2 haben. Simple type %1 is not allowed to have base type %2. - + Der einfache Typ %1 darf nicht den Basistyp %2 haben. Simple type %1 can only have simple atomic type as base type. - + Der einfache Typ %1 kann nur einen einfachen. atomaren Basistyp haben. Simple type %1 cannot derive from %2 as the latter defines restriction as final. - + %1 darf nicht von %2 abgeleitet werden, da letzterer die Einschränkung als final deklariert. Variety of item type of %1 must be either atomic or union. - + Die Varietät der Typen von %1 muss entweder atomar oder eine Vereinigung sein. Variety of member types of %1 must be atomic. - + Die Varietät der Typen von %1 muss atomar sein. %1 is not allowed to derive from %2 by list as the latter defines it as final. - + %1 darf nicht durch Listen von %2 abgeleitet werden, da sie letzterer sie als final deklariert. Simple type %1 is only allowed to have %2 facet. - + Der einfache Typ %1 darf nur die Facette %2 haben. Base type of simple type %1 must have variety of type list. - + Der Basistyp des einfachen Typs %1 muss eine Varietät des Typs Liste haben. Base type of simple type %1 has defined derivation by restriction as final. - + Der Basistyp des einfachen Typs %1 definiert Vererbung durch Einschränkung als final. Item type of base type does not match item type of %1. - + Der Elementtyp des Basistyps entspricht nicht dem Elementtyp von %1. Simple type %1 contains not allowed facet type %2. - + Der einfache Typ %1 enthält einen nicht erlaubten Facettentyp %2. %1 is not allowed to derive from %2 by union as the latter defines it as final. - + %1 darf nicht durch Vereinigung von %2 abgeleitet werden, da sie letzterer sie als final deklariert. %1 is not allowed to have any facets. - + %1 darf keine Facetten haben. Base type %1 of simple type %2 must have variety of union. - + Der Basistyp %1 des einfachen Typs %2 muss eine Varietät des Typs Vereinigung haben. Base type %1 of simple type %2 is not allowed to have restriction in %3 attribute. - + Der Basistyp %1 des einfachen Typs %2 darf keine Einschränkung im %3 Attribut haben. Member type %1 cannot be derived from member type %2 of %3's base type %4. - + Der Typ %1 des Mitglieds darf nicht vom Typ %2 des Mitglieds vom Basistyp %4 von %3 sein. Derivation method of %1 must be extension because the base type %2 is a simple type. - + Erweiterung muss als Vererbungsmethode für %1 verwendet werden, da der Basistyp %2 ein einfacher Typ ist. Complex type %1 has duplicated element %2 in its content model. - + Der komplexe Typ %1 hat ein dupliziertes Element %2 in seinem Inhaltsmodell. Complex type %1 has non-deterministic content. - + Der komplexe Typ %1 hat nicht-deterministischen Inhalt. Attributes of complex type %1 are not a valid extension of the attributes of base type %2: %3. - + Die Attribute des komplexen Typs %1 sind keine gültige Erweiterung der Attribute des Basistyps %2: %3. Content model of complex type %1 is not a valid extension of content model of %2. - + Das Inhaltsmodell des komplexen Typs %1 ist keine gültige Erweiterung des Inhaltsmodells von %2. Complex type %1 must have simple content. - + Der komplexe Typ %1 kann nur einfachen Inhalt haben. Complex type %1 must have the same simple type as its base class %2. - + Der komplexe Typ %1 kann nur einen einfachen Typ als Basisklasse %2 haben. Complex type %1 cannot be derived from base type %2%3. - + Der komplexe Typ %1 kann nicht vom Basistyp %2 abgeleitet werden%3. Attributes of complex type %1 are not a valid restriction from the attributes of base type %2: %3. - + Die Attribute des komplexen Typs %1 sind keine gültige Einschränkung der Attribute des Basistyps %2: %3. Complex type %1 with simple content cannot be derived from complex base type %2. - + Der komplexe Typ %1 einfachen Inhalts darf nicht vom komplexen Basistyp %2 abgeleitet werden. Item type of simple type %1 cannot be a complex type. - + Der Elementtyp des einfachen Typs %1 kann kein komplexer Typ sein. Member type of simple type %1 cannot be a complex type. - + Der Typ eines Mitglieds des einfachen Typs %1 kann kein komplexer Typ sein. %1 is not allowed to have a member type with the same name as itself. - + %1 darf keinen Typ eines Mitglieds desselben Namens haben. %1 facet collides with %2 facet. - + Die Facette %1 steht im Widerspruch zu der Facette %2. %1 facet must have the same value as %2 facet of base type. - + Die Facette %1 muss denselben Wert wie die Facette %2 des Basistyps haben. %1 facet must be equal or greater than %2 facet of base type. - + Die Facette %1 muss größer oder gleich der Facette %2 des Basistyps sein. @@ -8702,333 +8711,333 @@ Bitte wählen Sie einen anderen Dateinamen. %1 facet must be less than or equal to %2 facet of base type. - + Die Facette %1 muss kleiner oder gleich der Facette %2 des Basistyps sein. %1 facet contains invalid regular expression - + Die Facette %1 enthält einen ungültigen regulären Ausdruck Unknown notation %1 used in %2 facet. - + Die Facette %2 enthält eine ungültige Notation %1. %1 facet contains invalid value %2: %3. - + Die Facette %1 enthält einen ungültigen Wert %2: %3. %1 facet cannot be %2 or %3 if %4 facet of base type is %5. - + Die Facette %1 kann nicht %2 oder %3 sein, wenn die Facette %4 des Basistyps %5 ist. %1 facet cannot be %2 if %3 facet of base type is %4. - + Die Facette %1 kann nicht %2 sein, wenn die Facette %3 des Basistyps %4 ist. %1 facet must be less than or equal to %2 facet. - + Die Facette %1 muss kleiner oder gleich der Facette %2 sein. %1 facet must be less than %2 facet of base type. - + Die Facette %1 muss kleiner der Facette %2 des Basistyps sein. %1 facet and %2 facet cannot appear together. - + Die Facetten %1 und %2 können nicht zusammen erscheinen. %1 facet must be greater than %2 facet of base type. - + Die Facette %1 muss größer als die Facette %2 des Basistyps sein. %1 facet must be less than %2 facet. - + Die Facette %1 muss kleiner als die Facette %2 sein. %1 facet must be greater than or equal to %2 facet of base type. - + Die Facette %1 muss größer oder gleich der Facette %2 des Basistyps sein. Simple type contains not allowed facet %1. - + Der einfache Typ enthält eine unzulässige Facette %1. %1, %2, %3, %4, %5 and %6 facets are not allowed when derived by list. - + Die Facetten %1, %2, %3, %4, %5 und %6 sind bei Vererbung durch Listen nicht zulässig. Only %1 and %2 facets are allowed when derived by union. - + Bei Vererbung durch Vereinigung sind nur die Facetten %1 und %2 zulässig. %1 contains %2 facet with invalid data: %3. - + %1 enthält eine Facette %2 mit ungültigen Daten: %3. Attribute group %1 contains attribute %2 twice. - + Die Attributgruppe %1 enthält das Attribut %2 zweimal. Attribute group %1 contains two different attributes that both have types derived from %2. - + Die Attributgruppe %1 enthält zwei verschiedene Attribute mit Typen, die von %2 abgeleitet sind. Attribute group %1 contains attribute %2 that has value constraint but type that inherits from %3. - + Die Attributgruppe %1 enthält ein Attribut %2 mit einer Einschränkung des Werts, dessen Typ aber von %3 abgeleitet ist. Complex type %1 contains attribute %2 twice. - + Der komplexe Typ %1 enthält das Attribut %2 doppelt. Complex type %1 contains two different attributes that both have types derived from %2. - + Die Attributgruppe %1 enthält zwei verschiedene Attribute mit Typen, die beide von %2 abgeleitet sind. Complex type %1 contains attribute %2 that has value constraint but type that inherits from %3. - + Der komplexe Typ %1 enthält ein Attribut %2 mit einer Einschränkung des Werts, dessen Typ aber von %3 abgeleitet ist. Element %1 is not allowed to have a value constraint if its base type is complex. - + Das Element %1 darf keine Einschränkung des Werts haben, wenn der Basistyp komplex ist. Element %1 is not allowed to have a value constraint if its type is derived from %2. - + Das Element %1 darf keine Einschränkung des Werts haben, wenn sein Typ von %2 abgeleitet ist. Value constraint of element %1 is not of elements type: %2. - + Die Einschränkung des Werts des Elements %1 ist nicht vom Typ des Elements: %2. Element %1 is not allowed to have substitution group affiliation as it is no global element. - + Das Element %1 kann nicht zu einer Substitutionsgruppe gehören, da es kein globales Element ist. Type of element %1 cannot be derived from type of substitution group affiliation. - + Der Typ des Elements %1 kann nicht vom Typ der zugehörigen Substitutionsgruppe abgeleitet werden. Value constraint of attribute %1 is not of attributes type: %2. - + Die Einschränkung des Werts des Attributs %1 ist nicht vom Typ des Attributs: %2. Attribute %1 has value constraint but has type derived from %2. - + Das Attribut %1 hat eine Einschränkung des Werts, während sein Typ von %2 abgeleitet ist. %1 attribute in derived complex type must be %2 like in base type. - + Das Attribut %1 in einem abgeleiteten komplexen Typ muss wie im Basistyp '%2' sein. Attribute %1 in derived complex type must have %2 value constraint like in base type. - + Das Attribut %1 in einem abgeleiteten komplexen Typ muss wie der Basistyp eine Einschränkung des Werts (%2) haben. Attribute %1 in derived complex type must have the same %2 value constraint like in base type. - + Das Attribut %1 in einem abgeleiteten komplexen Typ muss die gleiche Einschränkung des Werts (%2) wie der Basistyp haben. Attribute %1 in derived complex type must have %2 value constraint. - + Das Attribut %1 in einem abgeleiteten komplexen Typ muss die Einschränkung des Werts '%2' haben. processContent of base wildcard must be weaker than derived wildcard. - + Das 'processContent'-Attribut des Basisuchmusters muss schwächer sein als das des abgeleiteten Suchmusters. Element %1 exists twice with different types. - + Es existieren zwei Vorkommen verschiedenen Typs des Elements %1. Particle contains non-deterministic wildcards. - + Der Partikel enthält nicht-deterministische Suchmuster. Base attribute %1 is required but derived attribute is not. - + Das Basisattribut %1 ist erforderlich, nicht jedoch das abgeleitete Attribut. Type of derived attribute %1 cannot be validly derived from type of base attribute. - + Der Typ des abgeleiteten Attributs %1 kann nicht aus Typ des Basisattributs bestimmt werden. Value constraint of derived attribute %1 does not match value constraint of base attribute. - + Die Einschränkung des Werts des abgeleiteten Attributs %1 entspricht nicht der Einschränkung des Werts des Basisattributs. Derived attribute %1 does not exists in the base definition. - + Das abgeleitete Attribut %1 existiert in der Basisdefinition nicht. Derived attribute %1 does not match the wildcard in the base definition. - + Das abgeleitete Attribut %1 entspricht nicht dem Suchmuster in der Basisdefinition. Base attribute %1 is required but missing in derived definition. - + Das erforderliche Basisattribut %1 fehlt in der abgeleiteten Definition. Derived definition contains an %1 element that does not exists in the base definition - + Die abgeleitete Definition enthält ein Element %1, was in der Basisdefinition nicht existiert Derived wildcard is not a subset of the base wildcard. - + Das abgeleitete Suchmuster ist keine Untermenge des Basissuchmusters. %1 of derived wildcard is not a valid restriction of %2 of base wildcard - + Das Attribut %1 des abgeleiteten Suchmusters ist keine gültige Einschränkung des Attributs '%2' des Basissuchmusters Attribute %1 from base type is missing in derived type. - + Das Attribut %1 des Basistyps fehlt im abgeleiteten Typ. Type of derived attribute %1 differs from type of base attribute. - + Der Typ des abgeleiteten Attributs %1 unterscheidet sich vom Basistyp. Base definition contains an %1 element that is missing in the derived definition - + Das Element %1 des Basistyps fehlt in der abgeleiteten Definition %1 references unknown %2 or %3 element %4. - + %1 verweist auf ein unbekanntes Element %4 ('%2' oder '%3'). %1 references identity constraint %2 that is no %3 or %4 element. - + %1 verweist auf eine Identitätseinschränkung %2, die weder ein '%3' noch ein '%4' Element ist. %1 has a different number of fields from the identity constraint %2 that it references. - + Bei %1 unterscheidet sich die Anzahl der Felder von der der Identitätseinschränkung %2, auf die es verweist. Base type %1 of %2 element cannot be resolved. - + Der Basistyp %1 des Elements %2 kann nicht aufgelöst werden. Item type %1 of %2 element cannot be resolved. - + Der Subtyp %1 des Elements %2 kann nicht aufgelöst werden. Member type %1 of %2 element cannot be resolved. - + Der Subtyp %1 des Elements %2 kann nicht aufgelöst werden. Type %1 of %2 element cannot be resolved. - + Der Typ %1 des Elements %2 kann nicht aufgelöst werden. Base type %1 of complex type cannot be resolved. - + Der Basistyp %1 des komplexen Typs kann nicht aufgelöst werden. %1 cannot have complex base type that has a %2. - + %1 kann keinen komplexen Basistyp haben, der '%2' spezifiziert. Content model of complex type %1 contains %2 element so it cannot be derived by extension from a non-empty type. - + Das Inhaltsmodell des komplexen Typs %1enthält ein Element '%2'; es kann daher nicht durch Erweiterung von einem nichtleeren Typ abgeleitet werden. Complex type %1 cannot be derived by extension from %2 as the latter contains %3 element in its content model. - + Der komplexe Typ % kann nicht durch Erweiterung von %2 abgeleitet werden, da letzterer ein '%3'-Element in seinem Inhaltsmodell hat. Type of %1 element must be a simple type, %2 is not. - + Der Typ des Elements %1 muss ein einfacher Typ sein, was %2 nicht ist. Substitution group %1 of %2 element cannot be resolved. - + Die Substitutionsgruppe %1 des Elements %2 kann nicht aufgelöst werden. Substitution group %1 has circular definition. - + Die Substitutionsgruppe %1 hat eine zirkuläre Definition. Duplicated element names %1 in %2 element. - + Der Elementname %1 kommt im Element %2 mehrfach vor. @@ -9036,207 +9045,207 @@ Bitte wählen Sie einen anderen Dateinamen. Reference %1 of %2 element cannot be resolved. - + Der Verweis %1 des Elements %2 kann nicht aufgelöst werden. Circular group reference for %1. - + Zirkulärer Verweis bei %1. %1 element is not allowed in this scope - + Das Element %1 ist in diesem Bereich nicht zulässig %1 element cannot have %2 attribute with value other than %3. - + Der Wert des Attributs %2 des Elements %1 kann nur %3 sein. %1 element cannot have %2 attribute with value other than %3 or %4. - + Der Wert des Attributs %2 des Elements %1 kann nur %3 oder %4 sein. %1 or %2 attribute of reference %3 does not match with the attribute declaration %4. - + Das Attribut %1 oder %2 des Verweises %3 entspricht nicht der Attributsdeklaration %4. Attribute group %1 has circular reference. - + Die Attributgruppe %1 hat einen zirkulären Verweis. %1 attribute in %2 must have %3 use like in base type %4. - + Das Attribut %1 aus %2 muss die Verwendung '%3' spezifizieren, wie im Basistyp %4. Attribute wildcard of %1 is not a valid restriction of attribute wildcard of base type %2. - + Das Attributssuchmuster %1 ist keine gültige Einschränkung des Attributssuchmuster des Basistyps %2. %1 has attribute wildcard but its base type %2 has not. - + %1 hat ein Attributssuchmuster, nicht jedoch sein Basistyp %2. Union of attribute wildcard of type %1 and attribute wildcard of its base type %2 is not expressible. - + Die Vereinigung der Attributssuchmuster des Typs %1 und seines Basistyps %2 ergibt keinen gültigen Ausdruck. Enumeration facet contains invalid content: {%1} is not a value of type %2. - + Ungültiger Inhalt einer Aufzählungsfacette: {%1} ist kein Wert des Typs %2. Namespace prefix of qualified name %1 is not defined. - + Der Namensraum-Präfix des qualifizierten Namens %1 ist nicht definiert. %1 element %2 is not a valid restriction of the %3 element it redefines: %4. - + Das Element %2 (%1) ist keine gültige Einschränkung des überschriebenen Elements (%3): %4. Empty particle cannot be derived from non-empty particle. - + Von einem nichtleeren Partikel kann kein leerer Partikel abgeleitet werden. Derived particle is missing element %1. - + Das Element %1 fehlt im abgeleiteten Partikel. Derived element %1 is missing value constraint as defined in base particle. - + Im abgeleiteten Element %1 fehlt Einschränkung des Wertes, wie sie im Basispartikel definiert ist. Derived element %1 has weaker value constraint than base particle. - + Das abgeleitete Element %1 hat eine schwächere Einschränkung des Wertes als der Basispartikel. Fixed value constraint of element %1 differs from value constraint in base particle. - + Die feste Einschränkung des Wertes des Elements %1 unterscheidet sich von der Einschränkung des Wertes des Basispartikels. Derived element %1 cannot be nillable as base element is not nillable. - + Das abgeleitete Element %1 kann kein 'nillable'-Attribut haben, da das Basiselement keines spezifiziert. Block constraints of derived element %1 must not be more weaker than in the base element. - + Die Blockeinschränkung des abgeleiteten Elements %1 darf nicht schwächer sein als im Basiselement. Simple type of derived element %1 cannot be validly derived from base element. - + Der einfache Typ des abgeleiteten Elements %1 kann nicht vom Basiselement abgeleitet werden. Complex type of derived element %1 cannot be validly derived from base element. - + Der komplexe Typ des abgeleiteten Elements %1 kann nicht vom Basiselement abgeleitet werden. Element %1 is missing in derived particle. - + Das Element %1 fehlt im abgeleiteten Partikel. Element %1 does not match namespace constraint of wildcard in base particle. - + Das Element %1 entspricht nicht der Namensraumeinschränkung des Basispartikels. Wildcard in derived particle is not a valid subset of wildcard in base particle. - + Das Suchmuster im abgeleiteten Partikel ist keine gültige Untermenge des Suchmusters des Basispartikels. processContent of wildcard in derived particle is weaker than wildcard in base particle. - + Das processContent-Attribut des Suchmusters des abgeleiteten Partikels ist schwächer als das Suchmuster des Basispartikels. Derived particle allows content that is not allowed in the base particle. - + Der abgeleitete Partikel gestattet Inhalt, der für den Basispartikel nicht zulässig ist. - + Can not process unknown element %1, expected elements are: %2. - + Das unbekannte Element %1 kann nicht verarbeitet werden; zulässig wären: %2. Element %1 is not allowed in this scope, possible elements are: %2. - + Das Element %1 ist in diesem Bereich nicht zulässig; möglich wären: %2. Child element is missing in that scope, possible child elements are: %1. - + Das Unterelement fehlt im Bereich; mögliche Unterelemente wären: %1. Document is not a XML schema. - + Das Dokument ist kein XML-Schema. %1 attribute of %2 element contains invalid content: {%3} is not a value of type %4. - + Das Attribut %1 des Elements %2 enthält ungültigen Inhalt: {%3} ist kein Wert des Typs %4. %1 attribute of %2 element contains invalid content: {%3}. - + Das Attribut %1 des Elements %2 enthält ungültigen Inhalt: {%3}. Target namespace %1 of included schema is different from the target namespace %2 as defined by the including schema. - + Der Zielnamensraum %1 des eingebundenen Schemas unterscheidet sich vom dem von ihm definierten Zielnamensraum %2. Target namespace %1 of imported schema is different from the target namespace %2 as defined by the importing schema. - + Der Zielnamensraum %1 des importierten Schemas unterscheidet sich vom dem von ihm definierten Zielnamensraum %2. %1 element is not allowed to have the same %2 attribute value as the target namespace %3. - + Das Element %1 kann nicht den Zielnamensraum %3 als Wert des Attributs '%2' spezifizieren. %1 element without %2 attribute is not allowed inside schema without target namespace. - + In einem Schema ohne Namensraum muss das Element %1 ein Attribut %2 haben. %1 element is not allowed inside %2 element if %3 attribute is present. - + Wenn das Attribut %3 vorhanden ist, darf das Element %1 nicht im Element %2 vorkommen. %1 element has neither %2 attribute nor %3 child element. - + Das Element %1 hat weder das Attribut %2 noch ein Unterelement %3. @@ -9254,23 +9263,23 @@ Bitte wählen Sie einen anderen Dateinamen. %1 element with %2 child element must not have a %3 attribute. - + Das Element %1 darf kein Attribut %3 haben, wenn das Unterelement %2 vorhanden ist. %1 attribute of %2 element must be %3 or %4. - + Das Attribut %1 des Elements %2 kann nur %3 oder %4 sein. %1 attribute of %2 element must have a value of %3. - + Das Attribut %1 des Elements %2 muss den Wert %3 haben. %1 attribute of %2 element must have a value of %3 or %4. - + Das Attribut %1 des Elements %2 kann nur einen der Werte %3 oder %4 haben. @@ -9288,626 +9297,626 @@ Bitte wählen Sie einen anderen Dateinamen. %1 element must not have %2 and %3 attribute together. - + Die Attribute %2 und %3 können nicht zusammen im Element %1 erscheinen. Content of %1 attribute of %2 element must not be from namespace %3. - + Der Inhalt des Attributs %1 des Elements %2 kann nicht vom Namensraum %3 stammen. %1 attribute of %2 element must not be %3. - + Das Attribut %1 des Elements %2 kann nicht %3 sein. %1 attribute of %2 element must have the value %3 because the %4 attribute is set. - + Das Attribut %1 des Elements %2 muss den Wert %3 haben, da das Attribut %4 gesetzt ist. Specifying use='prohibited' inside an attribute group has no effect. - + Die Angabe von use='prohibited' in einer Attributgruppe hat keinerlei Auswirkungen. %1 element must have either %2 or %3 attribute. - + Das Element %1 muss eines der Attribute %2 oder %3 spezifizieren. %1 element must have either %2 attribute or %3 or %4 as child element. - + Das Element %1 muss entweder das Attribut %2 spezifizieren oder über eines der Unterelemente %3 oder %4 verfügen. %1 element requires either %2 or %3 attribute. - + Das Element %1 erfordert eines der Attribute %2 oder %3. Text or entity references not allowed inside %1 element - + Text- oder Entitätsreferenzen sind innerhalb eines %1-Elements nicht zulässig. %1 attribute of %2 element must contain %3, %4 or a list of URIs. - + Das Attribut %1 des Elements %2 muss %3, %4 oder eine Liste der URIs enthalten. %1 element is not allowed in this context. - + Das Element %1 ist in diesem Kontext nicht zulässig. %1 attribute of %2 element has larger value than %3 attribute. - + Der Wert des Attributs %1 des Elements %2 ist größer als der des Attributs %3. Prefix of qualified name %1 is not defined. - + Der Präfix des qualifizierten Namens %1 ist nicht definiert. %1 attribute of %2 element must either contain %3 or the other values. - + Der Wert des Attributs %1 des Elements %2 muss entweder %3 oder die anderen Werte enthalten. Component with id %1 has been defined previously. - + Die Komponente mit der Id %1 ist bereits definiert. Element %1 already defined. - + Das Element %1 ist bereits definiert. Attribute %1 already defined. - + Das Attribut %1 ist bereits definiert. Type %1 already defined. - + Der Typ %1 ist bereits definiert. Attribute group %1 already defined. - + Die Attributgruppe %1 ist bereits definiert. Element group %1 already defined. - + Die Elementgruppe %1 ist bereits definiert. Notation %1 already defined. - + Die Notation %1 ist bereits definiert. Identity constraint %1 already defined. - + Die Identitätseinschränkung %1 ist bereits definiert. Duplicated facets in simple type %1. - + Im einfachen Typ %1 kommen Facetten mehrfach vor. %1 is not valid according to %2. - + %1 ist nach %2 ungültig. String content does not match the length facet. - + Der Zeichenketteninhalt entspricht nicht der Längenfacette. String content does not match the minLength facet. - + Der Zeichenketteninhalt entspricht nicht der Längenfacette (Minimumangabe). String content does not match the maxLength facet. - + Der Zeichenketteninhalt entspricht nicht der Längenfacette (Maximumangabe). String content does not match pattern facet. - + Der Zeichenketteninhalt entspricht nicht der Suchmusterfacette. String content is not listed in the enumeration facet. - + Der Zeichenketteninhalt ist nicht in der Aufzählungsfacette enthalten. Signed integer content does not match the maxInclusive facet. - + Der vorzeichenbehaftete Ganzzahlwert entspricht nicht der Facette 'maxInclusive'. Signed integer content does not match the maxExclusive facet. - + Der vorzeichenbehaftete Ganzzahlwert entspricht nicht der Facette 'maxExclusive'. Signed integer content does not match the minInclusive facet. - + Der vorzeichenbehaftete Ganzzahlwert entspricht nicht der Facette 'minInclusive'. Signed integer content does not match the minExclusive facet. - + Der vorzeichenbehaftete Ganzzahlwert entspricht nicht der Facette 'minExclusive'. Signed integer content is not listed in the enumeration facet. - + Der vorzeichenbehaftete Ganzzahlwert ist nicht in der Aufzählungsfacette enthalten. Signed integer content does not match pattern facet. - + Der vorzeichenbehaftete Ganzzahlwert entspricht nicht der Suchmusterfacette. Signed integer content does not match in the totalDigits facet. - + Der vorzeichenbehaftete Ganzzahlwert entspricht nicht der Facette 'totalDigits'. Unsigned integer content does not match the maxInclusive facet. - + Der vorzeichenlose Ganzzahlwert entspricht nicht der Facette 'maxInclusive'. Unsigned integer content does not match the maxExclusive facet. - + Der vorzeichenlose Ganzzahlwert entspricht nicht der Facette 'maxExclusive'. Unsigned integer content does not match the minInclusive facet. - + Der vorzeichenlose Ganzzahlwert entspricht nicht der Facette 'minInclusive'. Unsigned integer content does not match the minExclusive facet. - + Der vorzeichenlose Ganzzahlwert entspricht nicht der Facette 'minExclusive'. Unsigned integer content is not listed in the enumeration facet. - + Der vorzeichenlose Ganzzahlwert ist nicht in der Aufzählungsfacette enthalten. Unsigned integer content does not match pattern facet. - + Der vorzeichenlose Ganzzahlwert entspricht nicht der Suchmusterfacette. Unsigned integer content does not match in the totalDigits facet. - + Der vorzeichenlose Ganzzahlwert entspricht nicht der Facette 'totalDigits'. Double content does not match the maxInclusive facet. - + Die Gleitkommazahl entspricht nicht der Facette 'maxInclusive'. Double content does not match the maxExclusive facet. - + Die Gleitkommazahl entspricht nicht der Facette 'maxExclusive'. Double content does not match the minInclusive facet. - + Die Gleitkommazahl entspricht nicht der Facette 'minInclusive'. Double content does not match the minExclusive facet. - + Die Gleitkommazahl entspricht nicht der Facette 'minExclusive'. Double content is not listed in the enumeration facet. - + Die Gleitkommazahl ist nicht in der Aufzählungsfacette enthalten. Double content does not match pattern facet. - + Die Gleitkommazahl entspricht nicht der Suchmusterfacette. Decimal content does not match in the fractionDigits facet. - + Die Dezimalzahl entspricht nicht der Facette 'fractionDigit'. Decimal content does not match in the totalDigits facet. - + Die Dezimalzahl entspricht nicht der Facette 'totalDigits'. Date time content does not match the maxInclusive facet. - + Die Datumsangabe entspricht nicht der Facette 'maxInclusive'. Date time content does not match the maxExclusive facet. - + Die Datumsangabe entspricht nicht der Facette 'maxExclusive'. Date time content does not match the minInclusive facet. - + Die Datumsangabe entspricht nicht der Facette 'minInclusive'. Date time content does not match the minExclusive facet. - + Die Datumsangabe entspricht nicht der Facette 'minExclusive'. Date time content is not listed in the enumeration facet. - + Die Datumsangabe ist nicht in der Aufzählungsfacette enthalten. Date time content does not match pattern facet. - + Die Datumsangabe entspricht nicht der Suchmusterfacette. Duration content does not match the maxInclusive facet. - + Die Angabe der Zeitdauer entspricht nicht der Facette 'maxInclusive'. Duration content does not match the maxExclusive facet. - + Die Angabe der Zeitdauer entspricht nicht der Facette 'maxExclusive'. Duration content does not match the minInclusive facet. - + Die Angabe der Zeitdauer entspricht nicht der Facette 'minInclusive'. Duration content does not match the minExclusive facet. - + Die Angabe der Zeitdauer entspricht nicht der Facette 'minExclusive'. Duration content is not listed in the enumeration facet. - + Die Angabe der Zeitdauer ist nicht in der Aufzählungsfacette enthalten. Duration content does not match pattern facet. - + Die Angabe der Zeitdauer entspricht nicht der Suchmusterfacette. Boolean content does not match pattern facet. - + Der Boolesche Wert entspricht nicht der Suchmusterfacette. Binary content does not match the length facet. - + Der binäre Inhalt entspricht nicht der Längenfacette. Binary content does not match the minLength facet. - + Der binäre Inhalt entspricht nicht der Facette 'minLength'. Binary content does not match the maxLength facet. - + Der binäre Inhalt entspricht nicht der Facette 'maxLength'. Binary content is not listed in the enumeration facet. - + Der binäre Inhalt ist nicht in der Aufzählungsfacette enthalten. Invalid QName content: %1. - + Der Inhalt des qualifizierten Namens ist ungültig: %1. QName content is not listed in the enumeration facet. - + Der Inhalt des qualifizierten Namens ist nicht in der Aufzählungsfacette enthalten. QName content does not match pattern facet. - + Der Inhalt des qualifizierten Namens entspricht nicht der Suchmusterfacette. Notation content is not listed in the enumeration facet. - + Der Inhalt der Notation ist nicht in der Aufzählungsfacette enthalten. List content does not match length facet. - + Der Listeninhalt entspricht nicht der Längenfacette. List content does not match minLength facet. - + Der Listeninhalt entspricht nicht der Facette 'minLength'. List content does not match maxLength facet. - + Der Listeninhalt entspricht nicht der Facette 'maxLength'. List content is not listed in the enumeration facet. - + Der Listeninhalt ist nicht in der Aufzählungsfacette enthalten. List content does not match pattern facet. - + Der Listeninhalt entspricht nicht der Suchmusterfacette. Union content is not listed in the enumeration facet. - + Der Inhalt der Vereinigung ist nicht in der Aufzählungsfacette enthalten. Union content does not match pattern facet. - + Der Inhalt der Vereinigung entspricht nicht der Suchmusterfacette. Data of type %1 are not allowed to be empty. - + Daten vom Typ %1 können nicht leer sein. Element %1 is missing child element. - + Beim Element %1 fehlt ein Unterelement. There is one IDREF value with no corresponding ID: %1. - + Es existiert ein IDREF-Wert, für den keine zugehörige ID vorhanden ist: %1. Loaded schema file is invalid. - + Das geladene Schema ist ungültig. %1 contains invalid data. - + %1 enthält ungültige Daten. xsi:schemaLocation namespace %1 has already appeared earlier in the instance document. - + xsi:schemaLocation namespace %1 wurde im Instanzdokument bereits spezifiziert. xsi:noNamespaceSchemaLocation cannot appear after the first no-namespace element or attribute. - + xsi:noNamespaceSchemaLocation kann nicht nach dem ersten Element oder Attribut ohne Namensraum erscheinen. No schema defined for validation. - + Es ist kein Schema für die Validierung definiert. No definition for element %1 available. - + Für das Element %1 ist keine Definition verfügbar. Specified type %1 is not known to the schema. - + Der angegebene Typ %1 ist im Schema nicht spezifiziert. Element %1 is not defined in this scope. - + Das Element %1 ist in diesem Bereich nicht definiert. Declaration for element %1 does not exist. - + Für das Element %1 ist keine Deklaration verfügbar. Element %1 contains invalid content. - + Das Element %1 enthält ungültigen Inhalt. Element %1 is declared as abstract. - + Das Element %1 ist als abstrakt deklariert. Element %1 is not nillable. - + Das Element %1 hat das Attribut 'nillable' nicht spezifiziert. Attribute %1 contains invalid data: %2 - + Das Attribut %1 enthält ungültigeDaten: %2 Element contains content although it is nillable. - + Das Element hat Inhalt, obwohl es 'nillable' spezifiziert. Fixed value constrained not allowed if element is nillable. - + Eine feste Einschränkung des Werts ist nicht zulässig, wenn das Element 'nillable' spezifiert. Specified type %1 is not validly substitutable with element type %2. - + Der angebenene Typ %1 kann nicht durch den Elementtyp %2 substituiert werden. Complex type %1 is not allowed to be abstract. - + Der komplexe Typ %1 kann nicht abstrakt sein. Element %1 contains not allowed attributes. - + Das Element %1 enthält unzulässige Attribute. Element %1 contains not allowed child element. - + Das Element %1 enthält ein unzulässiges Unterelement. Content of element %1 does not match its type definition: %2. - + Der Inhalt des Elements %1 entspricht nicht seiner Typdefinition: %2. Content of element %1 does not match defined value constraint. - + Der Inhalt des Elements %1 entspricht nicht der definierten Einschränkung des Werts. Element %1 contains not allowed child content. - + Das Element %1 enthält unzulässigen Unterinhalt. Element %1 contains not allowed text content. - + Das Element %1 enthält unzulässigen Textinhalt. Element %1 can not contain other elements, as it has a fixed content. - + Das Element %1 darf kann keine Unterelemente haben, da es festen Inhalt enthält. Element %1 is missing required attribute %2. - + Bei dem Element %1 fehlt ein erforderliches Attribut %2. Attribute %1 does not match the attribute wildcard. - + Das Attribut %1 entspricht nicht dem Attributssuchmuster. Declaration for attribute %1 does not exist. - + Für das Attribut %1 ist keine Deklaration verfügbar. Element %1 contains two attributes of type %2. - + Das Element %1 enthält zwei Attribute des Typs %2. Attribute %1 contains invalid content. - + Das Attribut %1 enthält ungültigen Inhalt. Element %1 contains unknown attribute %2. - + Das Element %1 enthält ein unbekanntes Attribut %2. Content of attribute %1 does not match its type definition: %2. - + Der Inhalt des Attributs %1 entspricht nicht seiner Typdefinition: %2. Content of attribute %1 does not match defined value constraint. - + Der Inhalt des Attributs %1 entspricht nicht der definierten Einschränkung des Werts. Non-unique value found for constraint %1. - + Für die Einschränkung %1 wurde ein nicht eindeutiger Wert gefunden. Key constraint %1 contains absent fields. - + Die Einschränkung des Schlüssels %1 enthält nicht vorhandene Felder. Key constraint %1 contains references nillable element %2. - + Die Einschränkung des Schlüssels %1 verweist auf das Element %2, was 'nillable' spezifiziert. No referenced value found for key reference %1. - + Der referenzierte Wert der Schlüsselreferenz %1 konnte nicht gefunden werden. More than one value found for field %1. - + Für das Feld %1 wurden mehrere Werte gefunden. Field %1 has no simple type. - + Das Feld %1 hat keinen einfachen Typ. ID value '%1' is not unique. - + Der ID-Wert '%1' ist nicht eindeutig. '%1' attribute contains invalid QName content: %2. - + Das Attribut '%1' enthält einen ungültigen qualifizierten Namen: %2. -- cgit v0.12 From a95375593228e00186dbd50a04736bb32a24730e Mon Sep 17 00:00:00 2001 From: Janne Anttila Date: Tue, 20 Oct 2009 12:37:27 +0300 Subject: Doc update for QDir::rootPath and QDir::homePath in Symbian. Task-number: QTBUG-4867 Reviewed-by: Aleksandar Sasha Babic --- src/corelib/io/qdir.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index a67b3bd..59db9a6 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -1930,7 +1930,7 @@ QString QDir::currentPath() Under non-Windows operating systems the \c HOME environment variable is used if it exists, otherwise the path returned by the - rootPath(). + rootPath(). On Symbian always the same as the path returned by the rootPath(). \sa home(), currentPath(), rootPath(), tempPath() */ @@ -2002,7 +2002,8 @@ QString QDir::tempPath() Returns the absolute path of the root directory. For Unix operating systems this returns "/". For Windows file - systems this normally returns "c:/". + systems this normally returns "c:/". On Symbian this typically returns + "c:/data", i.e. the same as native PathInfo::PhoneMemoryRootPath(). \sa root(), drives(), currentPath(), homePath(), tempPath() */ -- cgit v0.12 From ccb376e04c29c4a9214f71c173c81f5877dc9502 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 20 Oct 2009 11:44:36 +0200 Subject: changes-4.6.0 updated --- dist/changes-4.6.0 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dist/changes-4.6.0 b/dist/changes-4.6.0 index cd9f130..7f723da 100644 --- a/dist/changes-4.6.0 +++ b/dist/changes-4.6.0 @@ -49,6 +49,12 @@ information about a particular change. QRegion. The native handle is for reading out only. Any GDI calls made on the HRGN handle will not affect the QRegion. + - [259221] QFileInfo::symLinkTarget() now supports NTFS symbolic links + thanks to Konstantin Ritt (merge request 1217). + + - The reading code of QLocalSocket on Windows has been rewritten to improve + reading performance. + **************************************************************************** * Important Behavior Changes * **************************************************************************** -- cgit v0.12 From da3e89e8d98a4d3322eae94aafd38ddb444f144e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20Meril=C3=A4?= Date: Tue, 20 Oct 2009 13:31:33 +0300 Subject: QT-693 QS60Style does not regard selection beahviors with itemviews QS60Style disregards all selection behaviors for itemviews. This leads to error when showing a highlighted selection rect; rect is only shown for cell having focus. Fixed by setting the highlight to all 'selected' cells. Task-number: QT-693 Reviewed-by: Alessandro Portale --- src/gui/styles/qs60style.cpp | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 4fa1d03..6d95336 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -1313,7 +1313,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, painter->save(); painter->setClipRect(voptAdj.rect); - const bool isSelected = (voptAdj.state & QStyle::State_HasFocus); + const bool isSelected = (vopt->state & QStyle::State_Selected); bool isVisible = false; int scrollBarWidth = 0; @@ -1358,7 +1358,27 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, // draw the focus rect if (isSelected) { - const QRect highlightRect = option->rect.adjusted(1,1,-1,-1); + QRect highlightRect = option->rect.adjusted(1,1,-1,-1); + const QAbstractItemView *view = qobject_cast(widget); + if (view && view->selectionBehavior() != QAbstractItemView::SelectItems) { + // set highlight rect so that it is continuous from cell to cell, yet sligthly + // smaller than cell rect + int xBeginning = 0, yBeginning = 0, xEnd = 0, yEnd = 0; + if (view->selectionBehavior() == QAbstractItemView::SelectRows) { + yBeginning = 1; yEnd = -1; + if (vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning) + xBeginning = 1; + else if (vopt->viewItemPosition == QStyleOptionViewItemV4::End) + xEnd = -1; + } else if (view->selectionBehavior() == QAbstractItemView::SelectColumns) { + xBeginning = 1; xEnd = -1; + if (vopt->viewItemPosition == QStyleOptionViewItemV4::Beginning) + yBeginning = 1; + else if (vopt->viewItemPosition == QStyleOptionViewItemV4::End) + yEnd = -1; + } + highlightRect = option->rect.adjusted(xBeginning, yBeginning, xEnd, xBeginning); + } QS60StylePrivate::drawSkinElement(QS60StylePrivate::SE_ListHighlight, painter, highlightRect, flags); } -- cgit v0.12 From f7d826f1a42c912f1db15da0a1cefe13bdd54906 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Tue, 20 Oct 2009 13:34:55 +0200 Subject: Use premultiplied alpha pixel format in Symbian Gives better performance in the raster paint engine. For Symbian 9.3 onwards, this can also be used as the native pixmap format. For 9.2, conversion is required. Reviewed-by: Sami Merila Reviewed-by: Jani Hautakangas --- src/gui/image/qpixmap_s60.cpp | 19 +++++++++++------ src/gui/kernel/qapplication_s60.cpp | 7 ++++++ src/gui/kernel/qt_s60_p.h | 10 +++++---- src/gui/styles/qs60style_s60.cpp | 7 +++--- src/s60installs/eabi/QtGuiu.def | 39 ++++++++++++++++++++++++++++------ src/s60installs/eabi/QtMultimediau.def | 6 ++++-- src/s60installs/eabi/QtNetworku.def | 2 ++ src/s60installs/eabi/QtScriptu.def | 1 + src/s60installs/eabi/QtXmlu.def | 1 - src/s60installs/eabi/phononu.def | 10 +++++++++ tests/auto/qpixmap/tst_qpixmap.cpp | 2 +- 11 files changed, 78 insertions(+), 26 deletions(-) diff --git a/src/gui/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp index 9ae8d72..666d608 100644 --- a/src/gui/image/qpixmap_s60.cpp +++ b/src/gui/image/qpixmap_s60.cpp @@ -496,11 +496,12 @@ void QS60PixmapData::fromImage(const QImage &img, Qt::ImageConversionFlags flags mode = EColor16MU; break; case QImage::Format_ARGB32_Premultiplied: -#if !defined(__SERIES60_31__) && !defined(__S60_32__) - mode = EColor16MAP; - break; -#endif - destFormat = QImage::Format_ARGB32; + if (S60->supportsPremultipliedAlpha) { + mode = Q_SYMBIAN_ECOLOR16MAP; + break; + } else { + destFormat = QImage::Format_ARGB32; + } // Fall through intended case QImage::Format_ARGB32: mode = EColor16MA; @@ -690,6 +691,10 @@ void QS60PixmapData::beginDataAccess() bytes = newBytes; TDisplayMode mode = cfbsBitmap->DisplayMode(); QImage::Format format = qt_TDisplayMode2Format(mode); + //on S60 3.1, premultiplied alpha pixels are stored in a bitmap with 16MA type + if (format == QImage::Format_ARGB32) + format = QImage::Format_ARGB32_Premultiplied; // pixel data is actually in premultiplied format + TSize size = cfbsBitmap->SizeInPixels(); QVector savedColorTable; @@ -794,8 +799,8 @@ void* QS60PixmapData::toNativeType(NativeType type) bool needsCopy = false; QSysInfo::SymbianVersion symbianVersion = QSysInfo::symbianVersion(); - if (symbianVersion == QSysInfo::SV_9_2 || symbianVersion == QSysInfo::SV_9_3) { - // Convert argb32_premultiplied to argb32 since Symbian 9.2 and Symbian 9.3 do + if (!(S60->supportsPremultipliedAlpha)) { + // Convert argb32_premultiplied to argb32 since Symbian 9.2 does // not support premultipied format. if (image.format() == QImage::Format_ARGB32_Premultiplied) { diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index cb9dda4..656bbc9 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -1056,6 +1056,13 @@ void qt_init(QApplicationPrivate * /* priv */, int) TDisplayMode mode = S60->screenDevice()->DisplayMode(); S60->screenDepth = TDisplayModeUtils::NumDisplayModeBitsPerPixel(mode); + //NB: RWsSession::GetColorModeList tells you what window modes are supported, + //not what bitmap formats. + if(QSysInfo::symbianVersion() == QSysInfo::SV_9_2) + S60->supportsPremultipliedAlpha = 0; + else + S60->supportsPremultipliedAlpha = 1; + RProcess me; TSecureId securId = me.SecureId(); S60->uid = securId.operator TUid(); diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h index d33791b..e25bc81 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -81,6 +81,9 @@ QT_BEGIN_NAMESPACE // system events seems to start with 0x10 const TInt KInternalStatusPaneChange = 0x50000000; +//this macro exists because EColor16MAP enum value doesn't exist in Symbian OS 9.2 +#define Q_SYMBIAN_ECOLOR16MAP TDisplayMode(13) + class QS60Data { public: @@ -108,6 +111,7 @@ public: int mouseInteractionEnabled : 1; int virtualMouseRequired : 1; int qtOwnsS60Environment : 1; + int supportsPremultipliedAlpha : 1; QApplication::QS60MainApplicationFactory s60ApplicationFactory; // typedef'ed pointer type static inline void updateScreenSize(); static inline RWsSession& wsSession(); @@ -199,7 +203,7 @@ inline void QS60Data::updateScreenSize() S60->screenHeightInPixels = params.iPixelSize.iHeight; S60->screenWidthInTwips = params.iTwipsSize.iWidth; S60->screenHeightInTwips = params.iTwipsSize.iHeight; - + S60->virtualMouseMaxAccel = qMax(S60->screenHeightInPixels, S60->screenWidthInPixels) / 20; TReal inches = S60->screenHeightInTwips / (TReal)KTwipsPerInch; @@ -302,11 +306,9 @@ static inline QImage::Format qt_TDisplayMode2Format(TDisplayMode mode) case EColor16MA: format = QImage::Format_ARGB32; break; -#if !defined(__SERIES60_31__) && !defined(__S60_32__) - case EColor16MAP: + case Q_SYMBIAN_ECOLOR16MAP: format = QImage::Format_ARGB32_Premultiplied; break; -#endif default: format = QImage::Format_Invalid; break; diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp index cde48d8..d760016 100644 --- a/src/gui/styles/qs60style_s60.cpp +++ b/src/gui/styles/qs60style_s60.cpp @@ -747,9 +747,8 @@ QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(QS60StylePrivate::SkinFr QPixmap result; // QS60WindowSurface::unlockBitmapHeap(); - static const bool canDoEColor16MAP = !(QSysInfo::s60Version() == QSysInfo::SV_S60_3_1 || QSysInfo::s60Version() == QSysInfo::SV_S60_3_2); - static const TDisplayMode displayMode = canDoEColor16MAP ? TDisplayMode(13) : EColor16MA; // 13 = EColor16MAP - static const TInt drawParam = canDoEColor16MAP ? KAknsDrawParamDefault : KAknsDrawParamNoClearUnderImage|KAknsDrawParamRGBOnly; + static const TDisplayMode displayMode = S60->supportsPremultipliedAlpha ? Q_SYMBIAN_ECOLOR16MAP : EColor16MA; + static const TInt drawParam = S60->supportsPremultipliedAlpha ? KAknsDrawParamDefault : KAknsDrawParamNoClearUnderImage|KAknsDrawParamRGBOnly; CFbsBitmap *frame = new (ELeave) CFbsBitmap(); //offscreen CleanupStack::PushL(frame); @@ -776,7 +775,7 @@ QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(QS60StylePrivate::SkinFr frameSkinID, centerSkinID, drawParam ); - if (canDoEColor16MAP) { + if (S60->supportsPremultipliedAlpha) { if (drawn) result = fromFbsBitmap(frame, NULL, flags, QImage::Format_ARGB32_Premultiplied); } else { diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def index 7c3542e..97d6bee 100644 --- a/src/s60installs/eabi/QtGuiu.def +++ b/src/s60installs/eabi/QtGuiu.def @@ -2288,7 +2288,7 @@ EXPORTS _ZN13QGestureEvent11setAcceptedEP8QGestureb @ 2287 NONAME _ZN13QGestureEvent6acceptEP8QGesture @ 2288 NONAME _ZN13QGestureEvent6ignoreEP8QGesture @ 2289 NONAME - _ZN13QGestureEvent7gestureEN2Qt11GestureTypeE @ 2290 NONAME + _ZN13QGestureEvent7gestureEN2Qt11GestureTypeE @ 2290 NONAME ABSENT ; MISSING: _ZN13QGestureEventC1ERK5QListIP8QGestureE @ 2291 NONAME _ZN13QGestureEventC2ERK5QListIP8QGestureE @ 2292 NONAME _ZN13QGraphicsItem10addToIndexEv @ 2293 NONAME @@ -2651,8 +2651,8 @@ EXPORTS _ZN13QSwipeGesture13setSwipeAngleEf @ 2650 NONAME _ZN13QSwipeGesture16staticMetaObjectE @ 2651 NONAME DATA 16 _ZN13QSwipeGesture19getStaticMetaObjectEv @ 2652 NONAME - _ZN13QSwipeGesture20setVerticalDirectionENS_14SwipeDirectionE @ 2653 NONAME - _ZN13QSwipeGesture22setHorizontalDirectionENS_14SwipeDirectionE @ 2654 NONAME + _ZN13QSwipeGesture20setVerticalDirectionENS_14SwipeDirectionE @ 2653 NONAME ABSENT ; MISSING: + _ZN13QSwipeGesture22setHorizontalDirectionENS_14SwipeDirectionE @ 2654 NONAME ABSENT ; MISSING: _ZN13QSwipeGestureC1EP7QObject @ 2655 NONAME _ZN13QSwipeGestureC2EP7QObject @ 2656 NONAME _ZN13QTextDocument10adjustSizeEv @ 2657 NONAME @@ -6369,12 +6369,12 @@ EXPORTS _ZN8QGesture15setTargetObjectEP7QObject @ 6368 NONAME _ZN8QGesture16staticMetaObjectE @ 6369 NONAME DATA 16 _ZN8QGesture19getStaticMetaObjectEv @ 6370 NONAME - _ZN8QGestureC1EN2Qt11GestureTypeEP7QObject @ 6371 NONAME + _ZN8QGestureC1EN2Qt11GestureTypeEP7QObject @ 6371 NONAME ABSENT ; MISSING: _ZN8QGestureC1EP7QObject @ 6372 NONAME - _ZN8QGestureC1ER15QGesturePrivateN2Qt11GestureTypeEP7QObject @ 6373 NONAME - _ZN8QGestureC2EN2Qt11GestureTypeEP7QObject @ 6374 NONAME + _ZN8QGestureC1ER15QGesturePrivateN2Qt11GestureTypeEP7QObject @ 6373 NONAME ABSENT ; MISSING: + _ZN8QGestureC2EN2Qt11GestureTypeEP7QObject @ 6374 NONAME ABSENT ; MISSING: _ZN8QGestureC2EP7QObject @ 6375 NONAME - _ZN8QGestureC2ER15QGesturePrivateN2Qt11GestureTypeEP7QObject @ 6376 NONAME + _ZN8QGestureC2ER15QGesturePrivateN2Qt11GestureTypeEP7QObject @ 6376 NONAME ABSENT ; MISSING: _ZN8QGestureD0Ev @ 6377 NONAME _ZN8QGestureD1Ev @ 6378 NONAME _ZN8QGestureD2Ev @ 6379 NONAME @@ -11557,4 +11557,29 @@ EXPORTS qt_pixmap_cleanup_hook @ 11556 NONAME DATA 4 qt_pixmap_cleanup_hook_64 @ 11557 NONAME DATA 4 qt_tab_all_widgets @ 11558 NONAME DATA 1 + _ZN18QGuiPlatformPlugin11qt_metacallEN11QMetaObject4CallEiPPv @ 11559 NONAME + _ZN18QGuiPlatformPlugin11qt_metacastEPKc @ 11560 NONAME + _ZN18QGuiPlatformPlugin12platformHintENS_12PlatformHintE @ 11561 NONAME + _ZN18QGuiPlatformPlugin14fileSystemIconERK9QFileInfo @ 11562 NONAME + _ZN18QGuiPlatformPlugin16staticMetaObjectE @ 11563 NONAME DATA 16 + _ZN18QGuiPlatformPlugin19getStaticMetaObjectEv @ 11564 NONAME + _ZN18QGuiPlatformPlugin19systemIconThemeNameEv @ 11565 NONAME + _ZN18QGuiPlatformPlugin20iconThemeSearchPathsEv @ 11566 NONAME + _ZN18QGuiPlatformPlugin7paletteEv @ 11567 NONAME + _ZN18QGuiPlatformPlugin9styleNameEv @ 11568 NONAME + _ZN18QGuiPlatformPluginC1EP7QObject @ 11569 NONAME + _ZN18QGuiPlatformPluginC2EP7QObject @ 11570 NONAME + _ZN18QGuiPlatformPluginD0Ev @ 11571 NONAME + _ZN18QGuiPlatformPluginD1Ev @ 11572 NONAME + _ZN18QGuiPlatformPluginD2Ev @ 11573 NONAME + _ZN8QGestureC1ER15QGesturePrivateP7QObject @ 11574 NONAME + _ZN8QGestureC2ER15QGesturePrivateP7QObject @ 11575 NONAME + _ZNK13QGestureEvent7gestureEN2Qt11GestureTypeE @ 11576 NONAME + _ZNK18QGuiPlatformPlugin10metaObjectEv @ 11577 NONAME + _ZTI18QGuiPlatformPlugin @ 11578 NONAME + _ZTI27QGuiPlatformPluginInterface @ 11579 NONAME + _ZTV18QGuiPlatformPlugin @ 11580 NONAME + _ZThn8_N18QGuiPlatformPluginD0Ev @ 11581 NONAME + _ZThn8_N18QGuiPlatformPluginD1Ev @ 11582 NONAME + _Z22qt_paint_device_metricPK12QPaintDeviceNS_17PaintDeviceMetricE @ 11583 NONAME diff --git a/src/s60installs/eabi/QtMultimediau.def b/src/s60installs/eabi/QtMultimediau.def index 787ad3a..30f921c 100644 --- a/src/s60installs/eabi/QtMultimediau.def +++ b/src/s60installs/eabi/QtMultimediau.def @@ -115,8 +115,8 @@ EXPORTS _ZN19QAbstractAudioInput6notifyEv @ 114 NONAME _ZN19QVideoSurfaceFormat11setPropertyEPKcRK8QVariant @ 115 NONAME _ZN19QVideoSurfaceFormat11setViewportERK5QRect @ 116 NONAME - _ZN19QVideoSurfaceFormat12setFrameRateERK5QPairIiiE @ 117 NONAME - _ZN19QVideoSurfaceFormat12setFrameRateEii @ 118 NONAME + _ZN19QVideoSurfaceFormat12setFrameRateERK5QPairIiiE @ 117 NONAME ABSENT + _ZN19QVideoSurfaceFormat12setFrameRateEii @ 118 NONAME ABSENT _ZN19QVideoSurfaceFormat12setFrameSizeERK5QSizeNS_12ViewportModeE @ 119 NONAME _ZN19QVideoSurfaceFormat12setFrameSizeEiiNS_12ViewportModeE @ 120 NONAME _ZN19QVideoSurfaceFormat16setYuvColorSpaceENS_13YuvColorSpaceE @ 121 NONAME @@ -275,4 +275,6 @@ EXPORTS _ZThn8_N18QAudioEnginePluginD0Ev @ 274 NONAME _ZThn8_N18QAudioEnginePluginD1Ev @ 275 NONAME _Zls6QDebugRK19QVideoSurfaceFormat @ 276 NONAME + _ZTV28QAudioEngineFactoryInterface @ 277 NONAME ABSENT + _ZN19QVideoSurfaceFormat12setFrameRateEf @ 278 NONAME diff --git a/src/s60installs/eabi/QtNetworku.def b/src/s60installs/eabi/QtNetworku.def index f216f85..e561511 100644 --- a/src/s60installs/eabi/QtNetworku.def +++ b/src/s60installs/eabi/QtNetworku.def @@ -989,4 +989,6 @@ EXPORTS _ZlsR11QDataStreamRK21QNetworkCacheMetaData @ 988 NONAME _ZrsR11QDataStreamR12QHostAddress @ 989 NONAME _ZrsR11QDataStreamR21QNetworkCacheMetaData @ 990 NONAME + _ZN15QNetworkRequest20setOriginatingObjectEP7QObject @ 991 NONAME + _ZNK15QNetworkRequest17originatingObjectEv @ 992 NONAME diff --git a/src/s60installs/eabi/QtScriptu.def b/src/s60installs/eabi/QtScriptu.def index d0a3e3e..1592664 100644 --- a/src/s60installs/eabi/QtScriptu.def +++ b/src/s60installs/eabi/QtScriptu.def @@ -341,4 +341,5 @@ EXPORTS _ZThn8_N22QScriptExtensionPluginD1Ev @ 340 NONAME _ZlsR11QDataStreamRK18QScriptContextInfo @ 341 NONAME _ZrsR11QDataStreamR18QScriptContextInfo @ 342 NONAME + _Z5qHashRK13QScriptString @ 343 NONAME diff --git a/src/s60installs/eabi/QtXmlu.def b/src/s60installs/eabi/QtXmlu.def index d1ba69d..cc5115c 100644 --- a/src/s60installs/eabi/QtXmlu.def +++ b/src/s60installs/eabi/QtXmlu.def @@ -458,4 +458,3 @@ EXPORTS _ZThn8_N18QXmlDefaultHandler18unparsedEntityDeclERK7QStringS2_S2_S2_ @ 457 NONAME _ZThn8_NK18QXmlDefaultHandler11errorStringEv @ 458 NONAME _ZlsR11QTextStreamRK8QDomNode @ 459 NONAME - diff --git a/src/s60installs/eabi/phononu.def b/src/s60installs/eabi/phononu.def index 651a0b8..af1e3cc 100644 --- a/src/s60installs/eabi/phononu.def +++ b/src/s60installs/eabi/phononu.def @@ -534,4 +534,14 @@ EXPORTS _ZThn8_N6Phonon19AbstractAudioOutputD1Ev @ 533 NONAME _ZThn8_N6Phonon6EffectD0Ev @ 534 NONAME _ZThn8_N6Phonon6EffectD1Ev @ 535 NONAME + _ZTIN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE0EEE @ 536 NONAME + _ZTIN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE1EEE @ 537 NONAME + _ZTIN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE2EEE @ 538 NONAME + _ZTIN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE3EEE @ 539 NONAME + _ZTIN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE4EEE @ 540 NONAME + _ZTVN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE0EEE @ 541 NONAME + _ZTVN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE1EEE @ 542 NONAME + _ZTVN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE2EEE @ 543 NONAME + _ZTVN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE3EEE @ 544 NONAME + _ZTVN6Phonon22ObjectDescriptionModelILNS_21ObjectDescriptionTypeE4EEE @ 545 NONAME diff --git a/tests/auto/qpixmap/tst_qpixmap.cpp b/tests/auto/qpixmap/tst_qpixmap.cpp index 36c1518..9f5aee2 100644 --- a/tests/auto/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/qpixmap/tst_qpixmap.cpp @@ -1144,7 +1144,7 @@ void tst_QPixmap::fromSymbianCFbsBitmap_data() // QTest::newRow("EColor16MA small trans") << EColor16MA << smallWidth << smallHeight << QColor(255, 255, 0, 0); // QTest::newRow("EColor16MA big trans") << EColor16MA << largeWidth << largeHeight << QColor(255, 255, 0, 0); -#if !defined(__SERIES60_31__) && !defined(__S60_32__) +#if !defined(__SERIES60_31__) QTest::newRow("EColor16MAP small") << EColor16MAP << smallWidth << smallHeight << QColor(Qt::red); QTest::newRow("EColor16MAP big") << EColor16MAP << largeWidth << largeHeight << QColor(Qt::red); #endif -- cgit v0.12 From c238f7b7e299e742e71fdb043a7bc81bbfd6c419 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Tue, 20 Oct 2009 14:47:42 +0300 Subject: Fixed QFileDialog crash on Symbian softKeyActions QHash in QDialogButtonBoxPrivate was not kept properly in sync with standardButtonHash, causing QFileDialog to crash upon startup. Reviewed-by: Sami Merila --- src/gui/widgets/qdialogbuttonbox.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/gui/widgets/qdialogbuttonbox.cpp b/src/gui/widgets/qdialogbuttonbox.cpp index 10f8db8..2231b98 100644 --- a/src/gui/widgets/qdialogbuttonbox.cpp +++ b/src/gui/widgets/qdialogbuttonbox.cpp @@ -873,6 +873,11 @@ void QDialogButtonBox::setOrientation(Qt::Orientation orientation) void QDialogButtonBox::clear() { Q_D(QDialogButtonBox); +#ifdef QT_SOFTKEYS_ENABLED + // Delete softkey actions as they have the buttons as parents + qDeleteAll(d->softKeyActions.values()); + d->softKeyActions.clear(); +#endif // Remove the created standard buttons, they should be in the other lists, which will // do the deletion d->standardButtonHash.clear(); @@ -1025,6 +1030,11 @@ QPushButton *QDialogButtonBox::addButton(StandardButton button) void QDialogButtonBox::setStandardButtons(StandardButtons buttons) { Q_D(QDialogButtonBox); +#ifdef QT_SOFTKEYS_ENABLED + // Delete softkey actions since they have the buttons as parents + qDeleteAll(d->softKeyActions.values()); + d->softKeyActions.clear(); +#endif // Clear out all the old standard buttons, then recreate them. qDeleteAll(d->standardButtonHash.keys()); d->standardButtonHash.clear(); -- cgit v0.12 From ce03601e522ab10381f375c7bfd8862938d6955a Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 20 Oct 2009 10:11:00 +0200 Subject: Mac: fix bug when reparenting non-native menu bars If we reparent a naive menu bar inside a widget that has a menu bar from before, the old menu bar is lost. This patch makes sure that we don't set the new menu bar in this case, but let it remain as-is in case the widget is reparanted out again later. Rev-By: MortenS --- src/gui/widgets/qmenu_mac.mm | 20 ++++++++++++++++++-- src/gui/widgets/qmenubar.cpp | 9 +++++++-- src/gui/widgets/qmenubar_p.h | 1 + 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm index cee38ee..b238faf 100644 --- a/src/gui/widgets/qmenu_mac.mm +++ b/src/gui/widgets/qmenu_mac.mm @@ -1771,6 +1771,16 @@ QMenuBarPrivate::QMacMenuBarPrivate::removeAction(QMacMenuAction *action) actionItems.removeAll(action); } +bool QMenuBarPrivate::macWidgetHasNativeMenubar(QWidget *widget) +{ + // This function is different from q->isNativeMenuBar(), as + // it returns true only if a native menu bar is actually + // _created_. + if (!widget) + return false; + return menubars()->contains(widget->window()); +} + void QMenuBarPrivate::macCreateMenuBar(QWidget *parent) { @@ -1778,16 +1788,22 @@ QMenuBarPrivate::macCreateMenuBar(QWidget *parent) static int dontUseNativeMenuBar = -1; // We call the isNativeMenuBar function here // because that will make sure that local overrides - // are dealt with correctly. + // are dealt with correctly. q->isNativeMenuBar() will, if not + // overridden, depend on the attribute Qt::AA_DontUseNativeMenuBar: bool qt_mac_no_native_menubar = !q->isNativeMenuBar(); if (qt_mac_no_native_menubar == false && dontUseNativeMenuBar < 0) { + // The menubar is set to be native. Let's check (one time only + // for all menubars) if this is OK with the rest of the environment. + // As a result, Qt::AA_DontUseNativeMenuBar is set. NB: the application + // might still choose to not respect, or change, this flag. bool isPlugin = QApplication::testAttribute(Qt::AA_MacPluginApplication); bool environmentSaysNo = !qgetenv("QT_MAC_NO_NATIVE_MENUBAR").isEmpty(); dontUseNativeMenuBar = isPlugin || environmentSaysNo; QApplication::instance()->setAttribute(Qt::AA_DontUseNativeMenuBar, dontUseNativeMenuBar); qt_mac_no_native_menubar = !q->isNativeMenuBar(); } - if (!qt_mac_no_native_menubar) { + if (qt_mac_no_native_menubar == false) { + // INVARIANT: Use native menubar. extern void qt_event_request_menubarupdate(); //qapplication_mac.cpp qt_event_request_menubarupdate(); if (!parent && !fallback) { diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp index 13e7de4..f2f0722 100644 --- a/src/gui/widgets/qmenubar.cpp +++ b/src/gui/widgets/qmenubar.cpp @@ -1370,8 +1370,13 @@ void QMenuBarPrivate::handleReparent() oldWindow = newWindow; #ifdef Q_WS_MAC - macDestroyMenuBar(); - macCreateMenuBar(newParent); + if (q->isNativeMenuBar() && !macWidgetHasNativeMenubar(newParent)) { + // If the new parent got a native menubar from before, keep that + // menubar rather than replace it with this one (because a parents + // menubar has precedence over children menubars). + macDestroyMenuBar(); + macCreateMenuBar(newParent); + } #endif #ifdef Q_WS_WINCE diff --git a/src/gui/widgets/qmenubar_p.h b/src/gui/widgets/qmenubar_p.h index 0b27b97..7815969 100644 --- a/src/gui/widgets/qmenubar_p.h +++ b/src/gui/widgets/qmenubar_p.h @@ -196,6 +196,7 @@ public: return 0; } } *mac_menubar; + bool macWidgetHasNativeMenubar(QWidget *widget); void macCreateMenuBar(QWidget *); void macDestroyMenuBar(); OSMenuRef macMenu(); -- cgit v0.12 From 3aa8e4defdf104aeb0101815decfebe9e7ebc660 Mon Sep 17 00:00:00 2001 From: ninerider Date: Tue, 20 Oct 2009 14:31:30 +0200 Subject: Test fixes for Windows Mobile. Accounting for double resolution devices on Windows Mobile in the test data sets (tst_qgraphicsview_2.cpp). Skipped a test involving mouse tracking (tst_qgraphicsview.cpp). Reviewed-by: Joerg --- tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 4 + tests/auto/qgraphicsview/tst_qgraphicsview_2.cpp | 212 +++++++++++++---------- 2 files changed, 120 insertions(+), 96 deletions(-) diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index 389200b..dc08d0e 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -3664,6 +3664,10 @@ void tst_QGraphicsView::task253415_reconnectUpdateSceneOnSceneChanged() void tst_QGraphicsView::task255529_transformationAnchorMouseAndViewportMargins() { +#if defined(Q_OS_WINCE) + QSKIP("Qt/CE does not implement mouse tracking at this point", SkipAll); +#endif + QGraphicsScene scene(-100, -100, 200, 200); scene.addRect(QRectF(-50, -50, 100, 100), QPen(Qt::black), QBrush(Qt::blue)); diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview_2.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview_2.cpp index 9567f9e..1bfaf51 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview_2.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview_2.cpp @@ -43,6 +43,20 @@ #include #include +#ifdef Q_OS_WINCE +#include + +bool qt_wince_is_high_dpi() { + HDC deviceContext = GetDC(0); + int dpi = GetDeviceCaps(deviceContext, LOGPIXELSX); + ReleaseDC(0, deviceContext); + if ((dpi < 1000) && (dpi > 0)) + return dpi > 96; + else + return false; +} +#endif + Q_DECLARE_METATYPE(QList) Q_DECLARE_METATYPE(QList) Q_DECLARE_METATYPE(QMatrix) @@ -51,7 +65,7 @@ Q_DECLARE_METATYPE(QPointF) Q_DECLARE_METATYPE(QRectF) Q_DECLARE_METATYPE(Qt::ScrollBarPolicy) -static void _scrollBarRanges_data_1() +static void _scrollBarRanges_data_1(int offset) { // No motif, flat frame QTest::newRow("1") << QSize(150, 100) << QRectF(0, 0, 150, 100) << QTransform() @@ -59,73 +73,73 @@ static void _scrollBarRanges_data_1() << 0 << 0 << 0 << 0 << false << false; QTest::newRow("2") << QSize(150, 100) << QRectF(0, 0, 200, 100) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (50 + 16) << 0 << 16 << false << false; + << 0 << (50 + offset) << 0 << offset << false << false; QTest::newRow("3") << QSize(150, 100) << QRectF(0, 0, 200, 200) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (50 + 16) << 0 << (100 + 16) << false << false; + << 0 << (50 + offset) << 0 << (100 + offset) << false << false; QTest::newRow("4") << QSize(150, 100) << QRectF(-100, -100, 150, 100) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded << 0 << 0 << 0 << 0 << false << false; QTest::newRow("5") << QSize(150, 100) << QRectF(-100, -100, 200, 100) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << -100 << (16-50) << -100 << (-100 + 16) << false << false; + << -100 << (offset -50) << -100 << (-100 + offset) << false << false; QTest::newRow("6") << QSize(150, 100) << QRectF(-100, -100, 200, 200) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << -100 << (16-50) << -100 << 16 << false << false; + << -100 << (offset -50) << -100 << offset << false << false; QTest::newRow("7") << QSize(150, 100) << QRectF(0, 0, 151, 101) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << 17 << 0 << 17 << false << false; + << 0 << (offset + 1) << 0 << offset + 1 << false << false; QTest::newRow("8") << QSize(150, 100) << QRectF(0, 0, 201, 101) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (50 + 17) << 0 << 17 << false << false; + << 0 << (50 + offset + 1) << 0 << offset + 1 << false << false; QTest::newRow("9") << QSize(150, 100) << QRectF(0, 0, 201, 201) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (50 + 17) << 0 << (100 + 17) << false << false; + << 0 << (50 + offset + 1) << 0 << (100 + offset + 1) << false << false; QTest::newRow("10") << QSize(150, 100) << QRectF(-101, -101, 151, 101) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << -101 << (-100 + 16) << -101 << (-100 + 16) << false << false; + << -101 << (-100 + offset) << -101 << (-100 + offset) << false << false; QTest::newRow("11") << QSize(150, 100) << QRectF(-101, -101, 201, 101) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << (-101) << (16-50) << -101 << (-100 + 16) << false << false; + << (-101) << (offset + -50) << -101 << (-100 + offset) << false << false; QTest::newRow("12") << QSize(150, 100) << QRectF(-101, -101, 201, 201) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << (-101) << (16-50) << (-101) << 16 << false << false; + << (-101) << (offset -50) << (-101) << offset << false << false; QTest::newRow("13") << QSize(150, 100) << QRectF(0, 0, 166, 116) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (16 + 16) << 0 << (16 + 16) << false << false; + << 0 << (offset + 16) << 0 << (offset + 16) << false << false; QTest::newRow("14") << QSize(150, 100) << QRectF(0, 0, 216, 116) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (50 + 16 + 16) << 0 << (16 + 16) << false << false; + << 0 << (50 + offset + 16) << 0 << (offset + 16) << false << false; QTest::newRow("15") << QSize(150, 100) << QRectF(0, 0, 216, 216) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (50 + 16 + 16) << 0 << (100 + 16 + 16) << false << false; + << 0 << (50 + offset + 16) << 0 << (100 + offset + 16) << false << false; QTest::newRow("16") << QSize(150, 100) << QRectF(-116, -116, 166, 116) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << (-100 - 16) << (-100 + 16) << (-100 - 16) << (-100 + 16) << false << false; + << (-100 - 16) << (-100 + offset) << (-100 - 16 ) << (-100 + offset) << false << false; QTest::newRow("17") << QSize(150, 100) << QRectF(-116, -116, 216, 116) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << (-100 - 16) << (16-50) << (-100 - 16) << (-100 + 16) << false << false; + << (-100 - 16) << (offset -50) << (-100 - 16) << (-100 + offset) << false << false; QTest::newRow("18") << QSize(150, 100) << QRectF(-116, -116, 216, 216) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << (-100 - 16) << (16-50) << (-100 - 16) << 16 << false << false; + << (-100 - 16) << (offset -50) << (-100 - 16) << offset << false << false; QTest::newRow("1 x2") << QSize(150, 100) << QRectF(0, 0, 150, 100) << QTransform().scale(2, 2) << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (150 + 16) << 0 << (100 + 16) << false << false; + << 0 << (150 + offset) << 0 << (100 + offset) << false << false; QTest::newRow("2 x2") << QSize(150, 100) << QRectF(0, 0, 200, 100) << QTransform().scale(2, 2) << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (250 + 16) << 0 << (100 + 16) << false << false; + << 0 << (250 + offset) << 0 << (100 + offset) << false << false; QTest::newRow("3 x2") << QSize(150, 100) << QRectF(0, 0, 200, 200) << QTransform().scale(2, 2) << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (250 + 16) << 0 << (300 + 16) << false << false; + << 0 << (250 + offset) << 0 << (300 + offset) << false << false; QTest::newRow("4 x2") << QSize(150, 100) << QRectF(-100, -100, 150, 100) << QTransform().scale(2, 2) << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << -200 << (-50 + 16) << -200 << (-100 + 16) << false << false; + << -200 << (-50 + offset) << -200 << (-100 + offset) << false << false; QTest::newRow("5 x2") << QSize(150, 100) << QRectF(-100, -100, 200, 100) << QTransform().scale(2, 2) << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << -200 << (50 + 16) << -200 << (-100 + 16) << false << false; + << -200 << (50 + offset) << -200 << (-100 + offset) << false << false; QTest::newRow("6 x2") << QSize(150, 100) << QRectF(-100, -100, 200, 200) << QTransform().scale(2, 2) << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << -200 << (50 + 16) << -200 << (100 + 16) << false << false; + << -200 << (50 + offset) << -200 << (100 + offset) << false << false; QTest::newRow("1 No ScrollBars") << QSize(150, 100) << QRectF(0, 0, 150, 100) << QTransform() << Qt::ScrollBarAlwaysOff << Qt::ScrollBarAlwaysOff << 0 << 0 << 0 << 0 << false << false; @@ -272,7 +286,7 @@ static void _scrollBarRanges_data_1() << -200 << (50 + 16) << -200 << (100 + 16) << false << false; } -static void _scrollBarRanges_data_2() +static void _scrollBarRanges_data_2(int offset) { // Motif, flat frame QTest::newRow("Motif, 1") << QSize(150, 100) << QRectF(0, 0, 150, 100) << QTransform() @@ -280,73 +294,73 @@ static void _scrollBarRanges_data_2() << 0 << 0 << 0 << 0 << true << false; QTest::newRow("Motif, 2") << QSize(150, 100) << QRectF(0, 0, 200, 100) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (50 + 16) << 0 << 16 << true << false; + << 0 << (50 + offset) << 0 << offset << true << false; QTest::newRow("Motif, 3") << QSize(150, 100) << QRectF(0, 0, 200, 200) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (50 + 16) << 0 << (100 + 16) << true << false; + << 0 << (50 + offset) << 0 << (100 + offset) << true << false; QTest::newRow("Motif, 4") << QSize(150, 100) << QRectF(-100, -100, 150, 100) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded << 0 << 0 << 0 << 0 << true << false; QTest::newRow("Motif, 5") << QSize(150, 100) << QRectF(-100, -100, 200, 100) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << -100 << (16-50) << -100 << (-100 + 16) << true << false; + << -100 << (offset-50) << -100 << (-100 + offset) << true << false; QTest::newRow("Motif, 6") << QSize(150, 100) << QRectF(-100, -100, 200, 200) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << -100 << (16-50) << -100 << 16 << true << false; + << -100 << (offset-50) << -100 << offset << true << false; QTest::newRow("Motif, 7") << QSize(150, 100) << QRectF(0, 0, 151, 101) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << 17 << 0 << 17 << true << false; + << 0 << offset + 1 << 0 << offset + 1 << true << false; QTest::newRow("Motif, 8") << QSize(150, 100) << QRectF(0, 0, 201, 101) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (50 + 17) << 0 << 17 << true << false; + << 0 << (50 + offset + 1) << 0 << offset + 1 << true << false; QTest::newRow("Motif, 9") << QSize(150, 100) << QRectF(0, 0, 201, 201) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (50 + 17) << 0 << (100 + 17) << true << false; + << 0 << (50 + offset + 1) << 0 << (100 + offset + 1) << true << false; QTest::newRow("Motif, 10") << QSize(150, 100) << QRectF(-101, -101, 151, 101) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << -101 << (-100 + 16) << -101 << (-100 + 16) << true << false; + << -101 << (-100 + offset) << -101 << (-100 + offset) << true << false; QTest::newRow("Motif, 11") << QSize(150, 100) << QRectF(-101, -101, 201, 101) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << (-101) << (16-50) << -101 << (-100 + 16) << true << false; + << (-101) << (offset-50) << -101 << (-100 + offset) << true << false; QTest::newRow("Motif, 12") << QSize(150, 100) << QRectF(-101, -101, 201, 201) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << (-101) << (16-50) << (-101) << 16 << true << false; + << (-101) << (offset-50) << (-101) << offset << true << false; QTest::newRow("Motif, 13") << QSize(150, 100) << QRectF(0, 0, 166, 116) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (16 + 16) << 0 << (16 + 16) << true << false; + << 0 << (offset + 16) << 0 << (offset + 16) << true << false; QTest::newRow("Motif, 14") << QSize(150, 100) << QRectF(0, 0, 216, 116) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (50 + 16 + 16) << 0 << (16 + 16) << true << false; + << 0 << (50 + offset + 16) << 0 << (offset + 16) << true << false; QTest::newRow("Motif, 15") << QSize(150, 100) << QRectF(0, 0, 216, 216) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (50 + 16 + 16) << 0 << (100 + 16 + 16) << true << false; + << 0 << (50 + offset + 16) << 0 << (100 + offset + 16) << true << false; QTest::newRow("Motif, 16") << QSize(150, 100) << QRectF(-116, -116, 166, 116) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << (-100 - 16) << (-100 + 16) << (-100 - 16) << (-100 + 16) << true << false; + << (-100 - 16) << (-100 + offset) << (-100 - 16) << (-100 + offset) << true << false; QTest::newRow("Motif, 17") << QSize(150, 100) << QRectF(-116, -116, 216, 116) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << (-100 - 16) << (16-50) << (-100 - 16) << (-100 + 16) << true << false; + << (-100 - 16) << (offset-50) << (-100 - 16) << (-100 + offset) << true << false; QTest::newRow("Motif, 18") << QSize(150, 100) << QRectF(-116, -116, 216, 216) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << (-100 - 16) << (16-50) << (-100 - 16) << 16 << true << false; + << (-100 - 16) << (offset-50) << (-100 - 16) << offset << true << false; QTest::newRow("Motif, 1 x2") << QSize(150, 100) << QRectF(0, 0, 150, 100) << QTransform().scale(2, 2) << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (150 + 16) << 0 << (100 + 16) << true << false; + << 0 << (150 + offset) << 0 << (100 + offset) << true << false; QTest::newRow("Motif, 2 x2") << QSize(150, 100) << QRectF(0, 0, 200, 100) << QTransform().scale(2, 2) << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (250 + 16) << 0 << (100 + 16) << true << false; + << 0 << (250 + offset) << 0 << (100 + offset) << true << false; QTest::newRow("Motif, 3 x2") << QSize(150, 100) << QRectF(0, 0, 200, 200) << QTransform().scale(2, 2) << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (250 + 16) << 0 << (300 + 16) << true << false; + << 0 << (250 + offset) << 0 << (300 + offset) << true << false; QTest::newRow("Motif, 4 x2") << QSize(150, 100) << QRectF(-100, -100, 150, 100) << QTransform().scale(2, 2) << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << -200 << (-50 + 16) << -200 << (-100 + 16) << true << false; + << -200 << (-50 + offset) << -200 << (-100 + offset) << true << false; QTest::newRow("Motif, 5 x2") << QSize(150, 100) << QRectF(-100, -100, 200, 100) << QTransform().scale(2, 2) << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << -200 << (50 + 16) << -200 << (-100 + 16) << true << false; + << -200 << (50 + offset) << -200 << (-100 + offset) << true << false; QTest::newRow("Motif, 6 x2") << QSize(150, 100) << QRectF(-100, -100, 200, 200) << QTransform().scale(2, 2) << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << -200 << (50 + 16) << -200 << (100 + 16) << true << false; + << -200 << (50 + offset) << -200 << (100 + offset) << true << false; QTest::newRow("Motif, 1 No ScrollBars") << QSize(150, 100) << QRectF(0, 0, 150, 100) << QTransform() << Qt::ScrollBarAlwaysOff << Qt::ScrollBarAlwaysOff << 0 << 0 << 0 << 0 << true << false; @@ -493,7 +507,7 @@ static void _scrollBarRanges_data_2() << -200 << (50 + 16) << -200 << (100 + 16) << true << false; } -static void _scrollBarRanges_data_3() +static void _scrollBarRanges_data_3(int offset) { // No motif, styled panel QTest::newRow("Styled, 1") << QSize(150, 100) << QRectF(0, 0, 150, 100) << QTransform() @@ -501,73 +515,73 @@ static void _scrollBarRanges_data_3() << 0 << 0 << 0 << 0 << false << true; QTest::newRow("Styled, 2") << QSize(150, 100) << QRectF(0, 0, 200, 100) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (50 + 16) << 0 << 16 << false << true; + << 0 << (50 + offset) << 0 << offset << false << true; QTest::newRow("Styled, 3") << QSize(150, 100) << QRectF(0, 0, 200, 200) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (50 + 16) << 0 << (100 + 16) << false << true; + << 0 << (50 + offset) << 0 << (100 + offset) << false << true; QTest::newRow("Styled, 4") << QSize(150, 100) << QRectF(-100, -100, 150, 100) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded << 0 << 0 << 0 << 0 << false << true; QTest::newRow("Styled, 5") << QSize(150, 100) << QRectF(-100, -100, 200, 100) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << -100 << (16-50) << -100 << (-100 + 16) << false << true; + << -100 << (offset-50) << -100 << (-100 + offset) << false << true; QTest::newRow("Styled, 6") << QSize(150, 100) << QRectF(-100, -100, 200, 200) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << -100 << (16-50) << -100 << 16 << false << true; + << -100 << (offset-50) << -100 << offset << false << true; QTest::newRow("Styled, 7") << QSize(150, 100) << QRectF(0, 0, 151, 101) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << 17 << 0 << 17 << false << true; + << 0 << offset + 1 << 0 << offset + 1 << false << true; QTest::newRow("Styled, 8") << QSize(150, 100) << QRectF(0, 0, 201, 101) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (50 + 17) << 0 << 17 << false << true; + << 0 << (50 + offset + 1) << 0 << offset + 1 << false << true; QTest::newRow("Styled, 9") << QSize(150, 100) << QRectF(0, 0, 201, 201) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (50 + 17) << 0 << (100 + 17) << false << true; + << 0 << (50 + offset + 1) << 0 << (100 + offset + 1) << false << true; QTest::newRow("Styled, 10") << QSize(150, 100) << QRectF(-101, -101, 151, 101) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << -101 << (-100 + 16) << -101 << (-100 + 16) << false << true; + << -101 << (-100 + offset) << -101 << (-100 + offset) << false << true; QTest::newRow("Styled, 11") << QSize(150, 100) << QRectF(-101, -101, 201, 101) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << (-101) << (16-50) << -101 << (-100 + 16) << false << true; + << (-101) << (offset-50) << -101 << (-100 + offset) << false << true; QTest::newRow("Styled, 12") << QSize(150, 100) << QRectF(-101, -101, 201, 201) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << (-101) << (16-50) << (-101) << 16 << false << true; + << (-101) << (offset-50) << (-101) << offset << false << true; QTest::newRow("Styled, 13") << QSize(150, 100) << QRectF(0, 0, 166, 116) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (16 + 16) << 0 << (16 + 16) << false << true; + << 0 << (offset + 16) << 0 << (offset + 16) << false << true; QTest::newRow("Styled, 14") << QSize(150, 100) << QRectF(0, 0, 216, 116) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (50 + 16 + 16) << 0 << (16 + 16) << false << true; + << 0 << (50 + offset + 16) << 0 << (offset + 16) << false << true; QTest::newRow("Styled, 15") << QSize(150, 100) << QRectF(0, 0, 216, 216) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (50 + 16 + 16) << 0 << (100 + 16 + 16) << false << true; + << 0 << (50 + offset + 16) << 0 << (100 + offset + 16) << false << true; QTest::newRow("Styled, 16") << QSize(150, 100) << QRectF(-116, -116, 166, 116) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << (-100 - 16) << (-100 + 16) << (-100 - 16) << (-100 + 16) << false << true; + << (-100 - 16) << (-100 + offset) << (-100 - 16) << (-100 + offset) << false << true; QTest::newRow("Styled, 17") << QSize(150, 100) << QRectF(-116, -116, 216, 116) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << (-100 - 16) << (16-50) << (-100 - 16) << (-100 + 16) << false << true; + << (-100 - 16) << (offset-50) << (-100 - 16) << (-100 + offset) << false << true; QTest::newRow("Styled, 18") << QSize(150, 100) << QRectF(-116, -116, 216, 216) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << (-100 - 16) << (16-50) << (-100 - 16) << 16 << false << true; + << (-100 - 16) << (offset-50) << (-100 - 16) << offset << false << true; QTest::newRow("Styled, 1 x2") << QSize(150, 100) << QRectF(0, 0, 150, 100) << QTransform().scale(2, 2) << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (150 + 16) << 0 << (100 + 16) << false << true; + << 0 << (150 + offset) << 0 << (100 + offset) << false << true; QTest::newRow("Styled, 2 x2") << QSize(150, 100) << QRectF(0, 0, 200, 100) << QTransform().scale(2, 2) << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (250 + 16) << 0 << (100 + 16) << false << true; + << 0 << (250 + offset) << 0 << (100 + offset) << false << true; QTest::newRow("Styled, 3 x2") << QSize(150, 100) << QRectF(0, 0, 200, 200) << QTransform().scale(2, 2) << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (250 + 16) << 0 << (300 + 16) << false << true; + << 0 << (250 + offset) << 0 << (300 + offset) << false << true; QTest::newRow("Styled, 4 x2") << QSize(150, 100) << QRectF(-100, -100, 150, 100) << QTransform().scale(2, 2) << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << -200 << (-50 + 16) << -200 << (-100 + 16) << false << true; + << -200 << (-50 + offset) << -200 << (-100 + offset) << false << true; QTest::newRow("Styled, 5 x2") << QSize(150, 100) << QRectF(-100, -100, 200, 100) << QTransform().scale(2, 2) << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << -200 << (50 + 16) << -200 << (-100 + 16) << false << true; + << -200 << (50 + offset) << -200 << (-100 + offset) << false << true; QTest::newRow("Styled, 6 x2") << QSize(150, 100) << QRectF(-100, -100, 200, 200) << QTransform().scale(2, 2) << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << -200 << (50 + 16) << -200 << (100 + 16) << false << true; + << -200 << (50 + offset) << -200 << (100 + offset) << false << true; QTest::newRow("Styled, 1 No ScrollBars") << QSize(150, 100) << QRectF(0, 0, 150, 100) << QTransform() << Qt::ScrollBarAlwaysOff << Qt::ScrollBarAlwaysOff << 0 << 0 << 0 << 0 << false << true; @@ -714,7 +728,7 @@ static void _scrollBarRanges_data_3() << -200 << (50 + 16) << -200 << (100 + 16) << false << true; } -static void _scrollBarRanges_data_4() +static void _scrollBarRanges_data_4(int offset) { // Motif, styled panel QTest::newRow("Motif, Styled, 1") << QSize(150, 100) << QRectF(0, 0, 150, 100) << QTransform() @@ -722,73 +736,73 @@ static void _scrollBarRanges_data_4() << 0 << 0 << 0 << 0 << true << true; QTest::newRow("Motif, Styled, 2") << QSize(150, 100) << QRectF(0, 0, 200, 100) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (50 + 16 + 4) << 0 << (16 + 4) << true << true; + << 0 << (50 + offset + 4) << 0 << (offset + 4) << true << true; QTest::newRow("Motif, Styled, 3") << QSize(150, 100) << QRectF(0, 0, 200, 200) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (50 + 16 + 4) << 0 << (100 + 16 + 4) << true << true; + << 0 << (50 + offset + 4) << 0 << (100 + offset + 4) << true << true; QTest::newRow("Motif, Styled, 4") << QSize(150, 100) << QRectF(-100, -100, 150, 100) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded << 0 << 0 << 0 << 0 << true << true; QTest::newRow("Motif, Styled, 5") << QSize(150, 100) << QRectF(-100, -100, 200, 100) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << -100 << (16 + 4 - 50) << -100 << (-100 + 16 + 4) << true << true; + << -100 << (offset + 4 - 50) << -100 << (-100 + offset + 4) << true << true; QTest::newRow("Motif, Styled, 6") << QSize(150, 100) << QRectF(-100, -100, 200, 200) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << -100 << (16 + 4 - 50) << -100 << (16 + 4) << true << true; + << -100 << (offset + 4 - 50) << -100 << (offset + 4) << true << true; QTest::newRow("Motif, Styled, 7") << QSize(150, 100) << QRectF(0, 0, 151, 101) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (17 + 4) << 0 << (17 + 4) << true << true; + << 0 << (offset + 1 + 4) << 0 << (offset + 1 + 4) << true << true; QTest::newRow("Motif, Styled, 8") << QSize(150, 100) << QRectF(0, 0, 201, 101) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (50 + 17 + 4) << 0 << (17 + 4) << true << true; + << 0 << (50 + offset + 1 + 4) << 0 << (offset + 1 + 4) << true << true; QTest::newRow("Motif, Styled, 9") << QSize(150, 100) << QRectF(0, 0, 201, 201) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (50 + 17 + 4) << 0 << (100 + 17 + 4) << true << true; + << 0 << (50 + offset + 1 + 4) << 0 << (100 + offset + 1 + 4) << true << true; QTest::newRow("Motif, Styled, 10") << QSize(150, 100) << QRectF(-101, -101, 151, 101) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << -101 << (-100 + 16 + 4) << -101 << (-100 + 16 + 4) << true << true; + << -101 << (-100 + offset + 4) << -101 << (-100 + offset + 4) << true << true; QTest::newRow("Motif, Styled, 11") << QSize(150, 100) << QRectF(-101, -101, 201, 101) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << (-101) << (16 + 4 - 50) << -101 << (-100 + 16 + 4) << true << true; + << (-101) << (offset + 4 - 50) << -101 << (-100 + offset + 4) << true << true; QTest::newRow("Motif, Styled, 12") << QSize(150, 100) << QRectF(-101, -101, 201, 201) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << (-101) << (16 + 4 - 50) << (-101) << (16 + 4) << true << true; + << (-101) << (offset + 4 - 50) << (-101) << (offset + 4) << true << true; QTest::newRow("Motif, Styled, 13") << QSize(150, 100) << QRectF(0, 0, 166, 116) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (16 + 16 + 4) << 0 << (16 + 16 + 4) << true << true; + << 0 << (offset + 16 + 4) << 0 << (offset + 16 + 4) << true << true; QTest::newRow("Motif, Styled, 14") << QSize(150, 100) << QRectF(0, 0, 216, 116) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (50 + 16 + 16 + 4) << 0 << (16 + 16 + 4) << true << true; + << 0 << (50 + offset + 16 + 4) << 0 << (offset + 16 + 4) << true << true; QTest::newRow("Motif, Styled, 15") << QSize(150, 100) << QRectF(0, 0, 216, 216) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (50 + 16 + 16 + 4) << 0 << (100 + 16 + 16 + 4) << true << true; + << 0 << (50 + offset + 16 + 4) << 0 << (100 + offset + 16 + 4) << true << true; QTest::newRow("Motif, Styled, 16") << QSize(150, 100) << QRectF(-116, -116, 166, 116) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << (-100 - 16) << (-100 + 16 + 4) << (-100 - 16) << (-100 + 16 + 4) << true << true; + << (-100 - 16) << (-100 + offset + 4) << (-100 - 16) << (-100 + offset + 4) << true << true; QTest::newRow("Motif, Styled, 17") << QSize(150, 100) << QRectF(-116, -116, 216, 116) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << (-100 - 16) << (16 + 4 - 50) << (-100 - 16) << (-100 + 16 + 4) << true << true; + << (-100 - 16) << (offset + 4 - 50) << (-100 - 16) << (-100 + offset + 4) << true << true; QTest::newRow("Motif, Styled, 18") << QSize(150, 100) << QRectF(-116, -116, 216, 216) << QTransform() << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << (-100 - 16) << (16 + 4 - 50) << (-100 - 16) << (16 + 4) << true << true; + << (-100 - 16) << (offset + 4 - 50) << (-100 - 16) << (offset + 4) << true << true; QTest::newRow("Motif, Styled, 1 x2") << QSize(150, 100) << QRectF(0, 0, 150, 100) << QTransform().scale(2, 2) << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (150 + 16 + 4) << 0 << (100 + 16 + 4) << true << true; + << 0 << (150 + offset + 4) << 0 << (100 + offset + 4) << true << true; QTest::newRow("Motif, Styled, 2 x2") << QSize(150, 100) << QRectF(0, 0, 200, 100) << QTransform().scale(2, 2) << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (250 + 16 + 4) << 0 << (100 + 16 + 4) << true << true; + << 0 << (250 + offset + 4) << 0 << (100 + offset + 4) << true << true; QTest::newRow("Motif, Styled, 3 x2") << QSize(150, 100) << QRectF(0, 0, 200, 200) << QTransform().scale(2, 2) << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << 0 << (250 + 16 + 4) << 0 << (300 + 16 + 4) << true << true; + << 0 << (250 + offset + 4) << 0 << (300 + offset + 4) << true << true; QTest::newRow("Motif, Styled, 4 x2") << QSize(150, 100) << QRectF(-100, -100, 150, 100) << QTransform().scale(2, 2) << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << -200 << (-50 + 16 + 4) << -200 << (-100 + 16 + 4) << true << true; + << -200 << (-50 + offset + 4) << -200 << (-100 + offset + 4) << true << true; QTest::newRow("Motif, Styled, 5 x2") << QSize(150, 100) << QRectF(-100, -100, 200, 100) << QTransform().scale(2, 2) << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << -200 << (50 + 16 + 4) << -200 << (-100 + 16 + 4) << true << true; + << -200 << (50 + offset + 4) << -200 << (-100 + offset + 4) << true << true; QTest::newRow("Motif, Styled, 6 x2") << QSize(150, 100) << QRectF(-100, -100, 200, 200) << QTransform().scale(2, 2) << Qt::ScrollBarAsNeeded << Qt::ScrollBarAsNeeded - << -200 << (50 + 16 + 4) << -200 << (100 + 16 + 4) << true << true; + << -200 << (50 + offset + 4) << -200 << (100 + offset + 4) << true << true; QTest::newRow("Motif, Styled, 1 No ScrollBars") << QSize(150, 100) << QRectF(0, 0, 150, 100) << QTransform() << Qt::ScrollBarAlwaysOff << Qt::ScrollBarAlwaysOff << 0 << 0 << 0 << 0 << true << true; @@ -949,8 +963,14 @@ void _scrollBarRanges_data() QTest::addColumn("useMotif"); QTest::addColumn("useStyledPanel"); - _scrollBarRanges_data_1(); - _scrollBarRanges_data_2(); - _scrollBarRanges_data_3(); - _scrollBarRanges_data_4(); + int offset = 16; +#ifdef Q_OS_WINCE + if (qt_wince_is_high_dpi()) + offset *= 2; +#endif + + _scrollBarRanges_data_1(offset); + _scrollBarRanges_data_2(offset); + _scrollBarRanges_data_3(offset); + _scrollBarRanges_data_4(offset); } -- cgit v0.12 From 76ef766a32cdcfd9cd64cf1d288c92a2b2040c15 Mon Sep 17 00:00:00 2001 From: ninerider Date: Tue, 20 Oct 2009 14:40:26 +0200 Subject: Windows CE gets a different paint event count than windows Reviewed-by: Joerg --- tests/auto/qtabwidget/tst_qtabwidget.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/auto/qtabwidget/tst_qtabwidget.cpp b/tests/auto/qtabwidget/tst_qtabwidget.cpp index 27c19df..1387a92 100644 --- a/tests/auto/qtabwidget/tst_qtabwidget.cpp +++ b/tests/auto/qtabwidget/tst_qtabwidget.cpp @@ -590,9 +590,11 @@ void tst_QTabWidget::paintEventCount() QTest::qWait(1000); - // Mac and Windows get multiple repaints on the first show, so use those as a starting point. + // Mac, Windows and Windows CE get multiple repaints on the first show, so use those as a starting point. static const int MaxInitialPaintCount = -#if defined(Q_WS_WIN) +#if defined(Q_OS_WINCE) + 4; +#elif defined(Q_WS_WIN) 2; #elif defined(Q_WS_MAC) 5; -- cgit v0.12 From 147c524e703d4727d03c5f2ea3f98ace25905b73 Mon Sep 17 00:00:00 2001 From: Frans Englich Date: Tue, 20 Oct 2009 16:10:57 +0200 Subject: Fix bug introduced by cleanup commit. Reviewed-by: Gareth Stockwell --- src/3rdparty/phonon/mmf/audiooutput.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/3rdparty/phonon/mmf/audiooutput.cpp b/src/3rdparty/phonon/mmf/audiooutput.cpp index bb0e5bc..82af9f1 100644 --- a/src/3rdparty/phonon/mmf/audiooutput.cpp +++ b/src/3rdparty/phonon/mmf/audiooutput.cpp @@ -105,8 +105,6 @@ QHash MMF::AudioOutput::audioOutputDescription(int index) QHash retval; if (index == AudioOutputDeviceID) { - QHash retval; - retval.insert("name", QCoreApplication::translate("Phonon::MMF", "Audio Output")); retval.insert("description", QCoreApplication::translate("Phonon::MMF", "The audio output device")); retval.insert("available", true); -- cgit v0.12 From e47ea4694fb9228d111e31d8c590e6d5c16e7461 Mon Sep 17 00:00:00 2001 From: Martin Pejcoch Date: Thu, 15 Oct 2009 16:07:02 +0200 Subject: Set OFN_PATHMUSTEXIT as a default parameter This will result in a warning if the path entered doesn't exist, which is the behavior of native applications. Reviewed-by: Prasanth --- src/gui/dialogs/qfiledialog_win.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/dialogs/qfiledialog_win.cpp b/src/gui/dialogs/qfiledialog_win.cpp index b59c28b..8089b43 100644 --- a/src/gui/dialogs/qfiledialog_win.cpp +++ b/src/gui/dialogs/qfiledialog_win.cpp @@ -251,10 +251,10 @@ static OPENFILENAME* qt_win_make_OFN(QWidget *parent, ofn->nMaxFile = maxLen; ofn->lpstrInitialDir = (wchar_t*)tInitDir.utf16(); ofn->lpstrTitle = (wchar_t*)tTitle.utf16(); - ofn->Flags = (OFN_NOCHANGEDIR | OFN_HIDEREADONLY | OFN_EXPLORER); + ofn->Flags = (OFN_NOCHANGEDIR | OFN_HIDEREADONLY | OFN_EXPLORER | OFN_PATHMUSTEXIST); if (mode == QFileDialog::ExistingFile || mode == QFileDialog::ExistingFiles) - ofn->Flags |= (OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST); + ofn->Flags |= (OFN_FILEMUSTEXIST); if (mode == QFileDialog::ExistingFiles) ofn->Flags |= (OFN_ALLOWMULTISELECT); if (!(options & QFileDialog::DontConfirmOverwrite)) -- cgit v0.12 From 0bdb8aa64deef437b94f4998f4c2f6ed93a38489 Mon Sep 17 00:00:00 2001 From: ck Date: Tue, 20 Oct 2009 17:42:18 +0200 Subject: Assistant: Fix syntax error. The offending code is normally ifdef'ed out, so the bug did not manifest itself before. --- tools/assistant/lib/qhelpsearchquerywidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/assistant/lib/qhelpsearchquerywidget.cpp b/tools/assistant/lib/qhelpsearchquerywidget.cpp index 361e9ac..f2f40ec 100644 --- a/tools/assistant/lib/qhelpsearchquerywidget.cpp +++ b/tools/assistant/lib/qhelpsearchquerywidget.cpp @@ -289,7 +289,7 @@ private slots: { QList queryList; #if !defined(QT_CLUCENE_SUPPORT) - queryList.append(QHelSearchQuery(QHelpSearchQuery::DEFAULT, + queryList.append(QHelpSearchQuery(QHelpSearchQuery::DEFAULT, QStringList(defaultQuery->text()))); #else -- cgit v0.12 From 77f2319ab80be40268da689d5bc4726257ddd7ab Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Tue, 20 Oct 2009 17:40:40 +0200 Subject: Implement QAccesibleValueInterface for QProgressBar Patch has been tested thorougly in the accessibility-fixes branch of the qt-maemo repository, thus no review --- src/plugins/accessible/widgets/main.cpp | 4 +++- src/plugins/accessible/widgets/simplewidgets.cpp | 28 ++++++++++++++++++++++++ src/plugins/accessible/widgets/simplewidgets.h | 19 ++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/plugins/accessible/widgets/main.cpp b/src/plugins/accessible/widgets/main.cpp index 667de88..9a9a778 100644 --- a/src/plugins/accessible/widgets/main.cpp +++ b/src/plugins/accessible/widgets/main.cpp @@ -234,8 +234,10 @@ QAccessibleInterface *AccessibleFactory::create(const QString &classname, QObjec iface = new QAccessibleDisplay(widget, Grouping); } else if (classname == QLatin1String("QStatusBar")) { iface = new QAccessibleWidgetEx(widget, StatusBar); +#ifndef QT_NO_PROGRESSBAR } else if (classname == QLatin1String("QProgressBar")) { - iface = new QAccessibleDisplay(widget); + iface = new QAccessibleProgressBar(widget); +#endif } else if (classname == QLatin1String("QToolBar")) { iface = new QAccessibleWidgetEx(widget, ToolBar, widget->windowTitle()); #ifndef QT_NO_MENUBAR diff --git a/src/plugins/accessible/widgets/simplewidgets.cpp b/src/plugins/accessible/widgets/simplewidgets.cpp index 1aadd6c..89482bb 100644 --- a/src/plugins/accessible/widgets/simplewidgets.cpp +++ b/src/plugins/accessible/widgets/simplewidgets.cpp @@ -756,6 +756,34 @@ void QAccessibleLineEdit::scrollToSubstring(int startIndex, int endIndex) #endif // QT_NO_LINEEDIT +#ifndef QT_NO_PROGRESSBAR +QAccessibleProgressBar::QAccessibleProgressBar(QWidget *o) + : QAccessibleDisplay(o) +{ + Q_ASSERT(progressBar()); +} + +QVariant QAccessibleProgressBar::currentValue() +{ + return progressBar()->value(); +} + +QVariant QAccessibleProgressBar::maximumValue() +{ + return progressBar()->maximum(); +} + +QVariant QAccessibleProgressBar::minimumValue() +{ + return progressBar()->minimum(); +} + +QProgressBar *QAccessibleProgressBar::progressBar() const +{ + return qobject_cast(object()); +} +#endif + #endif // QT_NO_ACCESSIBILITY QT_END_NAMESPACE diff --git a/src/plugins/accessible/widgets/simplewidgets.h b/src/plugins/accessible/widgets/simplewidgets.h index abe5bdc..8de35ef 100644 --- a/src/plugins/accessible/widgets/simplewidgets.h +++ b/src/plugins/accessible/widgets/simplewidgets.h @@ -52,6 +52,7 @@ QT_BEGIN_NAMESPACE class QAbstractButton; class QLineEdit; class QToolButton; +class QProgressBar; class QAccessibleButton : public QAccessibleWidgetEx { @@ -150,6 +151,24 @@ protected: }; #endif // QT_NO_LINEEDIT +#ifndef QT_NO_PROGRESSBAR +class QAccessibleProgressBar : public QAccessibleDisplay, public QAccessibleValueInterface +{ + Q_ACCESSIBLE_OBJECT +public: + explicit QAccessibleProgressBar(QWidget *o); + + // QAccessibleValueInterface + QVariant currentValue(); + QVariant maximumValue(); + QVariant minimumValue(); + inline void setCurrentValue(const QVariant &) {} + +protected: + QProgressBar *progressBar() const; +}; +#endif + #endif // QT_NO_ACCESSIBILITY QT_END_NAMESPACE -- cgit v0.12 From 339b5b04a98ad3a5569180b0a1a000e82e985867 Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Tue, 20 Oct 2009 17:45:48 +0200 Subject: Introduce the QAccessibleActionInterface with a sample implementation for QAccessibleButton. Not implemented for all widgets yet (API is preliminary). Patch has been in the accessibility-fixes branch of qt-maemo for quite a while now without complains, thus no reviewer. --- src/gui/accessible/qaccessible.h | 7 ++- src/gui/accessible/qaccessible2.cpp | 12 +++++ src/gui/accessible/qaccessible2.h | 16 +++++++ src/plugins/accessible/widgets/simplewidgets.cpp | 56 ++++++++++++++++++++++++ src/plugins/accessible/widgets/simplewidgets.h | 14 +++++- 5 files changed, 103 insertions(+), 2 deletions(-) diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h index 96fe91c..8f6d9d9 100644 --- a/src/gui/accessible/qaccessible.h +++ b/src/gui/accessible/qaccessible.h @@ -310,7 +310,8 @@ namespace QAccessible2 TextInterface, EditableTextInterface, ValueInterface, - TableInterface + TableInterface, + ActionInterface }; } @@ -319,6 +320,7 @@ class QAccessibleTextInterface; class QAccessibleEditableTextInterface; class QAccessibleValueInterface; class QAccessibleTableInterface; +class QAccessibleActionInterface; class Q_GUI_EXPORT QAccessibleInterface : public QAccessible { @@ -376,6 +378,9 @@ public: inline QAccessibleTableInterface *tableInterface() { return reinterpret_cast(cast_helper(QAccessible2::TableInterface)); } + inline QAccessibleActionInterface *actionInterface() + { return reinterpret_cast(cast_helper(QAccessible2::ActionInterface)); } + private: QAccessible2Interface *cast_helper(QAccessible2::InterfaceType); }; diff --git a/src/gui/accessible/qaccessible2.cpp b/src/gui/accessible/qaccessible2.cpp index f731962..0867368 100644 --- a/src/gui/accessible/qaccessible2.cpp +++ b/src/gui/accessible/qaccessible2.cpp @@ -108,6 +108,18 @@ QT_BEGIN_NAMESPACE \link http://www.linux-foundation.org/en/Accessibility/IAccessible2 IAccessible2 Specification \endlink */ +/*! + \class QAccessibleActionInterface + \ingroup accessibility + \internal + \preliminary + + \brief The QAccessibleActionInterface class implements support for + the IAccessibleAction interface. + + \link http://www.linux-foundation.org/en/Accessibility/IAccessible2 IAccessible2 Specification \endlink +*/ + QAccessibleSimpleEditableTextInterface::QAccessibleSimpleEditableTextInterface( QAccessibleInterface *accessibleInterface) : iface(accessibleInterface) diff --git a/src/gui/accessible/qaccessible2.h b/src/gui/accessible/qaccessible2.h index 3281509..435c640 100644 --- a/src/gui/accessible/qaccessible2.h +++ b/src/gui/accessible/qaccessible2.h @@ -81,6 +81,7 @@ inline QAccessible2Interface *qAccessibleValueCastHelper() { return 0; } inline QAccessible2Interface *qAccessibleTextCastHelper() { return 0; } inline QAccessible2Interface *qAccessibleEditableTextCastHelper() { return 0; } inline QAccessible2Interface *qAccessibleTableCastHelper() { return 0; } +inline QAccessible2Interface *qAccessibleActionCastHelper() { return 0; } #define Q_ACCESSIBLE_OBJECT \ public: \ @@ -95,6 +96,8 @@ inline QAccessible2Interface *qAccessibleTableCastHelper() { return 0; } return qAccessibleValueCastHelper(); \ case QAccessible2::TableInterface: \ return qAccessibleTableCastHelper(); \ + case QAccessible2::ActionInterface: \ + return qAccessibleActionCastHelper(); \ } \ return 0; \ } \ @@ -208,6 +211,19 @@ public: int *columnSpan, bool *isSelected) = 0; }; +class Q_GUI_EXPORT QAccessibleActionInterface : public QAccessible2Interface +{ +public: + inline QAccessible2Interface *qAccessibleActionCastHelper() { return this; } + + virtual int actionCount() = 0; + virtual void doAction(int actionIndex) = 0; + virtual QString description(int actionIndex) = 0; + virtual QString name(int actionIndex) = 0; + virtual QString localizedName(int actionIndex) = 0; + virtual QStringList keyBindings(int actionIndex) = 0; +}; + #endif // QT_NO_ACCESSIBILITY QT_END_NAMESPACE diff --git a/src/plugins/accessible/widgets/simplewidgets.cpp b/src/plugins/accessible/widgets/simplewidgets.cpp index 89482bb..aa51759 100644 --- a/src/plugins/accessible/widgets/simplewidgets.cpp +++ b/src/plugins/accessible/widgets/simplewidgets.cpp @@ -209,6 +209,62 @@ QAccessible::State QAccessibleButton::state(int child) const return state; } +int QAccessibleButton::actionCount() +{ + return 1; +} + +void QAccessibleButton::doAction(int actionIndex) +{ + switch (actionIndex) { + case 0: + button()->click(); + break; + } +} + +QString QAccessibleButton::description(int actionIndex) +{ + switch (actionIndex) { + case 0: + return QLatin1String("Clicks the button."); + default: + return QString(); + } +} + +QString QAccessibleButton::name(int actionIndex) +{ + switch (actionIndex) { + case 0: + return QLatin1String("Press"); + default: + return QString(); + } +} + +QString QAccessibleButton::localizedName(int actionIndex) +{ + switch (actionIndex) { + case 0: + return tr("Press"); + default: + return QString(); + } +} + +QStringList QAccessibleButton::keyBindings(int actionIndex) +{ + switch (actionIndex) { +#ifdef QT_NO_SHORTCUT + case 0: + return button()->shortcut().toString(); +#endif + default: + return QStringList(); + } +} + #ifndef QT_NO_TOOLBUTTON /*! \class QAccessibleToolButton diff --git a/src/plugins/accessible/widgets/simplewidgets.h b/src/plugins/accessible/widgets/simplewidgets.h index 8de35ef..0c1cf5e 100644 --- a/src/plugins/accessible/widgets/simplewidgets.h +++ b/src/plugins/accessible/widgets/simplewidgets.h @@ -42,6 +42,7 @@ #ifndef SIMPLEWIDGETS_H #define SIMPLEWIDGETS_H +#include #include #include @@ -54,8 +55,10 @@ class QLineEdit; class QToolButton; class QProgressBar; -class QAccessibleButton : public QAccessibleWidgetEx +class QAccessibleButton : public QAccessibleWidgetEx, public QAccessibleActionInterface { + Q_ACCESSIBLE_OBJECT + Q_DECLARE_TR_FUNCTIONS(QAccessibleButton) public: QAccessibleButton(QWidget *w, Role r); @@ -65,6 +68,14 @@ public: QString actionText(int action, Text text, int child) const; bool doAction(int action, int child, const QVariantList ¶ms); + // QAccessibleActionInterface + int actionCount(); + void doAction(int actionIndex); + QString description(int actionIndex); + QString name(int actionIndex); + QString localizedName(int actionIndex); + QStringList keyBindings(int actionIndex); + protected: QAbstractButton *button() const; }; @@ -102,6 +113,7 @@ protected: class QAccessibleDisplay : public QAccessibleWidgetEx { + Q_ACCESSIBLE_OBJECT public: explicit QAccessibleDisplay(QWidget *w, Role role = StaticText); -- cgit v0.12 From 613866eb719e35fa2459cb12d46315ca9dcefa62 Mon Sep 17 00:00:00 2001 From: Liang QI Date: Tue, 20 Oct 2009 18:35:11 +0200 Subject: Fix tst_QHeaderView::length() on Symbian. Just the default font size will not work for this case. We set it to smaller one. Notice: we should make sure view->length() is different between view->setStretchLastSection(true) and view->setStretchLastSection(false). RevBy: Aleksandar Babic --- tests/auto/qheaderview/tst_qheaderview.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/auto/qheaderview/tst_qheaderview.cpp b/tests/auto/qheaderview/tst_qheaderview.cpp index 3286768..c13e829 100644 --- a/tests/auto/qheaderview/tst_qheaderview.cpp +++ b/tests/auto/qheaderview/tst_qheaderview.cpp @@ -682,9 +682,12 @@ void tst_QHeaderView::visualIndexAt() void tst_QHeaderView::length() { -#ifdef Q_OS_WINCE +#if defined(Q_OS_WINCE) QFont font(QLatin1String("Tahoma"), 7); view->setFont(font); +#elif defined(Q_OS_SYMBIAN) + QFont font(QLatin1String("Series 60 Sans"), 6); + view->setFont(font); #endif view->setStretchLastSection(true); view->show(); -- cgit v0.12 From 1315bcdd1e2add0ce26f0cb9a4d2a95477434315 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Tue, 20 Oct 2009 20:24:44 +0200 Subject: Ensure qmake does not lose the error code when going over the subdirs When qmake was ran with -r over a subdirs project then it would lose the error code if a later project succeeded. This is a refix of the previous revert which has been confirmed to work all over the place now. Reviewed-by: Marius Storm-Olsen --- qmake/generators/metamakefile.cpp | 17 ++++++++++++----- qmake/generators/metamakefile.h | 2 +- qmake/main.cpp | 6 +++++- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/qmake/generators/metamakefile.cpp b/qmake/generators/metamakefile.cpp index 5915fcf..819cdaf 100644 --- a/qmake/generators/metamakefile.cpp +++ b/qmake/generators/metamakefile.cpp @@ -291,6 +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; @@ -336,14 +337,18 @@ SubdirsMetaMakefileGenerator::init() } qmake_setpwd(sub->input_dir); Option::output_dir = sub->output_dir; - sub_proj->read(subdir.fileName()); + bool tmpError = !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(), sub_proj->values("QMAKE_FAILED_REQUIREMENTS").join(" ").toLatin1().constData()); delete sub; delete sub_proj; + Option::output_dir = old_output_dir; + qmake_setpwd(oldpwd); continue; + } else { + hasError |= tmpError; } sub->makefile = MetaMakefileGenerator::createMetaGenerator(sub_proj, sub_name); if(0 && sub->makefile->type() == SUBDIRSMETATYPE) { @@ -351,7 +356,7 @@ SubdirsMetaMakefileGenerator::init() } else { const QString output_name = Option::output.fileName(); Option::output.setFileName(sub->output_file); - sub->makefile->write(sub->output_dir); + hasError |= !sub->makefile->write(sub->output_dir); delete sub; qmakeClearCaches(); sub = 0; @@ -376,7 +381,7 @@ SubdirsMetaMakefileGenerator::init() self->makefile->init(); subs.append(self); - return true; + return !hasError; } bool @@ -482,7 +487,7 @@ MetaMakefileGenerator::createMakefileGenerator(QMakeProject *proj, bool noIO) } MetaMakefileGenerator * -MetaMakefileGenerator::createMetaGenerator(QMakeProject *proj, const QString &name, bool op) +MetaMakefileGenerator::createMetaGenerator(QMakeProject *proj, const QString &name, bool op, bool *success) { MetaMakefileGenerator *ret = 0; if ((Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || @@ -492,7 +497,9 @@ MetaMakefileGenerator::createMetaGenerator(QMakeProject *proj, const QString &na } if (!ret) ret = new BuildsMetaMakefileGenerator(proj, name, op); - ret->init(); + bool res = ret->init(); + if (success) + *success = res; return ret; } diff --git a/qmake/generators/metamakefile.h b/qmake/generators/metamakefile.h index e69304a..f74f4a2 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); + static MetaMakefileGenerator *createMetaGenerator(QMakeProject *proj, const QString &name, bool op=true, bool *success = 0); 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 73fdda9..a0346c5 100644 --- a/qmake/main.cpp +++ b/qmake/main.cpp @@ -168,7 +168,11 @@ int runQMake(int argc, char **argv) continue; } - MetaMakefileGenerator *mkfile = MetaMakefileGenerator::createMetaGenerator(&project, QString(), false); + bool success = true; + MetaMakefileGenerator *mkfile = MetaMakefileGenerator::createMetaGenerator(&project, QString(), false, &success); + if (!success) + exit_val = 3; + 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 7997279bc22d30bf1d1a30a567bda33ecc9aeb2d Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Wed, 21 Oct 2009 07:48:52 +1000 Subject: Increase PowerVR memory alignment from 8 to 32 for SGX systems. Increasing the alignment does not seem to affect MBX. --- src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.c b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.c index 17345a9..a9c22ef 100644 --- a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.c +++ b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.c @@ -662,7 +662,7 @@ int pvrQwsAllocBuffers(PvrQwsDrawable *drawable) PVR2DMemFree(pvrQwsDisplay.context, drawable->backBuffers[index]); } } - drawable->stridePixels = (drawable->rect.width + 7) & ~7; + drawable->stridePixels = (drawable->rect.width + 31) & ~31; drawable->strideBytes = drawable->stridePixels * pvrQwsDisplay.screens[drawable->screen].bytesPerPixel; -- cgit v0.12