From ab56759cefbcf2072ac777f0d897e561f5a3c8af Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 1 Apr 2009 13:53:02 +0200 Subject: don't display warning message when calling checksdk -list checksdk -list now displays the list of available SDK without yielding the warning message "No SDK specified: Defaulting to ...". Reviewed-by: mauricek --- tools/checksdk/main.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/checksdk/main.cpp b/tools/checksdk/main.cpp index 1d4b616..717f5c9 100644 --- a/tools/checksdk/main.cpp +++ b/tools/checksdk/main.cpp @@ -97,12 +97,6 @@ int main(int argc, char **argv) } } - // Check for SDK Name, otherwise use Windows Mobile as default - if (sdkName.isEmpty()) { - qWarning("No SDK specified: Defaulting to Windows Mobile 5.0 Pocket PC SDK"); - sdkName = QString::fromLatin1("Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"); - } - CeSdkHandler handler; if (!handler.parse()) { qWarning("Could not find any installed SDK, aborting!"); @@ -118,6 +112,12 @@ int main(int argc, char **argv) return 0; } + // Check for SDK Name, otherwise use Windows Mobile as default + if (sdkName.isEmpty()) { + qWarning("No SDK specified: Defaulting to Windows Mobile 5.0 Pocket PC SDK"); + sdkName = QString::fromLatin1("Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"); + } + // finally find the given SDK and prompt out the environment to be set for (QList::iterator it = list.begin(); it != list.end(); ++it ) { if (sdkName == it->name()) { -- cgit v0.12 From 38b5bff2fab59e965aba59b4f121a7c8945e4d75 Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Mon, 6 Apr 2009 12:39:13 +0200 Subject: Doc - Clarified that button style on X11 platforms may depend on the desktop environment. Task-number: 250338 Reviewed-by: Jens Bache-Wiig --- src/gui/widgets/qdialogbuttonbox.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/widgets/qdialogbuttonbox.cpp b/src/gui/widgets/qdialogbuttonbox.cpp index 246da95..4a95292 100644 --- a/src/gui/widgets/qdialogbuttonbox.cpp +++ b/src/gui/widgets/qdialogbuttonbox.cpp @@ -752,7 +752,8 @@ QDialogButtonBox::~QDialogButtonBox() \value KdeLayout Use a policy appropriate for applications on KDE. \value GnomeLayout Use a policy appropriate for applications on GNOME. - The button layout is specified by the \l{style()}{current style}. + The button layout is specified by the \l{style()}{current style}. However, + on the X11 platform, it may be influenced by the desktop environment. */ /*! -- cgit v0.12 From 1a125061f201bb7ee746f1eddc0604cd85a6545c Mon Sep 17 00:00:00 2001 From: jasplin Date: Mon, 6 Apr 2009 12:43:53 +0200 Subject: Corrected typo. Reviewed-by: jasplin --- dist/README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/README b/dist/README index 110be1c..38b3a1c 100644 --- a/dist/README +++ b/dist/README @@ -114,7 +114,7 @@ HOW TO REPORT A BUG If you think you have found a bug in Qt, we would like to hear about it so that we can fix it. Before reporting a bug, please check http://qtsoftware.com/developer/faqs/ and -http://qtsoftware.com/products/appdev/platform/platforms/ to see if the to see if +http://qtsoftware.com/products/appdev/platform/platforms/ to see if the issue is already known. Always include the following information in your bug report: the name -- cgit v0.12 From 73f5131793d52d93b18a40d36599e063f18246e9 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 6 Apr 2009 11:18:34 +0200 Subject: Install the animation.mng file. Otherwise, for people who install Qt (everyone outside Nokia), the animation file isn't present. Reviewed-by: Trust Me BT: yes --- examples/widgets/movie/movie.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/widgets/movie/movie.pro b/examples/widgets/movie/movie.pro index b5f0a7a..1c7cbae 100644 --- a/examples/widgets/movie/movie.pro +++ b/examples/widgets/movie/movie.pro @@ -4,6 +4,6 @@ SOURCES = main.cpp \ # install target.path = $$[QT_INSTALL_EXAMPLES]/widgets/movie -sources.files = $$SOURCES $$HEADERS $$RESOURCES movie.pro movies +sources.files = $$SOURCES $$HEADERS $$RESOURCES movie.pro animation.mng sources.path = $$[QT_INSTALL_EXAMPLES]/widgets/movie INSTALLS += target sources -- cgit v0.12 From 5bb504a78cad5e38cd522785a37898f4e88cd272 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 6 Apr 2009 13:16:39 +0200 Subject: Rename these files to have lowercase .txt extension. mkdist doesn't case-insensitive comparison. Reviewed-by: TrustMe BT: yes --- FAQ | 18 ------------------ FAQ.txt | 18 ++++++++++++++++++ LGPL_EXCEPTION.TXT | 3 --- LGPL_EXCEPTION.txt | 3 +++ 4 files changed, 21 insertions(+), 21 deletions(-) delete mode 100644 FAQ create mode 100644 FAQ.txt delete mode 100644 LGPL_EXCEPTION.TXT create mode 100644 LGPL_EXCEPTION.txt diff --git a/FAQ b/FAQ deleted file mode 100644 index c243e5c..0000000 --- a/FAQ +++ /dev/null @@ -1,18 +0,0 @@ -This is a list of Frequently Asked Questions regarding Qt Release 4.5.0. - -Q: I'm using a Unix system and I downloaded the Zip package. However, when I try -to run the configure script, I get the following error message: -"bash: ./configure: /bin/sh^M: bad interpreter: No such file or directory" -A: The problem here is converting files from Windows style line endings (CRLF) -to Unix style line endings (LF). To avoid this problem, uncompress the file -again and give the option "-a" to unzip, which will then add the correct line -endings. - -Q: I'm running Windows XP and I downloaded the qt-win-eval-4.5.0-vs2008.exe -version of Qt. However, when I try to run the examples I get an error saying: -"The application failed to start because the application configuration is -incorrect. Reinstalling the application may fix this problem.". I reinstalled -the package but the error persists. What am I doing wrong? -A: The problem is an incorrect version of the CRT. Visual studio requires CRT90 -while Windows XP comes with CRT80. To solve this problem, please install the -2008 CRT redistributable package from Microsoft. diff --git a/FAQ.txt b/FAQ.txt new file mode 100644 index 0000000..c243e5c --- /dev/null +++ b/FAQ.txt @@ -0,0 +1,18 @@ +This is a list of Frequently Asked Questions regarding Qt Release 4.5.0. + +Q: I'm using a Unix system and I downloaded the Zip package. However, when I try +to run the configure script, I get the following error message: +"bash: ./configure: /bin/sh^M: bad interpreter: No such file or directory" +A: The problem here is converting files from Windows style line endings (CRLF) +to Unix style line endings (LF). To avoid this problem, uncompress the file +again and give the option "-a" to unzip, which will then add the correct line +endings. + +Q: I'm running Windows XP and I downloaded the qt-win-eval-4.5.0-vs2008.exe +version of Qt. However, when I try to run the examples I get an error saying: +"The application failed to start because the application configuration is +incorrect. Reinstalling the application may fix this problem.". I reinstalled +the package but the error persists. What am I doing wrong? +A: The problem is an incorrect version of the CRT. Visual studio requires CRT90 +while Windows XP comes with CRT80. To solve this problem, please install the +2008 CRT redistributable package from Microsoft. diff --git a/LGPL_EXCEPTION.TXT b/LGPL_EXCEPTION.TXT deleted file mode 100644 index 8d0f85e..0000000 --- a/LGPL_EXCEPTION.TXT +++ /dev/null @@ -1,3 +0,0 @@ -Nokia Qt LGPL Exception version 1.0 - -As a special exception to the GNU Lesser General Public License version 2.1, the object code form of a "work that uses the Library" may incorporate material from a header file that is part of the Library. You may distribute such object code under terms of your choice, provided that the incorporated material (i) does not exceed more than 5% of the total size of the Library; and (ii) is limited to numerical parameters, data structure layouts, accessors, macros, inline functions and templates. \ No newline at end of file diff --git a/LGPL_EXCEPTION.txt b/LGPL_EXCEPTION.txt new file mode 100644 index 0000000..8d0f85e --- /dev/null +++ b/LGPL_EXCEPTION.txt @@ -0,0 +1,3 @@ +Nokia Qt LGPL Exception version 1.0 + +As a special exception to the GNU Lesser General Public License version 2.1, the object code form of a "work that uses the Library" may incorporate material from a header file that is part of the Library. You may distribute such object code under terms of your choice, provided that the incorporated material (i) does not exceed more than 5% of the total size of the Library; and (ii) is limited to numerical parameters, data structure layouts, accessors, macros, inline functions and templates. \ No newline at end of file -- cgit v0.12 From cf65dea821a2ba796bb1f32c80de6b9db224dff5 Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Mon, 6 Apr 2009 13:15:00 +0200 Subject: Doc - Mentioned what the default filters are for QFileSystemModel::filter(). Task-number: 250285 Reviewed-by: Benjamin Poulain --- src/gui/dialogs/qfilesystemmodel.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/dialogs/qfilesystemmodel.cpp b/src/gui/dialogs/qfilesystemmodel.cpp index c7b3137..012d3a1 100644 --- a/src/gui/dialogs/qfilesystemmodel.cpp +++ b/src/gui/dialogs/qfilesystemmodel.cpp @@ -1430,7 +1430,10 @@ void QFileSystemModel::setFilter(QDir::Filters filters) } /*! - Returns the filter specification for the directory model. + Returns the filter specified for the directory model. + + If a filter has not been set, the default filter is QDir::AllEntries | + QDir::NoDotAndDotDot | QDir::AllDirs. \sa QDir::Filters */ -- cgit v0.12 From e27743bdeda7aa3cb42f2d81a521121f8ee04eae Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Wed, 25 Feb 2009 12:18:28 +0100 Subject: Fixes: Optimize QGraphicsView::itemUpdated. Task: - RevBy: Andreas AutoTest: - Details: Accumulate the parentToItem transform as we iterate instead of creating it from bottom-up each time. --- src/gui/graphicsview/qgraphicsview.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 2f7f57a..9b0e12d 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -804,10 +804,17 @@ void QGraphicsViewPrivate::itemUpdated(QGraphicsItem *item, const QRectF &rect) if (item->isClipped()) { // Minimize unnecessary redraw. QGraphicsItem *p = item; + QTransform xform; + QGraphicsItem *lastTransformItem = 0; while ((p = p->d_ptr->parent)) { if (p->flags() & QGraphicsItem::ItemClipsChildrenToShape) { - updateRect &= p->itemTransform(item).mapRect(p->boundingRect()); - if (updateRect.isNull()) + if (!lastTransformItem) + xform = item->itemTransform(p); + else + xform *= lastTransformItem->itemTransform(p); + lastTransformItem = p; + updateRect &= xform.inverted().mapRect(p->boundingRect()); + if (updateRect.isEmpty()) return; } @@ -815,7 +822,7 @@ void QGraphicsViewPrivate::itemUpdated(QGraphicsItem *item, const QRectF &rect) break; } - if (updateRect.isNull()) + if (updateRect.isEmpty()) return; } -- cgit v0.12 From be6be8c73929f2ddee9a02f59db05c3ba453a63e Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Thu, 26 Feb 2009 14:49:47 +0100 Subject: Fixes: Optimize QGraphicsViewPrivate::updateRect()/updateRegion(). Details: Those cut-offs are extremely important. After few seconds interaction with the iphone demo, updateRect() was called approx. 3000 times with an empty rect. Then imagine what happens when having e.g. FullViewportUpdate. We do q->viewport()->update() JUST FOR FUN! --- src/gui/graphicsview/qgraphicsview.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 9b0e12d..aa5f069 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -928,6 +928,9 @@ void QGraphicsViewPrivate::updateAll() void QGraphicsViewPrivate::updateRegion(const QRegion &r) { + if (r.isEmpty()) + return; + Q_Q(QGraphicsView); // Rect intersects viewport - update everything? @@ -976,6 +979,9 @@ void QGraphicsViewPrivate::updateRegion(const QRegion &r) void QGraphicsViewPrivate::updateRect(const QRect &r) { + if (r.isEmpty()) + return; + Q_Q(QGraphicsView); // Rect intersects viewport - update everything? -- cgit v0.12 From e9fa8ba1ad0b0b2d3363fb33635071677f42b983 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Thu, 26 Feb 2009 15:00:08 +0100 Subject: Fixes: Cleanup calls to QGraphicsViewPrivate::updateRect()/updateRegion() Details: Checking for QRect::isNull() was wrong in the first place, and checking for isEmpty()/isNull() is overhead after 4a491a84aeba68279927597a261522dcc23bb3ff. --- src/gui/graphicsview/qgraphicsview.cpp | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index aa5f069..b92c886 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -829,17 +829,10 @@ void QGraphicsViewPrivate::itemUpdated(QGraphicsItem *item, const QRectF &rect) // Map the rect to view coordinates. QRect vr = viewport->rect(); - if (!item->d_ptr->hasBoundingRegionGranularity) { - QRect r = mapToViewRect(item, updateRect) & vr; - if (r.isNull()) - return; - this->updateRect(r); - } else { - QRegion r = mapToViewRegion(item, updateRect) & vr; - if (r.isEmpty()) - return; - updateRegion(r); - } + if (!item->d_ptr->hasBoundingRegionGranularity) + this->updateRect(mapToViewRect(item, updateRect) & vr); + else + updateRegion(mapToViewRegion(item, updateRect) & vr); } void QGraphicsViewPrivate::updateLater() @@ -863,9 +856,7 @@ void QGraphicsViewPrivate::_q_updateLaterSlot() for (int i = 0; i < dirtyItems.size(); ++i) { const QGraphicsItem *item = dirtyItems.at(i); QTransform x = item->sceneTransform() * viewTransform; - QRect viewRect = x.mapRect(item->boundingRect()).toAlignedRect() & vr; - if (!viewRect.isNull()) - updateRect(viewRect); + updateRect(x.mapRect(item->boundingRect()).toAlignedRect() & vr); } dirtyRectCount += dirtyRects.size(); -- cgit v0.12 From 8a2ebc96220f50be3a9c382c32d7eaab89921ff7 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Thu, 26 Feb 2009 15:47:04 +0100 Subject: Fixes: Use QRect::isEmpty() rather than isNull() if possible. RevBy: Andreas Details: Note that isNull() implies isEmpty(), but it only catches the cases where width and height is 0. --- src/gui/graphicsview/qgraphicsitem.cpp | 2 +- src/gui/graphicsview/qgraphicsscene.cpp | 2 +- src/gui/graphicsview/qgraphicsview.cpp | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 83a7e67..b982393 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -3757,7 +3757,7 @@ bool QGraphicsItemPrivate::isProxyWidget() const */ void QGraphicsItem::update(const QRectF &rect) { - if (d_ptr->dirty) + if (d_ptr->dirty || (rect.isEmpty() && !rect.isNull())) return; if (d_ptr->scene && isVisible()) { if (CacheMode(d_ptr->cacheMode) != NoCache) { diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index ff46e2e..9b06945 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -3455,7 +3455,7 @@ QVariant QGraphicsScene::inputMethodQuery(Qt::InputMethodQuery query) const void QGraphicsScene::update(const QRectF &rect) { Q_D(QGraphicsScene); - if (d->updateAll) + if (d->updateAll || (rect.isEmpty() && !rect.isNull())) return; // Check if anyone's connected; if not, we can send updates directly to diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index b92c886..f88918f 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -862,7 +862,7 @@ void QGraphicsViewPrivate::_q_updateLaterSlot() dirtyRectCount += dirtyRects.size(); bool noUpdate = !fullUpdatePending && viewportUpdateMode == QGraphicsView::FullViewportUpdate; - if ((dirtyRectCount > 0 || !dirtyBoundingRect.isNull()) && !fullUpdatePending && !noUpdate) { + if ((dirtyRectCount > 0 || !dirtyBoundingRect.isEmpty()) && !fullUpdatePending && !noUpdate) { if (viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate || (viewportUpdateMode == QGraphicsView::SmartViewportUpdate && dirtyRectCount >= QGRAPHICSVIEW_REGION_RECT_THRESHOLD)) { @@ -3284,7 +3284,7 @@ void QGraphicsView::mouseMoveEvent(QMouseEvent *event) } // Update old rubberband - if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate && !d->rubberBandRect.isNull()) { + if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate && !d->rubberBandRect.isEmpty()) { if (d->viewportUpdateMode != FullViewportUpdate) viewport()->update(d->rubberBandRegion(viewport(), d->rubberBandRect)); else @@ -3466,7 +3466,7 @@ void QGraphicsView::paintEvent(QPaintEvent *event) QPainter painter(viewport()); QTransform original = painter.worldTransform(); #ifndef QT_NO_RUBBERBAND - if (d->rubberBanding && !d->rubberBandRect.isNull()) + if (d->rubberBanding && !d->rubberBandRect.isEmpty()) painter.save(); #endif // Set up render hints @@ -3561,7 +3561,7 @@ void QGraphicsView::paintEvent(QPaintEvent *event) #ifndef QT_NO_RUBBERBAND // Rubberband - if (d->rubberBanding && !d->rubberBandRect.isNull()) { + if (d->rubberBanding && !d->rubberBandRect.isEmpty()) { painter.restore(); QStyleOptionRubberBand option; option.initFrom(viewport()); @@ -3645,7 +3645,7 @@ void QGraphicsView::scrollContentsBy(int dx, int dy) #ifndef QT_NO_RUBBERBAND // Update old rubberband - if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate && !d->rubberBandRect.isNull()) { + if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate && !d->rubberBandRect.isEmpty()) { if (d->viewportUpdateMode != FullViewportUpdate) viewport()->update(d->rubberBandRegion(viewport(), d->rubberBandRect)); else -- cgit v0.12 From eda77b7c410a59d1b77c263994679452613d9d0b Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Fri, 27 Feb 2009 16:00:55 +0100 Subject: Fixes: Small optimization: reduce calls to QTransform::type(). Task: none RevBy: Ariya Hidayat AutoTest: Still pass. Details: QTransform::type() is cached, so only the first call to it should be expensive. However, it is not inlined so there's an overhead involved (especially when these functions are called a gazillion times). --- src/gui/painting/qtransform.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp index c70208c..c120143 100644 --- a/src/gui/painting/qtransform.cpp +++ b/src/gui/painting/qtransform.cpp @@ -1222,7 +1222,8 @@ static QPolygonF mapProjective(const QTransform &transform, const QPolygonF &pol */ QPolygonF QTransform::map(const QPolygonF &a) const { - if (type() >= QTransform::TxProject) + TransformationType t = type(); + if (t >= QTransform::TxProject) return mapProjective(*this, a); int size = a.size(); @@ -1231,7 +1232,6 @@ QPolygonF QTransform::map(const QPolygonF &a) const const QPointF *da = a.constData(); QPointF *dp = p.data(); - TransformationType t = type(); for(i = 0; i < size; ++i) { MAP(da[i].xp, da[i].yp, dp[i].xp, dp[i].yp); } @@ -1249,7 +1249,8 @@ QPolygonF QTransform::map(const QPolygonF &a) const */ QPolygon QTransform::map(const QPolygon &a) const { - if (type() >= QTransform::TxProject) + TransformationType t = type(); + if (t >= QTransform::TxProject) return mapProjective(*this, QPolygonF(a)).toPolygon(); int size = a.size(); @@ -1258,7 +1259,6 @@ QPolygon QTransform::map(const QPolygon &a) const const QPoint *da = a.constData(); QPoint *dp = p.data(); - TransformationType t = type(); for(i = 0; i < size; ++i) { qreal nx = 0, ny = 0; MAP(da[i].xp, da[i].yp, nx, ny); @@ -2061,10 +2061,11 @@ QTransform::operator QVariant() const Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale) { - if (transform.type() <= QTransform::TxTranslate) { + const QTransform::TransformationType type = transform.type(); + if (type <= QTransform::TxTranslate) { *scale = 1; return true; - } else if (transform.type() == QTransform::TxScale) { + } else if (type == QTransform::TxScale) { const qreal xScale = qAbs(transform.m11()); const qreal yScale = qAbs(transform.m22()); *scale = qMax(xScale, yScale); @@ -2076,7 +2077,7 @@ bool qt_scaleForTransform(const QTransform &transform, qreal *scale) const qreal yScale = transform.m12() * transform.m12() + transform.m22() * transform.m22(); *scale = qSqrt(qMax(xScale, yScale)); - return transform.type() == QTransform::TxRotate && qFuzzyCompare(xScale, yScale); + return type == QTransform::TxRotate && qFuzzyCompare(xScale, yScale); } QT_END_NAMESPACE -- cgit v0.12 From b4456f8775c36bcb2ceef9ca1a00c7765f1d2735 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Fri, 27 Feb 2009 18:10:08 +0100 Subject: Fixes: Get rid of a gazillion calls to QTransform::operator*=. Details: Be a little bit smarter before doing *= :) --- src/gui/graphicsview/qgraphicsitem.cpp | 38 +++++++++++++++++++++------------ src/gui/graphicsview/qgraphicsscene.cpp | 5 +++-- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index b982393..bb95543 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -2511,10 +2511,10 @@ QTransform QGraphicsItem::sceneTransform() const QTransform m; if (d_ptr->hasTransform) { m = transform(); - m *= QTransform::fromTranslate(d_ptr->pos.x(), d_ptr->pos.y()); - } else { - // ### ? QTransform::fromTranslate(d_ptr->pos.x(), d_ptr->pos.y()) - m.translate(d_ptr->pos.x(), d_ptr->pos.y()); + if (!d_ptr->pos.isNull()) + m *= QTransform::fromTranslate(d_ptr->pos.x(), d_ptr->pos.y()); + } else if (!d_ptr->pos.isNull()) { + m = QTransform::fromTranslate(d_ptr->pos.x(), d_ptr->pos.y()); } // Combine with parent and add to cache. @@ -2639,6 +2639,8 @@ QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) co if (ok) *ok = true; const QPointF &itemPos = d_ptr->pos; + if (itemPos.isNull()) + return d_ptr->hasTransform ? transform() : QTransform(); if (d_ptr->hasTransform) return transform() * QTransform::fromTranslate(itemPos.x(), itemPos.y()); return QTransform::fromTranslate(itemPos.x(), itemPos.y()); @@ -2649,7 +2651,8 @@ QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) co const QPointF &otherPos = other->d_ptr->pos; if (other->d_ptr->hasTransform) { QTransform otherToParent = other->transform(); - otherToParent *= QTransform::fromTranslate(otherPos.x(), otherPos.y()); + if (!otherPos.isNull()) + otherToParent *= QTransform::fromTranslate(otherPos.x(), otherPos.y()); return otherToParent.inverted(ok); } else { if (ok) @@ -2674,11 +2677,11 @@ QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) co QTransform itemToParent = QTransform::fromTranslate(itemPos.x(), itemPos.y()); if (hasTr) - itemToParent = transform() * itemToParent; + itemToParent = itemPos.isNull() ? transform() : transform() * itemToParent; QTransform otherToParent = QTransform::fromTranslate(otherPos.x(), otherPos.y()); if (otherHasTr) - otherToParent = other->transform() * otherToParent; + otherToParent = otherPos.isNull() ? other->transform() : other->transform() * otherToParent; return itemToParent * otherToParent.inverted(ok); } @@ -2718,7 +2721,8 @@ QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) co const QGraphicsItemPrivate *pd = p->d_ptr; if (pd->hasTransform) x *= p->transform(); - x *= QTransform::fromTranslate(pd->pos.x(), pd->pos.y()); + if (!pd->pos.isNull()) + x *= QTransform::fromTranslate(pd->pos.x(), pd->pos.y()); } while ((p = p->d_ptr->parent) && p != root); if (parentOfOther) return x.inverted(ok); @@ -2995,7 +2999,9 @@ QRectF QGraphicsItem::childrenBoundingRect() const QRectF childRect; foreach (QGraphicsItem *child, children()) { QPointF childPos = child->pos(); - QTransform matrix = child->transform() * QTransform::fromTranslate(childPos.x(), childPos.y()); + QTransform matrix = child->transform(); + if (!childPos.isNull()) + matrix *= QTransform::fromTranslate(childPos.x(), childPos.y()); childRect |= matrix.mapRect(child->boundingRect() | child->childrenBoundingRect()); } return childRect; @@ -8544,13 +8550,17 @@ void QGraphicsItemGroup::addToGroup(QGraphicsItem *item) QTransform oldSceneMatrix = item->sceneTransform(); item->setPos(mapFromItem(item, 0, 0)); item->setParentItem(this); - item->setTransform(oldSceneMatrix - * sceneTransform().inverted() - * QTransform::fromTranslate(-item->x(), -item->y())); + QTransform newItemTransform(oldSceneMatrix); + newItemTransform *= sceneTransform().inverted(); + if (!item->pos().isNull()) + newItemTransform *= QTransform::fromTranslate(-item->x(), -item->y()); + item->setTransform(newItemTransform); item->d_func()->setIsMemberOfGroup(true); prepareGeometryChange(); - d->itemsBoundingRect |= (item->transform() * QTransform::fromTranslate(item->x(), item->y())) - .mapRect(item->boundingRect() | item->childrenBoundingRect()); + QTransform itemTransform(item->transform()); + if (!item->pos().isNull()) + itemTransform *= QTransform::fromTranslate(item->x(), item->y()); + d->itemsBoundingRect |= itemTransform.mapRect(item->boundingRect() | item->childrenBoundingRect()); update(); } diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 9b06945..b509507 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4772,8 +4772,9 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte if (itemCache->allExposed || !itemCache->exposed.isEmpty() || !scrollExposure.isEmpty()) { // Construct an item-to-pixmap transform. QPointF p = deviceRect.topLeft(); - QTransform itemToPixmap = QTransform::fromTranslate(-p.x(), -p.y()); - itemToPixmap = painter->worldTransform() * itemToPixmap; + QTransform itemToPixmap = painter->worldTransform(); + if (!p.isNull()) + itemToPixmap *= QTransform::fromTranslate(-p.x(), -p.y()); // Map the item's logical expose to pixmap coordinates. QRegion pixmapExposed = scrollExposure; -- cgit v0.12 From fac3c7b73ba2c6b39332445ae00b2fe26a578913 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Mon, 2 Mar 2009 10:34:50 +0100 Subject: Fixes: Optimization: Important cut-offs for QTransform. Task: none RevBy: Samuel AutoTest: Still pass Details: Please do not perform (potentially expensive) calculations just for fun :) --- src/gui/painting/qtransform.cpp | 29 ++++++++++++++++++++++++++--- src/gui/painting/qtransform.h | 8 ++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp index c120143..fa808d0 100644 --- a/src/gui/painting/qtransform.cpp +++ b/src/gui/painting/qtransform.cpp @@ -399,6 +399,9 @@ QTransform QTransform::inverted(bool *invertible) const */ QTransform & QTransform::translate(qreal dx, qreal dy) { + if (dx == 0 && dy == 0) + return *this; + switch(type()) { case TxNone: affine._dx = dx; @@ -435,7 +438,10 @@ QTransform & QTransform::translate(qreal dx, qreal dy) QTransform QTransform::fromTranslate(qreal dx, qreal dy) { QTransform transform(1, 0, 0, 1, dx, dy); - transform.m_dirty = TxTranslate; + if (dx == 0 && dy == 0) + transform.m_dirty = TxNone; + else + transform.m_dirty = TxTranslate; return transform; } @@ -447,6 +453,9 @@ QTransform QTransform::fromTranslate(qreal dx, qreal dy) */ QTransform & QTransform::scale(qreal sx, qreal sy) { + if (sx == 1 && sy == 1) + return *this; + switch(type()) { case TxNone: case TxTranslate: @@ -481,7 +490,10 @@ QTransform & QTransform::scale(qreal sx, qreal sy) QTransform QTransform::fromScale(qreal sx, qreal sy) { QTransform transform(sx, 0, 0, sy, 0, 0); - transform.m_dirty = TxScale; + if (sx == 1 && sy == 1) + transform.m_dirty = TxNone; + else + transform.m_dirty = TxScale; return transform; } @@ -544,6 +556,9 @@ const qreal inv_dist_to_plane = 1. / 1024.; */ QTransform & QTransform::rotate(qreal a, Qt::Axis axis) { + if (a == 0) + return *this; + qreal sina = 0; qreal cosa = 0; if (a == 90. || a == -270.) @@ -715,7 +730,15 @@ bool QTransform::operator!=(const QTransform &o) const */ QTransform & QTransform::operator*=(const QTransform &o) { - TransformationType t = qMax(type(), o.type()); + const TransformationType otherType = o.type(); + if (otherType == TxNone) + return *this; + + const TransformationType thisType = type(); + if (thisType == TxNone) + return operator=(o); + + TransformationType t = qMax(thisType, otherType); switch(t) { case TxNone: break; diff --git a/src/gui/painting/qtransform.h b/src/gui/painting/qtransform.h index de7ebcd..c76409b 100644 --- a/src/gui/painting/qtransform.h +++ b/src/gui/painting/qtransform.h @@ -257,6 +257,8 @@ inline qreal QTransform::dy() const inline QTransform &QTransform::operator*=(qreal num) { + if (num == 1.) + return *this; affine._m11 *= num; affine._m12 *= num; m_13 *= num; @@ -271,11 +273,15 @@ inline QTransform &QTransform::operator*=(qreal num) } inline QTransform &QTransform::operator/=(qreal div) { + if (div == 0) + return *this; div = 1/div; return operator*=(div); } inline QTransform &QTransform::operator+=(qreal num) { + if (num == 0) + return *this; affine._m11 += num; affine._m12 += num; m_13 += num; @@ -290,6 +296,8 @@ inline QTransform &QTransform::operator+=(qreal num) } inline QTransform &QTransform::operator-=(qreal num) { + if (num == 0) + return *this; affine._m11 -= num; affine._m12 -= num; m_13 -= num; -- cgit v0.12 From ab130a0019fadeff4622778ca9f8b3e630da14da Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Mon, 2 Mar 2009 16:22:20 +0100 Subject: Fixes: Speed up QGrahicsItemPrivate::effectiveOpacity(). RevBy: Andreas AutoTest: tst_QGraphicsItem::opacity still passes --- src/gui/graphicsview/qgraphicsitem.cpp | 12 +++++++++++- src/gui/graphicsview/qgraphicsitem_p.h | 2 ++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index bb95543..cda1bd1 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1862,6 +1862,9 @@ qreal QGraphicsItem::opacity() const */ qreal QGraphicsItem::effectiveOpacity() const { + if (!d_ptr->hasEffectiveOpacity) + return qreal(1.0); + QVariant effectiveOpacity = d_ptr->extra(QGraphicsItemPrivate::ExtraEffectiveOpacity); return effectiveOpacity.isNull() ? qreal(1.0) : qreal(effectiveOpacity.toDouble()); } @@ -3680,7 +3683,14 @@ void QGraphicsItemPrivate::resolveEffectiveOpacity(qreal parentEffectiveOpacity) } // Set this item's resolved opacity. - setExtra(ExtraEffectiveOpacity, myEffectiveOpacity); + if (qFuzzyCompare(myEffectiveOpacity, qreal(1.0))) { + // Opaque, unset effective opacity. + hasEffectiveOpacity = 0; + unsetExtra(ExtraEffectiveOpacity); + } else { + hasEffectiveOpacity = 1; + setExtra(ExtraEffectiveOpacity, myEffectiveOpacity); + } // Resolve children always. for (int i = 0; i < children.size(); ++i) diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 07f6958..98fe6ed 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -133,6 +133,7 @@ public: hasBoundingRegionGranularity(0), flags(0), hasOpacity(0), + hasEffectiveOpacity(0), isWidget(0), dirty(0), dirtyChildren(0), @@ -262,6 +263,7 @@ public: // New 32 bytes quint32 hasOpacity : 1; + quint32 hasEffectiveOpacity : 1; quint32 isWidget : 1; quint32 dirty : 1; quint32 dirtyChildren : 1; -- cgit v0.12 From 7f50f45da0ad4a9eedd3ad7d8a82f719f7f8dd73 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Tue, 3 Mar 2009 13:06:05 +0100 Subject: Fixes: Optimize: QGraphicsItem::clipPath. RevBy: Andreas AutoTest: Still pass --- src/gui/graphicsview/qgraphicsitem.cpp | 46 +++++++++++----------------------- 1 file changed, 15 insertions(+), 31 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index cda1bd1..8b37648 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -3143,48 +3143,32 @@ QPainterPath QGraphicsItem::clipPath() const // Start with the item's bounding rect. clip.addRect(boundingRect()); - bool clipAway = false; if (d->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) { - // Make list of parents up to the farthest ancestor that clips its - // children to its shape. - QVarLengthArray clippingAncestors; - const QGraphicsItem *parent = parentItem(); - const QGraphicsItem *clipOwner = 0; - do { + const QGraphicsItem *parent = this; + const QGraphicsItem *lastParent = this; + + // Intersect any in-between clips starting at the top and moving downwards. + while ((parent = parent->d_ptr->parent)) { if (parent->d_ptr->flags & ItemClipsChildrenToShape) { - clippingAncestors.append(parent); - clipOwner = parent; + // Map clip to the current parent and intersect with its shape. + clip = (lastParent->itemTransform(parent).map(clip)).intersected(parent->shape()); + if (clip.isEmpty()) + return clip; + lastParent = parent; } - } while ((parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) && (parent = parent->parentItem())); - - // Start with the topmost clip. - QPainterPath parentClip = clipOwner->shape(); - // Intersect any in-between clips starting at the bottom and moving - // upwards. - for (int i = clippingAncestors.size() - 2; i >= 0; --i) { - const QGraphicsItem *item = clippingAncestors[i]; - // ### what if itemtransform fails - if (clipOwner) - parentClip = clipOwner->itemTransform(item).map(parentClip); - parentClip = parentClip.intersected(item->shape()); - if (parentClip.isEmpty()) { - clip = parentClip; - clipAway = true; + if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) break; - } - clipOwner = item; } - if (!clipAway) { + if (lastParent != this) { + // Map clip back to the item's transform. // ### what if itemtransform fails - clip = clip.intersected(clipOwner->itemTransform(this).map(parentClip)); - if (clip.isEmpty()) - clipAway = true; + clip = lastParent->itemTransform(this).map(clip); } } - if (!clipAway && d->flags & ItemClipsToShape) + if (d->flags & ItemClipsToShape) clip = clip.intersected(shape()); return clip; -- cgit v0.12 From b67dffcccea9166918ac93c281d87fd5eb3baf84 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Tue, 3 Mar 2009 13:30:33 +0100 Subject: Fixes: Small optimization in QGraphicsItem::clipPath(). RevBy: Andreas Details: Use QPainterPath::addRect() rather than addPolygon() and closeSubPath(). --- src/gui/graphicsview/qgraphicsitem.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 8b37648..fa77fd9 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -3259,8 +3259,8 @@ bool QGraphicsItem::collidesWithPath(const QPainterPath &path, Qt::ItemSelection return false; } - QRectF rectA = _q_adjustedRect(boundingRect()); - QRectF rectB = _q_adjustedRect(path.controlPointRect()); + const QRectF rectA = _q_adjustedRect(boundingRect()); + const QRectF rectB = _q_adjustedRect(path.controlPointRect()); if (!rectA.intersects(rectB)) { // This we can determine efficiently. If the two rects neither // intersect nor contain eachother, then the two items do not collide. @@ -3269,12 +3269,11 @@ bool QGraphicsItem::collidesWithPath(const QPainterPath &path, Qt::ItemSelection // For further testing, we need this item's shape or bounding rect. QPainterPath thisShape; - if (mode == Qt::IntersectsItemShape || mode == Qt::ContainsItemShape) { + if (mode == Qt::IntersectsItemShape || mode == Qt::ContainsItemShape) thisShape = (isClipped() && !d_ptr->localCollisionHack) ? clipPath() : shape(); - } else { - thisShape.addPolygon(_q_adjustedRect(boundingRect())); - thisShape.closeSubpath(); - } + else + thisShape.addRect(rectA); + if (thisShape == QPainterPath()) { // Empty shape? No collision. return false; -- cgit v0.12 From d74f1a91b05b943c1a8ae7847de6ee50b2093b89 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 3 Mar 2009 17:08:30 +0100 Subject: Fixes: Be a bit more smarter when calling setGeometry from itemChange RevBy: bnilsen AutoTest: Bench Details : if we come from setPosHelper (so itemChange) we don't need to do all the stuff regarding the size in setGeometry because the size doesn't change. I remove two calls to fullUpdateHelper and update() because prepareGeometryChange already call updateHelper and setPosHelper call fullUpdaterHelper too so we don't need to call them inside setGeometry. We can only call prepareGeometryChange only if we don't come from setPos. --- src/gui/graphicsview/qgraphicsitem.cpp | 6 +-- src/gui/graphicsview/qgraphicsitem_p.h | 2 +- src/gui/graphicsview/qgraphicswidget.cpp | 58 ++++++++++++--------- src/gui/graphicsview/qgraphicswidget_p.h | 2 + .../benchmarks/qgraphicswidget/qgraphicswidget.pro | 6 +++ .../qgraphicswidget/tst_qgraphicswidget.cpp | 60 ++++++++++++++++++++++ 6 files changed, 105 insertions(+), 29 deletions(-) create mode 100644 tests/benchmarks/qgraphicswidget/qgraphicswidget.pro create mode 100644 tests/benchmarks/qgraphicswidget/tst_qgraphicswidget.cpp diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index fa77fd9..443cc8c 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -2352,7 +2352,7 @@ QPointF QGraphicsItem::scenePos() const the item is also updated; otherwise it is not updated before and after the change. */ -void QGraphicsItemPrivate::setPosHelper(const QPointF &pos, bool update) +void QGraphicsItemPrivate::setPosHelper(const QPointF &pos) { Q_Q(QGraphicsItem); if (this->pos == pos) @@ -2364,7 +2364,7 @@ void QGraphicsItemPrivate::setPosHelper(const QPointF &pos, bool update) return; // Update and repositition. - if (scene && update) { + if (scene) { fullUpdateHelper(true); q->prepareGeometryChange(); } @@ -2387,7 +2387,7 @@ void QGraphicsItemPrivate::setPosHelper(const QPointF &pos, bool update) */ void QGraphicsItem::setPos(const QPointF &pos) { - d_ptr->setPosHelper(pos, /* update = */ true); + d_ptr->setPosHelper(pos); } /*! diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 98fe6ed..7deae52 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -158,7 +158,7 @@ public: virtual QVariant inputMethodQueryHelper(Qt::InputMethodQuery query) const; static bool movableAncestorIsSelected(const QGraphicsItem *item); - void setPosHelper(const QPointF &pos, bool update); + void setPosHelper(const QPointF &pos); void setVisibleHelper(bool newVisible, bool explicitly, bool update = true); void setEnabledHelper(bool newEnabled, bool explicitly, bool update = true); void updateHelper(const QRectF &rect = QRectF(), bool force = false); diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index 64ec0e7..7f02fb9 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -366,32 +366,33 @@ void QGraphicsWidget::resize(const QSizeF &size) void QGraphicsWidget::setGeometry(const QRectF &rect) { QGraphicsWidgetPrivate *wd = QGraphicsWidget::d_func(); - const QGraphicsLayoutItemPrivate *d = QGraphicsLayoutItem::d_ptr; - setAttribute(Qt::WA_Resized); - QRectF newGeom = rect; - newGeom.setSize(rect.size().expandedTo(effectiveSizeHint(Qt::MinimumSize)) - .boundedTo(effectiveSizeHint(Qt::MaximumSize))); - if (newGeom == d->geom) - return; - - // Update and prepare to change the geometry (remove from index). - if (wd->scene) { - if (rect.topLeft() != d->geom.topLeft()) - wd->fullUpdateHelper(true); - else - update(); - } - prepareGeometryChange(); - - // setPos triggers ItemPositionChange, which can adjust position + QGraphicsLayoutItemPrivate *d = QGraphicsLayoutItem::d_ptr; + QRectF newGeom; QPointF oldPos = d->geom.topLeft(); - wd->inSetGeometry = 1; - wd->setPosHelper(newGeom.topLeft(), /* update = */ false); - wd->inSetGeometry = 0; - newGeom.moveTopLeft(pos()); - - if (newGeom == d->geom) - return; + if (!wd->inSetPos) { + setAttribute(Qt::WA_Resized); + newGeom = rect; + newGeom.setSize(rect.size().expandedTo(effectiveSizeHint(Qt::MinimumSize)) + .boundedTo(effectiveSizeHint(Qt::MaximumSize))); + if (newGeom == d->geom) + return; + + // setPos triggers ItemPositionChange, which can adjust position + wd->inSetGeometry = 1; + wd->setPosHelper(newGeom.topLeft()); + wd->inSetGeometry = 0; + newGeom.moveTopLeft(pos()); + + if (newGeom == d->geom) + return; + + // Update and prepare to change the geometry (remove from index) if the size has changed. + if (wd->scene) { + if (rect.topLeft() == d->geom.topLeft()) { + prepareGeometryChange(); + } + } + } // Update the layout item geometry bool moved = oldPos != pos(); @@ -401,6 +402,11 @@ void QGraphicsWidget::setGeometry(const QRectF &rect) event.setOldPos(oldPos); event.setNewPos(pos()); QApplication::sendEvent(this, &event); + if (wd->inSetPos) { + //set the new pos + d->geom.moveTopLeft(pos()); + return; + } } QSizeF oldSize = size(); QGraphicsLayoutItem::setGeometry(newGeom); @@ -1016,9 +1022,11 @@ QVariant QGraphicsWidget::itemChange(GraphicsItemChange change, const QVariant & break; case ItemPositionHasChanged: if (!d->inSetGeometry) { + d->inSetPos = 1; // Ensure setGeometry is called (avoid recursion when setPos is // called from within setGeometry). setGeometry(QRectF(pos(), size())); + d->inSetPos = 0 ; } break; case ItemParentChange: { diff --git a/src/gui/graphicsview/qgraphicswidget_p.h b/src/gui/graphicsview/qgraphicswidget_p.h index 455a129..53eaa31 100644 --- a/src/gui/graphicsview/qgraphicswidget_p.h +++ b/src/gui/graphicsview/qgraphicswidget_p.h @@ -86,6 +86,7 @@ public: inheritedFontResolveMask(0), inSetGeometry(0), polished(0), + inSetPos(0), focusPolicy(Qt::NoFocus), focusNext(0), focusPrev(0), @@ -195,6 +196,7 @@ public: quint32 attributes : 10; quint32 inSetGeometry : 1; quint32 polished: 1; + quint32 inSetPos : 1; // Focus Qt::FocusPolicy focusPolicy; diff --git a/tests/benchmarks/qgraphicswidget/qgraphicswidget.pro b/tests/benchmarks/qgraphicswidget/qgraphicswidget.pro new file mode 100644 index 0000000..f1ec54e --- /dev/null +++ b/tests/benchmarks/qgraphicswidget/qgraphicswidget.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_qgraphicswidget +TEMPLATE = app +# Input +SOURCES += tst_qgraphicswidget.cpp diff --git a/tests/benchmarks/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/benchmarks/qgraphicswidget/tst_qgraphicswidget.cpp new file mode 100644 index 0000000..97837e2 --- /dev/null +++ b/tests/benchmarks/qgraphicswidget/tst_qgraphicswidget.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +****************************************************************************/ + +#include +#include +#include +#include +#include +//TESTED_FILES= + +class tst_QGraphicsWidget : public QObject +{ + Q_OBJECT + +public: + tst_QGraphicsWidget(); + virtual ~tst_QGraphicsWidget(); + +public slots: + void init(); + void cleanup(); + +private slots: + void move(); +}; + +tst_QGraphicsWidget::tst_QGraphicsWidget() +{ +} + +tst_QGraphicsWidget::~tst_QGraphicsWidget() +{ +} + +void tst_QGraphicsWidget::init() +{ +} + +void tst_QGraphicsWidget::cleanup() +{ +} + +void tst_QGraphicsWidget::move() +{ + QGraphicsScene scene; + QGraphicsWidget *widget = new QGraphicsWidget(); + scene.addItem(widget); + QGraphicsView view(&scene); + view.show(); + QBENCHMARK { + widget->setPos(qrand(),qrand()); + } +} + +QTEST_MAIN(tst_QGraphicsWidget) +#include "tst_qgraphicswidget.moc" -- cgit v0.12 From 0985805ab3c7de5b15c115a98afb15944b6d93b9 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Mon, 9 Mar 2009 14:33:02 +0100 Subject: Fixes: Don't fill the pixmap because we will copy the cache into it. RevBy: bnilsen AutoTest: All pass + plasma ok --- src/gui/graphicsview/qgraphicsscene.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index b509507..8a67d24 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4736,11 +4736,9 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte if (newCacheIndent != deviceData->cacheIndent || deviceRect.size() != pix.size()) { QPoint diff = newCacheIndent - deviceData->cacheIndent; QPixmap newPix(deviceRect.size()); - // ### Investigate removing this fill (test with Plasma and - // graphicssystem raster). - newPix.fill(Qt::transparent); if (!pix.isNull()) { QPainter newPixPainter(&newPix); + newPixPainter.setCompositionMode(QPainter::CompositionMode_Source); newPixPainter.drawPixmap(-diff, pix); newPixPainter.end(); } -- cgit v0.12 From 4556bcbd40c8feb7185aae7da5f0686f12d87565 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Wed, 11 Mar 2009 17:24:41 +0100 Subject: Fixes: Optimization: Cache QGraphicsItem::clipPath(). RevBy: Alexis AutoTest: Still pass Details: No-brainer. --- src/gui/graphicsview/qgraphicsitem.cpp | 46 ++++++++++++++++++++++++++++------ src/gui/graphicsview/qgraphicsitem_p.h | 14 +++++++++++ 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 443cc8c..5b997f4 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -631,6 +631,7 @@ void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag ch case QGraphicsItem::ItemClipsChildrenToShape: flag = AncestorClipsChildren; enabled = flags & QGraphicsItem::ItemClipsChildrenToShape; + invalidateCachedClipPathRecursively(/*childrenOnly=*/true); break; case QGraphicsItem::ItemIgnoresTransformations: flag = AncestorIgnoresTransformations; @@ -1270,6 +1271,9 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) d_ptr->updateAncestorFlag(ItemClipsChildrenToShape); } + if ((flags & ItemClipsToShape) != (oldFlags & ItemClipsToShape)) + d_ptr->invalidateCachedClipPath(); + if ((flags & ItemIgnoresTransformations) != (oldFlags & ItemIgnoresTransformations)) { // Item children clipping changes. Propagate the ancestor flag to // all children. @@ -3136,10 +3140,15 @@ bool QGraphicsItem::isClipped() const QPainterPath QGraphicsItem::clipPath() const { Q_D(const QGraphicsItem); - QPainterPath clip; - if (!isClipped()) - return clip; + if (!d->dirtyClipPath) + return d->cachedClipPath; + + if (!isClipped()) { + d_ptr->setCachedClipPath(QPainterPath()); + return d->cachedClipPath; + } + QPainterPath clip; // Start with the item's bounding rect. clip.addRect(boundingRect()); @@ -3150,15 +3159,27 @@ QPainterPath QGraphicsItem::clipPath() const // Intersect any in-between clips starting at the top and moving downwards. while ((parent = parent->d_ptr->parent)) { if (parent->d_ptr->flags & ItemClipsChildrenToShape) { - // Map clip to the current parent and intersect with its shape. - clip = (lastParent->itemTransform(parent).map(clip)).intersected(parent->shape()); - if (clip.isEmpty()) + // Map clip to the current parent and intersect with its shape/clipPath + clip = lastParent->itemTransform(parent).map(clip); + if (!parent->d_ptr->dirtyClipPath) { + clip = clip.intersected(parent->d_ptr->cachedClipPath); + if (!(parent->d_ptr->flags & ItemClipsToShape)) + clip = clip.intersected(parent->shape()); + } else { + clip = clip.intersected(parent->shape()); + } + + if (clip.isEmpty()) { + d_ptr->setCachedClipPath(clip); return clip; + } lastParent = parent; } - if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) + if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) + || !parent->d_ptr->dirtyClipPath) { break; + } } if (lastParent != this) { @@ -3171,6 +3192,7 @@ QPainterPath QGraphicsItem::clipPath() const if (d->flags & ItemClipsToShape) clip = clip.intersected(shape()); + d_ptr->setCachedClipPath(clip); return clip; } @@ -3726,6 +3748,15 @@ void QGraphicsItemPrivate::removeExtraItemCache() unsetExtra(ExtraCacheData); } +void QGraphicsItemPrivate::invalidateCachedClipPathRecursively(bool childrenOnly) +{ + if (!childrenOnly) + invalidateCachedClipPath(); + // ### Return if this item doesn't clip its children? + for (int i = 0; i < children.size(); ++i) + children.at(i)->d_ptr->invalidateCachedClipPathRecursively(false); +} + /*! \internal @@ -5505,6 +5536,7 @@ void QGraphicsItem::prepareGeometryChange() QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func(); scenePrivate->removeFromIndex(this); + d_ptr->invalidateCachedClipPathRecursively(); } } diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 7deae52..1e2c09b 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -138,6 +138,7 @@ public: dirty(0), dirtyChildren(0), localCollisionHack(0), + dirtyClipPath(1), globalStackingOrder(-1), sceneTransformIndex(-1), q_ptr(0) @@ -234,6 +235,18 @@ public: QGraphicsItemCache *extraItemCache() const; void removeExtraItemCache(); + inline void setCachedClipPath(const QPainterPath &path) + { + cachedClipPath = path; + dirtyClipPath = 0; + } + + inline void invalidateCachedClipPath() + { dirtyClipPath = 1; } + + void invalidateCachedClipPathRecursively(bool childrenOnly = false); + + QPainterPath cachedClipPath; QPointF pos; qreal z; QGraphicsScene *scene; @@ -268,6 +281,7 @@ public: quint32 dirty : 1; quint32 dirtyChildren : 1; quint32 localCollisionHack : 1; + quint32 dirtyClipPath : 1; // Optional stacking order int globalStackingOrder; -- cgit v0.12 From f4547b98b52bfc95fb0c14ec58df204cfcec0db2 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Fri, 3 Apr 2009 14:19:12 +0200 Subject: Fixes: Cleanup/Optimize QGraphicsView::findItems. RevBy: Alexis AutoTest: Still pass Details: findItems() does almost exactly the same as QGraphicsView::items, the only difference is that it checks whether we are about to redraw all items. Next step is to optimize the items_helper functions. The patch does also include a fix for ::items/childItems_helper(const QPainterPath ...); it didn't take Qt::Intersects/ContainsItemBoundingRect into account (in the same fashion as we do in the other helper functions). --- src/gui/graphicsview/qgraphicsscene.cpp | 80 ++++++++++++++++----- src/gui/graphicsview/qgraphicsview.cpp | 122 ++++++++------------------------ src/gui/graphicsview/qgraphicsview_p.h | 7 +- 3 files changed, 94 insertions(+), 115 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 8a67d24..3db8e35 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1487,21 +1487,46 @@ QList QGraphicsScenePrivate::items_helper(const QPainterPath &p Qt::SortOrder order) const { QList items; + const QRectF pathRect = _q_adjustedRect(path.controlPointRect()); + // The index returns a rough estimate of what items are inside the rect. // Refine it by iterating through all returned items. - foreach (QGraphicsItem *item, estimateItemsInRect(_q_adjustedRect(path.controlPointRect()))) { + foreach (QGraphicsItem *item, estimateItemsInRect(pathRect)) { // Find the item's scene transform in a clever way. QTransform x = item->sceneTransform(); - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) { - QPainterPath mappedPath = xinv.map(path); - if (itemCollidesWithPath(item, mappedPath, mode)) { + bool keep = false; + + // ### _q_adjustedRect is only needed because QRectF::intersects, + // QRectF::contains and QTransform::map() and friends don't work with + // flat rectangles. + QRectF br = _q_adjustedRect(item->boundingRect()); + if (mode >= Qt::ContainsItemBoundingRect) { + // Path contains/intersects item's bounding rect + if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(x.mapRect(br))) + || (mode == Qt::ContainsItemBoundingRect && path.contains(x.mapRect(br)))) { items << item; - if (item->flags() & QGraphicsItem::ItemClipsChildrenToShape) - childItems_helper(&items, item, mappedPath, mode); + keep = true; + } + } else { + // Path contains/intersects item's shape + if (QRectF_intersects(pathRect, x.mapRect(br))) { + bool ok; + QTransform xinv = x.inverted(&ok); + if (ok) { + if (itemCollidesWithPath(item, xinv.map(path), mode)) { + items << item; + keep = true; + } + } } } + + if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) { + bool ok; + QTransform xinv = x.inverted(&ok); + if (ok) + childItems_helper(&items, item, xinv.map(path), mode); + } } if (order != Qt::SortOrder(-1)) @@ -1629,29 +1654,46 @@ void QGraphicsScenePrivate::childItems_helper(QList *items, Qt::ItemSelectionMode mode) const { bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); - QPainterPath intersectedPath = !parentClip ? path : path.intersected(parent->shape()); - if (intersectedPath.isEmpty()) + QRectF pathRect = _q_adjustedRect(path.boundingRect()); + QRectF r = !parentClip ? pathRect : pathRect.intersected(_q_adjustedRect(parent->boundingRect())); + if (r.isEmpty()) return; QList &children = parent->d_ptr->children; for (int i = 0; i < children.size(); ++i) { QGraphicsItem *item = children.at(i); + if (item->d_ptr->hasTransform && !item->transform().isInvertible()) + continue; // Skip invisible items. if (!item->d_ptr->visible || qFuzzyCompare(item->effectiveOpacity(), qreal(0.0))) continue; - QTransform x = item->sceneTransform(); - - bool ok; - QTransform xinv = x.inverted(&ok); - if (ok) { - QPainterPath mappedPath = xinv.map(path); - if (itemCollidesWithPath(item, mappedPath, mode)) { + // ### _q_adjustedRect is only needed because QRectF::intersects, + // QRectF::contains and QTransform::map() and friends don't work with + // flat rectangles. + QRectF br = _q_adjustedRect(item->boundingRect()); + bool keep = false; + if (mode >= Qt::ContainsItemBoundingRect) { + // Polygon contains/intersects item's bounding rect + if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br))) + || (mode == Qt::ContainsItemBoundingRect && path.contains(item->mapRectToParent(br)))) { items->append(item); - if (!item->d_ptr->children.isEmpty()) - childItems_helper(items, item, mappedPath, mode); + keep = true; } + } else { + // Path contains/intersects item's shape + if (QRectF_intersects(pathRect, item->mapRectToParent(br))) { + if (itemCollidesWithPath(item, item->mapFromParent(path), mode)) { + items->append(item); + keep = true; + } + } + } + + if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) { + // Recurse into children that clip children. + childItems_helper(items, item, item->mapFromParent(path), mode); } } } diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index f88918f..c421417 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -1029,103 +1029,40 @@ void QGraphicsViewPrivate::freeStyleOptionsArray(QStyleOptionGraphicsItem *array extern QPainterPath qt_regionToPath(const QRegion ®ion); -QList QGraphicsViewPrivate::findItems(const QRegion &exposedRegion, - const QTransform &worldTransform, - bool *allItems) const +QList QGraphicsViewPrivate::findItems(const QRegion &exposedRegion, bool *allItems) const { Q_Q(const QGraphicsView); - QList itemList; - QSet tmp; - bool simpleTransform = worldTransform.type() <= QTransform::TxScale; - - QPainterPath path = qt_regionToPath(exposedRegion); - *allItems = path.contains(q->mapFromScene(scene->d_func()->growingItemsBoundingRect).boundingRect()); - QList exposedRects; - QList exposedPolys; - - // Transform the exposed viewport rects to scene rects or polygons - foreach (const QRect &rect, exposedRegion.rects()) { - QPolygonF exposedPoly = q->mapToScene(rect.adjusted(-1, -1, 1, 1)); - QRectF exposedRect = exposedPoly.boundingRect(); - if (!simpleTransform) - exposedPolys << exposedPoly; - exposedRects << exposedRect; - } - - // Find which items need to be drawn. - if (*allItems) { + const QPainterPath exposedPath(qt_regionToPath(exposedRegion)); + const QPainterPath exposedScenePath(q->mapToScene(exposedPath)); + + if (exposedScenePath.contains(scene->d_func()->growingItemsBoundingRect)) { + Q_ASSERT(allItems); + *allItems = true; + // All items are guaranteed within the exposed region, don't bother using the index. - foreach (QGraphicsItem *item, scene->items()) { + QList itemList(scene->items()); + int i = 0; + while (i < itemList.size()) { // But we only want to include items that are visible - if (item->isVisible()) - itemList << item; - } - } else if (simpleTransform) { - // Simple rect lookups will do. - if (exposedRects.size() > 1) { - foreach (const QRectF &rect, exposedRects) { - foreach (QGraphicsItem *item, scene->d_func()->items_helper(rect, Qt::IntersectsItemBoundingRect, Qt::SortOrder(-1) /* don't sort */)) { - if (!tmp.contains(item)) { - tmp << item; - itemList << item; - } - } - } - } else { - itemList += scene->d_func()->items_helper(exposedRects[0], Qt::IntersectsItemBoundingRect, Qt::SortOrder(-1) /* don't sort */); - } - } else { - // Polygon lookup is necessary. - if (exposedRects.size() > 1) { - foreach (const QPolygonF &poly, exposedPolys) { - foreach (QGraphicsItem *item, scene->d_func()->items_helper(poly, Qt::IntersectsItemBoundingRect, Qt::SortOrder(-1) /* don't sort */)) { - if (!tmp.contains(item)) { - tmp << item; - itemList << item; - } - } - } - } else { - itemList += scene->d_func()->items_helper(exposedPolys[0], Qt::IntersectsItemBoundingRect, Qt::SortOrder(-1) /* don't sort */); + if (!itemList.at(i)->isVisible()) + itemList.removeAt(i); + else + ++i; } - } - // Check for items that ignore inherited transformations, and add them if - // necessary. - QRectF untr = scene->d_func()->largestUntransformableItem; - if (!*allItems && !untr.isNull()) { - // Map the largest untransformable item subtree boundingrect from view - // to scene coordinates, and use this to expand all exposed rects in - // search for untransformable items. - QRectF ltri = matrix.inverted().mapRect(untr); - ltri.adjust(-untr.width(), -untr.height(), untr.width(), untr.height()); - - foreach (const QRect &rect, exposedRegion.rects()) { - QRectF exposed = q->mapToScene(rect.adjusted(-1, -1, 1, 1)).boundingRect(); - exposed.adjust(-ltri.width(), -ltri.height(), ltri.width(), ltri.height()); - - foreach (QGraphicsItem *item, scene->d_func()->estimateItemsInRect(exposed)) { - if (item->d_ptr->itemIsUntransformable()) { - if (!tmp.contains(item)) { - QPainterPath rectPath; - rectPath.addRect(rect); - QPainterPath path = item->deviceTransform(q->viewportTransform()).inverted().map(rectPath); - if (item->collidesWithPath(path, Qt::IntersectsItemBoundingRect)) { - itemList << item; - tmp << item; - } - } - } - } - } + // Sort the items. + QGraphicsScenePrivate::sortItems(&itemList, Qt::DescendingOrder, scene->d_func()->sortCacheEnabled); + return itemList; } - tmp.clear(); - // Sort the items. - QGraphicsScenePrivate::sortItems(&itemList, Qt::DescendingOrder, - scene->d_func()->sortCacheEnabled); + if (scene->d_func()->largestUntransformableItem.isNull()) { + return scene->d_func()->items_helper(exposedScenePath, + Qt::IntersectsItemBoundingRect, + Qt::DescendingOrder); + } - return itemList; + // NB! Path must be in viewport coordinates. + return itemsInArea(exposedPath, Qt::IntersectsItemBoundingRect, Qt::DescendingOrder); } void QGraphicsViewPrivate::generateStyleOptions(const QList &itemList, @@ -2228,7 +2165,8 @@ QList QGraphicsView::items() const certainly room for improvement. */ QList QGraphicsViewPrivate::itemsInArea(const QPainterPath &path, - Qt::ItemSelectionMode mode) const + Qt::ItemSelectionMode mode, + Qt::SortOrder order) const { Q_Q(const QGraphicsView); @@ -2278,8 +2216,8 @@ QList QGraphicsViewPrivate::itemsInArea(const QPainterPath &pat } // ### Insertion sort would be faster. - QGraphicsScenePrivate::sortItems(&result, Qt::AscendingOrder, - scene->d_func()->sortCacheEnabled); + if (order != Qt::SortOrder(-1)) + QGraphicsScenePrivate::sortItems(&result, order, scene->d_func()->sortCacheEnabled); return result; } @@ -3485,7 +3423,7 @@ void QGraphicsView::paintEvent(QPaintEvent *event) // Find all exposed items bool allItems = false; - QList itemList = d->findItems(exposedRegion, viewTransform, &allItems); + QList itemList = d->findItems(exposedRegion, &allItems); #ifdef QGRAPHICSVIEW_DEBUG int exposedTime = stopWatch.elapsed(); diff --git a/src/gui/graphicsview/qgraphicsview_p.h b/src/gui/graphicsview/qgraphicsview_p.h index 2109673..a76279e 100644 --- a/src/gui/graphicsview/qgraphicsview_p.h +++ b/src/gui/graphicsview/qgraphicsview_p.h @@ -85,7 +85,8 @@ public: qint64 verticalScroll() const; QList itemsInArea(const QPainterPath &path, - Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const; + Qt::ItemSelectionMode mode = Qt::IntersectsItemShape, + Qt::SortOrder = Qt::AscendingOrder) const; QPointF mousePressItemPoint; QPointF mousePressScenePoint; @@ -172,9 +173,7 @@ public: void updateRegion(const QRegion ®ion); bool updateSceneSlotReimplementedChecked; - QList findItems(const QRegion &exposedRegion, - const QTransform &worldTransform, - bool *allItems) const; + QList findItems(const QRegion &exposedRegion, bool *allItems) const; void generateStyleOptions(const QList &itemList, QGraphicsItem **itemArray, -- cgit v0.12 From 4020327503eaefae42da4bd6e71125b6972ac97f Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Fri, 3 Apr 2009 14:43:11 +0200 Subject: Add a cut-off for simple rectangle lookups. Make sure we use the rect-variation of QGraphicsScene's item lookup functions if the view has a simple transform and a simple expose region. Reviewed-by: Bjoern Erik Nilsen --- src/gui/graphicsview/qgraphicsview.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index c421417..9191fc5 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -1056,6 +1056,11 @@ QList QGraphicsViewPrivate::findItems(const QRegion &exposedReg } if (scene->d_func()->largestUntransformableItem.isNull()) { + if (exposedRegion.numRects() == 1 && matrix.type() <= QTransform::TxScale) { + return scene->d_func()->items_helper(exposedScenePath.controlPointRect(), + Qt::IntersectsItemBoundingRect, + Qt::DescendingOrder); + } return scene->d_func()->items_helper(exposedScenePath, Qt::IntersectsItemBoundingRect, Qt::DescendingOrder); -- cgit v0.12 From 4d019e66fb62d6f25627144539abd7f59413abee Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Tue, 17 Mar 2009 11:42:07 +0100 Subject: Fixes: Only use the parent's cached clip path if it is clipped. RevBy: TrustMe Details: ...otherwise it'll be empty and too much will be clipped away. --- src/gui/graphicsview/qgraphicsitem.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 5b997f4..a3a12e7 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -3157,11 +3157,12 @@ QPainterPath QGraphicsItem::clipPath() const const QGraphicsItem *lastParent = this; // Intersect any in-between clips starting at the top and moving downwards. + bool foundValidClipPath = false; while ((parent = parent->d_ptr->parent)) { if (parent->d_ptr->flags & ItemClipsChildrenToShape) { // Map clip to the current parent and intersect with its shape/clipPath clip = lastParent->itemTransform(parent).map(clip); - if (!parent->d_ptr->dirtyClipPath) { + if ((foundValidClipPath = !parent->d_ptr->dirtyClipPath && parent->isClipped())) { clip = clip.intersected(parent->d_ptr->cachedClipPath); if (!(parent->d_ptr->flags & ItemClipsToShape)) clip = clip.intersected(parent->shape()); @@ -3177,7 +3178,7 @@ QPainterPath QGraphicsItem::clipPath() const } if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) - || !parent->d_ptr->dirtyClipPath) { + || foundValidClipPath) { break; } } -- cgit v0.12 From bd4b177e051852f0fb94df9c0ee2e512478e0d38 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Wed, 18 Mar 2009 13:27:16 +0100 Subject: Fixes: Get rid of lots of calls to qFuzzyCompare. RevBy: Olivier AutoTest: Still pass. Details: Items usually don't have effective opacity, i.e. it is 1.0, so don't bother doing fuzzy compare if that's the case. --- src/gui/graphicsview/qgraphicsitem_p.h | 6 ++++++ src/gui/graphicsview/qgraphicsscene.cpp | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 1e2c09b..df07b87 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -246,6 +246,12 @@ public: void invalidateCachedClipPathRecursively(bool childrenOnly = false); + inline bool isInvisible() const + { + return !visible || (hasEffectiveOpacity + && qFuzzyCompare(q_func()->effectiveOpacity() + 1.0, qreal(1.0))); + } + QPainterPath cachedClipPath; QPointF pos; qreal z; diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 3db8e35..1422184 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1552,7 +1552,7 @@ void QGraphicsScenePrivate::childItems_helper(QList *items, continue; // Skip invisible items and all their children. - if (!item->d_ptr->visible || qFuzzyCompare(item->effectiveOpacity(), qreal(0.0))) + if (item->d_ptr->isInvisible()) continue; // ### _q_adjustedRect is only needed because QRectF::intersects, @@ -1612,7 +1612,7 @@ void QGraphicsScenePrivate::childItems_helper(QList *items, continue; // Skip invisible items. - if (!item->d_ptr->visible || qFuzzyCompare(item->effectiveOpacity() + 1, qreal(1.0))) + if (item->d_ptr->isInvisible()) continue; // ### _q_adjustedRect is only needed because QRectF::intersects, @@ -1666,7 +1666,7 @@ void QGraphicsScenePrivate::childItems_helper(QList *items, continue; // Skip invisible items. - if (!item->d_ptr->visible || qFuzzyCompare(item->effectiveOpacity(), qreal(0.0))) + if (item->d_ptr->isInvisible()) continue; // ### _q_adjustedRect is only needed because QRectF::intersects, -- cgit v0.12 From 5910dbe6e7a024301d431102703f9abe323ebd13 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Thu, 19 Mar 2009 15:31:56 +0100 Subject: Fixes: Compile on funky scratchbox ARM compiler. --- src/gui/graphicsview/qgraphicsitem_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index df07b87..98e7c13 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -249,7 +249,7 @@ public: inline bool isInvisible() const { return !visible || (hasEffectiveOpacity - && qFuzzyCompare(q_func()->effectiveOpacity() + 1.0, qreal(1.0))); + && qFuzzyCompare(q_func()->effectiveOpacity() + 1, qreal(1.0))); } QPainterPath cachedClipPath; -- cgit v0.12 From c1909321a486621ef196dd4bb3cf354406d86d46 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Fri, 20 Mar 2009 18:06:05 +0100 Subject: Fixes: Clever invalidating of the cached clip path. RevBy: Andreas AutoTest: still pass Details: Adds emptyClipPath bit, a cut-off to test if the item has an empty clip path (i.e., is clipped away). Also adds code for invalidating the cache from inside setPos(). --- src/gui/graphicsview/qgraphicsitem.cpp | 124 ++++++++++++++++++++++++++++++--- src/gui/graphicsview/qgraphicsitem_p.h | 18 ++++- 2 files changed, 129 insertions(+), 13 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index a3a12e7..badc41e 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -2368,15 +2368,18 @@ void QGraphicsItemPrivate::setPosHelper(const QPointF &pos) return; // Update and repositition. + inSetPosHelper = 1; if (scene) { fullUpdateHelper(true); q->prepareGeometryChange(); } this->pos = newPos; invalidateSceneTransformCache(); + updateCachedClipPathFromSetPosHelper(); // Send post-notification. q->itemChange(QGraphicsItem::ItemPositionHasChanged, newPos); + inSetPosHelper = 0; } /*! @@ -3141,7 +3144,7 @@ QPainterPath QGraphicsItem::clipPath() const { Q_D(const QGraphicsItem); if (!d->dirtyClipPath) - return d->cachedClipPath; + return d->emptyClipPath ? QPainterPath() : d->cachedClipPath; if (!isClipped()) { d_ptr->setCachedClipPath(QPainterPath()); @@ -3163,6 +3166,13 @@ QPainterPath QGraphicsItem::clipPath() const // Map clip to the current parent and intersect with its shape/clipPath clip = lastParent->itemTransform(parent).map(clip); if ((foundValidClipPath = !parent->d_ptr->dirtyClipPath && parent->isClipped())) { + if (parent->d_ptr->emptyClipPath) { + if (d_ptr->flags & ItemClipsChildrenToShape) + d_ptr->setEmptyCachedClipPathRecursively(); + else + d_ptr->setEmptyCachedClipPath(); + return QPainterPath(); + } clip = clip.intersected(parent->d_ptr->cachedClipPath); if (!(parent->d_ptr->flags & ItemClipsToShape)) clip = clip.intersected(parent->shape()); @@ -3171,7 +3181,10 @@ QPainterPath QGraphicsItem::clipPath() const } if (clip.isEmpty()) { - d_ptr->setCachedClipPath(clip); + if (d_ptr->flags & ItemClipsChildrenToShape) + d_ptr->setEmptyCachedClipPathRecursively(); + else + d_ptr->setEmptyCachedClipPath(); return clip; } lastParent = parent; @@ -3749,13 +3762,95 @@ void QGraphicsItemPrivate::removeExtraItemCache() unsetExtra(ExtraCacheData); } -void QGraphicsItemPrivate::invalidateCachedClipPathRecursively(bool childrenOnly) +void QGraphicsItemPrivate::setEmptyCachedClipPathRecursively(const QRectF &emptyIfOutsideThisRect) +{ + setEmptyCachedClipPath(); + + const bool checkRect = !emptyIfOutsideThisRect.isNull() + && !(flags & QGraphicsItem::ItemClipsChildrenToShape); + for (int i = 0; i < children.size(); ++i) { + if (!checkRect) { + children.at(i)->d_ptr->setEmptyCachedClipPathRecursively(); + continue; + } + + QGraphicsItem *child = children.at(i); + const QRectF rect = child->mapRectFromParent(emptyIfOutsideThisRect); + if (rect.intersects(child->boundingRect())) + child->d_ptr->invalidateCachedClipPathRecursively(false, rect); + else + child->d_ptr->setEmptyCachedClipPathRecursively(rect); + } +} + +void QGraphicsItemPrivate::invalidateCachedClipPathRecursively(bool childrenOnly, const QRectF &emptyIfOutsideThisRect) { if (!childrenOnly) invalidateCachedClipPath(); - // ### Return if this item doesn't clip its children? - for (int i = 0; i < children.size(); ++i) - children.at(i)->d_ptr->invalidateCachedClipPathRecursively(false); + + const bool checkRect = !emptyIfOutsideThisRect.isNull(); + for (int i = 0; i < children.size(); ++i) { + if (!checkRect) { + children.at(i)->d_ptr->invalidateCachedClipPathRecursively(false); + continue; + } + + QGraphicsItem *child = children.at(i); + const QRectF rect = child->mapRectFromParent(emptyIfOutsideThisRect); + if (rect.intersects(child->boundingRect())) + child->d_ptr->invalidateCachedClipPathRecursively(false, rect); + else + child->d_ptr->setEmptyCachedClipPathRecursively(rect); + } +} + +void QGraphicsItemPrivate::updateCachedClipPathFromSetPosHelper() +{ + Q_ASSERT(inSetPosHelper); + + if (!(ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) + return; // Not clipped by any ancestor. + + // Find closest clip ancestor. + QGraphicsItem *clipParent = parent; + while (clipParent && !(clipParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape)) + clipParent = clipParent->d_ptr->parent; + + Q_ASSERT(clipParent); + Q_Q(QGraphicsItem); + + // From here everything is calculated in clip parent's coordinates. + const QTransform thisToParentTransform(q->itemTransform(clipParent)); + const QRectF parentBoundingRect(clipParent->boundingRect()); + const QRectF thisBoundingRect(thisToParentTransform.mapRect(q->boundingRect())); + + if (!parentBoundingRect.intersects(thisBoundingRect)) { + // Item is moved outside the clip parent's bounding rect, + // i.e. it is fully clipped and the clip path is empty. + if (flags & QGraphicsItem::ItemClipsChildrenToShape) + setEmptyCachedClipPathRecursively(); + else + setEmptyCachedClipPathRecursively(thisToParentTransform.inverted().mapRect(parentBoundingRect)); + return; + } + + const QPainterPath parentClip(clipParent->isClipped() ? clipParent->clipPath() : clipParent->shape()); + if (parentClip.contains(thisBoundingRect)) + return; // Item is inside the clip parent's shape. No update required. + + const QRectF parentClipRect(parentClip.controlPointRect()); + if (!parentClipRect.intersects(thisBoundingRect)) { + // Item is moved outside the clip parent's shape, + // i.e. it is fully clipped and the clip path is empty. + if (flags & QGraphicsItem::ItemClipsChildrenToShape) + setEmptyCachedClipPathRecursively(); + else + setEmptyCachedClipPathRecursively(thisToParentTransform.inverted().mapRect(parentClipRect)); + } else { + // Item is partially inside the clip parent's shape, + // i.e. the cached clip path must be invalidated. + invalidateCachedClipPathRecursively(false, thisToParentTransform.inverted().mapRect(parentClipRect)); + } } /*! @@ -5532,13 +5627,20 @@ void QGraphicsItem::removeFromIndex() */ void QGraphicsItem::prepareGeometryChange() { - if (d_ptr->scene) { - d_ptr->updateHelper(); + if (!d_ptr->scene) + return; + + d_ptr->updateHelper(); + QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func(); + scenePrivate->removeFromIndex(this); - QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func(); - scenePrivate->removeFromIndex(this); + if (d_ptr->inSetPosHelper) + return; + + if (d_ptr->flags & ItemClipsChildrenToShape) d_ptr->invalidateCachedClipPathRecursively(); - } + else + d_ptr->invalidateCachedClipPath(); } /*! diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 98e7c13..f5c3505 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -139,6 +139,8 @@ public: dirtyChildren(0), localCollisionHack(0), dirtyClipPath(1), + emptyClipPath(0), + inSetPosHelper(0), globalStackingOrder(-1), sceneTransformIndex(-1), q_ptr(0) @@ -239,12 +241,22 @@ public: { cachedClipPath = path; dirtyClipPath = 0; + emptyClipPath = 0; } + inline void setEmptyCachedClipPath() + { + emptyClipPath = 1; + dirtyClipPath = 0; + } + + void setEmptyCachedClipPathRecursively(const QRectF &emptyIfOutsideThisRect = QRectF()); + inline void invalidateCachedClipPath() - { dirtyClipPath = 1; } + { /*static int count = 0 ;qWarning("%i", ++count);*/ dirtyClipPath = 1; emptyClipPath = 0; } - void invalidateCachedClipPathRecursively(bool childrenOnly = false); + void invalidateCachedClipPathRecursively(bool childrenOnly = false, const QRectF &emptyIfOutsideThisRect = QRectF()); + void updateCachedClipPathFromSetPosHelper(); inline bool isInvisible() const { @@ -288,6 +300,8 @@ public: quint32 dirtyChildren : 1; quint32 localCollisionHack : 1; quint32 dirtyClipPath : 1; + quint32 emptyClipPath : 1; + quint32 inSetPosHelper : 1; // Optional stacking order int globalStackingOrder; -- cgit v0.12 From 95fa7a93bc840e0f49ee30e76abb2b4f8579c997 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Mon, 23 Mar 2009 15:54:30 +0100 Subject: Fixes: Optimization: Clip path is empty if the bounding rect is empty. RevBy: TrustMe --- src/gui/graphicsview/qgraphicsitem.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index badc41e..75b6cf1 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -3151,9 +3151,18 @@ QPainterPath QGraphicsItem::clipPath() const return d->cachedClipPath; } + const QRectF thisBoundingRect(boundingRect()); + if (thisBoundingRect.isEmpty()) { + if (d_ptr->flags & ItemClipsChildrenToShape) + d_ptr->setEmptyCachedClipPathRecursively(); + else + d_ptr->setEmptyCachedClipPath(); + return QPainterPath(); + } + QPainterPath clip; // Start with the item's bounding rect. - clip.addRect(boundingRect()); + clip.addRect(thisBoundingRect); if (d->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) { const QGraphicsItem *parent = this; -- cgit v0.12 From deccc867b244fbc52ca58e21623febbc27310b05 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Mon, 23 Mar 2009 19:37:41 +0100 Subject: Fixes: Don't bother processing items that are clipped away. RevBy: Andreas --- src/gui/graphicsview/qgraphicsitem_p.h | 3 + src/gui/graphicsview/qgraphicsscene.cpp | 116 ++++++++++++++++++-------------- 2 files changed, 67 insertions(+), 52 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index f5c3505..3e4c269 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -264,6 +264,9 @@ public: && qFuzzyCompare(q_func()->effectiveOpacity() + 1, qreal(1.0))); } + inline bool isClippedAway() const + { return !dirtyClipPath && q_func()->isClipped() && (emptyClipPath || cachedClipPath.isEmpty()); } + QPainterPath cachedClipPath; QPointF pos; qreal z; diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 1422184..f32fe71 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1539,12 +1539,14 @@ void QGraphicsScenePrivate::childItems_helper(QList *items, const QRectF &rect, Qt::ItemSelectionMode mode) const { - QPainterPath path; bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); + if (parentClip && parent->d_ptr->isClippedAway()) + return; QRectF r = !parentClip ? _q_adjustedRect(rect) : _q_adjustedRect(rect).intersected(_q_adjustedRect(parent->boundingRect())); if (r.isEmpty()) return; + QPainterPath path; QList &children = parent->d_ptr->children; for (int i = 0; i < children.size(); ++i) { QGraphicsItem *item = children.at(i); @@ -1555,28 +1557,30 @@ void QGraphicsScenePrivate::childItems_helper(QList *items, if (item->d_ptr->isInvisible()) continue; - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - QRectF br = _q_adjustedRect(item->boundingRect()); - QRectF mbr = item->mapRectToParent(br); bool keep = false; - if (mode >= Qt::ContainsItemBoundingRect) { - // Rect intersects/contains item's bounding rect - if ((mode == Qt::IntersectsItemBoundingRect && QRectF_intersects(rect, mbr)) - || (mode == Qt::ContainsItemBoundingRect && rect != mbr && rect.contains(br))) { - items->append(item); - keep = true; - } - } else { - // Rect intersects/contains item's shape - if (QRectF_intersects(rect, mbr)) { - if (path == QPainterPath()) - path.addRect(rect); - if (itemCollidesWithPath(item, item->mapFromParent(path), mode)) { + if (!item->d_ptr->isClippedAway()) { + // ### _q_adjustedRect is only needed because QRectF::intersects, + // QRectF::contains and QTransform::map() and friends don't work with + // flat rectangles. + QRectF br = _q_adjustedRect(item->boundingRect()); + QRectF mbr = item->mapRectToParent(br); + if (mode >= Qt::ContainsItemBoundingRect) { + // Rect intersects/contains item's bounding rect + if ((mode == Qt::IntersectsItemBoundingRect && QRectF_intersects(rect, mbr)) + || (mode == Qt::ContainsItemBoundingRect && rect != mbr && rect.contains(br))) { items->append(item); keep = true; } + } else { + // Rect intersects/contains item's shape + if (QRectF_intersects(rect, mbr)) { + if (path == QPainterPath()) + path.addRect(rect); + if (itemCollidesWithPath(item, item->mapFromParent(path), mode)) { + items->append(item); + keep = true; + } + } } } @@ -1598,13 +1602,15 @@ void QGraphicsScenePrivate::childItems_helper(QList *items, const QPolygonF &polygon, Qt::ItemSelectionMode mode) const { - QPainterPath path; bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); + if (parentClip && parent->d_ptr->isClippedAway()) + return; QRectF polyRect = _q_adjustedRect(polygon.boundingRect()); QRectF r = !parentClip ? polyRect : polyRect.intersected(_q_adjustedRect(parent->boundingRect())); if (r.isEmpty()) return; + QPainterPath path; QList &children = parent->d_ptr->children; for (int i = 0; i < children.size(); ++i) { QGraphicsItem *item = children.at(i); @@ -1615,29 +1621,31 @@ void QGraphicsScenePrivate::childItems_helper(QList *items, if (item->d_ptr->isInvisible()) continue; - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - QRectF br = _q_adjustedRect(item->boundingRect()); bool keep = false; - if (mode >= Qt::ContainsItemBoundingRect) { - // Polygon contains/intersects item's bounding rect - if (path == QPainterPath()) - path.addPolygon(polygon); - if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br))) - || (mode == Qt::ContainsItemBoundingRect && path.contains(item->mapRectToParent(br)))) { - items->append(item); - keep = true; - } - } else { - // Polygon contains/intersects item's shape - if (QRectF_intersects(polyRect, item->mapRectToParent(br))) { + if (!item->d_ptr->isClippedAway()) { + // ### _q_adjustedRect is only needed because QRectF::intersects, + // QRectF::contains and QTransform::map() and friends don't work with + // flat rectangles. + QRectF br = _q_adjustedRect(item->boundingRect()); + if (mode >= Qt::ContainsItemBoundingRect) { + // Polygon contains/intersects item's bounding rect if (path == QPainterPath()) path.addPolygon(polygon); - if (itemCollidesWithPath(item, item->mapFromParent(path), mode)) { + if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br))) + || (mode == Qt::ContainsItemBoundingRect && path.contains(item->mapRectToParent(br)))) { items->append(item); keep = true; } + } else { + // Polygon contains/intersects item's shape + if (QRectF_intersects(polyRect, item->mapRectToParent(br))) { + if (path == QPainterPath()) + path.addPolygon(polygon); + if (itemCollidesWithPath(item, item->mapFromParent(path), mode)) { + items->append(item); + keep = true; + } + } } } @@ -1654,6 +1662,8 @@ void QGraphicsScenePrivate::childItems_helper(QList *items, Qt::ItemSelectionMode mode) const { bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); + if (parentClip && parent->d_ptr->isClippedAway()) + return; QRectF pathRect = _q_adjustedRect(path.boundingRect()); QRectF r = !parentClip ? pathRect : pathRect.intersected(_q_adjustedRect(parent->boundingRect())); if (r.isEmpty()) @@ -1669,25 +1679,27 @@ void QGraphicsScenePrivate::childItems_helper(QList *items, if (item->d_ptr->isInvisible()) continue; - // ### _q_adjustedRect is only needed because QRectF::intersects, - // QRectF::contains and QTransform::map() and friends don't work with - // flat rectangles. - QRectF br = _q_adjustedRect(item->boundingRect()); bool keep = false; - if (mode >= Qt::ContainsItemBoundingRect) { - // Polygon contains/intersects item's bounding rect - if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br))) - || (mode == Qt::ContainsItemBoundingRect && path.contains(item->mapRectToParent(br)))) { - items->append(item); - keep = true; - } - } else { - // Path contains/intersects item's shape - if (QRectF_intersects(pathRect, item->mapRectToParent(br))) { - if (itemCollidesWithPath(item, item->mapFromParent(path), mode)) { + if (!item->d_ptr->isClippedAway()) { + // ### _q_adjustedRect is only needed because QRectF::intersects, + // QRectF::contains and QTransform::map() and friends don't work with + // flat rectangles. + QRectF br = _q_adjustedRect(item->boundingRect()); + if (mode >= Qt::ContainsItemBoundingRect) { + // Polygon contains/intersects item's bounding rect + if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br))) + || (mode == Qt::ContainsItemBoundingRect && path.contains(item->mapRectToParent(br)))) { items->append(item); keep = true; } + } else { + // Path contains/intersects item's shape + if (QRectF_intersects(pathRect, item->mapRectToParent(br))) { + if (itemCollidesWithPath(item, item->mapFromParent(path), mode)) { + items->append(item); + keep = true; + } + } } } -- cgit v0.12 From 0d959a6c402ea3a3a55d7076d453d4bdbf8dce8e Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Tue, 24 Mar 2009 15:50:26 +0100 Subject: Fixes: Discard update requests if possible. AutoTest: Still pass. Details: Update requests can be discarded if the item itself is clipped away and the item clips all its children to shape. This cut-off is extremely effective (and aggressive:)) --- src/gui/graphicsview/qgraphicsitem.cpp | 54 ++++++++++++++++++++++------------ src/gui/graphicsview/qgraphicsitem_p.h | 9 ++++-- src/gui/graphicsview/qgraphicsview.cpp | 2 ++ 3 files changed, 44 insertions(+), 21 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 75b6cf1..a5d6021 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1063,7 +1063,7 @@ void QGraphicsItem::setParentItem(QGraphicsItem *parent) qVariantSetValue(variant, this); d_ptr->parent->itemChange(ItemChildAddedChange, variant); if (!implicitUpdate) - d_ptr->updateHelper(); + d_ptr->updateHelper(QRectF(), false, true); // Inherit ancestor flags from the new parent. d_ptr->updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1)); @@ -1092,7 +1092,7 @@ void QGraphicsItem::setParentItem(QGraphicsItem *parent) if (!d_ptr->enabled && !d_ptr->explicitlyDisabled) d_ptr->setEnabledHelper(true, /* explicit = */ false); - d_ptr->updateHelper(); + d_ptr->updateHelper(QRectF(), false, true); } if (d_ptr->scene) { @@ -1236,7 +1236,7 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) int geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations); bool fullUpdate = (flags & geomChangeFlagsMask) != (d_ptr->flags & geomChangeFlagsMask); if (fullUpdate) - d_ptr->fullUpdateHelper(); + d_ptr->fullUpdateHelper(false, true); // Keep the old flags to compare the diff. GraphicsItemFlags oldFlags = this->flags(); @@ -1281,7 +1281,7 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) } // ### Why updateHelper? - d_ptr->updateHelper(); + d_ptr->updateHelper(QRectF(), false, true); // Notify change. itemChange(ItemFlagsHaveChanged, quint32(flags)); @@ -2369,13 +2369,13 @@ void QGraphicsItemPrivate::setPosHelper(const QPointF &pos) // Update and repositition. inSetPosHelper = 1; + updateCachedClipPathFromSetPosHelper(newPos); if (scene) { fullUpdateHelper(true); q->prepareGeometryChange(); } this->pos = newPos; invalidateSceneTransformCache(); - updateCachedClipPathFromSetPosHelper(); // Send post-notification. q->itemChange(QGraphicsItem::ItemPositionHasChanged, newPos); @@ -2771,7 +2771,7 @@ void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine) return; // Update and set the new transformation. - d_ptr->fullUpdateHelper(true); + d_ptr->fullUpdateHelper(true, true); prepareGeometryChange(); d_ptr->hasTransform = !newTransform.isIdentity(); d_ptr->setExtra(QGraphicsItemPrivate::ExtraTransform, newTransform); @@ -2817,7 +2817,7 @@ void QGraphicsItem::setTransform(const QTransform &matrix, bool combine) return; // Update and set the new transformation. - d_ptr->fullUpdateHelper(true); + d_ptr->fullUpdateHelper(true, true); prepareGeometryChange(); d_ptr->hasTransform = !newTransform.isIdentity(); d_ptr->setExtra(QGraphicsItemPrivate::ExtraTransform, newTransform); @@ -3626,7 +3626,7 @@ void QGraphicsItem::setBoundingRegionGranularity(qreal granularity) only case where the item's background should be marked as dirty even when the item isn't visible. */ -void QGraphicsItemPrivate::updateHelper(const QRectF &rect, bool force) +void QGraphicsItemPrivate::updateHelper(const QRectF &rect, bool force, bool maybeDirtyClipPath) { // No scene, or if the scene is updating everything, means we have nothing // to do. The only exception is if the scene tracks the growing scene rect. @@ -3634,6 +3634,8 @@ void QGraphicsItemPrivate::updateHelper(const QRectF &rect, bool force) return; if (!scene || (scene && scene->d_func()->updateAll && scene->d_func()->hasSceneRect)) return; + if (!force && !maybeDirtyClipPath && discardUpdateRequest()) + return; if (scene && (visible || force)) { if (rect.isNull()) dirty = 1; @@ -3646,17 +3648,19 @@ void QGraphicsItemPrivate::updateHelper(const QRectF &rect, bool force) Propagates updates to \a item and all its children. */ -void QGraphicsItemPrivate::fullUpdateHelper(bool childrenOnly) +void QGraphicsItemPrivate::fullUpdateHelper(bool childrenOnly, bool maybeDirtyClipPath) { + if (!maybeDirtyClipPath && discardUpdateRequest()) + return; // No scene, or if the scene is updating everything, means we have nothing // to do. The only exception is if the scene tracks the growing scene rect. if (!scene || (scene && scene->d_func()->updateAll && scene->d_func()->hasSceneRect)) return; if (!childrenOnly && !dirty) - updateHelper(); + updateHelper(QRectF(), false, maybeDirtyClipPath); if (children.isEmpty() || dirtyChildren) return; - if (flags & QGraphicsItem::ItemClipsChildrenToShape) { + if (flags & QGraphicsItem::ItemClipsChildrenToShape || children.isEmpty()) { // ### mark all children dirty? // Unnecessary to update children as well. return; @@ -3683,7 +3687,7 @@ void QGraphicsItemPrivate::fullUpdateHelper(bool childrenOnly) } } foreach (QGraphicsItem *child, children) - child->d_ptr->fullUpdateHelper(); + child->d_ptr->fullUpdateHelper(false, maybeDirtyClipPath); dirtyChildren = 1; } @@ -3813,23 +3817,35 @@ void QGraphicsItemPrivate::invalidateCachedClipPathRecursively(bool childrenOnly } } -void QGraphicsItemPrivate::updateCachedClipPathFromSetPosHelper() +void QGraphicsItemPrivate::updateCachedClipPathFromSetPosHelper(const QPointF &newPos) { Q_ASSERT(inSetPosHelper); if (!(ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) return; // Not clipped by any ancestor. - // Find closest clip ancestor. + // Find closest clip ancestor and transform. + Q_Q(QGraphicsItem); + QTransform thisToParentTransform = hasTransform + ? q->transform() * QTransform::fromTranslate(newPos.x(), newPos.y()) + : QTransform::fromTranslate(newPos.x(), newPos.y()); QGraphicsItem *clipParent = parent; - while (clipParent && !(clipParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape)) + while (clipParent && !(clipParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape)) { + if (clipParent->d_ptr->hasTransform) + thisToParentTransform *= clipParent->transform(); + if (!clipParent->d_ptr->pos.isNull()) { + thisToParentTransform *= QTransform::fromTranslate(clipParent->d_ptr->pos.x(), + clipParent->d_ptr->pos.y()); + } clipParent = clipParent->d_ptr->parent; + } + // thisToParentTransform is now the same as q->itemTransform(clipParent), except + // that the new position (which is not yet set on the item) is taken into account. Q_ASSERT(clipParent); - Q_Q(QGraphicsItem); + Q_ASSERT(clipParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape); // From here everything is calculated in clip parent's coordinates. - const QTransform thisToParentTransform(q->itemTransform(clipParent)); const QRectF parentBoundingRect(clipParent->boundingRect()); const QRectF thisBoundingRect(thisToParentTransform.mapRect(q->boundingRect())); @@ -3894,6 +3910,8 @@ void QGraphicsItem::update(const QRectF &rect) { if (d_ptr->dirty || (rect.isEmpty() && !rect.isNull())) return; + if (d_ptr->discardUpdateRequest()) + return; if (d_ptr->scene && isVisible()) { if (CacheMode(d_ptr->cacheMode) != NoCache) { QGraphicsItemCache *cache = d_ptr->extraItemCache(); @@ -5639,7 +5657,7 @@ void QGraphicsItem::prepareGeometryChange() if (!d_ptr->scene) return; - d_ptr->updateHelper(); + d_ptr->updateHelper(QRectF(), false, /*maybeDirtyClipPath=*/!d_ptr->inSetPosHelper); QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func(); scenePrivate->removeFromIndex(this); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 3e4c269..dabbe53 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -164,8 +164,8 @@ public: void setPosHelper(const QPointF &pos); void setVisibleHelper(bool newVisible, bool explicitly, bool update = true); void setEnabledHelper(bool newEnabled, bool explicitly, bool update = true); - void updateHelper(const QRectF &rect = QRectF(), bool force = false); - void fullUpdateHelper(bool childrenOnly = false); + void updateHelper(const QRectF &rect = QRectF(), bool force = false, bool maybeDirtyClipPath = false); + void fullUpdateHelper(bool childrenOnly = false, bool maybeDirtyClipPath = false); void resolveEffectiveOpacity(qreal effectiveParentOpacity); void resolveDepth(int parentDepth); void invalidateSceneTransformCache(); @@ -256,7 +256,7 @@ public: { /*static int count = 0 ;qWarning("%i", ++count);*/ dirtyClipPath = 1; emptyClipPath = 0; } void invalidateCachedClipPathRecursively(bool childrenOnly = false, const QRectF &emptyIfOutsideThisRect = QRectF()); - void updateCachedClipPathFromSetPosHelper(); + void updateCachedClipPathFromSetPosHelper(const QPointF &newPos); inline bool isInvisible() const { @@ -267,6 +267,9 @@ public: inline bool isClippedAway() const { return !dirtyClipPath && q_func()->isClipped() && (emptyClipPath || cachedClipPath.isEmpty()); } + inline bool discardUpdateRequest() const + { return ((flags & QGraphicsItem::ItemClipsChildrenToShape) || children.isEmpty()) && isClippedAway(); } + QPainterPath cachedClipPath; QPointF pos; qreal z; diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 9191fc5..43263da 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -855,6 +855,8 @@ void QGraphicsViewPrivate::_q_updateLaterSlot() const QList &dirtyItems = scene->d_func()->dirtyItems; for (int i = 0; i < dirtyItems.size(); ++i) { const QGraphicsItem *item = dirtyItems.at(i); + if (item->d_ptr->discardUpdateRequest()) + continue; QTransform x = item->sceneTransform() * viewTransform; updateRect(x.mapRect(item->boundingRect()).toAlignedRect() & vr); } -- cgit v0.12 From 9ed299a3edba92791e1c5af64b8fd9c9fe74c0ea Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Wed, 25 Mar 2009 12:38:35 +0100 Subject: Fixes: Optimize QGraphicsViewPrivate::itemUpdated. AutoTest: Still pass Details: Get rid of QTransform::inverted()/operator*= and do nothing if the item clips all its children and the update rect is outside the bounding rect. --- src/gui/graphicsview/qgraphicsview.cpp | 40 ++++++++++++++++------------------ 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 43263da..4db2257 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -801,38 +801,36 @@ void QGraphicsViewPrivate::itemUpdated(QGraphicsItem *item, const QRectF &rect) updateLater(); QRectF updateRect = rect; - if (item->isClipped()) { + if ((item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape) || item->d_ptr->children.isEmpty()) { + updateRect &= item->boundingRect(); + if (updateRect.isEmpty()) + return; + } + + QGraphicsItem *clipItem = item; + if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) { // Minimize unnecessary redraw. - QGraphicsItem *p = item; - QTransform xform; - QGraphicsItem *lastTransformItem = 0; - while ((p = p->d_ptr->parent)) { - if (p->flags() & QGraphicsItem::ItemClipsChildrenToShape) { - if (!lastTransformItem) - xform = item->itemTransform(p); - else - xform *= lastTransformItem->itemTransform(p); - lastTransformItem = p; - updateRect &= xform.inverted().mapRect(p->boundingRect()); + QGraphicsItem *parent = item; + while ((parent = parent->d_ptr->parent)) { + if (parent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape) { + // Map update rect to the current parent and itersect with its bounding rect. + updateRect = clipItem->itemTransform(parent).mapRect(updateRect) & parent->boundingRect(); if (updateRect.isEmpty()) return; + clipItem = parent; } - if (!(p->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) + if (!(parent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) break; } - - if (updateRect.isEmpty()) - return; } - // Map the rect to view coordinates. - QRect vr = viewport->rect(); - + // Map update rect from clipItem coordinates to view coordinates. + Q_ASSERT(clipItem); if (!item->d_ptr->hasBoundingRegionGranularity) - this->updateRect(mapToViewRect(item, updateRect) & vr); + this->updateRect(mapToViewRect(clipItem, updateRect) & viewport->rect()); else - updateRegion(mapToViewRegion(item, updateRect) & vr); + updateRegion(mapToViewRegion(clipItem, updateRect) & viewport->rect()); } void QGraphicsViewPrivate::updateLater() -- cgit v0.12 From a914eb155e085ba0efa5b95154bf7345d4be7cd7 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Wed, 25 Mar 2009 13:41:10 +0100 Subject: Fixes: Minimize QVariant constr/destr in setPosHelper. RevBy: TrustMe --- src/gui/graphicsview/qgraphicsitem.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index a5d6021..396fdbd 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -2363,7 +2363,8 @@ void QGraphicsItemPrivate::setPosHelper(const QPointF &pos) return; // Notify the item that the position is changing. - QPointF newPos = q->itemChange(QGraphicsItem::ItemPositionChange, pos).toPointF(); + const QVariant newPosVariant(q->itemChange(QGraphicsItem::ItemPositionChange, pos)); + QPointF newPos = newPosVariant.toPointF(); if (newPos == this->pos) return; @@ -2378,7 +2379,7 @@ void QGraphicsItemPrivate::setPosHelper(const QPointF &pos) invalidateSceneTransformCache(); // Send post-notification. - q->itemChange(QGraphicsItem::ItemPositionHasChanged, newPos); + q->itemChange(QGraphicsItem::ItemPositionHasChanged, newPosVariant); inSetPosHelper = 0; } -- cgit v0.12 From 5564ef89f46fe96aa0b22b888a9a8ba053eea6c7 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Thu, 26 Mar 2009 16:48:48 +0100 Subject: Fixes: Don't check the force boolean. Details: It's clipped away regardless. --- src/gui/graphicsview/qgraphicsitem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 396fdbd..c691206 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -3635,7 +3635,7 @@ void QGraphicsItemPrivate::updateHelper(const QRectF &rect, bool force, bool may return; if (!scene || (scene && scene->d_func()->updateAll && scene->d_func()->hasSceneRect)) return; - if (!force && !maybeDirtyClipPath && discardUpdateRequest()) + if (!maybeDirtyClipPath && discardUpdateRequest()) return; if (scene && (visible || force)) { if (rect.isNull()) -- cgit v0.12 From 15098c5ec73db5de8ca724f744a1484f888ed271 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Thu, 26 Mar 2009 17:05:59 +0100 Subject: Fixes: Do not update children if not required. AutoTest: Still pass --- src/gui/graphicsview/qgraphicsitem.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index c691206..b4f36de 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1583,9 +1583,10 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo } // Update children with explicitly = false. + const bool updateChildren = update && !(flags & QGraphicsItem::ItemClipsChildrenToShape); foreach (QGraphicsItem *child, children) { if (!newVisible || !child->d_ptr->explicitlyHidden) - child->d_ptr->setVisibleHelper(newVisible, false); + child->d_ptr->setVisibleHelper(newVisible, false, updateChildren); } // Enable subfocus -- cgit v0.12 From d85835580463f88df6a71d27d2577739e5366f68 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Thu, 26 Mar 2009 17:16:36 +0100 Subject: Fixes: Don't bother updating hidden items. AutoTest: Still pass --- src/gui/graphicsview/qgraphicsitem.cpp | 2 +- src/gui/graphicsview/qgraphicsscene.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index b4f36de..327b352 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -3652,7 +3652,7 @@ void QGraphicsItemPrivate::updateHelper(const QRectF &rect, bool force, bool may */ void QGraphicsItemPrivate::fullUpdateHelper(bool childrenOnly, bool maybeDirtyClipPath) { - if (!maybeDirtyClipPath && discardUpdateRequest()) + if (!visible || (!maybeDirtyClipPath && discardUpdateRequest())) return; // No scene, or if the scene is updating everything, means we have nothing // to do. The only exception is if the scene tracks the growing scene rect. diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index f32fe71..e13a767 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -5174,6 +5174,9 @@ void QGraphicsScene::itemUpdated(QGraphicsItem *item, const QRectF &rect) d->resetDirtyItemsLater(); } + if (!item->isVisible()) + return; // Hiding an item won't effect the largestUntransformableItem/sceneRect. + // Update d->largestUntransformableItem by mapping this item's bounding // rect back to the topmost untransformable item's untransformed // coordinate system (which sort of equals the 1:1 coordinate system of an -- cgit v0.12 From 23c73210fc79055f4bac44de0e43f9917f8d0e7f Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Tue, 24 Mar 2009 15:50:26 +0100 Subject: Fixes: Discard update requests if possible. AutoTest: Still pass. Details: Update requests can be discarded if the item itself is clipped away and the item clips all its children to shape. This cut-off is extremely effective (and aggressive:)) --- src/gui/graphicsview/qgraphicsitem.cpp | 39 +++++++++++++++++++++++++--------- src/gui/graphicsview/qgraphicsitem_p.h | 6 ++++++ 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 327b352..23787a7 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1102,10 +1102,7 @@ void QGraphicsItem::setParentItem(QGraphicsItem *parent) } // Resolve opacity. - if (QGraphicsItem *p = d_ptr->parent) - d_ptr->resolveEffectiveOpacity(p->effectiveOpacity()); - else - d_ptr->resolveEffectiveOpacity(1.0); + d_ptr->updateEffectiveOpacity(); // Resolve depth. d_ptr->resolveDepth(parent ? parent->d_ptr->depth : -1); @@ -1246,12 +1243,8 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) // Reresolve effective opacity if the opacity flags change. static const quint32 opacityFlagsMask = ItemIgnoresParentOpacity | ItemDoesntPropagateOpacityToChildren; - if ((flags & opacityFlagsMask) != (oldFlags & opacityFlagsMask)) { - if (QGraphicsItem *p = d_ptr->parent) - d_ptr->resolveEffectiveOpacity(p->effectiveOpacity()); - else - d_ptr->resolveEffectiveOpacity(1.0); - } + if ((flags & opacityFlagsMask) != (oldFlags & opacityFlagsMask)) + d_ptr->updateEffectiveOpacity(); if (!(d_ptr->flags & ItemIsFocusable) && hasFocus()) { // Clear focus on the item if it has focus when the focusable flag @@ -3693,6 +3686,32 @@ void QGraphicsItemPrivate::fullUpdateHelper(bool childrenOnly, bool maybeDirtyCl dirtyChildren = 1; } +static inline bool allChildrenCombineOpacity(QGraphicsItem *parent) +{ + Q_ASSERT(parent); + if (parent->flags() & QGraphicsItem::ItemDoesntPropagateOpacityToChildren) + return false; + + const QList children(parent->childItems()); + for (int i = 0; i < children.size(); ++i) { + if (children.at(i)->flags() & QGraphicsItem::ItemIgnoresParentOpacity) + return false; + } + return true; +} + +void QGraphicsItemPrivate::updateEffectiveOpacity() +{ + Q_Q(QGraphicsItem); + if (parent) { + resolveEffectiveOpacity(parent->effectiveOpacity()); + parent->d_ptr->allChildrenCombineOpacity = ::allChildrenCombineOpacity(parent); + } else { + resolveEffectiveOpacity(1.0); + } + allChildrenCombineOpacity = ::allChildrenCombineOpacity(q); +} + /*! \internal diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index dabbe53..c795915 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -141,6 +141,7 @@ public: dirtyClipPath(1), emptyClipPath(0), inSetPosHelper(0), + allChildrenCombineOpacity(1), globalStackingOrder(-1), sceneTransformIndex(-1), q_ptr(0) @@ -166,6 +167,7 @@ public: void setEnabledHelper(bool newEnabled, bool explicitly, bool update = true); void updateHelper(const QRectF &rect = QRectF(), bool force = false, bool maybeDirtyClipPath = false); void fullUpdateHelper(bool childrenOnly = false, bool maybeDirtyClipPath = false); + void updateEffectiveOpacity(); void resolveEffectiveOpacity(qreal effectiveParentOpacity); void resolveDepth(int parentDepth); void invalidateSceneTransformCache(); @@ -264,6 +266,9 @@ public: && qFuzzyCompare(q_func()->effectiveOpacity() + 1, qreal(1.0))); } + inline bool childrenCombineOpacity() const + { return allChildrenCombineOpacity || children.isEmpty(); } + inline bool isClippedAway() const { return !dirtyClipPath && q_func()->isClipped() && (emptyClipPath || cachedClipPath.isEmpty()); } @@ -308,6 +313,7 @@ public: quint32 dirtyClipPath : 1; quint32 emptyClipPath : 1; quint32 inSetPosHelper : 1; + quint32 allChildrenCombineOpacity : 1; // Optional stacking order int globalStackingOrder; -- cgit v0.12 From 73ce29e6bc09651a4e70b5e61c36d56e568905c7 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Fri, 27 Mar 2009 18:53:02 +0100 Subject: Fixes: Simplify the cut-offs and be more agressive :-) AutoTest: Still pass. Details: It's easier to read and understand the code now. --- src/gui/graphicsview/qgraphicsitem.cpp | 84 ++++++++++++++++++++-------------- src/gui/graphicsview/qgraphicsitem_p.h | 21 ++++++--- src/gui/graphicsview/qgraphicsview.cpp | 5 +- 3 files changed, 68 insertions(+), 42 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 23787a7..d27d3cd 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -3613,6 +3613,24 @@ void QGraphicsItem::setBoundingRegionGranularity(qreal granularity) /*! \internal + Returns true if we can discard an update request; otherwise false. +*/ +bool QGraphicsItemPrivate::discardUpdateRequest(bool ignoreClipping, + bool ignoreVisibleBit, + bool ignoreDirtyBit) const +{ + // No scene, or if the scene is updating everything, means we have nothing + // to do. The only exception is if the scene tracks the growing scene rect. + return (!visible && !ignoreVisibleBit) + || (dirty && !ignoreDirtyBit) + || !scene + || (scene->d_func()->updateAll && scene->d_func()->hasSceneRect) + || (!ignoreClipping && (childrenClippedToShape() && isClippedAway())) + || (childrenCombineOpacity() && isFullyTransparent()); +} + +/*! + \internal Asks the scene to mark this item's scene rect as dirty, requesting a redraw. This does not invalidate any cache. @@ -3625,17 +3643,12 @@ void QGraphicsItemPrivate::updateHelper(const QRectF &rect, bool force, bool may { // No scene, or if the scene is updating everything, means we have nothing // to do. The only exception is if the scene tracks the growing scene rect. - if (dirty) - return; - if (!scene || (scene && scene->d_func()->updateAll && scene->d_func()->hasSceneRect)) + if (discardUpdateRequest(/*ignoreClipping=*/maybeDirtyClipPath, /*ignoreVisibleBit=*/force)) return; - if (!maybeDirtyClipPath && discardUpdateRequest()) - return; - if (scene && (visible || force)) { - if (rect.isNull()) - dirty = 1; - scene->itemUpdated(q_ptr, rect); - } + + if (rect.isNull()) + dirty = 1; + scene->itemUpdated(q_ptr, rect); } /*! @@ -3645,21 +3658,23 @@ void QGraphicsItemPrivate::updateHelper(const QRectF &rect, bool force, bool may */ void QGraphicsItemPrivate::fullUpdateHelper(bool childrenOnly, bool maybeDirtyClipPath) { - if (!visible || (!maybeDirtyClipPath && discardUpdateRequest())) - return; - // No scene, or if the scene is updating everything, means we have nothing - // to do. The only exception is if the scene tracks the growing scene rect. - if (!scene || (scene && scene->d_func()->updateAll && scene->d_func()->hasSceneRect)) - return; - if (!childrenOnly && !dirty) - updateHelper(QRectF(), false, maybeDirtyClipPath); - if (children.isEmpty() || dirtyChildren) + if (discardUpdateRequest(/*ignoreClipping=*/maybeDirtyClipPath, + /*ignoreVisibleBit=*/false, + /*ignoreDirtyBit=*/true)) { return; - if (flags & QGraphicsItem::ItemClipsChildrenToShape || children.isEmpty()) { - // ### mark all children dirty? + } + + if (!childrenOnly && !dirty) { + // Effectively the same as updateHelper(QRectF(), false, maybeDirtyClipPath). + dirty = 1; + scene->itemUpdated(q_ptr, QRectF()); + } + + if (dirtyChildren || childrenClippedToShape()) { // Unnecessary to update children as well. return; } + if (ancestorFlags & AncestorClipsChildren) { Q_Q(QGraphicsItem); // Check if we can avoid updating all children. @@ -3929,22 +3944,23 @@ bool QGraphicsItemPrivate::isProxyWidget() const */ void QGraphicsItem::update(const QRectF &rect) { - if (d_ptr->dirty || (rect.isEmpty() && !rect.isNull())) + if ((rect.isEmpty() && !rect.isNull()) || d_ptr->discardUpdateRequest()) return; - if (d_ptr->discardUpdateRequest()) - return; - if (d_ptr->scene && isVisible()) { - if (CacheMode(d_ptr->cacheMode) != NoCache) { - QGraphicsItemCache *cache = d_ptr->extraItemCache(); - if (rect.isNull()) { - cache->allExposed = true; - cache->exposed.clear(); - } else { - cache->exposed.append(rect); - } + + if (CacheMode(d_ptr->cacheMode) != NoCache) { + QGraphicsItemCache *cache = d_ptr->extraItemCache(); + if (rect.isNull()) { + cache->allExposed = true; + cache->exposed.clear(); + } else { + cache->exposed.append(rect); } - d_ptr->updateHelper(rect); } + + // Effectively the same as updateHelper(rect); + if (rect.isNull()) + d_ptr->dirty = 1; + d_ptr->scene->itemUpdated(this, rect); } diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index c795915..a5871a7 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -165,6 +165,9 @@ public: void setPosHelper(const QPointF &pos); void setVisibleHelper(bool newVisible, bool explicitly, bool update = true); void setEnabledHelper(bool newEnabled, bool explicitly, bool update = true); + bool discardUpdateRequest(bool ignoreClipping = false, + bool ignoreVisibleBit = false, + bool ignoreDirtyBit = false) const; void updateHelper(const QRectF &rect = QRectF(), bool force = false, bool maybeDirtyClipPath = false); void fullUpdateHelper(bool childrenOnly = false, bool maybeDirtyClipPath = false); void updateEffectiveOpacity(); @@ -260,11 +263,8 @@ public: void invalidateCachedClipPathRecursively(bool childrenOnly = false, const QRectF &emptyIfOutsideThisRect = QRectF()); void updateCachedClipPathFromSetPosHelper(const QPointF &newPos); - inline bool isInvisible() const - { - return !visible || (hasEffectiveOpacity - && qFuzzyCompare(q_func()->effectiveOpacity() + 1, qreal(1.0))); - } + inline bool isFullyTransparent() const + { return hasEffectiveOpacity && qFuzzyCompare(q_func()->effectiveOpacity() + 1, qreal(1.0)); } inline bool childrenCombineOpacity() const { return allChildrenCombineOpacity || children.isEmpty(); } @@ -272,8 +272,15 @@ public: inline bool isClippedAway() const { return !dirtyClipPath && q_func()->isClipped() && (emptyClipPath || cachedClipPath.isEmpty()); } - inline bool discardUpdateRequest() const - { return ((flags & QGraphicsItem::ItemClipsChildrenToShape) || children.isEmpty()) && isClippedAway(); } + inline bool childrenClippedToShape() const + { return (flags & QGraphicsItem::ItemClipsChildrenToShape) || children.isEmpty(); } + + inline bool isInvisible() const + { + return !visible + || (childrenClippedToShape() && isClippedAway()) + || (childrenCombineOpacity() && isFullyTransparent()); + } QPainterPath cachedClipPath; QPointF pos; diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 4db2257..f0d360a 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -853,8 +853,11 @@ void QGraphicsViewPrivate::_q_updateLaterSlot() const QList &dirtyItems = scene->d_func()->dirtyItems; for (int i = 0; i < dirtyItems.size(); ++i) { const QGraphicsItem *item = dirtyItems.at(i); - if (item->d_ptr->discardUpdateRequest()) + if (item->d_ptr->discardUpdateRequest(/*ignoreClipping=*/false, + /*ignoreVisibleBit=*/false, + /*ignoreDirtyBit=*/true)) { continue; + } QTransform x = item->sceneTransform() * viewTransform; updateRect(x.mapRect(item->boundingRect()).toAlignedRect() & vr); } -- cgit v0.12 From 30d01c387179160c8c418ecedfb4506a55d282e8 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 27 Mar 2009 22:17:10 +0100 Subject: Optimise QGraphicsScene/View::items(const QPointF &pos) Implement specialized (and more efficient versions) of item_helper() and child_helper() that test for QPointF in the scene. --- src/gui/graphicsview/qgraphicsscene.cpp | 94 ++++++++++++++++++++++++++++----- src/gui/graphicsview/qgraphicsscene_p.h | 4 ++ src/gui/graphicsview/qgraphicsview.cpp | 4 +- 3 files changed, 88 insertions(+), 14 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index e13a767..b4dc62c 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1358,6 +1358,48 @@ QGraphicsWidget *QGraphicsScenePrivate::windowForItem(const QGraphicsItem *item) return 0; } + +QList QGraphicsScenePrivate::items_helper(const QPointF &pos) const +{ + QList items; + + // The index returns a rough estimate of what items are inside the rect. + // Refine it by iterating through all returned items. + QRectF adjustedRect = QRectF(pos, QSize(1,1)); + foreach (QGraphicsItem *item, estimateItemsInRect(adjustedRect)) { + // Find the item's scene transform in a clever way. + QTransform x = item->sceneTransform(); + bool keep = false; + + // ### _q_adjustedRect is only needed because QRectF::intersects, + // QRectF::contains and QTransform::map() and friends don't work with + // flat rectangles. + QRectF br = _q_adjustedRect(item->boundingRect()); + // Rect intersects/contains item's shape + if (QRectF_intersects(adjustedRect, x.mapRect(br))) { + bool ok; + QTransform xinv = x.inverted(&ok); + if (ok) { + if (item->contains(xinv.map(pos))) { + items << item; + keep = true; + } + } + } + + if (keep && (item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) { + // Recurse into children that clip children. + bool ok; + QTransform xinv = x.inverted(&ok); + if (ok) + childItems_helper(&items, item, xinv.map(pos)); + } + } + + sortItems(&items, Qt::AscendingOrder, sortCacheEnabled); + return items; +} + QList QGraphicsScenePrivate::items_helper(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order) const @@ -1392,7 +1434,7 @@ QList QGraphicsScenePrivate::items_helper(const QRectF &rect, bool ok; QTransform xinv = x.inverted(&ok); if (ok) { - if (path == QPainterPath()) + if (path.isEmpty()) path.addRect(rect); if (itemCollidesWithPath(item, xinv.map(path), mode)) { items << item; @@ -1536,6 +1578,42 @@ QList QGraphicsScenePrivate::items_helper(const QPainterPath &p void QGraphicsScenePrivate::childItems_helper(QList *items, const QGraphicsItem *parent, + const QPointF &pos) const +{ + bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); + if (parentClip && parent->d_ptr->isClippedAway()) + return; + // ### is this needed? + if (parentClip && !parent->boundingRect().contains(pos)) + return; + + QList &children = parent->d_ptr->children; + for (int i = 0; i < children.size(); ++i) { + QGraphicsItem *item = children.at(i); + if (item->d_ptr->hasTransform && !item->transform().isInvertible()) + continue; + + // Skip invisible items and all their children. + if (item->d_ptr->isInvisible()) + continue; + + bool keep = false; + if (!item->d_ptr->isClippedAway()) { + if (item->contains(item->mapFromParent(pos))) { + items->append(item); + keep = true; + } + } + + if ((keep || !(item->flags() & QGraphicsItem::ItemClipsChildrenToShape)) && !item->d_ptr->children.isEmpty()) + // Recurse into children. + childItems_helper(items, item, item->mapFromParent(pos)); + } +} + + +void QGraphicsScenePrivate::childItems_helper(QList *items, + const QGraphicsItem *parent, const QRectF &rect, Qt::ItemSelectionMode mode) const { @@ -1597,6 +1675,7 @@ void QGraphicsScenePrivate::childItems_helper(QList *items, } } + void QGraphicsScenePrivate::childItems_helper(QList *items, const QGraphicsItem *parent, const QPolygonF &polygon, @@ -2380,17 +2459,8 @@ QList QGraphicsScene::items() const */ QList QGraphicsScene::items(const QPointF &pos) const { - QList itemsAtPoint; - - // Find all items within a 1x1 rect area starting at pos. This can be - // inefficient for scenes that use small coordinates (like unity - // coordinates), or for detailed graphs. ### The index should support - // fetching items at a pos to avoid this limitation. - foreach (QGraphicsItem *item, items(QRectF(pos, QSizeF(1, 1)), Qt::IntersectsItemBoundingRect)) { - if (item->contains(item->mapFromScene(pos))) - itemsAtPoint << item; - } - return itemsAtPoint; + Q_D(const QGraphicsScene); + return d->items_helper(pos); } diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 9c165d1..befbbd8 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -197,6 +197,7 @@ public: void mousePressEventHandler(QGraphicsSceneMouseEvent *mouseEvent); QGraphicsWidget *windowForItem(const QGraphicsItem *item) const; + QList items_helper(const QPointF &pos) const; QList items_helper(const QRectF &rect, Qt::ItemSelectionMode mode, Qt::SortOrder order) const; @@ -208,6 +209,9 @@ public: Qt::SortOrder order) const; void childItems_helper(QList *items, const QGraphicsItem *parent, + const QPointF &pos) const; + void childItems_helper(QList *items, + const QGraphicsItem *parent, const QRectF &rect, Qt::ItemSelectionMode mode) const; void childItems_helper(QList *items, diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index f0d360a..ba9cdbf 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -2251,9 +2251,9 @@ QList QGraphicsView::items(const QPoint &pos) const if (d->scene->d_func()->largestUntransformableItem.isNull()) { if ((d->identityMatrix || d->matrix.type() <= QTransform::TxScale)) { QTransform xinv = viewportTransform().inverted(); - return d->scene->items(xinv.mapRect(QRectF(pos.x(), pos.y(), 1, 1))); + return d->scene->items(xinv.map(pos)); } - return d->scene->items(mapToScene(pos.x(), pos.y(), 2, 2)); + return d->scene->items(mapToScene(pos)); } QPainterPath path; -- cgit v0.12 From bc3d96a902d16a9bb358c05de9f6bfede3594731 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 27 Mar 2009 22:18:47 +0100 Subject: Optimise QPainterPath::contains(QPointF) We can shortcut quite some calculations for the common case by first checking whether the point is contained in the control point rect. --- src/gui/painting/qpainterpath.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp index 70036e1..e1f5eea 100644 --- a/src/gui/painting/qpainterpath.cpp +++ b/src/gui/painting/qpainterpath.cpp @@ -1725,7 +1725,7 @@ static void qt_painterpath_isect_curve(const QBezier &bezier, const QPointF &pt, */ bool QPainterPath::contains(const QPointF &pt) const { - if (isEmpty()) + if (isEmpty() || !controlPointRect().contains(pt)) return false; QPainterPathData *d = d_func(); -- cgit v0.12 From d516e5fbed3a7eac20229ead34221c732f85cdb6 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Tue, 31 Mar 2009 14:58:15 +0200 Subject: Fixes: Minimize QVariant overhead related to QGraphicsItem::itemChange. RevBy: Andreas AutoTest: included --- src/gui/graphicsview/qgraphicsitem.cpp | 70 ++++++++++++++------------ src/gui/graphicsview/qgraphicsscene.cpp | 24 +++++---- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 18 +++++++ 3 files changed, 69 insertions(+), 43 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index d27d3cd..11a03b6 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1024,9 +1024,8 @@ void QGraphicsItem::setParentItem(QGraphicsItem *parent) } if (parent == d_ptr->parent) return; - QVariant variant; - qVariantSetValue(variant, parent); - parent = qVariantValue(itemChange(ItemParentChange, variant)); + const QVariant newParentVariant(itemChange(ItemParentChange, qVariantFromValue(parent))); + parent = qVariantValue(newParentVariant); if (parent == d_ptr->parent) return; @@ -1041,11 +1040,11 @@ void QGraphicsItem::setParentItem(QGraphicsItem *parent) // We anticipate geometry changes prepareGeometryChange(); + const QVariant thisPointerVariant(qVariantFromValue(this)); if (d_ptr->parent) { // Remove from current parent qt_graphicsitem_removeChild(this, &d_ptr->parent->d_func()->children); - qVariantSetValue(variant, this); - d_ptr->parent->itemChange(ItemChildRemovedChange, variant); + d_ptr->parent->itemChange(ItemChildRemovedChange, thisPointerVariant); } if ((d_ptr->parent = parent)) { @@ -1060,8 +1059,7 @@ void QGraphicsItem::setParentItem(QGraphicsItem *parent) } d_ptr->parent->d_func()->children << this; - qVariantSetValue(variant, this); - d_ptr->parent->itemChange(ItemChildAddedChange, variant); + d_ptr->parent->itemChange(ItemChildAddedChange, thisPointerVariant); if (!implicitUpdate) d_ptr->updateHelper(QRectF(), false, true); @@ -1111,7 +1109,7 @@ void QGraphicsItem::setParentItem(QGraphicsItem *parent) d_ptr->invalidateSceneTransformCache(); // Deliver post-change notification - itemChange(QGraphicsItem::ItemParentHasChanged, qVariantFromValue(parent)); + itemChange(QGraphicsItem::ItemParentHasChanged, newParentVariant); } /*! @@ -1372,9 +1370,9 @@ QString QGraphicsItem::toolTip() const */ void QGraphicsItem::setToolTip(const QString &toolTip) { - QString newCursor = itemChange(ItemToolTipChange, toolTip).toString(); - d_ptr->setExtra(QGraphicsItemPrivate::ExtraToolTip, toolTip); - itemChange(ItemToolTipHasChanged, toolTip); + const QVariant toolTipVariant(itemChange(ItemToolTipChange, toolTip)); + d_ptr->setExtra(QGraphicsItemPrivate::ExtraToolTip, toolTipVariant.toString()); + itemChange(ItemToolTipHasChanged, toolTipVariant); } #endif // QT_NO_TOOLTIP @@ -1416,9 +1414,8 @@ QCursor QGraphicsItem::cursor() const */ void QGraphicsItem::setCursor(const QCursor &cursor) { - QCursor newCursor = qVariantValue(itemChange(ItemCursorChange, - qVariantFromValue(cursor))); - d_ptr->setExtra(QGraphicsItemPrivate::ExtraCursor, newCursor); + const QVariant cursorVariant(itemChange(ItemCursorChange, qVariantFromValue(cursor))); + d_ptr->setExtra(QGraphicsItemPrivate::ExtraCursor, qVariantValue(cursorVariant)); d_ptr->hasCursor = 1; if (d_ptr->scene) { foreach (QGraphicsView *view, d_ptr->scene->views()) { @@ -1435,7 +1432,7 @@ void QGraphicsItem::setCursor(const QCursor &cursor) } } } - itemChange(ItemCursorHasChanged, qVariantFromValue(newCursor)); + itemChange(ItemCursorHasChanged, cursorVariant); } /*! @@ -1529,7 +1526,9 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo return; // Modify the property. - newVisible = q_ptr->itemChange(QGraphicsItem::ItemVisibleChange, quint32(newVisible)).toBool(); + const QVariant newVisibleVariant(q_ptr->itemChange(QGraphicsItem::ItemVisibleChange, + quint32(newVisible))); + newVisible = newVisibleVariant.toBool(); if (visible == quint32(newVisible)) return; visible = newVisible; @@ -1591,7 +1590,7 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo } // Deliver post-change notification. - q_ptr->itemChange(QGraphicsItem::ItemVisibleHasChanged, quint32(visible)); + q_ptr->itemChange(QGraphicsItem::ItemVisibleHasChanged, newVisibleVariant); } /*! @@ -1697,7 +1696,9 @@ void QGraphicsItemPrivate::setEnabledHelper(bool newEnabled, bool explicitly, bo } // Modify the property. - enabled = q_ptr->itemChange(QGraphicsItem::ItemEnabledChange, quint32(newEnabled)).toBool(); + const QVariant newEnabledVariant(q_ptr->itemChange(QGraphicsItem::ItemEnabledChange, + quint32(newEnabled))); + enabled = newEnabledVariant.toBool(); // Schedule redraw. if (update) @@ -1709,7 +1710,7 @@ void QGraphicsItemPrivate::setEnabledHelper(bool newEnabled, bool explicitly, bo } // Deliver post-change notification. - q_ptr->itemChange(QGraphicsItem::ItemEnabledHasChanged, quint32(enabled)); + q_ptr->itemChange(QGraphicsItem::ItemEnabledHasChanged, newEnabledVariant); } /*! @@ -1796,7 +1797,8 @@ void QGraphicsItem::setSelected(bool selected) selected = false; if (d_ptr->selected == selected) return; - bool newSelected = itemChange(ItemSelectedChange, quint32(selected)).toBool(); + const QVariant newSelectedVariant(itemChange(ItemSelectedChange, quint32(selected))); + bool newSelected = newSelectedVariant.toBool(); if (d_ptr->selected == newSelected) return; d_ptr->selected = newSelected; @@ -1816,7 +1818,7 @@ void QGraphicsItem::setSelected(bool selected) } // Deliver post-change notification. - itemChange(QGraphicsItem::ItemSelectedHasChanged, quint32(d_ptr->selected)); + itemChange(QGraphicsItem::ItemSelectedHasChanged, newSelectedVariant); } /*! @@ -1892,7 +1894,8 @@ qreal QGraphicsItem::effectiveOpacity() const void QGraphicsItem::setOpacity(qreal opacity) { // Notify change. - qreal newOpacity = itemChange(ItemOpacityChange, double(opacity)).toDouble(); + const QVariant newOpacityVariant(itemChange(ItemOpacityChange, double(opacity))); + qreal newOpacity = newOpacityVariant.toDouble(); // Normalize. newOpacity = qBound(0.0, newOpacity, 1.0); @@ -2759,9 +2762,9 @@ void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine) return; // Notify the item that the matrix is changing. - QVariant variant; - qVariantSetValue(variant, newTransform.toAffine()); - newTransform = QTransform(qVariantValue(itemChange(ItemMatrixChange, variant))); + QVariant newTransformVariant(itemChange(ItemMatrixChange, + qVariantFromValue(newTransform.toAffine()))); + newTransform = QTransform(qVariantValue(newTransformVariant)); if (oldTransform == newTransform) return; @@ -2773,7 +2776,9 @@ void QGraphicsItem::setMatrix(const QMatrix &matrix, bool combine) d_ptr->invalidateSceneTransformCache(); // Send post-notification. - itemChange(ItemTransformHasChanged, newTransform); + // NB! We have to change the value from QMatrix to QTransform. + qVariantSetValue(newTransformVariant, newTransform); + itemChange(ItemTransformHasChanged, newTransformVariant); } /*! @@ -2805,9 +2810,9 @@ void QGraphicsItem::setTransform(const QTransform &matrix, bool combine) return; // Notify the item that the transformation matrix is changing. - QVariant variant; - qVariantSetValue(variant, newTransform); - newTransform = qVariantValue(itemChange(ItemTransformChange, variant)); + const QVariant newTransformVariant(itemChange(ItemTransformChange, + qVariantFromValue(newTransform))); + newTransform = qVariantValue(newTransformVariant); if (oldTransform == newTransform) return; @@ -2819,7 +2824,7 @@ void QGraphicsItem::setTransform(const QTransform &matrix, bool combine) d_ptr->invalidateSceneTransformCache(); // Send post-notification. - itemChange(ItemTransformHasChanged, newTransform); + itemChange(ItemTransformHasChanged, newTransformVariant); } /*! @@ -2967,7 +2972,8 @@ qreal QGraphicsItem::zValue() const */ void QGraphicsItem::setZValue(qreal z) { - qreal newZ = qreal(itemChange(ItemZValueChange, double(z)).toDouble()); + const QVariant newZVariant(itemChange(ItemZValueChange, double(z))); + qreal newZ = qreal(newZVariant.toDouble()); if (newZ == d_ptr->z) return; d_ptr->z = z; @@ -2979,7 +2985,7 @@ void QGraphicsItem::setZValue(qreal z) d_ptr->scene->d_func()->invalidateSortCache(); } - itemChange(ItemZValueHasChanged, double(newZ)); + itemChange(ItemZValueHasChanged, newZVariant); } /*! diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index b4dc62c..bcc329e 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -632,10 +632,11 @@ void QGraphicsScenePrivate::_q_updateLater() */ void QGraphicsScenePrivate::_q_polishItems() { + const QVariant booleanTrueVariant(true); foreach (QGraphicsItem *item, unpolishedItems) { if (!item->d_ptr->explicitlyHidden) { - item->itemChange(QGraphicsItem::ItemVisibleChange, true); - item->itemChange(QGraphicsItem::ItemVisibleHasChanged, true); + item->itemChange(QGraphicsItem::ItemVisibleChange, booleanTrueVariant); + item->itemChange(QGraphicsItem::ItemVisibleHasChanged, booleanTrueVariant); } if (item->isWidget()) { QEvent event(QEvent::Polish); @@ -691,9 +692,8 @@ void QGraphicsScenePrivate::_q_removeItemLater(QGraphicsItem *item) Q_Q(QGraphicsScene); if (QGraphicsItem *parent = item->d_func()->parent) { - QVariant variant; - qVariantSetValue(variant, item); - parent->itemChange(QGraphicsItem::ItemChildRemovedChange, variant); + parent->itemChange(QGraphicsItem::ItemChildRemovedChange, + qVariantFromValue(item)); parent->d_func()->children.removeAll(item); } @@ -2847,8 +2847,9 @@ void QGraphicsScene::addItem(QGraphicsItem *item) // Notify the item that its scene is changing, and allow the item to // react. - QGraphicsScene *targetScene = qVariantValue(item->itemChange(QGraphicsItem::ItemSceneChange, - qVariantFromValue(this))); + const QVariant newSceneVariant(item->itemChange(QGraphicsItem::ItemSceneChange, + qVariantFromValue(this))); + QGraphicsScene *targetScene = qVariantValue(newSceneVariant); if (targetScene != this) { if (targetScene && item->scene() != targetScene) targetScene->addItem(item); @@ -2942,7 +2943,7 @@ void QGraphicsScene::addItem(QGraphicsItem *item) emit selectionChanged(); // Deliver post-change notification - item->itemChange(QGraphicsItem::ItemSceneHasChanged, qVariantFromValue(this)); + item->itemChange(QGraphicsItem::ItemSceneHasChanged, newSceneVariant); } /*! @@ -3206,8 +3207,9 @@ void QGraphicsScene::removeItem(QGraphicsItem *item) // Notify the item that it's scene is changing to 0, allowing the item to // react. - QGraphicsScene *targetScene = qVariantValue(item->itemChange(QGraphicsItem::ItemSceneChange, - qVariantFromValue(0))); + const QVariant newSceneVariant(item->itemChange(QGraphicsItem::ItemSceneChange, + qVariantFromValue(0))); + QGraphicsScene *targetScene = qVariantValue(newSceneVariant); if (targetScene != 0 && targetScene != this) { targetScene->addItem(item); return; @@ -3305,7 +3307,7 @@ void QGraphicsScene::removeItem(QGraphicsItem *item) emit selectionChanged(); // Deliver post-change notification - item->itemChange(QGraphicsItem::ItemSceneHasChanged, qVariantFromValue(0)); + item->itemChange(QGraphicsItem::ItemSceneHasChanged, newSceneVariant); } /*! diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 0f2d671..ad0dc97 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -3934,8 +3934,26 @@ void tst_QGraphicsItem::itemChange() tester.itemSceneChangeTargetScene = 0; tester.itemChangeReturnValue = QVariant(); scene.removeItem(&tester); + ++changeCount; // ItemSceneChange + ++changeCount; // ItemSceneHasChanged QCOMPARE(tester.scene(), (QGraphicsScene *)0); } + { + // ItemToolTipChange/ItemToolTipHasChanged + const QString toolTip(QLatin1String("I'm soo cool")); + const QString overridenToolTip(QLatin1String("No, you are not soo cool")); + tester.itemChangeReturnValue = overridenToolTip; + tester.setToolTip(toolTip); + ++changeCount; // ItemToolTipChange + ++changeCount; // ItemToolTipHasChanged + QCOMPARE(tester.changes.size(), changeCount); + QCOMPARE(tester.changes.at(changeCount - 2), QGraphicsItem::ItemToolTipChange); + QCOMPARE(tester.values.at(changeCount - 2).toString(), toolTip); + QCOMPARE(tester.changes.at(changeCount - 1), QGraphicsItem::ItemToolTipHasChanged); + QCOMPARE(tester.values.at(changeCount - 1).toString(), overridenToolTip); + QCOMPARE(tester.toolTip(), overridenToolTip); + tester.itemChangeReturnValue = QVariant(); + } } class EventFilterTesterItem : public QGraphicsLineItem -- cgit v0.12 From 79799ec4788692d44862832d85f80953d386cb27 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Wed, 1 Apr 2009 11:25:01 +0200 Subject: Fixes: Partially revert 9b0af2395c84a6895a5ce6368f151d4ec00c8755 RevBy: Andreas AutoTest: tst_QGraphicsView::itemAt2 pass again Details: A QPoint in the view has to be mapped to a pixel in the scene, otherwise it won't be possible to e.g. click on items that are smaller than a pixel. So...we have to optimize the hit-testing code in another way --- src/gui/graphicsview/qgraphicsview.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index ba9cdbf..f0d360a 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -2251,9 +2251,9 @@ QList QGraphicsView::items(const QPoint &pos) const if (d->scene->d_func()->largestUntransformableItem.isNull()) { if ((d->identityMatrix || d->matrix.type() <= QTransform::TxScale)) { QTransform xinv = viewportTransform().inverted(); - return d->scene->items(xinv.map(pos)); + return d->scene->items(xinv.mapRect(QRectF(pos.x(), pos.y(), 1, 1))); } - return d->scene->items(mapToScene(pos)); + return d->scene->items(mapToScene(pos.x(), pos.y(), 2, 2)); } QPainterPath path; -- cgit v0.12 From 32767aa5699937a3737b9515f4f82acc04ccdfcd Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Fri, 3 Apr 2009 11:47:59 +0200 Subject: Fixes: Optimize the way we adjust rectangles. RevBy: Olivier AutoTest: Still pass --- src/gui/graphicsview/qgraphicsitem.cpp | 39 ++++++++--------- src/gui/graphicsview/qgraphicsscene.cpp | 76 +++++++++++++++++++++------------ 2 files changed, 68 insertions(+), 47 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 11a03b6..8478561 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -528,25 +528,22 @@ QT_BEGIN_NAMESPACE // QRectF::intersects() returns false always if either the source or target // rectangle's width or height are 0. This works around that problem. -static QRectF _q_adjustedRect(const QRectF &rect) -{ - static const qreal p = (qreal)0.00001; - QRectF r = rect; - if (!r.width()) - r.adjust(-p, 0, p, 0); - if (!r.height()) - r.adjust(0, -p, 0, p); - return r; +static inline void _q_adjustRect(QRectF *rect) +{ + Q_ASSERT(rect); + if (!rect->width()) + rect->adjust(-0.00001, 0, 0.00001, 0); + if (!rect->height()) + rect->adjust(0, -0.00001, 0, 0.00001); } -static QRect _q_adjustedRect(const QRect &rect) +static inline void _q_adjustRect(QRect *rect) { - QRect r = rect; - if (!r.width()) - r.adjust(0, 0, 1, 0); - if (!r.height()) - r.adjust(0, 0, 0, 1); - return r; + Q_ASSERT(rect); + if (!rect->width()) + rect->adjust(0, 0, 1, 0); + if (!rect->height()) + rect->adjust(0, 0, 0, 1); } /* @@ -3305,8 +3302,10 @@ bool QGraphicsItem::collidesWithPath(const QPainterPath &path, Qt::ItemSelection return false; } - const QRectF rectA = _q_adjustedRect(boundingRect()); - const QRectF rectB = _q_adjustedRect(path.controlPointRect()); + QRectF rectA(boundingRect()); + _q_adjustRect(&rectA); + QRectF rectB(path.controlPointRect()); + _q_adjustRect(&rectB); if (!rectA.intersects(rectB)) { // This we can determine efficiently. If the two rects neither // intersect nor contain eachother, then the two items do not collide. @@ -3489,7 +3488,9 @@ QRegion QGraphicsItem::boundingRegion(const QTransform &itemToDeviceTransform) c // into the bitmap, converts the result to a QRegion and scales the region // back to device space with inverse granularity. qreal granularity = boundingRegionGranularity(); - QRect deviceRect = _q_adjustedRect(itemToDeviceTransform.mapRect(boundingRect()).toRect()); + QRectF adjustedMappedBoundingRect(itemToDeviceTransform.mapRect(boundingRect())); + _q_adjustRect(&adjustedMappedBoundingRect); + QRect deviceRect = adjustedMappedBoundingRect.toRect(); if (granularity == 0.0) return QRegion(deviceRect); diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index bcc329e..a5fec69 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -292,15 +292,21 @@ static inline bool QRectF_intersects(const QRectF &s, const QRectF &r) // QRectF::intersects() returns false always if either the source or target // rectangle's width or height are 0. This works around that problem. -static QRectF _q_adjustedRect(const QRectF &rect) +static inline void _q_adjustRect(QRectF *rect) { - static const qreal p = (qreal)0.00001; - QRectF r = rect; - if (!r.width()) - r.adjust(-p, 0, p, 0); - if (!r.height()) - r.adjust(0, -p, 0, p); - return r; + Q_ASSERT(rect); + if (!rect->width()) + rect->adjust(-0.00001, 0, 0.00001, 0); + if (!rect->height()) + rect->adjust(0, -0.00001, 0, 0.00001); +} + +static inline QRectF adjustedItemBoundingRect(const QGraphicsItem *item) +{ + Q_ASSERT(item); + QRectF boundingRect(item->boundingRect()); + _q_adjustRect(&boundingRect); + return boundingRect; } static void _q_hoverFromMouseEvent(QGraphicsSceneHoverEvent *hover, const QGraphicsSceneMouseEvent *mouseEvent) @@ -1374,7 +1380,7 @@ QList QGraphicsScenePrivate::items_helper(const QPointF &pos) c // ### _q_adjustedRect is only needed because QRectF::intersects, // QRectF::contains and QTransform::map() and friends don't work with // flat rectangles. - QRectF br = _q_adjustedRect(item->boundingRect()); + const QRectF br(adjustedItemBoundingRect(item)); // Rect intersects/contains item's shape if (QRectF_intersects(adjustedRect, x.mapRect(br))) { bool ok; @@ -1410,7 +1416,8 @@ QList QGraphicsScenePrivate::items_helper(const QRectF &rect, // The index returns a rough estimate of what items are inside the rect. // Refine it by iterating through all returned items. - QRectF adjustedRect = _q_adjustedRect(rect); + QRectF adjustedRect(rect); + _q_adjustRect(&adjustedRect); foreach (QGraphicsItem *item, estimateItemsInRect(adjustedRect)) { // Find the item's scene transform in a clever way. QTransform x = item->sceneTransform(); @@ -1419,7 +1426,7 @@ QList QGraphicsScenePrivate::items_helper(const QRectF &rect, // ### _q_adjustedRect is only needed because QRectF::intersects, // QRectF::contains and QTransform::map() and friends don't work with // flat rectangles. - QRectF br = _q_adjustedRect(item->boundingRect()); + const QRectF br(adjustedItemBoundingRect(item)); if (mode >= Qt::ContainsItemBoundingRect) { // Rect intersects/contains item's bounding rect QRectF mbr = x.mapRect(br); @@ -1471,7 +1478,8 @@ QList QGraphicsScenePrivate::items_helper(const QPolygonF &poly { QList items; - QRectF polyRect = _q_adjustedRect(polygon.boundingRect()); + QRectF polyRect(polygon.boundingRect()); + _q_adjustRect(&polyRect); QPainterPath path; // The index returns a rough estimate of what items are inside the rect. @@ -1484,7 +1492,7 @@ QList QGraphicsScenePrivate::items_helper(const QPolygonF &poly // ### _q_adjustedRect is only needed because QRectF::intersects, // QRectF::contains and QTransform::map() and friends don't work with // flat rectangles. - QRectF br = _q_adjustedRect(item->boundingRect()); + const QRectF br(adjustedItemBoundingRect(item)); if (mode >= Qt::ContainsItemBoundingRect) { // Polygon contains/intersects item's bounding rect if (path == QPainterPath()) @@ -1529,7 +1537,8 @@ QList QGraphicsScenePrivate::items_helper(const QPainterPath &p Qt::SortOrder order) const { QList items; - const QRectF pathRect = _q_adjustedRect(path.controlPointRect()); + QRectF pathRect(path.controlPointRect()); + _q_adjustRect(&pathRect); // The index returns a rough estimate of what items are inside the rect. // Refine it by iterating through all returned items. @@ -1541,7 +1550,7 @@ QList QGraphicsScenePrivate::items_helper(const QPainterPath &p // ### _q_adjustedRect is only needed because QRectF::intersects, // QRectF::contains and QTransform::map() and friends don't work with // flat rectangles. - QRectF br = _q_adjustedRect(item->boundingRect()); + const QRectF br(adjustedItemBoundingRect(item)); if (mode >= Qt::ContainsItemBoundingRect) { // Path contains/intersects item's bounding rect if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(x.mapRect(br))) @@ -1620,7 +1629,9 @@ void QGraphicsScenePrivate::childItems_helper(QList *items, bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); if (parentClip && parent->d_ptr->isClippedAway()) return; - QRectF r = !parentClip ? _q_adjustedRect(rect) : _q_adjustedRect(rect).intersected(_q_adjustedRect(parent->boundingRect())); + QRectF adjustedRect(rect); + _q_adjustRect(&adjustedRect); + QRectF r = !parentClip ? adjustedRect : adjustedRect.intersected(adjustedItemBoundingRect(parent)); if (r.isEmpty()) return; @@ -1640,7 +1651,7 @@ void QGraphicsScenePrivate::childItems_helper(QList *items, // ### _q_adjustedRect is only needed because QRectF::intersects, // QRectF::contains and QTransform::map() and friends don't work with // flat rectangles. - QRectF br = _q_adjustedRect(item->boundingRect()); + const QRectF br(adjustedItemBoundingRect(item)); QRectF mbr = item->mapRectToParent(br); if (mode >= Qt::ContainsItemBoundingRect) { // Rect intersects/contains item's bounding rect @@ -1684,8 +1695,9 @@ void QGraphicsScenePrivate::childItems_helper(QList *items, bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); if (parentClip && parent->d_ptr->isClippedAway()) return; - QRectF polyRect = _q_adjustedRect(polygon.boundingRect()); - QRectF r = !parentClip ? polyRect : polyRect.intersected(_q_adjustedRect(parent->boundingRect())); + QRectF polyRect(polygon.boundingRect()); + _q_adjustRect(&polyRect); + QRectF r = !parentClip ? polyRect : polyRect.intersected(adjustedItemBoundingRect(parent)); if (r.isEmpty()) return; @@ -1705,7 +1717,7 @@ void QGraphicsScenePrivate::childItems_helper(QList *items, // ### _q_adjustedRect is only needed because QRectF::intersects, // QRectF::contains and QTransform::map() and friends don't work with // flat rectangles. - QRectF br = _q_adjustedRect(item->boundingRect()); + const QRectF br(adjustedItemBoundingRect(item)); if (mode >= Qt::ContainsItemBoundingRect) { // Polygon contains/intersects item's bounding rect if (path == QPainterPath()) @@ -1743,8 +1755,9 @@ void QGraphicsScenePrivate::childItems_helper(QList *items, bool parentClip = (parent->flags() & QGraphicsItem::ItemClipsChildrenToShape); if (parentClip && parent->d_ptr->isClippedAway()) return; - QRectF pathRect = _q_adjustedRect(path.boundingRect()); - QRectF r = !parentClip ? pathRect : pathRect.intersected(_q_adjustedRect(parent->boundingRect())); + QRectF pathRect(path.boundingRect()); + _q_adjustRect(&pathRect); + QRectF r = !parentClip ? pathRect : pathRect.intersected(adjustedItemBoundingRect(parent)); if (r.isEmpty()) return; @@ -1763,7 +1776,7 @@ void QGraphicsScenePrivate::childItems_helper(QList *items, // ### _q_adjustedRect is only needed because QRectF::intersects, // QRectF::contains and QTransform::map() and friends don't work with // flat rectangles. - QRectF br = _q_adjustedRect(item->boundingRect()); + const QRectF br(adjustedItemBoundingRect(item)); if (mode >= Qt::ContainsItemBoundingRect) { // Polygon contains/intersects item's bounding rect if ((mode == Qt::IntersectsItemBoundingRect && path.intersects(item->mapRectToParent(br))) @@ -4690,7 +4703,9 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte // Item's (local) bounding rect QRectF brect = item->boundingRect(); - if (_q_adjustedRect(brect).isEmpty()) + QRectF adjustedBrect(brect); + _q_adjustRect(&adjustedBrect); + if (adjustedBrect.isEmpty()) return; // Fetch the off-screen transparent buffer and exposed area info. @@ -5232,9 +5247,12 @@ void QGraphicsScene::itemUpdated(QGraphicsItem *item, const QRectF &rect) update(item->sceneBoundingRect()); } else { // ### Remove _q_adjustedRects(). - QRectF boundingRect = _q_adjustedRect(item->boundingRect()); - if (!rect.isNull()) - boundingRect &= _q_adjustedRect(rect); + QRectF boundingRect(adjustedItemBoundingRect(item)); + if (!rect.isNull()) { + QRectF adjustedRect(rect); + _q_adjustRect(&adjustedRect); + boundingRect &= adjustedRect; + } // Update each view directly. for (int i = 0; i < d->views.size(); ++i) @@ -5264,7 +5282,9 @@ void QGraphicsScene::itemUpdated(QGraphicsItem *item, const QRectF &rect) // defined scene rect. if (!d->hasSceneRect) { QRectF oldGrowingItemsBoundingRect = d->growingItemsBoundingRect; - d->growingItemsBoundingRect |= _q_adjustedRect(item->sceneBoundingRect()); + QRectF adjustedItemSceneBoundingRect(item->sceneBoundingRect()); + _q_adjustRect(&adjustedItemSceneBoundingRect); + d->growingItemsBoundingRect |= adjustedItemSceneBoundingRect; if (d->growingItemsBoundingRect != oldGrowingItemsBoundingRect) emit sceneRectChanged(d->growingItemsBoundingRect); } -- cgit v0.12 From 3dc62362f3380fa653bc1225ce06e5e4cefa745a Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Fri, 3 Apr 2009 16:39:58 +0200 Subject: Fixes: We have to adjust the item's bounding rect. RevBy: Andreas AutoTest: Still pass Details: QRectF::intersects does not work with flat rectangles, so we cannot intersect the bounding rect without adjusting it first. --- src/gui/graphicsview/qgraphicsview.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index f0d360a..c4297df 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -790,6 +790,19 @@ QRegion QGraphicsViewPrivate::mapToViewRegion(const QGraphicsItem *item, const Q return item->boundingRegion(itv) & itv.mapRect(rect).toAlignedRect(); } +// QRectF::intersects() returns false always if either the source or target +// rectangle's width or height are 0. This works around that problem. +static inline QRectF adjustedItemBoundingRect(const QGraphicsItem *item) +{ + Q_ASSERT(item); + QRectF boundingRect(item->boundingRect()); + if (!boundingRect.width()) + boundingRect.adjust(-0.00001, 0, 0.00001, 0); + if (!boundingRect.height()) + boundingRect.adjust(0, -0.00001, 0, 0.00001); + return boundingRect; +} + /*! \internal */ @@ -802,7 +815,7 @@ void QGraphicsViewPrivate::itemUpdated(QGraphicsItem *item, const QRectF &rect) QRectF updateRect = rect; if ((item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape) || item->d_ptr->children.isEmpty()) { - updateRect &= item->boundingRect(); + updateRect &= adjustedItemBoundingRect(item); if (updateRect.isEmpty()) return; } @@ -814,7 +827,8 @@ void QGraphicsViewPrivate::itemUpdated(QGraphicsItem *item, const QRectF &rect) while ((parent = parent->d_ptr->parent)) { if (parent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape) { // Map update rect to the current parent and itersect with its bounding rect. - updateRect = clipItem->itemTransform(parent).mapRect(updateRect) & parent->boundingRect(); + updateRect = clipItem->itemTransform(parent).mapRect(updateRect) + & adjustedItemBoundingRect(parent); if (updateRect.isEmpty()) return; clipItem = parent; -- cgit v0.12 From 416fd77e653d089b7832002a68d5b7725fa492db Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Fri, 3 Apr 2009 16:52:10 +0200 Subject: Fixes: Wrong adjustment of rect added in 0aa2ef27249dc8e782c2942340776bb19de80a0d RevBy: TrustMe AutoTest: tst_QGraphicsItem::boundingRegion() pass again Details: The original code adjusted the QRect version of a mapped bounding rect, wheras my patch adjusted a mapped bounding rect (QRectF) and then converted it to a QRect. --- src/gui/graphicsview/qgraphicsitem.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 8478561..9d320b7 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -3488,9 +3488,8 @@ QRegion QGraphicsItem::boundingRegion(const QTransform &itemToDeviceTransform) c // into the bitmap, converts the result to a QRegion and scales the region // back to device space with inverse granularity. qreal granularity = boundingRegionGranularity(); - QRectF adjustedMappedBoundingRect(itemToDeviceTransform.mapRect(boundingRect())); - _q_adjustRect(&adjustedMappedBoundingRect); - QRect deviceRect = adjustedMappedBoundingRect.toRect(); + QRect deviceRect = itemToDeviceTransform.mapRect(boundingRect()).toRect(); + _q_adjustRect(&deviceRect); if (granularity == 0.0) return QRegion(deviceRect); -- cgit v0.12 From cc18633fe45d599bfeac2a8b2737d155f1dd5564 Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Mon, 6 Apr 2009 13:31:02 +0200 Subject: Fixup update rect regression by adjusting expose rectangles. This change shows a limitation in Graphics View caused by QPen's default width being 0 (cosmetic), while Graphics View actually does not support cosmetic pens at all. Because items are at risk of drawing lines that poke 1 pixel outside their bounding rect, QGraphicsView must look for items that are up to one pixel larger than their bounding rect mapped to viewport coordinates. Furthermore, mapToScene(QRect) forces us to adjust the input rectangle by (0, 0, 1, 1), because it uses QRect::bottomRight() (etc) when mapping the rectangle to a polygon (which is _wrong_). Since this behavior has been there since 4.2, we don't want to fix it in a 4.5 patch release... The only _proper_ fix to this problem is for the view to know the item's "adjust" in device coordinates, allowing items to use cosmetic pens freely. Fex, we could introduce QGraphicsItem::viewportMargins() or so. Added an autotest to ensure this doesn't break again. Reviewed-by: bnilsen --- src/gui/graphicsview/qgraphicsview.cpp | 42 ++++++++++++++---- tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 61 ++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 8 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index c4297df..418638f 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -1046,13 +1046,24 @@ void QGraphicsViewPrivate::freeStyleOptionsArray(QStyleOptionGraphicsItem *array extern QPainterPath qt_regionToPath(const QRegion ®ion); +/*! + ### Adjustments in findItems: mapToScene(QRect) forces us to adjust the + input rectangle by (0, 0, 1, 1), because it uses QRect::bottomRight() + (etc) when mapping the rectangle to a polygon (which is _wrong_). In + addition, as QGraphicsItem::boundingRect() is defined in logical space, + but the default pen for QPainter is cosmetic with a width of 0, QPainter + is at risk of painting 1 pixel outside the bounding rect. Therefore we + must search for items with an adjustment of (-1, -1, 1, 1). +*/ QList QGraphicsViewPrivate::findItems(const QRegion &exposedRegion, bool *allItems) const { Q_Q(const QGraphicsView); - const QPainterPath exposedPath(qt_regionToPath(exposedRegion)); - const QPainterPath exposedScenePath(q->mapToScene(exposedPath)); - if (exposedScenePath.contains(scene->d_func()->growingItemsBoundingRect)) { + // Step 1) If all items are contained within the expose region, then + // return a list of all visible items. + const QRectF exposedRegionSceneBounds = q->mapToScene(exposedRegion.boundingRect().adjusted(-1, -1, 2, 2)) + .boundingRect(); + if (exposedRegionSceneBounds.contains(scene->d_func()->growingItemsBoundingRect)) { Q_ASSERT(allItems); *allItems = true; @@ -1072,12 +1083,27 @@ QList QGraphicsViewPrivate::findItems(const QRegion &exposedReg return itemList; } + // Step 2) If the expose region is a simple rect and the view is only + // translated or scaled, search for items using + // QGraphicsScene::items(QRectF). + bool simpleRectLookup = (scene->d_func()->largestUntransformableItem.isNull() + && exposedRegion.numRects() == 1 && matrix.type() <= QTransform::TxScale); + if (simpleRectLookup) { + return scene->d_func()->items_helper(exposedRegionSceneBounds, + Qt::IntersectsItemBoundingRect, + Qt::DescendingOrder); + } + + // If the region is complex or the view has a complex transform, adjust + // the expose region, convert it to a path, and then search for items + // using QGraphicsScene::items(QPainterPath); + QRegion adjustedRegion; + foreach (const QRect &r, exposedRegion.rects()) + adjustedRegion += r.adjusted(-1, -1, 1, 1); + + const QPainterPath exposedPath(qt_regionToPath(adjustedRegion)); if (scene->d_func()->largestUntransformableItem.isNull()) { - if (exposedRegion.numRects() == 1 && matrix.type() <= QTransform::TxScale) { - return scene->d_func()->items_helper(exposedScenePath.controlPointRect(), - Qt::IntersectsItemBoundingRect, - Qt::DescendingOrder); - } + const QPainterPath exposedScenePath(q->mapToScene(exposedPath)); return scene->d_func()->items_helper(exposedScenePath, Qt::IntersectsItemBoundingRect, Qt::DescendingOrder); diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index 4368e76..412c6c5 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -155,6 +155,8 @@ private slots: void fitInView(); void itemsAtPoint(); void itemsInRect(); + void itemsInRect_cosmeticAdjust_data(); + void itemsInRect_cosmeticAdjust(); void itemsInPoly(); void itemsInPath(); void itemAt(); @@ -1310,6 +1312,65 @@ void tst_QGraphicsView::itemsInRect() QCOMPARE(items.takeFirst()->zValue(), qreal(3)); } +class CountPaintItem : public QGraphicsRectItem +{ +public: + int numPaints; + + CountPaintItem(const QRectF &rect) + : QGraphicsRectItem(rect), numPaints(0) + { } + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0) + { + ++numPaints; + QGraphicsRectItem::paint(painter, option, widget); + } +}; + +void tst_QGraphicsView::itemsInRect_cosmeticAdjust_data() +{ + QTest::addColumn("updateRect"); + QTest::addColumn("numPaints"); + + QTest::newRow("nil") << QRect() << 1; + QTest::newRow("0, 0, 300, 100") << QRect(0, 0, 300, 100) << 1; + QTest::newRow("0, 0, 100, 300") << QRect(0, 0, 100, 300) << 1; + QTest::newRow("200, 0, 100, 300") << QRect(200, 0, 100, 300) << 1; + QTest::newRow("0, 200, 300, 100") << QRect(0, 200, 300, 100) << 1; + QTest::newRow("0, 0, 300, 99") << QRect(0, 0, 300, 99) << 0; + QTest::newRow("0, 0, 99, 300") << QRect(0, 0, 99, 300) << 0; + QTest::newRow("201, 0, 99, 300") << QRect(201, 0, 99, 300) << 0; + QTest::newRow("0, 201, 300, 99") << QRect(0, 201, 300, 99) << 0; +} + +void tst_QGraphicsView::itemsInRect_cosmeticAdjust() +{ + QFETCH(QRect, updateRect); + QFETCH(int, numPaints); + + QGraphicsScene scene(-100, -100, 200, 200); + CountPaintItem *rect = new CountPaintItem(QRectF(-50, -50, 100, 100)); + scene.addItem(rect); + + QGraphicsView view(&scene); + view.setFrameStyle(0); + view.resize(300, 300); + view.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&view); +#endif + QTest::qWait(125); + + rect->numPaints = 0; + if (updateRect.isNull()) + view.viewport()->update(); + else + view.viewport()->update(updateRect); + qApp->processEvents(); + QCOMPARE(rect->numPaints, numPaints); +} + void tst_QGraphicsView::itemsInPoly() { QGraphicsScene scene; -- cgit v0.12 From f06c4f2d7378b40a0a184393a8986032d5a700ee Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Mon, 6 Apr 2009 14:17:15 +0200 Subject: BT: Fix combobox background color regression There was a regression in the background color for QComboBox popups. This should resolve it. It essentially tells the system to stay off the system palette while QGtkStyle is used. We will introduce a cleaner style hint for this in 4.6. Reviewed-by: nrc --- src/gui/kernel/qapplication_x11.cpp | 6 ++++-- src/gui/styles/gtksymbols.cpp | 8 +------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index 10fb886..b1270bc 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -1362,8 +1362,10 @@ static void qt_set_x11_resources(const char* font = 0, const char* fg = 0, pal.setColor(QPalette::Disabled, QPalette::Highlight, Qt::darkBlue); } - QApplicationPrivate::setSystemPalette(pal); - + // QGtkStyle sets it's own system palette + if (!(QApplicationPrivate::app_style && QApplicationPrivate::app_style->inherits("QGtkStyle"))) { + QApplicationPrivate::setSystemPalette(pal); + } QColor::setAllowX11ColorNames(allowX11ColorNames); } diff --git a/src/gui/styles/gtksymbols.cpp b/src/gui/styles/gtksymbols.cpp index 8123d32..f7af8f8 100644 --- a/src/gui/styles/gtksymbols.cpp +++ b/src/gui/styles/gtksymbols.cpp @@ -504,13 +504,6 @@ static QPalette gtkWidgetPalette(const QString >kWidgetName) pal.setBrush(QPalette::Disabled, QPalette::WindowText, disabledTextColor); pal.setBrush(QPalette::All, QPalette::ButtonText, textColor); pal.setBrush(QPalette::Disabled, QPalette::ButtonText, disabledTextColor); - if (gtkWidgetName == QLS("GtkMenu")) { - // This really applies to the combo box rendering since - // QComboBox copies the palette from a QMenu - GdkColor gdkBg = gtkWidget->style->bg[GTK_STATE_NORMAL]; - QColor bgColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8); - pal.setBrush(QPalette::Base, bgColor); - } return pal; } @@ -528,6 +521,7 @@ void QGtk::applyCustomPaletteHash() GdkColor gdkBg = QGtk::gtkWidget(QLS("GtkMenu"))->style->bg[GTK_STATE_NORMAL]; QColor bgColor(gdkBg.red>>8, gdkBg.green>>8, gdkBg.blue>>8); menuPal.setBrush(QPalette::Base, bgColor); + menuPal.setBrush(QPalette::Window, bgColor); qApp->setPalette(menuPal, "QMenu"); QPalette toolbarPal = gtkWidgetPalette(QLS("GtkToolbar")); -- cgit v0.12 From b8dcae1572651774085024ddf4cb02e4a954bcd7 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Mon, 6 Apr 2009 14:29:02 +0200 Subject: compile for systems without Qt3Support Reviewed-by: joerg QTest::newRow only accepts char* and without Qt3Support there is no implicit cast available. --- tests/auto/qpainter/tst_qpainter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qpainter/tst_qpainter.cpp b/tests/auto/qpainter/tst_qpainter.cpp index a4c768d..fb8df2e 100644 --- a/tests/auto/qpainter/tst_qpainter.cpp +++ b/tests/auto/qpainter/tst_qpainter.cpp @@ -3629,7 +3629,7 @@ void tst_QPainter::drawImage_data() QString("srcFormat %1, dstFormat %2, odd x: %3, odd width: %4") .arg(srcFormat).arg(dstFormat).arg(odd_x).arg(odd_width); - QTest::newRow(description) << (10 + odd_x) << 10 << (20 + odd_width) << 20 + QTest::newRow(qPrintable(description)) << (10 + odd_x) << 10 << (20 + odd_width) << 20 << QImage::Format(srcFormat) << QImage::Format(dstFormat); } -- cgit v0.12 From 6ce4a3b66e2b31f80d1a2d09a4c4087f88a7a9e8 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Mon, 6 Apr 2009 14:42:31 +0200 Subject: remove dead code Reviewed-by: jbache --- tests/auto/qmenubar/tst_qmenubar.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/auto/qmenubar/tst_qmenubar.cpp b/tests/auto/qmenubar/tst_qmenubar.cpp index 277e15c..e0a9f42 100644 --- a/tests/auto/qmenubar/tst_qmenubar.cpp +++ b/tests/auto/qmenubar/tst_qmenubar.cpp @@ -1337,7 +1337,6 @@ tst_QMenuBar::allowActiveAndDisabled() // disabled menu items are added QMenu fileMenu("&File"); - QAction disabledAction() ; // Task 241043 : check that second menu is activated // if all items are disabled QAction *act = fileMenu.addAction("Disabled"); -- cgit v0.12 From e517ecc9025b68179c67a383791eefbedfee0543 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Mon, 6 Apr 2009 15:07:58 +0200 Subject: compile Reviewed-by: thartman function declaration was missing arguments as done in the other testcases in 831d2742b7c41924f052acd81620e8bfc58afde7 --- tests/auto/qsqlthread/tst_qsqlthread.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qsqlthread/tst_qsqlthread.cpp b/tests/auto/qsqlthread/tst_qsqlthread.cpp index d871be4..8b8fc65 100644 --- a/tests/auto/qsqlthread/tst_qsqlthread.cpp +++ b/tests/auto/qsqlthread/tst_qsqlthread.cpp @@ -70,7 +70,7 @@ public: void recreateTestTables(); void repopulateTestTables(); - void generic_data(); + void generic_data(const QString &engine=QString()); tst_Databases dbs; public slots: -- cgit v0.12 From 1d3706f2b66ba5fbb586e532fc29852f55d81c86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 6 Apr 2009 15:57:22 +0200 Subject: Update WebKit from code.staikos.net/srv/git/webkit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using branch origin/qtwebkit-4.5 (f72c14123c593dc9d649d25b7186334bba0026b5) Changes in WebKit since the last update: ++ b/WebCore/ChangeLog 2009-04-06 Tor Arne Vestbø Reviewed by Simon Hausmann. [Qt] Don't show and hide the platformPluginWidget, as it's our QWebView * plugins/mac/PluginViewMac.cpp: (WebCore::PluginView::show): (WebCore::PluginView::hide): (WebCore::PluginView::setParentVisible): 2009-04-06 Mike Belshe Reviewed by Eric Seidel. HTMLCanvasElement crash when ImageBuffer creation fails. https://bugs.webkit.org/show_bug.cgi?id=23212 Check for NULL before using the ImageBuffer as we might be low on memory and creation may have failed. Test case creation blocked by: https://bugs.webkit.org/show_bug.cgi?id=25055 * html/HTMLCanvasElement.cpp: (WebCore::HTMLCanvasElement::createImageBuffer): 2009-04-05 Erik L. Bunce Reviewed by Simon Hausmann. https://bugs.webkit.org/show_bug.cgi?id=25050 Fix an assert failure when dropping an 'empty' text/uri-list on a QWebView. * platform/qt/DragDataQt.cpp: (WebCore::DragData::asURL): ++ b/WebKitTools/ChangeLog 2009-03-31 Adam Roben Make resolve-ChangeLogs -f work when the working tree has spaces in its path Reviewed by Mark Rowe and David Kilzer. * Scripts/resolve-ChangeLogs: (sub fixMergedChangeLogs): Quote the path to resolve-ChangeLogs in case it contains spaces. 2009-03-17 David Kilzer resolve-ChangeLogs should not die on unmerged non-ChangeLog files Reviewed by Adam Roben. Fixes the following bug in resolve-ChangeLogs: Use of uninitialized value in -e at ./WebKitTools/Scripts/resolve-ChangeLogs line 132. Died at ./WebKitTools/Scripts/resolve-ChangeLogs line 164. * Scripts/resolve-ChangeLogs: (findUnmergedChangeLogs): Check the result of findChangeLog() to make sure we don't add undef values to the list of files being returned. 2009-03-11 David Kilzer Bug 24378: resolve-ChangeLogs should use git status or svn status to find and fix unmerged ChangeLogs Reviewed by Adam Roben. * Scripts/resolve-ChangeLogs: If -f|--fix-merged is not passed and no file or directory names are specified on the command-line then try to find unmerged ChangeLog files based on 'svn stat' or 'git diff'. Added global $isGit and $isSVN variables so that isGit() and isSVN() only have to be called once. (findUnmergedChangeLogs): Added. --- src/3rdparty/webkit/VERSION | 2 +- src/3rdparty/webkit/WebCore/ChangeLog | 38 + .../webkit/WebCore/generated/CSSPropertyNames.cpp | 5 +- .../webkit/WebCore/generated/CSSValueKeywords.c | 5 +- src/3rdparty/webkit/WebCore/generated/ColorData.c | 5 +- .../webkit/WebCore/generated/DocTypeStrings.cpp | 5 +- .../webkit/WebCore/generated/HTMLEntityNames.c | 5 +- .../webkit/WebCore/generated/tokenizer.cpp | 2315 ++++++-------------- .../webkit/WebCore/html/HTMLCanvasElement.cpp | 4 + .../webkit/WebCore/platform/qt/DragDataQt.cpp | 6 +- .../webkit/WebCore/plugins/mac/PluginViewMac.cpp | 9 - src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp | 2 +- 12 files changed, 744 insertions(+), 1657 deletions(-) diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index 1ebf6ef..9decb66 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -8,4 +8,4 @@ The commit imported was from the and has the sha1 checksum - 9c6a4a25fe741b43dd64f5dbaeccfb647cb321fb + f72c14123c593dc9d649d25b7186334bba0026b5 diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index e8850f3..d0382f2 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,41 @@ +2009-04-06 Tor Arne Vestbø + + Reviewed by Simon Hausmann. + + [Qt] Don't show and hide the platformPluginWidget, as it's our QWebView + + * plugins/mac/PluginViewMac.cpp: + (WebCore::PluginView::show): + (WebCore::PluginView::hide): + (WebCore::PluginView::setParentVisible): + +2009-04-06 Mike Belshe + + Reviewed by Eric Seidel. + + HTMLCanvasElement crash when ImageBuffer creation fails. + https://bugs.webkit.org/show_bug.cgi?id=23212 + + Check for NULL before using the ImageBuffer as we might + be low on memory and creation may have failed. + + Test case creation blocked by: + https://bugs.webkit.org/show_bug.cgi?id=25055 + + * html/HTMLCanvasElement.cpp: + (WebCore::HTMLCanvasElement::createImageBuffer): + +2009-04-05 Erik L. Bunce + + Reviewed by Simon Hausmann. + + https://bugs.webkit.org/show_bug.cgi?id=25050 + + Fix an assert failure when dropping an 'empty' text/uri-list on a QWebView. + + * platform/qt/DragDataQt.cpp: + (WebCore::DragData::asURL): + 2009-03-27 Zack Rusin Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/WebCore/generated/CSSPropertyNames.cpp b/src/3rdparty/webkit/WebCore/generated/CSSPropertyNames.cpp index 25313ac..ca4ea5a 100644 --- a/src/3rdparty/webkit/WebCore/generated/CSSPropertyNames.cpp +++ b/src/3rdparty/webkit/WebCore/generated/CSSPropertyNames.cpp @@ -1,4 +1,4 @@ -/* ANSI-C code produced by gperf version 3.0.3 */ +/* ANSI-C code produced by gperf version 3.0.2 */ /* Command-line: gperf -a -L ANSI-C -E -C -c -o -t --key-positions='*' -NfindProp -Hhash_prop -Wwordlist_prop -D -s 2 CSSPropertyNames.gperf */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ @@ -217,9 +217,6 @@ hash_prop (register const char *str, register unsigned int len) #ifdef __GNUC__ __inline -#ifdef __GNUC_STDC_INLINE__ -__attribute__ ((__gnu_inline__)) -#endif #endif const struct props * findProp (register const char *str, register unsigned int len) diff --git a/src/3rdparty/webkit/WebCore/generated/CSSValueKeywords.c b/src/3rdparty/webkit/WebCore/generated/CSSValueKeywords.c index 5ff0858..d0433e0 100644 --- a/src/3rdparty/webkit/WebCore/generated/CSSValueKeywords.c +++ b/src/3rdparty/webkit/WebCore/generated/CSSValueKeywords.c @@ -1,4 +1,4 @@ -/* ANSI-C code produced by gperf version 3.0.3 */ +/* ANSI-C code produced by gperf version 3.0.2 */ /* Command-line: gperf -L ANSI-C -E -C -n -o -t --key-positions='*' -NfindValue -Hhash_val -Wwordlist_value -D CSSValueKeywords.gperf */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ @@ -179,9 +179,6 @@ hash_val (register const char *str, register unsigned int len) #ifdef __GNUC__ __inline -#ifdef __GNUC_STDC_INLINE__ -__attribute__ ((__gnu_inline__)) -#endif #endif const struct css_value * findValue (register const char *str, register unsigned int len) diff --git a/src/3rdparty/webkit/WebCore/generated/ColorData.c b/src/3rdparty/webkit/WebCore/generated/ColorData.c index 478566c..18d9926 100644 --- a/src/3rdparty/webkit/WebCore/generated/ColorData.c +++ b/src/3rdparty/webkit/WebCore/generated/ColorData.c @@ -1,5 +1,5 @@ #include // bogus -/* ANSI-C code produced by gperf version 3.0.3 */ +/* ANSI-C code produced by gperf version 3.0.2 */ /* Command-line: gperf -CDEot -L ANSI-C --key-positions='*' -N findColor -D -s 2 */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ @@ -141,9 +141,6 @@ hash (register const char *str, register unsigned int len) #ifdef __GNUC__ __inline -#ifdef __GNUC_STDC_INLINE__ -__attribute__ ((__gnu_inline__)) -#endif #endif const struct NamedColor * findColor (register const char *str, register unsigned int len) diff --git a/src/3rdparty/webkit/WebCore/generated/DocTypeStrings.cpp b/src/3rdparty/webkit/WebCore/generated/DocTypeStrings.cpp index 686629c..ad63b9e 100644 --- a/src/3rdparty/webkit/WebCore/generated/DocTypeStrings.cpp +++ b/src/3rdparty/webkit/WebCore/generated/DocTypeStrings.cpp @@ -1,5 +1,5 @@ #include // bogus -/* ANSI-C code produced by gperf version 3.0.3 */ +/* ANSI-C code produced by gperf version 3.0.2 */ /* Command-line: gperf -CEot -L ANSI-C --key-positions='*' -N findDoctypeEntry -F ,PubIDInfo::eAlmostStandards,PubIDInfo::eAlmostStandards */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ @@ -331,9 +331,6 @@ hash (register const char *str, register unsigned int len) #ifdef __GNUC__ __inline -#ifdef __GNUC_STDC_INLINE__ -__attribute__ ((__gnu_inline__)) -#endif #endif const struct PubIDInfo * findDoctypeEntry (register const char *str, register unsigned int len) diff --git a/src/3rdparty/webkit/WebCore/generated/HTMLEntityNames.c b/src/3rdparty/webkit/WebCore/generated/HTMLEntityNames.c index 993e106..470c4cd 100644 --- a/src/3rdparty/webkit/WebCore/generated/HTMLEntityNames.c +++ b/src/3rdparty/webkit/WebCore/generated/HTMLEntityNames.c @@ -1,4 +1,4 @@ -/* ANSI-C code produced by gperf version 3.0.3 */ +/* ANSI-C code produced by gperf version 3.0.2 */ /* Command-line: gperf -a -L ANSI-C -C -G -c -o -t --key-positions='*' -N findEntity -D -s 2 */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ @@ -520,9 +520,6 @@ static const short lookup[] = #ifdef __GNUC__ __inline -#ifdef __GNUC_STDC_INLINE__ -__attribute__ ((__gnu_inline__)) -#endif #endif const struct Entity * findEntity (register const char *str, register unsigned int len) diff --git a/src/3rdparty/webkit/WebCore/generated/tokenizer.cpp b/src/3rdparty/webkit/WebCore/generated/tokenizer.cpp index 8462f51..1da1a0b 100644 --- a/src/3rdparty/webkit/WebCore/generated/tokenizer.cpp +++ b/src/3rdparty/webkit/WebCore/generated/tokenizer.cpp @@ -78,42 +78,42 @@ static yyconst flex_int16_t yy_accept[479] = { 0, 0, 0, 0, 0, 0, 0, 69, 67, 2, 2, 67, 67, 67, 67, 67, 67, 67, 67, 67, 56, - 67, 67, 15, 15, 15, 67, 67, 67, 67, 66, + 67, 67, 67, 67, 15, 15, 15, 67, 67, 66, 15, 15, 15, 65, 15, 2, 0, 0, 0, 14, - 0, 0, 0, 18, 18, 0, 8, 0, 0, 9, - 0, 0, 15, 15, 15, 0, 57, 0, 55, 0, - 0, 56, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 16, 54, 54, 51, 54, 0, 54, 0, 0, - 35, 35, 35, 35, 35, 35, 35, 0, 62, 15, - 0, 0, 15, 15, 0, 15, 15, 15, 7, 6, + 0, 0, 0, 0, 18, 18, 8, 0, 0, 9, + 0, 0, 0, 15, 15, 15, 57, 0, 55, 0, + 0, 56, 0, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 16, 54, 54, 51, 54, 0, 0, + 0, 35, 35, 35, 35, 35, 35, 35, 15, 15, + 7, 62, 15, 0, 0, 15, 15, 0, 15, 6, 5, 15, 15, 15, 15, 0, 0, 0, 14, 0, - 0, 0, 18, 18, 0, 18, 18, 0, 0, 14, - 0, 0, 4, 16, 15, 0, 0, 54, 0, 41, - 54, 37, 39, 54, 52, 43, 54, 42, 50, 54, - 45, 44, 40, 54, 54, 54, 54, 54, 0, 35, - 35, 0, 35, 35, 35, 35, 35, 35, 35, 35, - 15, 15, 16, 15, 15, 63, 63, 15, 15, 12, - 10, 15, 13, 0, 0, 0, 17, 17, 18, 18, - 18, 0, 0, 15, 0, 1, 54, 54, 46, 54, - 53, 16, 47, 54, 54, 54, 3, 35, 35, 35, - - 35, 35, 35, 35, 35, 35, 35, 15, 58, 0, - 63, 63, 63, 62, 15, 11, 0, 0, 0, 18, - 18, 18, 0, 15, 0, 0, 54, 48, 49, 54, - 54, 35, 35, 35, 35, 35, 35, 35, 20, 35, - 15, 64, 63, 63, 63, 63, 0, 0, 0, 0, - 60, 0, 15, 0, 0, 0, 18, 18, 18, 0, - 15, 54, 54, 38, 35, 35, 35, 35, 35, 21, - 35, 35, 15, 64, 63, 63, 63, 63, 63, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, - 0, 15, 0, 0, 17, 17, 18, 18, 0, 15, - - 54, 54, 35, 35, 35, 35, 19, 35, 35, 15, - 64, 63, 63, 63, 63, 63, 63, 0, 59, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 15, 0, 0, 18, 18, 0, 15, 54, 54, 35, - 35, 23, 35, 35, 35, 15, 64, 63, 63, 63, + 0, 0, 18, 18, 18, 0, 18, 0, 0, 14, + 0, 0, 4, 16, 15, 0, 0, 54, 54, 54, + 0, 54, 41, 54, 37, 39, 54, 52, 43, 54, + 42, 50, 54, 45, 44, 40, 54, 54, 0, 35, + 35, 35, 35, 0, 35, 35, 35, 35, 35, 35, + 15, 15, 15, 16, 15, 15, 63, 63, 15, 12, + 10, 15, 13, 0, 0, 0, 17, 18, 18, 18, + 17, 0, 0, 15, 0, 1, 54, 54, 54, 54, + 46, 54, 53, 16, 47, 54, 3, 35, 35, 35, + + 35, 35, 35, 35, 35, 35, 35, 15, 15, 58, + 0, 63, 63, 63, 62, 11, 0, 0, 0, 18, + 18, 18, 0, 15, 0, 0, 54, 54, 54, 48, + 49, 35, 35, 35, 35, 35, 35, 35, 35, 20, + 15, 15, 64, 63, 63, 63, 63, 0, 0, 0, + 0, 60, 0, 0, 0, 0, 18, 18, 18, 0, + 15, 54, 54, 38, 35, 35, 35, 35, 35, 35, + 21, 35, 15, 15, 64, 63, 63, 63, 63, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, + 0, 0, 0, 0, 17, 18, 18, 17, 0, 15, + + 54, 54, 35, 35, 35, 35, 35, 19, 35, 15, + 15, 64, 63, 63, 63, 63, 63, 63, 0, 59, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 18, 18, 0, 15, 54, 54, 35, + 35, 35, 23, 35, 35, 15, 64, 63, 63, 63, 63, 63, 63, 63, 0, 59, 0, 0, 0, 59, 0, 0, 0, 0, 18, 15, 54, 35, 35, 35, 35, 64, 0, 0, 0, 36, 15, 35, 35, 35, @@ -122,7 +122,7 @@ static yyconst flex_int16_t yy_accept[479] = 35, 35, 35, 35, 35, 35, 35, 35, 0, 0, 0, 0, 0, 0, 35, 35, 35, 35, 25, 35, - 35, 35, 0, 61, 0, 0, 0, 0, 26, 35, + 35, 35, 0, 0, 0, 61, 0, 0, 26, 35, 35, 35, 35, 27, 35, 0, 0, 0, 0, 31, 35, 35, 35, 35, 0, 0, 0, 35, 35, 35, 35, 0, 0, 35, 35, 29, 35, 0, 0, 35, @@ -138,909 +138,437 @@ static yyconst flex_int32_t yy_ec[256] = 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 12, 18, 19, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 12, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 12, 54, 12, 55, 56, 12, 57, 58, 59, 60, - - 61, 62, 63, 64, 65, 37, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 12, 84, 1, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85 + 24, 25, 26, 27, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 12, 28, 12, 29, 30, 12, 31, 32, 33, 34, + + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 12, 59, 1, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60 } ; -static yyconst flex_int32_t yy_meta[86] = +static yyconst flex_int32_t yy_meta[61] = { 0, - 1, 2, 3, 4, 4, 5, 6, 7, 6, 6, - 6, 6, 7, 8, 9, 6, 6, 10, 6, 6, - 11, 6, 6, 6, 6, 12, 6, 13, 13, 13, - 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 6, 14, 13, 13, 13, 13, - 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 6, 6, 6, 14 + 1, 2, 3, 3, 3, 4, 5, 5, 5, 5, + 5, 5, 5, 6, 7, 5, 5, 8, 5, 5, + 9, 5, 5, 5, 5, 10, 5, 11, 5, 11, + 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 5, 5, 5, 11 } ; -static yyconst flex_int16_t yy_base[550] = +static yyconst flex_int16_t yy_base[517] = { 0, - 0, 0, 64, 66, 54, 56, 1407, 6578, 93, 98, - 107, 83, 155, 1376, 77, 1350, 99, 1345, 1328, 207, - 1334, 275, 100, 108, 125, 326, 1315, 1313, 1312, 6578, - 141, 110, 151, 6578, 105, 197, 295, 89, 107, 6578, - 387, 120, 0, 429, 1281, 471, 6578, 117, 532, 6578, - 1283, 269, 137, 176, 281, 574, 283, 1289, 1292, 1246, - 1257, 0, 1221, 249, 135, 282, 276, 153, 91, 169, - 299, 308, 318, 266, 1219, 320, 616, 102, 1246, 348, - 1209, 316, 127, 359, 346, 347, 375, 658, 6578, 208, - 700, 1241, 400, 409, 1220, 397, 327, 761, 6578, 6578, - - 6578, 411, 419, 414, 424, 248, 368, 355, 356, 822, - 883, 0, 1191, 925, 967, 1190, 1028, 381, 421, 464, - 1089, 1150, 6578, 214, 456, 1225, 312, 1151, 1192, 1142, - 442, 1139, 1134, 452, 1131, 1104, 458, 1082, 1060, 358, - 1046, 1028, 1027, 462, 453, 1000, 1253, 469, 1023, 463, - 986, 1295, 492, 486, 500, 484, 502, 513, 969, 1356, - 425, 1417, 1001, 545, 494, 193, 993, 543, 1459, 544, - 554, 558, 555, 508, 398, 1520, 0, 1562, 956, 1623, - 1684, 570, 1745, 563, 993, 6578, 948, 1806, 935, 520, - 921, 498, 914, 546, 1848, 564, 6578, 585, 913, 1909, - - 568, 576, 586, 606, 631, 640, 1951, 2012, 6578, 0, - 203, 924, 907, 694, 2054, 565, 543, 2115, 0, 2157, - 2218, 2279, 2340, 669, 912, 505, 2401, 856, 840, 2443, - 612, 615, 2504, 608, 557, 639, 682, 668, 839, 2546, - 2607, 0, 288, 863, 841, 819, 741, 794, 573, 418, - 6578, 2668, 2710, 620, 2771, 0, 2813, 2874, 2935, 2996, - 3057, 3131, 3173, 3234, 670, 3295, 718, 719, 729, 763, - 684, 3337, 3398, 0, 456, 782, 777, 760, 742, 829, - 649, 834, 3459, 572, 3520, 854, 894, 915, 920, 3581, - 3642, 3684, 593, 3745, 6578, 697, 3806, 3867, 3928, 3989, - - 4050, 4111, 730, 4172, 731, 683, 672, 759, 4214, 4275, - 0, 762, 682, 429, 417, 414, 411, 859, 6578, 650, - 838, 957, 4336, 4397, 607, 926, 988, 4458, 4519, 4580, - 1002, 672, 1010, 4622, 4664, 1042, 752, 4706, 4767, 756, - 4828, 376, 812, 847, 1069, 1033, 0, 387, 6578, 6578, - 6578, 6578, 6578, 6578, 1122, 924, 963, 4870, 1162, 1049, - 1050, 4912, 4973, 678, 1063, 850, 1074, 5005, 1103, 841, - 989, 0, 5062, 5104, 5146, 6578, 1066, 1080, 1081, 1084, - 1108, 1137, 877, 328, 273, 6578, 5188, 5230, 5272, 641, - 1140, 884, 916, 836, 1105, 1161, 5314, 5356, 1233, 1286, - - 1147, 1138, 919, 1206, 1165, 1186, 1141, 1207, 1291, 1263, - 1316, 1345, 1327, 5398, 1086, 1029, 1225, 1133, 258, 1247, - 1248, 1310, 1388, 6578, 1427, 5440, 1449, 5501, 242, 1311, - 1341, 1324, 1326, 173, 1317, 1454, 5562, 1480, 5604, 170, - 1061, 1328, 1355, 1372, 1552, 5646, 5688, 1351, 1374, 1389, - 1409, 5730, 5772, 1419, 1456, 154, 1453, 5814, 5856, 1457, - 112, 897, 793, 5898, 1557, 1418, 109, 1348, 1582, 1550, - 1477, 1481, 1485, 90, 1564, 1458, 39, 6578, 5959, 5964, - 5977, 5982, 5987, 5994, 6004, 6017, 296, 6022, 6032, 6045, - 6059, 651, 6064, 6074, 6079, 6089, 6099, 6103, 571, 6112, - - 6125, 6138, 6152, 6166, 6176, 6186, 6191, 6203, 657, 6217, - 758, 6222, 6234, 6247, 801, 6261, 859, 6266, 6278, 6291, - 6304, 6317, 6330, 1086, 6335, 6348, 1120, 6353, 6365, 6378, - 6391, 6404, 6417, 6430, 6435, 6448, 1216, 6453, 6465, 6478, - 6491, 6504, 6517, 1219, 1220, 6530, 6543, 6553, 6563 + 0, 0, 39, 41, 1573, 1566, 1594, 2399, 62, 71, + 76, 61, 69, 1560, 78, 1559, 89, 1561, 1565, 132, + 1573, 91, 123, 1555, 80, 104, 97, 1554, 1551, 2399, + 85, 176, 175, 2399, 177, 193, 204, 1531, 84, 2399, + 242, 110, 180, 196, 1545, 205, 2399, 113, 277, 2399, + 1547, 72, 221, 133, 206, 234, 181, 1555, 1548, 1530, + 1528, 0, 268, 118, 1515, 221, 60, 240, 92, 230, + 95, 223, 244, 267, 238, 286, 1512, 268, 1521, 279, + 294, 1510, 278, 190, 290, 232, 292, 293, 308, 335, + 2399, 2399, 317, 326, 1516, 351, 336, 356, 366, 2399, + + 2399, 320, 367, 369, 370, 1478, 393, 327, 345, 420, + 455, 398, 1495, 490, 1481, 446, 481, 372, 365, 386, + 525, 560, 2399, 325, 388, 1491, 387, 1477, 595, 1476, + 516, 399, 1475, 34, 1472, 1461, 378, 1438, 1430, 318, + 1429, 1426, 323, 1424, 1423, 1422, 231, 387, 1430, 377, + 1411, 630, 1396, 551, 382, 108, 415, 408, 419, 412, + 586, 436, 665, 1400, 624, 456, 419, 1382, 457, 490, + 491, 625, 492, 1362, 526, 656, 672, 681, 1378, 716, + 707, 527, 723, 561, 1374, 2399, 732, 1346, 767, 437, + 1322, 410, 1312, 445, 1311, 546, 2399, 469, 758, 1303, + + 802, 576, 482, 580, 470, 440, 472, 793, 809, 2399, + 818, 515, 1288, 1273, 853, 552, 1205, 839, 855, 861, + 877, 883, 899, 645, 1227, 483, 905, 921, 612, 1183, + 1168, 609, 927, 943, 626, 517, 628, 508, 629, 1167, + 949, 965, 971, 550, 1167, 1157, 1123, 1006, 1020, 666, + 682, 2399, 1047, 1091, 1006, 1038, 1055, 1063, 1071, 1079, + 632, 1087, 1095, 1105, 539, 1103, 1111, 542, 543, 681, + 1097, 683, 1119, 1127, 1135, 585, 1091, 1083, 1067, 1039, + 721, 752, 772, 1170, 717, 1205, 1184, 1217, 1244, 1258, + 1285, 1320, 984, 1244, 2399, 1276, 1311, 917, 1328, 767, + + 1336, 1344, 733, 1352, 1360, 734, 578, 899, 582, 1395, + 1381, 1397, 623, 853, 822, 794, 793, 760, 807, 2399, + 875, 788, 1432, 1459, 1494, 818, 769, 1440, 1529, 1564, + 1438, 702, 1485, 919, 1520, 1555, 849, 963, 1572, 587, + 1299, 1580, 706, 441, 614, 1615, 1601, 715, 2399, 2399, + 2399, 2399, 2399, 2399, 1473, 839, 856, 1617, 1652, 804, + 852, 1638, 1654, 633, 1480, 871, 1508, 1650, 1542, 644, + 834, 1673, 1679, 1695, 1701, 2399, 1015, 872, 915, 916, + 877, 959, 704, 616, 586, 2399, 1717, 1723, 1739, 1002, + 1148, 514, 961, 989, 990, 1016, 1745, 1761, 1767, 1802, + + 1137, 1008, 1018, 1017, 985, 1129, 878, 1038, 1790, 1806, + 1829, 1211, 1827, 1849, 944, 1057, 1152, 787, 584, 615, + 1196, 918, 1863, 1890, 1279, 2399, 1869, 1867, 516, 1199, + 1154, 943, 1242, 515, 653, 1904, 1906, 1941, 1968, 480, + 945, 1200, 1149, 1214, 1927, 1949, 1947, 1239, 1301, 1207, + 1302, 1974, 1990, 1392, 1267, 411, 1354, 1996, 2012, 1310, + 376, 1241, 1039, 2018, 2034, 1338, 348, 1377, 2040, 1216, + 1391, 1421, 1394, 324, 1226, 1376, 263, 2399, 2075, 2080, + 2091, 2096, 2101, 2110, 2117, 2128, 2137, 2142, 2153, 2165, + 2167, 2176, 2181, 2190, 2195, 2204, 2213, 2225, 2234, 2243, + + 2248, 2260, 2265, 2276, 2281, 2292, 2303, 2314, 2319, 2330, + 2341, 2346, 2357, 2366, 2377, 2386 } ; -static yyconst flex_int16_t yy_def[550] = +static yyconst flex_int16_t yy_def[517] = { 0, 478, 1, 1, 1, 1, 1, 478, 478, 478, 478, 478, 479, 480, 478, 481, 478, 482, 478, 478, 478, - 478, 483, 484, 484, 484, 485, 478, 478, 478, 478, - 484, 484, 484, 478, 484, 478, 478, 478, 479, 478, - 486, 480, 487, 488, 488, 489, 478, 481, 490, 478, - 478, 478, 484, 484, 484, 485, 20, 491, 478, 492, - 478, 20, 493, 493, 493, 493, 493, 493, 493, 493, - 493, 493, 493, 493, 493, 493, 494, 493, 478, 483, - 495, 495, 495, 495, 495, 495, 495, 496, 478, 484, - 497, 478, 484, 484, 498, 484, 484, 484, 478, 478, - - 478, 484, 484, 484, 484, 478, 479, 479, 479, 479, - 486, 499, 488, 488, 500, 488, 114, 501, 501, 501, - 501, 502, 478, 478, 484, 503, 504, 493, 505, 493, - 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, + 478, 483, 484, 478, 485, 485, 485, 478, 478, 478, + 485, 485, 485, 478, 485, 478, 478, 478, 479, 478, + 486, 480, 478, 487, 488, 488, 478, 481, 489, 478, + 478, 478, 484, 485, 485, 485, 20, 490, 478, 491, + 478, 20, 492, 493, 493, 493, 493, 493, 493, 493, + 493, 493, 493, 493, 493, 493, 493, 493, 478, 483, + 494, 495, 495, 495, 495, 495, 495, 495, 485, 485, + 478, 478, 485, 496, 478, 485, 485, 478, 485, 478, + + 478, 485, 485, 485, 485, 478, 479, 479, 479, 479, + 486, 478, 488, 46, 488, 497, 46, 481, 481, 481, + 481, 489, 478, 478, 485, 490, 498, 493, 493, 493, + 499, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 478, 495, - 495, 506, 495, 495, 495, 495, 495, 495, 495, 495, - 484, 98, 478, 484, 484, 507, 478, 484, 98, 484, - 484, 484, 484, 478, 508, 508, 509, 114, 488, 114, - 114, 501, 501, 484, 510, 478, 493, 147, 493, 493, - 493, 493, 493, 493, 147, 493, 478, 495, 495, 160, - - 495, 495, 495, 495, 495, 495, 160, 98, 478, 511, - 512, 478, 478, 513, 98, 484, 478, 514, 515, 114, - 114, 114, 501, 484, 510, 516, 147, 493, 493, 147, - 493, 495, 160, 495, 495, 495, 495, 495, 495, 160, - 98, 517, 518, 478, 478, 478, 519, 519, 520, 521, - 478, 522, 98, 478, 523, 524, 525, 525, 258, 526, - 98, 147, 147, 147, 495, 160, 495, 495, 495, 495, - 495, 160, 98, 527, 528, 478, 478, 478, 478, 478, - 520, 478, 529, 530, 531, 532, 532, 532, 532, 532, - 533, 98, 478, 534, 478, 535, 535, 297, 536, 98, - - 147, 301, 495, 160, 495, 495, 495, 495, 160, 98, - 537, 538, 478, 478, 478, 478, 478, 478, 478, 539, - 539, 539, 539, 540, 541, 541, 541, 541, 542, 543, - 300, 478, 534, 297, 298, 536, 300, 301, 301, 495, - 160, 495, 495, 495, 495, 300, 544, 478, 478, 478, - 478, 478, 478, 478, 539, 539, 539, 323, 541, 541, - 541, 328, 543, 478, 335, 300, 339, 495, 495, 495, - 495, 545, 323, 328, 363, 478, 300, 495, 495, 495, - 495, 495, 495, 495, 495, 478, 323, 328, 363, 300, - 495, 495, 495, 495, 495, 495, 323, 328, 543, 546, - - 495, 495, 495, 495, 495, 495, 495, 495, 539, 541, - 546, 546, 547, 548, 495, 495, 495, 495, 495, 495, - 495, 495, 478, 478, 547, 549, 547, 547, 495, 495, - 495, 495, 495, 495, 495, 547, 428, 547, 428, 495, - 495, 495, 495, 495, 547, 437, 428, 495, 495, 495, - 495, 437, 428, 495, 495, 495, 495, 437, 428, 495, - 495, 495, 495, 437, 547, 495, 495, 495, 547, 495, + 495, 495, 495, 500, 495, 495, 495, 495, 495, 495, + 90, 485, 90, 478, 485, 485, 501, 478, 485, 485, + 485, 485, 485, 478, 479, 110, 478, 114, 488, 114, + 46, 481, 121, 485, 502, 478, 129, 493, 129, 493, + 493, 493, 493, 493, 493, 493, 478, 495, 152, 495, + + 152, 495, 495, 495, 495, 495, 495, 90, 163, 478, + 478, 503, 478, 478, 504, 485, 478, 110, 478, 114, + 180, 46, 121, 485, 502, 498, 129, 189, 493, 493, + 493, 495, 152, 201, 495, 495, 495, 495, 495, 495, + 90, 163, 478, 505, 478, 478, 478, 504, 504, 506, + 507, 478, 508, 478, 110, 478, 114, 180, 46, 121, + 485, 129, 189, 493, 495, 152, 201, 495, 495, 495, + 495, 495, 90, 163, 478, 509, 478, 478, 478, 478, + 478, 506, 478, 510, 507, 511, 504, 504, 504, 504, + 504, 508, 478, 110, 478, 114, 180, 488, 121, 485, + + 129, 189, 495, 152, 201, 495, 495, 495, 495, 485, + 163, 478, 512, 478, 478, 478, 478, 478, 478, 478, + 506, 506, 506, 506, 510, 507, 507, 507, 507, 511, + 291, 478, 110, 488, 180, 121, 485, 493, 189, 495, + 495, 201, 495, 495, 495, 485, 478, 478, 478, 478, + 478, 478, 478, 478, 506, 506, 506, 324, 507, 507, + 507, 329, 291, 478, 488, 485, 493, 495, 495, 495, + 495, 478, 324, 329, 291, 478, 485, 495, 495, 495, + 495, 495, 495, 495, 495, 478, 324, 329, 291, 485, + 495, 495, 495, 495, 495, 495, 324, 329, 291, 513, + + 495, 495, 495, 495, 495, 495, 495, 495, 324, 329, + 513, 411, 514, 515, 495, 495, 495, 495, 495, 495, + 495, 495, 515, 515, 478, 478, 515, 516, 495, 495, + 495, 495, 495, 495, 495, 515, 424, 515, 424, 495, + 495, 495, 495, 495, 424, 515, 439, 495, 495, 495, + 495, 424, 439, 495, 495, 495, 495, 424, 439, 495, + 495, 495, 495, 424, 439, 495, 495, 495, 439, 495, 495, 495, 495, 495, 495, 495, 495, 0, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478 + 478, 478, 478, 478, 478, 478 } ; -static yyconst flex_int16_t yy_nxt[6664] = +static yyconst flex_int16_t yy_nxt[2460] = { 0, 8, 9, 10, 9, 9, 9, 11, 12, 13, 14, 8, 8, 15, 8, 8, 16, 8, 17, 18, 19, - 20, 8, 21, 8, 8, 8, 22, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 24, 23, 23, 23, 23, 23, 23, 25, 23, 23, - 23, 23, 23, 26, 27, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 24, 23, - 23, 23, 23, 23, 23, 25, 23, 23, 23, 23, - 23, 8, 28, 29, 23, 30, 35, 30, 35, 40, - 40, 31, 152, 31, 36, 36, 36, 36, 36, 36, - - 36, 36, 36, 36, 32, 33, 32, 33, 37, 37, - 37, 37, 37, 89, 40, 35, 51, 35, 89, 52, - 31, 89, 31, 89, 92, 93, 92, 93, 106, 40, - 49, 136, 32, 33, 32, 33, 41, 478, 89, 54, - 478, 95, 38, 152, 129, 34, 105, 34, 55, 94, - 89, 103, 56, 91, 89, 129, 106, 148, 91, 136, - 41, 91, 152, 91, 89, 152, 131, 54, 154, 96, - 49, 38, 42, 46, 105, 43, 55, 94, 91, 103, - 152, 102, 44, 44, 44, 44, 44, 44, 129, 89, - 91, 104, 92, 93, 91, 131, 154, 96, 36, 36, - - 36, 36, 36, 137, 91, 135, 129, 152, 46, 102, - 210, 44, 44, 44, 44, 44, 44, 59, 212, 104, - 210, 89, 129, 152, 60, 61, 152, 62, 244, 91, - 92, 92, 137, 135, 63, 63, 64, 65, 66, 63, - 67, 68, 69, 63, 70, 63, 71, 72, 63, 73, - 63, 74, 75, 76, 63, 63, 63, 63, 63, 63, - 77, 91, 78, 63, 63, 64, 65, 66, 63, 67, - 68, 69, 70, 63, 71, 72, 63, 73, 63, 74, - 75, 76, 63, 63, 63, 63, 63, 63, 130, 52, - 174, 63, 80, 144, 89, 152, 37, 37, 37, 37, - - 37, 478, 129, 57, 82, 210, 112, 83, 112, 124, - 84, 152, 125, 276, 85, 86, 130, 87, 174, 129, - 134, 132, 144, 63, 92, 140, 152, 127, 88, 129, - 38, 186, 133, 82, 91, 129, 83, 124, 138, 84, - 89, 125, 85, 86, 139, 87, 98, 141, 134, 132, - 153, 63, 129, 98, 98, 98, 98, 98, 98, 38, - 133, 129, 40, 40, 142, 478, 138, 145, 143, 152, - 39, 129, 139, 129, 157, 40, 141, 156, 192, 153, - 91, 152, 98, 98, 98, 98, 98, 98, 39, 39, - 39, 107, 142, 40, 109, 145, 143, 150, 155, 152, - - 152, 88, 158, 157, 210, 40, 156, 110, 41, 41, - 89, 129, 152, 89, 110, 110, 110, 110, 110, 110, - 164, 41, 89, 478, 89, 150, 155, 89, 152, 152, - 282, 158, 89, 40, 49, 168, 354, 89, 89, 353, - 111, 170, 352, 110, 110, 110, 110, 110, 110, 114, - 91, 41, 172, 91, 351, 165, 114, 114, 114, 114, - 114, 114, 91, 168, 91, 171, 478, 91, 173, 89, - 170, 285, 91, 210, 49, 189, 40, 91, 91, 190, - 172, 313, 115, 165, 184, 114, 114, 114, 114, 114, - 114, 117, 193, 171, 198, 129, 173, 194, 117, 117, - - 117, 117, 117, 117, 189, 129, 129, 209, 190, 91, - 191, 129, 196, 184, 204, 129, 152, 49, 192, 201, - 226, 193, 129, 198, 186, 194, 202, 117, 117, 117, - 117, 117, 117, 48, 48, 48, 118, 152, 191, 152, - 196, 205, 203, 204, 120, 152, 206, 91, 201, 217, - 228, 129, 121, 152, 202, 152, 214, 89, 89, 121, - 121, 121, 121, 121, 121, 164, 152, 209, 89, 205, - 203, 89, 478, 129, 268, 206, 89, 217, 89, 228, - 282, 177, 40, 177, 282, 122, 229, 254, 121, 121, - 121, 121, 121, 121, 98, 231, 91, 91, 91, 129, - - 224, 98, 98, 98, 98, 98, 98, 91, 91, 216, - 152, 91, 234, 232, 229, 254, 91, 129, 91, 282, - 332, 152, 235, 49, 231, 285, 283, 236, 224, 152, - 98, 98, 98, 98, 98, 98, 147, 216, 152, 152, - 234, 237, 232, 147, 147, 147, 147, 147, 147, 332, - 235, 264, 265, 267, 400, 236, 282, 282, 90, 152, - 285, 152, 238, 63, 63, 129, 293, 219, 152, 219, - 237, 239, 147, 147, 147, 147, 147, 147, 160, 264, - 265, 267, 89, 269, 152, 160, 160, 160, 160, 160, - 160, 238, 152, 152, 293, 247, 247, 247, 247, 247, - - 239, 249, 283, 283, 261, 303, 250, 350, 251, 270, - 343, 269, 364, 271, 160, 160, 160, 160, 160, 160, - 162, 152, 91, 152, 376, 152, 308, 162, 162, 162, - 162, 162, 162, 261, 303, 152, 152, 152, 270, 343, - 364, 271, 247, 247, 247, 247, 247, 252, 249, 305, - 115, 306, 376, 250, 308, 251, 162, 162, 162, 162, - 162, 162, 97, 97, 97, 97, 97, 317, 242, 90, - 242, 152, 152, 368, 89, 307, 340, 342, 305, 210, - 306, 169, 152, 152, 152, 316, 344, 349, 169, 169, - 169, 169, 169, 169, 252, 280, 280, 280, 280, 280, - - 366, 478, 315, 307, 340, 342, 478, 314, 251, 152, - 468, 256, 152, 256, 91, 344, 152, 169, 169, 169, - 169, 169, 169, 108, 175, 175, 175, 108, 366, 40, - 280, 280, 280, 280, 280, 318, 318, 318, 318, 318, - 478, 370, 176, 251, 279, 282, 152, 252, 319, 176, - 176, 176, 176, 176, 176, 280, 280, 280, 280, 280, - 318, 318, 318, 318, 318, 152, 278, 90, 251, 274, - 370, 274, 384, 319, 405, 41, 371, 377, 176, 176, - 176, 176, 176, 176, 39, 39, 39, 107, 277, 152, - 109, 283, 152, 129, 152, 280, 280, 280, 280, 280, - - 152, 384, 405, 110, 396, 371, 377, 252, 251, 129, - 110, 110, 110, 110, 110, 110, 280, 280, 280, 280, - 280, 280, 280, 280, 280, 280, 478, 226, 478, 251, - 152, 282, 246, 396, 251, 403, 111, 152, 282, 110, - 110, 110, 110, 110, 110, 178, 404, 252, 467, 245, - 152, 417, 178, 178, 178, 178, 178, 178, 355, 318, - 318, 318, 355, 403, 282, 478, 152, 129, 252, 152, - 282, 356, 152, 252, 129, 404, 467, 283, 115, 285, - 417, 178, 178, 178, 178, 178, 178, 180, 129, 359, - 318, 318, 318, 359, 180, 180, 180, 180, 180, 180, - - 282, 129, 360, 97, 97, 97, 97, 97, 226, 115, - 283, 108, 175, 175, 175, 108, 283, 40, 213, 90, - 385, 163, 152, 180, 180, 180, 180, 180, 180, 116, - 116, 116, 116, 116, 161, 161, 161, 161, 161, 152, - 197, 285, 152, 119, 182, 182, 182, 119, 181, 385, - 90, 478, 478, 129, 40, 181, 181, 181, 181, 181, - 181, 282, 282, 41, 179, 179, 179, 179, 179, 430, - 159, 159, 159, 159, 159, 187, 187, 187, 187, 187, - 129, 129, 152, 90, 181, 181, 181, 181, 181, 181, - 119, 182, 182, 182, 119, 49, 295, 430, 295, 129, - - 448, 40, 285, 285, 199, 199, 199, 199, 199, 183, - 390, 391, 392, 129, 152, 393, 183, 183, 183, 183, - 183, 183, 152, 355, 318, 318, 318, 355, 448, 282, - 311, 429, 311, 152, 152, 129, 356, 152, 390, 152, - 391, 392, 49, 406, 393, 183, 183, 183, 183, 183, - 183, 48, 48, 48, 118, 394, 152, 129, 152, 429, - 432, 152, 120, 359, 318, 318, 318, 359, 395, 401, - 121, 406, 402, 416, 282, 283, 360, 121, 121, 121, - 121, 121, 121, 394, 129, 415, 152, 129, 421, 432, - 152, 152, 129, 152, 152, 129, 419, 395, 401, 407, - - 152, 402, 416, 122, 129, 408, 121, 121, 121, 121, - 121, 121, 188, 415, 152, 285, 421, 420, 152, 188, - 188, 188, 188, 188, 188, 419, 347, 407, 347, 372, - 386, 372, 386, 408, 286, 286, 286, 286, 286, 152, - 127, 418, 422, 115, 115, 167, 420, 251, 188, 188, - 188, 188, 188, 188, 146, 146, 146, 146, 146, 152, - 152, 163, 152, 149, 326, 361, 361, 361, 326, 431, - 418, 422, 129, 195, 129, 282, 433, 57, 152, 434, - 195, 195, 195, 195, 195, 195, 252, 411, 411, 411, - 411, 411, 321, 357, 357, 357, 321, 431, 282, 77, - - 152, 152, 59, 412, 127, 433, 129, 123, 434, 195, - 195, 195, 195, 195, 195, 200, 285, 411, 411, 411, - 411, 411, 200, 200, 200, 200, 200, 200, 423, 423, - 423, 423, 423, 412, 115, 101, 100, 435, 99, 414, - 79, 424, 440, 58, 283, 444, 478, 478, 478, 478, - 478, 200, 200, 200, 200, 200, 200, 159, 159, 159, - 159, 159, 478, 152, 152, 57, 435, 442, 441, 414, - 152, 440, 443, 50, 444, 449, 207, 152, 471, 152, - 426, 152, 454, 207, 207, 207, 207, 207, 207, 423, - 423, 423, 423, 423, 152, 442, 450, 441, 414, 47, - - 443, 152, 424, 449, 152, 455, 478, 471, 152, 152, - 451, 454, 207, 207, 207, 207, 207, 207, 161, 161, - 161, 161, 161, 478, 450, 152, 478, 152, 423, 423, - 423, 423, 423, 456, 455, 478, 460, 208, 451, 478, - 457, 424, 152, 478, 208, 208, 208, 208, 208, 208, - 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, - 478, 456, 152, 424, 461, 470, 478, 478, 424, 457, - 478, 152, 152, 208, 208, 208, 208, 208, 208, 215, - 426, 423, 423, 423, 423, 423, 215, 215, 215, 215, - 215, 215, 461, 470, 424, 478, 478, 478, 463, 478, - - 462, 466, 426, 477, 478, 478, 152, 426, 473, 152, - 152, 152, 474, 478, 475, 215, 215, 215, 215, 215, - 215, 108, 175, 175, 175, 108, 463, 40, 462, 466, - 152, 477, 478, 426, 152, 478, 478, 473, 152, 478, - 218, 474, 478, 475, 478, 478, 478, 218, 218, 218, - 218, 218, 218, 423, 423, 423, 423, 423, 438, 438, - 438, 438, 438, 478, 478, 478, 424, 478, 478, 478, - 478, 424, 478, 41, 478, 478, 218, 218, 218, 218, - 218, 218, 220, 445, 445, 445, 445, 445, 472, 220, - 220, 220, 220, 220, 220, 478, 424, 478, 478, 478, - - 478, 478, 476, 152, 478, 426, 478, 478, 478, 478, - 426, 478, 478, 478, 478, 478, 472, 152, 220, 220, - 220, 220, 220, 220, 179, 179, 179, 179, 179, 478, - 476, 478, 478, 478, 478, 426, 478, 478, 478, 478, - 478, 478, 478, 221, 478, 478, 478, 478, 478, 478, - 221, 221, 221, 221, 221, 221, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 221, - 221, 221, 221, 221, 221, 116, 116, 116, 116, 116, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - - 478, 478, 478, 478, 222, 478, 478, 478, 478, 478, - 478, 222, 222, 222, 222, 222, 222, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 222, 222, 222, 222, 222, 222, 119, 182, 182, 182, - 119, 478, 478, 478, 478, 478, 478, 40, 478, 478, - 478, 478, 478, 478, 478, 223, 478, 478, 478, 478, - 478, 478, 223, 223, 223, 223, 223, 223, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 49, 478, - - 478, 223, 223, 223, 223, 223, 223, 187, 187, 187, - 187, 187, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 227, 478, 478, 478, - 478, 478, 478, 227, 227, 227, 227, 227, 227, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 227, 227, 227, 227, 227, 227, 230, 478, - 478, 478, 478, 478, 478, 230, 230, 230, 230, 230, - 230, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - - 478, 478, 478, 478, 230, 230, 230, 230, 230, 230, - 199, 199, 199, 199, 199, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 233, - 478, 478, 478, 478, 478, 478, 233, 233, 233, 233, - 233, 233, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 233, 233, 233, 233, 233, - 233, 240, 478, 478, 478, 478, 478, 478, 240, 240, - 240, 240, 240, 240, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - - 478, 478, 478, 478, 478, 478, 478, 240, 240, 240, - 240, 240, 240, 161, 161, 161, 161, 161, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 241, 478, 478, 478, 478, 478, 478, 241, - 241, 241, 241, 241, 241, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 241, 241, - 241, 241, 241, 241, 253, 478, 478, 478, 478, 478, - 478, 253, 253, 253, 253, 253, 253, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 253, 253, 253, 253, 253, 253, 108, 175, 175, 175, - 108, 478, 40, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 255, 478, 478, 478, 478, - 478, 478, 255, 255, 255, 255, 255, 255, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 41, 478, - 478, 255, 255, 255, 255, 255, 255, 257, 478, 478, - 478, 478, 478, 478, 257, 257, 257, 257, 257, 257, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 257, 257, 257, 257, 257, 257, 179, - 179, 179, 179, 179, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 258, 478, - 478, 478, 478, 478, 478, 258, 258, 258, 258, 258, - 258, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 258, 258, 258, 258, 258, 258, - 116, 116, 116, 116, 116, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 259, - - 478, 478, 478, 478, 478, 478, 259, 259, 259, 259, - 259, 259, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 259, 259, 259, 259, 259, - 259, 119, 182, 182, 182, 119, 478, 478, 478, 478, - 478, 478, 40, 478, 478, 478, 478, 478, 478, 478, - 260, 478, 478, 478, 478, 478, 478, 260, 260, 260, - 260, 260, 260, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 49, 478, 478, 260, 260, 260, 260, - - 260, 260, 187, 187, 187, 187, 187, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 262, 478, 478, 478, 478, 478, 478, 262, 262, - 262, 262, 262, 262, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 262, 262, 262, - 262, 262, 262, 263, 478, 478, 478, 478, 478, 478, - 263, 263, 263, 263, 263, 263, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 263, - - 263, 263, 263, 263, 263, 199, 199, 199, 199, 199, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 266, 478, 478, 478, 478, 478, - 478, 266, 266, 266, 266, 266, 266, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 266, 266, 266, 266, 266, 266, 272, 478, 478, 478, - 478, 478, 478, 272, 272, 272, 272, 272, 272, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - - 478, 478, 272, 272, 272, 272, 272, 272, 161, 161, - 161, 161, 161, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 273, 478, 478, - 478, 478, 478, 478, 273, 273, 273, 273, 273, 273, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 273, 273, 273, 273, 273, 273, 280, - 280, 280, 280, 286, 478, 288, 478, 478, 478, 478, - 288, 288, 289, 478, 478, 478, 478, 478, 290, 478, - 478, 478, 478, 478, 478, 290, 290, 290, 290, 290, - - 290, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 291, 478, 478, 290, 290, 290, 290, 290, 290, - 292, 478, 478, 478, 478, 478, 478, 292, 292, 292, - 292, 292, 292, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 292, 292, 292, 292, - 292, 292, 108, 175, 175, 175, 108, 478, 40, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 294, 478, 478, 478, 478, 478, 478, 294, 294, - - 294, 294, 294, 294, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 41, 478, 478, 294, 294, 294, - 294, 294, 294, 296, 478, 478, 478, 478, 478, 478, - 296, 296, 296, 296, 296, 296, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 115, 478, 478, 296, - 296, 296, 296, 296, 296, 179, 179, 179, 179, 179, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 297, 478, 478, 478, 478, 478, - - 478, 297, 297, 297, 297, 297, 297, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 115, 478, 478, - 297, 297, 297, 297, 297, 297, 116, 116, 116, 116, - 116, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 298, 478, 478, 478, 478, - 478, 478, 298, 298, 298, 298, 298, 298, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 298, 298, 298, 298, 298, 298, 119, 182, 182, - - 182, 119, 478, 478, 478, 478, 478, 478, 40, 478, - 478, 478, 478, 478, 478, 478, 299, 478, 478, 478, - 478, 478, 478, 299, 299, 299, 299, 299, 299, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 49, - 478, 478, 299, 299, 299, 299, 299, 299, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 90, 478, 478, - 478, 478, 478, 478, 90, 90, 90, 90, 90, 90, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - - 478, 478, 478, 300, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 90, 90, 90, 90, 90, 90, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 300, 187, 187, 187, 187, 187, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 301, 478, 478, 478, 478, 478, 478, 301, 301, - 301, 301, 301, 301, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 301, 301, 301, - 301, 301, 301, 302, 478, 478, 478, 478, 478, 478, - - 302, 302, 302, 302, 302, 302, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 302, - 302, 302, 302, 302, 302, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 128, 478, 478, 478, 478, 478, - 478, 128, 128, 128, 128, 128, 128, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 128, 128, 128, 128, 128, 128, 199, 199, 199, 199, - - 199, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 304, 478, 478, 478, 478, - 478, 478, 304, 304, 304, 304, 304, 304, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 304, 304, 304, 304, 304, 304, 309, 478, 478, - 478, 478, 478, 478, 309, 309, 309, 309, 309, 309, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 309, 309, 309, 309, 309, 309, 161, - - 161, 161, 161, 161, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 310, 478, - 478, 478, 478, 478, 478, 310, 310, 310, 310, 310, - 310, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 310, 310, 310, 310, 310, 310, - 281, 281, 281, 320, 478, 478, 322, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 323, - 478, 478, 478, 478, 478, 478, 323, 323, 323, 323, - 323, 323, 478, 478, 478, 478, 478, 478, 478, 478, - - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 324, 478, 478, 323, 323, 323, 323, 323, - 323, 284, 284, 284, 325, 478, 478, 478, 478, 478, - 478, 478, 327, 478, 478, 478, 478, 478, 478, 478, - 328, 478, 478, 478, 478, 478, 478, 328, 328, 328, - 328, 328, 328, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 329, 478, 478, 328, 328, 328, 328, - 328, 328, 286, 286, 286, 286, 286, 478, 478, 478, - 478, 478, 478, 478, 478, 251, 478, 478, 478, 478, - - 478, 330, 478, 478, 478, 478, 478, 478, 330, 330, - 330, 330, 330, 330, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 252, 478, 478, 330, 330, 330, - 330, 330, 330, 280, 280, 280, 280, 286, 478, 288, - 478, 478, 478, 478, 288, 288, 289, 478, 478, 478, - 478, 478, 290, 478, 478, 478, 478, 478, 478, 290, - 290, 290, 290, 290, 290, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 291, 478, 478, 290, 290, - - 290, 290, 290, 290, 331, 478, 478, 478, 478, 478, - 478, 331, 331, 331, 331, 331, 331, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 331, 331, 331, 331, 331, 331, 108, 175, 175, 175, - 108, 478, 40, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 333, 478, 478, 478, 478, - 478, 478, 333, 333, 333, 333, 333, 333, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 41, 478, - - 478, 333, 333, 333, 333, 333, 333, 179, 179, 179, - 179, 179, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 334, 478, 478, 478, - 478, 478, 478, 334, 334, 334, 334, 334, 334, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 115, - 478, 478, 334, 334, 334, 334, 334, 334, 116, 116, - 116, 116, 116, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 335, 478, 478, - 478, 478, 478, 478, 335, 335, 335, 335, 335, 335, - - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 335, 335, 335, 335, 335, 335, 119, - 182, 182, 182, 119, 478, 478, 478, 478, 478, 478, - 40, 478, 478, 478, 478, 478, 478, 478, 336, 478, - 478, 478, 478, 478, 478, 336, 336, 336, 336, 336, - 336, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 49, 478, 478, 336, 336, 336, 336, 336, 336, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - - 478, 478, 478, 478, 478, 478, 337, 478, 478, 90, - 478, 478, 478, 478, 478, 478, 90, 90, 90, 90, - 90, 90, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 90, 90, 90, 90, 90, - 90, 187, 187, 187, 187, 187, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 338, 478, 478, 478, 478, 478, 478, 338, 338, 338, - 338, 338, 338, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - - 478, 478, 478, 478, 478, 478, 338, 338, 338, 338, - 338, 338, 146, 146, 146, 146, 146, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 339, 478, 478, 478, 478, 478, 478, 339, 339, - 339, 339, 339, 339, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 339, 339, 339, - 339, 339, 339, 199, 199, 199, 199, 199, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 341, 478, 478, 478, 478, 478, 478, 341, - - 341, 341, 341, 341, 341, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 341, 341, - 341, 341, 341, 341, 345, 478, 478, 478, 478, 478, - 478, 345, 345, 345, 345, 345, 345, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 345, 345, 345, 345, 345, 345, 161, 161, 161, 161, - 161, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 346, 478, 478, 478, 478, - - 478, 478, 346, 346, 346, 346, 346, 346, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 346, 346, 346, 346, 346, 346, 321, 357, 357, - 357, 321, 478, 282, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 358, 478, 478, 478, - 478, 478, 478, 358, 358, 358, 358, 358, 358, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 283, - 478, 478, 358, 358, 358, 358, 358, 358, 281, 281, - - 281, 320, 478, 478, 322, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 323, 478, 478, - 478, 478, 478, 478, 323, 323, 323, 323, 323, 323, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 324, 478, 478, 323, 323, 323, 323, 323, 323, 326, - 361, 361, 361, 326, 478, 478, 478, 478, 478, 478, - 282, 478, 478, 478, 478, 478, 478, 478, 362, 478, - 478, 478, 478, 478, 478, 362, 362, 362, 362, 362, - 362, 478, 478, 478, 478, 478, 478, 478, 478, 478, - - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 285, 478, 478, 362, 362, 362, 362, 362, 362, - 284, 284, 284, 325, 478, 478, 478, 478, 478, 478, - 478, 327, 478, 478, 478, 478, 478, 478, 478, 328, - 478, 478, 478, 478, 478, 478, 328, 328, 328, 328, - 328, 328, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 329, 478, 478, 328, 328, 328, 328, 328, - 328, 286, 286, 286, 286, 286, 478, 478, 478, 478, - 478, 478, 478, 478, 251, 478, 478, 478, 478, 478, - - 363, 478, 478, 478, 478, 478, 478, 363, 363, 363, - 363, 363, 363, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 252, 478, 478, 363, 363, 363, 363, - 363, 363, 365, 478, 478, 478, 478, 478, 478, 365, - 365, 365, 365, 365, 365, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 365, 365, - 365, 365, 365, 365, 113, 478, 478, 478, 478, 478, - 478, 113, 113, 113, 113, 113, 113, 478, 478, 478, - - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 113, 113, 113, 113, 113, 113, 367, 478, 478, 478, - 478, 478, 478, 367, 367, 367, 367, 367, 367, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 367, 367, 367, 367, 367, 367, 146, 146, - 146, 146, 146, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 128, 478, 478, - 478, 478, 478, 478, 128, 128, 128, 128, 128, 128, - - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 128, 128, 128, 128, 128, 128, 199, - 199, 199, 199, 199, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 369, 478, - 478, 478, 478, 478, 478, 369, 369, 369, 369, 369, - 369, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 369, 369, 369, 369, 369, 369, - 373, 478, 478, 478, 478, 478, 478, 373, 373, 373, - - 373, 373, 373, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 373, 373, 373, 373, - 373, 373, 374, 478, 478, 478, 478, 478, 478, 374, - 374, 374, 374, 374, 374, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 374, 374, - 374, 374, 374, 374, 286, 286, 286, 286, 286, 478, - 478, 478, 478, 478, 478, 478, 478, 251, 478, 478, - 478, 478, 478, 375, 478, 478, 478, 478, 478, 478, - - 375, 375, 375, 375, 375, 375, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 252, 478, 478, 375, - 375, 375, 375, 375, 375, 378, 478, 478, 478, 478, - 478, 478, 379, 478, 380, 478, 478, 478, 478, 381, - 382, 478, 478, 383, 478, 478, 478, 478, 152, 478, - 478, 478, 478, 478, 378, 478, 478, 478, 478, 478, - 379, 478, 380, 478, 478, 478, 478, 381, 382, 478, - 478, 383, 387, 478, 478, 478, 478, 478, 478, 387, - 387, 387, 387, 387, 387, 478, 478, 478, 478, 478, - - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 387, 387, - 387, 387, 387, 387, 388, 478, 478, 478, 478, 478, - 478, 388, 388, 388, 388, 388, 388, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 388, 388, 388, 388, 388, 388, 389, 478, 478, 478, - 478, 478, 478, 389, 389, 389, 389, 389, 389, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - - 478, 478, 389, 389, 389, 389, 389, 389, 397, 478, - 478, 478, 478, 478, 478, 397, 397, 397, 397, 397, - 397, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 397, 397, 397, 397, 397, 397, - 398, 478, 478, 478, 478, 478, 478, 398, 398, 398, - 398, 398, 398, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 398, 398, 398, 398, - 398, 398, 399, 478, 478, 478, 478, 478, 478, 399, - - 399, 399, 399, 399, 399, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 399, 399, - 399, 399, 399, 399, 409, 478, 478, 478, 478, 478, - 478, 409, 409, 409, 409, 409, 409, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 409, 409, 409, 409, 409, 409, 410, 478, 478, 478, - 478, 478, 478, 410, 410, 410, 410, 410, 410, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 410, 410, 410, 410, 410, 410, 428, 478, - 478, 478, 478, 478, 478, 428, 428, 428, 428, 428, - 428, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 428, 428, 428, 428, 428, 428, - 437, 478, 478, 478, 478, 478, 478, 437, 437, 437, - 437, 437, 437, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 437, 437, 437, 437, - - 437, 437, 438, 438, 438, 438, 438, 478, 478, 478, - 478, 478, 478, 478, 478, 424, 478, 478, 478, 478, - 478, 439, 478, 478, 478, 478, 478, 478, 439, 439, - 439, 439, 439, 439, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 426, 478, 478, 439, 439, 439, - 439, 439, 439, 445, 445, 445, 445, 445, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 446, 478, 478, 478, 478, 478, 478, 446, - 446, 446, 446, 446, 446, 478, 478, 478, 478, 478, - - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 446, 446, - 446, 446, 446, 446, 447, 478, 478, 478, 478, 478, - 478, 447, 447, 447, 447, 447, 447, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 447, 447, 447, 447, 447, 447, 452, 478, 478, 478, - 478, 478, 478, 452, 452, 452, 452, 452, 452, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - - 478, 478, 452, 452, 452, 452, 452, 452, 453, 478, - 478, 478, 478, 478, 478, 453, 453, 453, 453, 453, - 453, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 453, 453, 453, 453, 453, 453, - 458, 478, 478, 478, 478, 478, 478, 458, 458, 458, - 458, 458, 458, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 458, 458, 458, 458, - 458, 458, 459, 478, 478, 478, 478, 478, 478, 459, - - 459, 459, 459, 459, 459, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 459, 459, - 459, 459, 459, 459, 464, 478, 478, 478, 478, 478, - 478, 464, 464, 464, 464, 464, 464, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 464, 464, 464, 464, 464, 464, 465, 478, 478, 478, - 478, 478, 478, 465, 465, 465, 465, 465, 465, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 465, 465, 465, 465, 465, 465, 469, 478, - 478, 478, 478, 478, 478, 469, 469, 469, 469, 469, - 469, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 469, 469, 469, 469, 469, 469, - 39, 478, 478, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 45, 45, 478, 45, 45, 48, 478, - 478, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 53, 53, 478, 53, 53, 81, 478, 478, 81, - - 81, 90, 478, 90, 90, 478, 90, 90, 97, 97, - 97, 97, 97, 97, 97, 97, 97, 97, 108, 108, + 20, 8, 21, 8, 8, 8, 22, 23, 24, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 26, 25, 25, 25, 25, 25, 25, + 27, 25, 25, 25, 25, 25, 8, 28, 29, 25, + 30, 131, 30, 36, 36, 36, 36, 36, 40, 31, + 191, 31, 36, 36, 36, 36, 36, 37, 37, 37, + 37, 37, 32, 33, 32, 33, 42, 131, 41, 43, + 40, 40, 52, 92, 134, 34, 44, 34, 92, 46, + + 46, 46, 46, 46, 46, 49, 51, 94, 80, 52, + 92, 41, 94, 98, 38, 124, 53, 92, 81, 131, + 95, 96, 131, 83, 94, 40, 84, 478, 102, 85, + 478, 94, 55, 86, 87, 154, 88, 44, 139, 137, + 49, 56, 59, 90, 99, 131, 92, 132, 97, 60, + 61, 203, 62, 90, 90, 90, 90, 90, 90, 63, + 94, 64, 65, 65, 66, 67, 68, 65, 69, 70, + 71, 65, 72, 65, 73, 74, 65, 75, 65, 76, + 77, 78, 65, 65, 65, 65, 65, 65, 92, 92, + 92, 65, 95, 96, 36, 36, 36, 36, 36, 478, + + 112, 57, 94, 94, 94, 37, 37, 37, 37, 37, + 112, 112, 112, 112, 112, 112, 114, 154, 104, 92, + 103, 105, 95, 96, 65, 117, 114, 114, 114, 114, + 114, 114, 116, 94, 156, 117, 117, 117, 117, 117, + 117, 90, 38, 39, 39, 39, 107, 92, 131, 109, + 131, 90, 90, 90, 90, 90, 90, 131, 131, 154, + 140, 94, 110, 133, 195, 131, 158, 131, 125, 111, + 144, 131, 110, 110, 110, 110, 110, 110, 48, 48, + 48, 118, 135, 95, 143, 138, 141, 145, 129, 120, + 154, 146, 142, 136, 131, 131, 478, 121, 129, 129, + + 129, 129, 129, 129, 122, 154, 81, 121, 121, 121, + 121, 121, 121, 131, 152, 155, 147, 154, 148, 154, + 154, 92, 159, 160, 152, 152, 152, 152, 152, 152, + 92, 150, 157, 92, 40, 94, 89, 89, 89, 89, + 89, 95, 95, 194, 94, 131, 163, 94, 92, 92, + 131, 154, 40, 170, 41, 161, 163, 163, 163, 163, + 163, 163, 94, 94, 92, 161, 161, 161, 161, 161, + 161, 165, 41, 193, 48, 154, 167, 40, 94, 92, + 92, 168, 92, 92, 40, 166, 167, 167, 167, 167, + 167, 167, 49, 94, 94, 39, 94, 94, 40, 49, + + 40, 92, 127, 154, 154, 131, 186, 169, 192, 154, + 172, 198, 202, 49, 131, 94, 171, 173, 177, 184, + 41, 108, 175, 175, 175, 108, 131, 40, 177, 177, + 177, 177, 177, 177, 196, 154, 211, 131, 154, 154, + 176, 205, 154, 230, 213, 190, 154, 41, 207, 92, + 176, 176, 176, 176, 176, 176, 39, 39, 39, 107, + 204, 206, 109, 94, 131, 194, 180, 154, 154, 210, + 215, 229, 131, 370, 239, 110, 180, 180, 180, 180, + 180, 180, 111, 94, 94, 110, 110, 110, 110, 110, + 110, 113, 113, 113, 113, 113, 154, 154, 226, 154, + + 232, 181, 186, 92, 210, 92, 240, 154, 238, 154, + 178, 181, 181, 181, 181, 181, 181, 94, 94, 94, + 178, 178, 178, 178, 178, 178, 119, 182, 182, 182, + 119, 236, 211, 40, 269, 154, 189, 40, 271, 40, + 245, 154, 154, 154, 154, 183, 189, 189, 189, 189, + 189, 189, 49, 41, 49, 183, 183, 183, 183, 183, + 183, 48, 48, 48, 118, 92, 154, 211, 403, 154, + 154, 201, 120, 131, 92, 277, 306, 303, 307, 94, + 121, 201, 201, 201, 201, 201, 201, 122, 94, 231, + 121, 121, 121, 121, 121, 121, 128, 128, 128, 128, + + 128, 224, 211, 154, 368, 154, 208, 154, 344, 154, + 314, 154, 345, 154, 154, 187, 208, 208, 208, 208, + 208, 208, 131, 235, 237, 187, 187, 187, 187, 187, + 187, 151, 151, 151, 151, 151, 154, 92, 92, 131, + 211, 154, 154, 154, 165, 92, 371, 433, 349, 265, + 199, 94, 94, 154, 264, 154, 154, 154, 92, 94, + 199, 199, 199, 199, 199, 199, 162, 162, 162, 162, + 162, 154, 94, 283, 268, 270, 218, 272, 384, 216, + 154, 300, 376, 261, 444, 209, 218, 218, 218, 218, + 218, 218, 219, 284, 283, 209, 209, 209, 209, 209, + + 209, 220, 219, 219, 219, 219, 219, 219, 154, 286, + 154, 220, 220, 220, 220, 220, 220, 179, 179, 179, + 179, 179, 281, 281, 281, 281, 281, 222, 309, 283, + 308, 154, 211, 154, 396, 252, 221, 222, 222, 222, + 222, 222, 222, 223, 286, 364, 221, 221, 221, 221, + 221, 221, 227, 223, 223, 223, 223, 223, 223, 283, + 154, 154, 227, 227, 227, 227, 227, 227, 188, 188, + 188, 188, 188, 319, 319, 319, 319, 319, 233, 284, + 92, 283, 340, 343, 337, 354, 320, 228, 233, 233, + 233, 233, 233, 233, 94, 283, 286, 228, 228, 228, + + 228, 228, 228, 200, 200, 200, 200, 200, 319, 319, + 319, 319, 319, 241, 154, 284, 283, 432, 353, 352, + 285, 320, 234, 241, 241, 241, 241, 241, 241, 242, + 283, 286, 234, 234, 234, 234, 234, 234, 243, 242, + 242, 242, 242, 242, 242, 286, 283, 351, 243, 243, + 243, 243, 243, 243, 248, 248, 248, 248, 248, 255, + 250, 154, 92, 283, 283, 251, 284, 252, 385, 255, + 255, 255, 255, 255, 255, 256, 94, 282, 350, 286, + 253, 257, 283, 284, 92, 256, 256, 256, 256, 256, + 256, 257, 257, 257, 257, 257, 257, 258, 94, 154, + + 366, 377, 284, 259, 154, 154, 391, 258, 258, 258, + 258, 258, 258, 259, 259, 259, 259, 259, 259, 260, + 113, 113, 113, 113, 113, 262, 154, 394, 421, 260, + 260, 260, 260, 260, 260, 262, 262, 262, 262, 262, + 262, 263, 154, 154, 116, 154, 116, 266, 435, 392, + 393, 263, 263, 263, 263, 263, 263, 266, 266, 266, + 266, 266, 266, 267, 128, 128, 128, 128, 128, 273, + 154, 154, 154, 267, 267, 267, 267, 267, 267, 273, + 273, 273, 273, 273, 273, 274, 154, 448, 154, 442, + 131, 275, 429, 395, 404, 274, 274, 274, 274, 274, + + 274, 275, 275, 275, 275, 275, 275, 248, 248, 248, + 248, 248, 154, 250, 332, 400, 154, 154, 251, 419, + 252, 281, 281, 281, 281, 281, 294, 478, 92, 94, + 405, 406, 478, 253, 252, 154, 294, 294, 294, 294, + 294, 294, 94, 154, 154, 154, 416, 253, 281, 281, + 281, 281, 287, 417, 289, 418, 468, 407, 295, 289, + 289, 290, 390, 408, 318, 154, 154, 291, 295, 295, + 295, 295, 295, 295, 292, 296, 422, 291, 291, 291, + 291, 291, 291, 297, 154, 296, 296, 296, 296, 296, + 296, 298, 317, 297, 297, 297, 297, 297, 297, 299, + + 430, 298, 298, 298, 298, 298, 298, 301, 316, 299, + 299, 299, 299, 299, 299, 302, 315, 301, 301, 301, + 301, 301, 301, 304, 154, 302, 302, 302, 302, 302, + 302, 305, 131, 304, 304, 304, 304, 304, 304, 310, + 293, 305, 305, 305, 305, 305, 305, 311, 280, 310, + 310, 310, 310, 310, 310, 312, 154, 311, 311, 311, + 311, 311, 311, 420, 154, 312, 312, 312, 312, 312, + 312, 282, 282, 282, 321, 154, 154, 323, 415, 154, + 401, 154, 279, 402, 441, 281, 281, 281, 281, 281, + 324, 478, 278, 450, 154, 131, 478, 325, 252, 431, + + 324, 324, 324, 324, 324, 324, 285, 285, 285, 326, + 131, 253, 478, 478, 478, 478, 478, 328, 281, 281, + 281, 281, 281, 154, 478, 329, 154, 154, 478, 478, + 434, 252, 330, 440, 154, 329, 329, 329, 329, 329, + 329, 154, 226, 154, 253, 281, 281, 281, 281, 281, + 449, 478, 254, 154, 456, 451, 478, 472, 252, 281, + 281, 281, 281, 281, 333, 478, 154, 476, 154, 154, + 478, 253, 252, 454, 333, 333, 333, 333, 333, 333, + 425, 425, 425, 425, 425, 253, 287, 287, 287, 287, + 287, 443, 478, 426, 154, 467, 334, 478, 247, 252, + + 151, 151, 151, 151, 151, 331, 334, 334, 334, 334, + 334, 334, 253, 246, 462, 331, 331, 331, 331, 331, + 331, 281, 281, 281, 281, 287, 154, 289, 154, 154, + 154, 335, 289, 289, 290, 455, 457, 154, 131, 131, + 291, 335, 335, 335, 335, 335, 335, 292, 336, 131, + 291, 291, 291, 291, 291, 291, 338, 466, 336, 336, + 336, 336, 336, 336, 339, 154, 338, 338, 338, 338, + 338, 338, 341, 131, 339, 339, 339, 339, 339, 339, + 342, 154, 341, 341, 341, 341, 341, 341, 470, 226, + 342, 342, 342, 342, 342, 342, 89, 89, 89, 89, + + 89, 346, 463, 154, 154, 116, 217, 214, 92, 460, + 471, 346, 346, 346, 346, 346, 346, 347, 154, 154, + 164, 154, 94, 154, 477, 473, 475, 347, 347, 347, + 347, 347, 347, 355, 319, 319, 319, 355, 154, 283, + 461, 359, 319, 319, 319, 359, 356, 197, 154, 131, + 131, 131, 283, 131, 360, 474, 131, 131, 363, 284, + 322, 357, 357, 357, 322, 131, 283, 286, 363, 363, + 363, 363, 363, 363, 355, 319, 319, 319, 355, 358, + 283, 179, 179, 179, 179, 179, 284, 356, 131, 358, + 358, 358, 358, 358, 358, 282, 282, 282, 321, 131, + + 284, 323, 131, 131, 131, 39, 127, 116, 116, 188, + 188, 188, 188, 188, 324, 39, 39, 39, 39, 39, + 39, 325, 116, 174, 324, 324, 324, 324, 324, 324, + 327, 361, 361, 361, 327, 131, 164, 154, 149, 131, + 365, 283, 131, 200, 200, 200, 200, 200, 57, 362, + 365, 365, 365, 365, 365, 365, 286, 63, 59, 362, + 362, 362, 362, 362, 362, 285, 285, 285, 326, 154, + 127, 123, 116, 106, 101, 48, 328, 100, 91, 79, + 58, 57, 50, 47, 329, 48, 48, 48, 48, 48, + 48, 330, 367, 478, 329, 329, 329, 329, 329, 329, + + 369, 35, 367, 367, 367, 367, 367, 367, 35, 478, + 369, 369, 369, 369, 369, 369, 162, 162, 162, 162, + 162, 372, 478, 478, 478, 478, 478, 478, 92, 478, + 478, 372, 372, 372, 372, 372, 372, 373, 478, 478, + 478, 478, 94, 478, 478, 478, 478, 373, 373, 373, + 373, 373, 373, 359, 319, 319, 319, 359, 374, 478, + 478, 478, 478, 478, 283, 478, 360, 478, 374, 374, + 374, 374, 374, 374, 375, 478, 478, 154, 478, 286, + 478, 478, 478, 378, 375, 375, 375, 375, 375, 375, + 379, 478, 380, 386, 478, 478, 478, 381, 382, 387, + + 478, 383, 478, 386, 386, 386, 386, 386, 386, 387, + 387, 387, 387, 387, 387, 388, 478, 478, 478, 478, + 478, 389, 478, 478, 478, 388, 388, 388, 388, 388, + 388, 389, 389, 389, 389, 389, 389, 397, 478, 478, + 478, 478, 478, 398, 478, 478, 478, 397, 397, 397, + 397, 397, 397, 398, 398, 398, 398, 398, 398, 399, + 478, 478, 478, 478, 478, 409, 478, 478, 478, 399, + 399, 399, 399, 399, 399, 409, 409, 409, 409, 409, + 409, 410, 478, 478, 478, 478, 478, 249, 478, 478, + 478, 410, 410, 410, 410, 410, 410, 249, 249, 249, + + 249, 249, 249, 411, 411, 411, 411, 411, 478, 478, + 282, 478, 478, 478, 478, 478, 478, 478, 478, 412, + 282, 282, 282, 282, 282, 282, 285, 478, 478, 413, + 411, 411, 411, 411, 411, 478, 285, 285, 285, 285, + 285, 285, 478, 478, 478, 478, 412, 424, 478, 478, + 425, 425, 425, 425, 425, 478, 413, 424, 424, 424, + 424, 424, 424, 426, 425, 425, 425, 425, 425, 478, + 425, 425, 425, 425, 425, 478, 428, 426, 478, 478, + 478, 478, 478, 426, 478, 478, 478, 439, 478, 478, + 428, 436, 436, 436, 436, 436, 428, 439, 439, 439, + + 439, 439, 439, 478, 426, 425, 425, 425, 425, 425, + 437, 478, 478, 478, 478, 478, 478, 428, 426, 478, + 437, 437, 437, 437, 437, 437, 445, 478, 478, 478, + 478, 428, 478, 478, 478, 478, 445, 445, 445, 445, + 445, 445, 425, 425, 425, 425, 425, 452, 478, 478, + 425, 425, 425, 425, 425, 426, 478, 452, 452, 452, + 452, 452, 452, 426, 478, 478, 478, 453, 428, 446, + 446, 446, 446, 446, 478, 478, 428, 453, 453, 453, + 453, 453, 453, 478, 478, 478, 478, 478, 447, 478, + 478, 478, 478, 478, 458, 478, 478, 478, 447, 447, + + 447, 447, 447, 447, 458, 458, 458, 458, 458, 458, + 459, 478, 478, 478, 478, 478, 464, 478, 478, 478, + 459, 459, 459, 459, 459, 459, 464, 464, 464, 464, + 464, 464, 465, 478, 478, 478, 478, 478, 427, 478, + 478, 478, 465, 465, 465, 465, 465, 465, 427, 427, + 427, 427, 427, 427, 469, 478, 478, 478, 478, 478, + 427, 478, 478, 478, 469, 469, 469, 469, 469, 469, + 427, 427, 427, 427, 427, 427, 39, 478, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 45, 45, 478, + 45, 45, 48, 478, 48, 48, 48, 48, 48, 48, + + 48, 48, 48, 54, 54, 478, 54, 54, 82, 478, + 478, 82, 82, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 93, 478, 93, 93, 478, 93, 93, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 113, 113, 478, 113, 113, 116, 116, 116, 116, - 116, 116, 116, 116, 116, 116, 119, 119, 119, 119, - 119, 119, 119, 119, 119, 119, 119, 119, 119, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 128, 128, 478, 128, 128, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 151, 151, - 478, 151, 151, 159, 159, 159, 159, 159, 159, 159, - - 159, 159, 159, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 161, 166, 166, 166, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 179, 48, 48, 478, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 119, - 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, - 119, 119, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, - - 211, 211, 211, 211, 39, 478, 478, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 225, 225, 225, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 115, + 115, 478, 115, 115, 119, 119, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 65, 65, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 130, 130, + 478, 130, 130, 151, 151, 151, 151, 151, 151, 151, + + 151, 151, 153, 153, 478, 153, 153, 162, 162, 162, + 162, 162, 162, 162, 162, 162, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 188, 188, 188, + 188, 188, 188, 188, 188, 188, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 212, 212, 212, 478, 212, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, - 225, 243, 243, 243, 243, 248, 248, 248, 248, 248, - 248, 478, 248, 248, 248, 248, 248, 248, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 185, 185, 185, 185, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 275, 275, 275, 275, 248, - 248, 248, 248, 248, 248, 478, 248, 248, 248, 248, - 248, 248, 281, 478, 478, 281, 281, 281, 281, 281, - - 281, 281, 281, 281, 281, 284, 478, 478, 284, 284, - 284, 284, 284, 284, 284, 284, 284, 284, 287, 287, - 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, - 287, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 113, 113, 478, 113, 113, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 312, 312, 312, 312, 321, 321, 321, 321, - 321, 321, 321, 321, 321, 321, 321, 321, 321, 284, - 478, 478, 284, 284, 284, 284, 284, 284, 284, 284, - 284, 284, 326, 326, 326, 326, 326, 326, 326, 326, - - 326, 326, 326, 326, 326, 248, 248, 248, 248, 248, - 478, 478, 248, 248, 248, 248, 248, 248, 287, 287, - 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, - 287, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 113, 113, 478, 113, 113, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 348, 348, 348, 348, 281, 281, 478, 281, - 281, 281, 281, 281, 281, 281, 281, 281, 281, 321, - 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, - 321, 321, 284, 284, 478, 284, 284, 284, 284, 284, - - 284, 284, 284, 284, 284, 326, 326, 326, 326, 326, - 326, 326, 326, 326, 326, 326, 326, 326, 248, 248, - 248, 248, 248, 478, 478, 248, 248, 248, 248, 248, - 248, 413, 413, 413, 413, 478, 478, 478, 478, 413, - 478, 478, 413, 413, 425, 425, 425, 425, 478, 478, - 478, 425, 425, 425, 478, 425, 425, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 436, 436, 436, - 436, 436, 436, 436, 436, 436, 436, 7, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 225, 225, 244, 244, 244, 478, 244, 249, 249, 249, + 249, 478, 249, 249, 249, 249, 249, 249, 276, 276, + 276, 478, 276, 282, 478, 282, 282, 282, 282, 282, + + 282, 282, 282, 282, 285, 478, 285, 285, 285, 285, + 285, 285, 285, 285, 285, 288, 288, 288, 288, 288, + 288, 288, 288, 288, 288, 288, 313, 313, 313, 478, + 313, 322, 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 327, 327, 327, 327, 327, 327, 327, 327, + 327, 327, 327, 348, 348, 348, 478, 348, 414, 414, + 414, 478, 478, 478, 414, 478, 478, 414, 414, 423, + 423, 423, 423, 423, 423, 423, 423, 423, 427, 427, + 427, 478, 478, 427, 427, 427, 478, 427, 427, 438, + 438, 438, 438, 438, 438, 438, 438, 438, 7, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478 + 478, 478, 478, 478, 478, 478, 478, 478, 478 } ; -static yyconst flex_int16_t yy_chk[6664] = +static yyconst flex_int16_t yy_chk[2460] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -1048,733 +576,270 @@ static yyconst flex_int16_t yy_chk[6664] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 3, 5, 4, 6, 15, - 12, 3, 477, 4, 9, 9, 9, 9, 9, 10, - - 10, 10, 10, 10, 3, 3, 4, 4, 11, 11, - 11, 11, 11, 23, 39, 5, 17, 6, 35, 17, - 3, 24, 4, 32, 24, 24, 32, 32, 38, 48, - 15, 69, 3, 3, 4, 4, 12, 42, 25, 17, - 42, 25, 11, 474, 69, 3, 35, 4, 17, 24, - 53, 32, 17, 23, 31, 78, 38, 78, 35, 69, - 39, 24, 467, 32, 33, 461, 65, 17, 83, 25, - 48, 11, 13, 42, 35, 13, 17, 24, 25, 32, - 83, 31, 13, 13, 13, 13, 13, 13, 65, 54, - 53, 33, 54, 54, 31, 65, 83, 25, 36, 36, - - 36, 36, 36, 70, 33, 68, 68, 456, 13, 31, - 166, 13, 13, 13, 13, 13, 13, 20, 166, 33, - 211, 90, 70, 440, 20, 20, 434, 20, 211, 54, - 124, 124, 70, 68, 20, 20, 20, 20, 20, 20, + 3, 134, 4, 9, 9, 9, 9, 9, 12, 3, + 134, 4, 10, 10, 10, 10, 10, 11, 11, 11, + 11, 11, 3, 3, 4, 4, 13, 67, 12, 13, + 15, 39, 52, 25, 67, 3, 13, 4, 31, 13, + + 13, 13, 13, 13, 13, 15, 17, 25, 22, 17, + 27, 39, 31, 27, 11, 52, 17, 26, 22, 69, + 26, 26, 71, 22, 27, 48, 22, 42, 31, 22, + 42, 26, 17, 22, 22, 156, 22, 42, 71, 69, + 48, 17, 20, 23, 27, 64, 54, 64, 26, 20, + 20, 156, 20, 23, 23, 23, 23, 23, 23, 20, + 54, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 90, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 64, 52, - 106, 20, 22, 74, 55, 429, 37, 37, 37, 37, - - 37, 57, 64, 57, 22, 243, 487, 22, 487, 52, - 22, 419, 55, 243, 22, 22, 64, 22, 106, 74, - 67, 66, 74, 57, 72, 72, 385, 127, 22, 67, - 37, 127, 66, 22, 55, 66, 22, 52, 71, 22, - 97, 55, 22, 22, 71, 22, 26, 73, 67, 66, - 82, 57, 71, 26, 26, 26, 26, 26, 26, 37, - 66, 72, 108, 109, 73, 80, 71, 76, 73, 82, - 107, 73, 71, 76, 86, 107, 73, 85, 140, 82, - 97, 384, 26, 26, 26, 26, 26, 26, 41, 41, - 41, 41, 73, 118, 41, 76, 73, 80, 84, 85, - - 86, 80, 87, 86, 348, 175, 85, 41, 108, 109, - 96, 140, 84, 93, 41, 41, 41, 41, 41, 41, - 93, 107, 94, 119, 102, 80, 84, 104, 87, 342, - 250, 87, 103, 119, 118, 96, 317, 105, 161, 316, - 41, 102, 315, 41, 41, 41, 41, 41, 41, 44, - 96, 175, 104, 93, 314, 94, 44, 44, 44, 44, - 44, 44, 94, 96, 102, 103, 120, 104, 105, 125, - 102, 250, 103, 275, 119, 131, 120, 105, 161, 134, - 104, 275, 44, 94, 125, 44, 44, 44, 44, 44, - 44, 46, 144, 103, 150, 131, 105, 145, 46, 46, - - 46, 46, 46, 46, 131, 134, 145, 165, 134, 125, - 137, 137, 148, 125, 156, 144, 150, 120, 192, 153, - 226, 144, 148, 150, 226, 145, 154, 46, 46, 46, - 46, 46, 46, 49, 49, 49, 49, 156, 137, 154, - 148, 157, 155, 156, 49, 153, 158, 165, 153, 174, - 190, 192, 49, 155, 154, 157, 168, 170, 164, 49, - 49, 49, 49, 49, 49, 164, 158, 171, 173, 157, - 155, 172, 182, 190, 235, 158, 184, 174, 216, 190, - 249, 499, 182, 499, 284, 49, 194, 217, 49, 49, - 49, 49, 49, 49, 56, 196, 168, 170, 164, 194, - - 184, 56, 56, 56, 56, 56, 56, 171, 173, 172, - 235, 172, 201, 198, 194, 217, 184, 196, 216, 325, - 293, 201, 202, 182, 196, 284, 249, 203, 184, 202, - 56, 56, 56, 56, 56, 56, 77, 172, 198, 203, - 201, 204, 198, 77, 77, 77, 77, 77, 77, 293, - 202, 231, 232, 234, 390, 203, 281, 320, 390, 204, - 325, 234, 205, 492, 492, 231, 254, 509, 232, 509, - 204, 206, 77, 77, 77, 77, 77, 77, 88, 231, - 232, 234, 224, 236, 205, 88, 88, 88, 88, 88, - 88, 205, 236, 206, 254, 214, 214, 214, 214, 214, - - 206, 214, 281, 320, 224, 265, 214, 313, 214, 237, - 306, 236, 332, 238, 88, 88, 88, 88, 88, 88, - 91, 238, 224, 265, 364, 307, 271, 91, 91, 91, - 91, 91, 91, 224, 265, 237, 306, 271, 237, 306, - 332, 238, 247, 247, 247, 247, 247, 214, 247, 267, - 296, 268, 364, 247, 271, 247, 91, 91, 91, 91, - 91, 91, 98, 98, 98, 98, 98, 279, 511, 337, - 511, 267, 268, 340, 98, 269, 303, 305, 267, 312, - 268, 98, 269, 303, 305, 278, 308, 312, 98, 98, - 98, 98, 98, 98, 247, 248, 248, 248, 248, 248, - - 337, 248, 277, 269, 303, 305, 248, 276, 248, 340, - 463, 515, 308, 515, 98, 308, 270, 98, 98, 98, - 98, 98, 98, 110, 110, 110, 110, 110, 337, 110, - 280, 280, 280, 280, 280, 282, 282, 282, 282, 282, - 321, 343, 110, 280, 246, 321, 463, 248, 282, 110, - 110, 110, 110, 110, 110, 286, 286, 286, 286, 286, - 318, 318, 318, 318, 318, 343, 245, 366, 286, 517, - 343, 517, 370, 318, 394, 110, 344, 366, 110, 110, - 110, 110, 110, 110, 111, 111, 111, 111, 244, 394, - 111, 321, 239, 229, 370, 287, 287, 287, 287, 287, - - 344, 370, 394, 111, 383, 344, 366, 286, 287, 228, - 111, 111, 111, 111, 111, 111, 288, 288, 288, 288, - 288, 289, 289, 289, 289, 289, 356, 225, 326, 288, - 383, 356, 213, 383, 289, 392, 111, 392, 326, 111, - 111, 111, 111, 111, 111, 114, 393, 287, 462, 212, - 462, 403, 114, 114, 114, 114, 114, 114, 322, 322, - 322, 322, 322, 392, 322, 357, 199, 193, 288, 393, - 357, 322, 403, 289, 191, 393, 462, 356, 114, 326, - 403, 114, 114, 114, 114, 114, 114, 115, 189, 327, - 327, 327, 327, 327, 115, 115, 115, 115, 115, 115, - - 327, 187, 327, 331, 331, 331, 331, 331, 185, 179, - 322, 333, 333, 333, 333, 333, 357, 333, 167, 331, - 371, 163, 159, 115, 115, 115, 115, 115, 115, 117, - 117, 117, 117, 117, 346, 346, 346, 346, 346, 151, - 149, 327, 371, 336, 336, 336, 336, 336, 117, 371, - 346, 360, 361, 146, 336, 117, 117, 117, 117, 117, - 117, 360, 361, 333, 365, 365, 365, 365, 365, 416, - 345, 345, 345, 345, 345, 367, 367, 367, 367, 367, - 143, 142, 416, 377, 117, 117, 117, 117, 117, 117, - 121, 121, 121, 121, 121, 336, 524, 416, 524, 141, - - 441, 121, 360, 361, 369, 369, 369, 369, 369, 121, - 377, 378, 379, 139, 441, 380, 121, 121, 121, 121, - 121, 121, 345, 355, 355, 355, 355, 355, 441, 355, - 527, 415, 527, 378, 379, 138, 355, 380, 377, 415, - 378, 379, 121, 395, 380, 121, 121, 121, 121, 121, - 121, 122, 122, 122, 122, 381, 369, 136, 395, 415, - 418, 381, 122, 359, 359, 359, 359, 359, 382, 391, - 122, 395, 391, 402, 359, 355, 359, 122, 122, 122, - 122, 122, 122, 381, 135, 401, 418, 133, 407, 418, - 382, 402, 132, 391, 407, 130, 405, 382, 391, 396, - - 401, 391, 402, 122, 128, 396, 122, 122, 122, 122, - 122, 122, 129, 401, 396, 359, 407, 406, 405, 129, - 129, 129, 129, 129, 129, 405, 537, 396, 537, 544, - 545, 544, 545, 396, 399, 399, 399, 399, 399, 406, - 126, 404, 408, 116, 113, 95, 406, 399, 129, 129, - 129, 129, 129, 129, 147, 147, 147, 147, 147, 404, - 408, 92, 81, 79, 410, 410, 410, 410, 410, 417, - 404, 408, 75, 147, 63, 410, 420, 61, 417, 421, - 147, 147, 147, 147, 147, 147, 399, 400, 400, 400, - 400, 400, 409, 409, 409, 409, 409, 417, 409, 60, - - 420, 421, 59, 400, 58, 420, 147, 51, 421, 147, - 147, 147, 147, 147, 147, 152, 410, 411, 411, 411, - 411, 411, 152, 152, 152, 152, 152, 152, 413, 413, - 413, 413, 413, 411, 45, 29, 28, 422, 27, 400, - 21, 413, 430, 19, 409, 435, 412, 412, 412, 412, - 412, 152, 152, 152, 152, 152, 152, 160, 160, 160, - 160, 160, 412, 422, 430, 18, 422, 432, 431, 411, - 435, 430, 433, 16, 435, 442, 160, 432, 468, 433, - 413, 442, 448, 160, 160, 160, 160, 160, 160, 423, - 423, 423, 423, 423, 431, 432, 443, 431, 412, 14, - - 433, 468, 423, 442, 448, 449, 7, 468, 443, 160, - 444, 448, 160, 160, 160, 160, 160, 160, 162, 162, - 162, 162, 162, 0, 443, 444, 0, 449, 425, 425, - 425, 425, 425, 450, 449, 0, 454, 162, 444, 0, - 451, 425, 450, 0, 162, 162, 162, 162, 162, 162, - 427, 427, 427, 427, 427, 436, 436, 436, 436, 436, - 0, 450, 451, 427, 454, 466, 0, 0, 436, 451, - 0, 466, 454, 162, 162, 162, 162, 162, 162, 169, - 425, 438, 438, 438, 438, 438, 169, 169, 169, 169, - 169, 169, 454, 466, 438, 0, 0, 0, 457, 0, - - 455, 460, 427, 476, 0, 0, 457, 436, 471, 455, - 460, 476, 472, 0, 473, 169, 169, 169, 169, 169, - 169, 176, 176, 176, 176, 176, 457, 176, 455, 460, - 471, 476, 0, 438, 472, 0, 0, 471, 473, 0, - 176, 472, 0, 473, 0, 0, 0, 176, 176, 176, - 176, 176, 176, 445, 445, 445, 445, 445, 465, 465, - 465, 465, 465, 0, 0, 0, 445, 0, 0, 0, - 0, 465, 0, 176, 0, 0, 176, 176, 176, 176, - 176, 176, 178, 469, 469, 469, 469, 469, 470, 178, - 178, 178, 178, 178, 178, 0, 469, 0, 0, 0, - - 0, 0, 475, 470, 0, 445, 0, 0, 0, 0, - 465, 0, 0, 0, 0, 0, 470, 475, 178, 178, - 178, 178, 178, 178, 180, 180, 180, 180, 180, 0, - 475, 0, 0, 0, 0, 469, 0, 0, 0, 0, - 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, - 180, 180, 180, 180, 180, 180, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, - 180, 180, 180, 180, 180, 181, 181, 181, 181, 181, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 181, 0, 0, 0, 0, 0, - 0, 181, 181, 181, 181, 181, 181, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 181, 181, 181, 181, 181, 181, 183, 183, 183, 183, - 183, 0, 0, 0, 0, 0, 0, 183, 0, 0, - 0, 0, 0, 0, 0, 183, 0, 0, 0, 0, - 0, 0, 183, 183, 183, 183, 183, 183, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 183, 0, - - 0, 183, 183, 183, 183, 183, 183, 188, 188, 188, - 188, 188, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 188, 0, 0, 0, - 0, 0, 0, 188, 188, 188, 188, 188, 188, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 188, 188, 188, 188, 188, 188, 195, 0, - 0, 0, 0, 0, 0, 195, 195, 195, 195, 195, - 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 195, 195, 195, 195, 195, 195, - 200, 200, 200, 200, 200, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, - 0, 0, 0, 0, 0, 0, 200, 200, 200, 200, - 200, 200, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 200, 200, 200, 200, 200, - 200, 207, 0, 0, 0, 0, 0, 0, 207, 207, - 207, 207, 207, 207, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 207, 207, 207, - 207, 207, 207, 208, 208, 208, 208, 208, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 208, 0, 0, 0, 0, 0, 0, 208, - 208, 208, 208, 208, 208, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 208, 208, - 208, 208, 208, 208, 215, 0, 0, 0, 0, 0, - 0, 215, 215, 215, 215, 215, 215, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 215, 215, 215, 215, 215, 215, 218, 218, 218, 218, - 218, 0, 218, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 218, 0, 0, 0, 0, - 0, 0, 218, 218, 218, 218, 218, 218, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 218, 0, - 0, 218, 218, 218, 218, 218, 218, 220, 0, 0, - 0, 0, 0, 0, 220, 220, 220, 220, 220, 220, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 220, 220, 220, 220, 220, 220, 221, - 221, 221, 221, 221, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 221, 0, - 0, 0, 0, 0, 0, 221, 221, 221, 221, 221, - 221, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 221, 221, 221, 221, 221, 221, - 222, 222, 222, 222, 222, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 222, - - 0, 0, 0, 0, 0, 0, 222, 222, 222, 222, - 222, 222, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 222, 222, 222, 222, 222, - 222, 223, 223, 223, 223, 223, 0, 0, 0, 0, - 0, 0, 223, 0, 0, 0, 0, 0, 0, 0, - 223, 0, 0, 0, 0, 0, 0, 223, 223, 223, - 223, 223, 223, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 223, 0, 0, 223, 223, 223, 223, - - 223, 223, 227, 227, 227, 227, 227, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 227, 0, 0, 0, 0, 0, 0, 227, 227, - 227, 227, 227, 227, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 227, 227, 227, - 227, 227, 227, 230, 0, 0, 0, 0, 0, 0, - 230, 230, 230, 230, 230, 230, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, - - 230, 230, 230, 230, 230, 233, 233, 233, 233, 233, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, - 0, 233, 233, 233, 233, 233, 233, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 233, 233, 233, 233, 233, 233, 240, 0, 0, 0, - 0, 0, 0, 240, 240, 240, 240, 240, 240, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 240, 240, 240, 240, 240, 240, 241, 241, - 241, 241, 241, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 241, 0, 0, - 0, 0, 0, 0, 241, 241, 241, 241, 241, 241, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 241, 241, 241, 241, 241, 241, 252, - 252, 252, 252, 252, 0, 252, 0, 0, 0, 0, - 252, 252, 252, 0, 0, 0, 0, 0, 252, 0, - 0, 0, 0, 0, 0, 252, 252, 252, 252, 252, - - 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 252, 0, 0, 252, 252, 252, 252, 252, 252, - 253, 0, 0, 0, 0, 0, 0, 253, 253, 253, - 253, 253, 253, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 253, 253, 253, 253, - 253, 253, 255, 255, 255, 255, 255, 0, 255, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 255, 0, 0, 0, 0, 0, 0, 255, 255, - - 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 255, 0, 0, 255, 255, 255, - 255, 255, 255, 257, 0, 0, 0, 0, 0, 0, - 257, 257, 257, 257, 257, 257, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 257, 0, 0, 257, - 257, 257, 257, 257, 257, 258, 258, 258, 258, 258, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 258, 0, 0, 0, 0, 0, - - 0, 258, 258, 258, 258, 258, 258, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 258, 0, 0, - 258, 258, 258, 258, 258, 258, 259, 259, 259, 259, - 259, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, - 0, 0, 259, 259, 259, 259, 259, 259, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 259, 259, 259, 259, 259, 259, 260, 260, 260, - - 260, 260, 0, 0, 0, 0, 0, 0, 260, 0, - 0, 0, 0, 0, 0, 0, 260, 0, 0, 0, - 0, 0, 0, 260, 260, 260, 260, 260, 260, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 260, - 0, 0, 260, 260, 260, 260, 260, 260, 261, 261, - 261, 261, 261, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 261, 0, 0, - 0, 0, 0, 0, 261, 261, 261, 261, 261, 261, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 261, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 261, 261, 261, 261, 261, 261, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 261, 262, 262, 262, 262, 262, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 262, 0, 0, 0, 0, 0, 0, 262, 262, - 262, 262, 262, 262, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 262, 262, 262, - 262, 262, 262, 263, 0, 0, 0, 0, 0, 0, - - 263, 263, 263, 263, 263, 263, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 263, - 263, 263, 263, 263, 263, 264, 264, 264, 264, 264, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 264, 0, 0, 0, 0, 0, - 0, 264, 264, 264, 264, 264, 264, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 264, 264, 264, 264, 264, 264, 266, 266, 266, 266, - - 266, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 266, 0, 0, 0, 0, - 0, 0, 266, 266, 266, 266, 266, 266, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 266, 266, 266, 266, 266, 266, 272, 0, 0, - 0, 0, 0, 0, 272, 272, 272, 272, 272, 272, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 272, 272, 272, 272, 272, 272, 273, - - 273, 273, 273, 273, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 273, 0, - 0, 0, 0, 0, 0, 273, 273, 273, 273, 273, - 273, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 273, 273, 273, 273, 273, 273, - 283, 283, 283, 283, 0, 0, 283, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 283, - 0, 0, 0, 0, 0, 0, 283, 283, 283, 283, - 283, 283, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 283, 0, 0, 283, 283, 283, 283, 283, - 283, 285, 285, 285, 285, 0, 0, 0, 0, 0, - 0, 0, 285, 0, 0, 0, 0, 0, 0, 0, - 285, 0, 0, 0, 0, 0, 0, 285, 285, 285, - 285, 285, 285, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 285, 0, 0, 285, 285, 285, 285, - 285, 285, 290, 290, 290, 290, 290, 0, 0, 0, - 0, 0, 0, 0, 0, 290, 0, 0, 0, 0, - - 0, 290, 0, 0, 0, 0, 0, 0, 290, 290, - 290, 290, 290, 290, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 290, 0, 0, 290, 290, 290, - 290, 290, 290, 291, 291, 291, 291, 291, 0, 291, - 0, 0, 0, 0, 291, 291, 291, 0, 0, 0, - 0, 0, 291, 0, 0, 0, 0, 0, 0, 291, - 291, 291, 291, 291, 291, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 291, 0, 0, 291, 291, - - 291, 291, 291, 291, 292, 0, 0, 0, 0, 0, - 0, 292, 292, 292, 292, 292, 292, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 292, 292, 292, 292, 292, 292, 294, 294, 294, 294, - 294, 0, 294, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 294, 0, 0, 0, 0, - 0, 0, 294, 294, 294, 294, 294, 294, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 294, 0, - - 0, 294, 294, 294, 294, 294, 294, 297, 297, 297, - 297, 297, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 297, 0, 0, 0, - 0, 0, 0, 297, 297, 297, 297, 297, 297, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 297, - 0, 0, 297, 297, 297, 297, 297, 297, 298, 298, - 298, 298, 298, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 298, 0, 0, - 0, 0, 0, 0, 298, 298, 298, 298, 298, 298, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 298, 298, 298, 298, 298, 298, 299, - 299, 299, 299, 299, 0, 0, 0, 0, 0, 0, - 299, 0, 0, 0, 0, 0, 0, 0, 299, 0, - 0, 0, 0, 0, 0, 299, 299, 299, 299, 299, - 299, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 299, 0, 0, 299, 299, 299, 299, 299, 299, - 300, 300, 300, 300, 300, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 300, 0, 0, 300, - 0, 0, 0, 0, 0, 0, 300, 300, 300, 300, - 300, 300, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 300, 300, 300, 300, 300, - 300, 301, 301, 301, 301, 301, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 301, 0, 0, 0, 0, 0, 0, 301, 301, 301, - 301, 301, 301, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 301, 301, 301, 301, - 301, 301, 302, 302, 302, 302, 302, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 302, 0, 0, 0, 0, 0, 0, 302, 302, - 302, 302, 302, 302, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 302, 302, 302, - 302, 302, 302, 304, 304, 304, 304, 304, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 304, 0, 0, 0, 0, 0, 0, 304, - - 304, 304, 304, 304, 304, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 304, 304, - 304, 304, 304, 304, 309, 0, 0, 0, 0, 0, - 0, 309, 309, 309, 309, 309, 309, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 309, 309, 309, 309, 309, 309, 310, 310, 310, 310, - 310, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 310, 0, 0, 0, 0, - - 0, 0, 310, 310, 310, 310, 310, 310, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 310, 310, 310, 310, 310, 310, 323, 323, 323, - 323, 323, 0, 323, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 323, 0, 0, 0, - 0, 0, 0, 323, 323, 323, 323, 323, 323, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 323, - 0, 0, 323, 323, 323, 323, 323, 323, 324, 324, - - 324, 324, 0, 0, 324, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 324, 0, 0, - 0, 0, 0, 0, 324, 324, 324, 324, 324, 324, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 324, 0, 0, 324, 324, 324, 324, 324, 324, 328, - 328, 328, 328, 328, 0, 0, 0, 0, 0, 0, - 328, 0, 0, 0, 0, 0, 0, 0, 328, 0, - 0, 0, 0, 0, 0, 328, 328, 328, 328, 328, - 328, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 328, 0, 0, 328, 328, 328, 328, 328, 328, - 329, 329, 329, 329, 0, 0, 0, 0, 0, 0, - 0, 329, 0, 0, 0, 0, 0, 0, 0, 329, - 0, 0, 0, 0, 0, 0, 329, 329, 329, 329, - 329, 329, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 329, 0, 0, 329, 329, 329, 329, 329, - 329, 330, 330, 330, 330, 330, 0, 0, 0, 0, - 0, 0, 0, 0, 330, 0, 0, 0, 0, 0, - - 330, 0, 0, 0, 0, 0, 0, 330, 330, 330, - 330, 330, 330, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 330, 0, 0, 330, 330, 330, 330, - 330, 330, 334, 0, 0, 0, 0, 0, 0, 334, - 334, 334, 334, 334, 334, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 334, 334, - 334, 334, 334, 334, 335, 0, 0, 0, 0, 0, - 0, 335, 335, 335, 335, 335, 335, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 335, 335, 335, 335, 335, 335, 338, 0, 0, 0, - 0, 0, 0, 338, 338, 338, 338, 338, 338, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 338, 338, 338, 338, 338, 338, 339, 339, - 339, 339, 339, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 339, 0, 0, - 0, 0, 0, 0, 339, 339, 339, 339, 339, 339, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 339, 339, 339, 339, 339, 339, 341, - 341, 341, 341, 341, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 341, 0, - 0, 0, 0, 0, 0, 341, 341, 341, 341, 341, - 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 341, 341, 341, 341, 341, 341, - 358, 0, 0, 0, 0, 0, 0, 358, 358, 358, - - 358, 358, 358, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 358, 358, 358, 358, - 358, 358, 362, 0, 0, 0, 0, 0, 0, 362, - 362, 362, 362, 362, 362, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 362, 362, - 362, 362, 362, 362, 363, 363, 363, 363, 363, 0, - 0, 0, 0, 0, 0, 0, 0, 363, 0, 0, - 0, 0, 0, 363, 0, 0, 0, 0, 0, 0, - - 363, 363, 363, 363, 363, 363, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 363, 0, 0, 363, - 363, 363, 363, 363, 363, 368, 0, 0, 0, 0, - 0, 0, 368, 0, 368, 0, 0, 0, 0, 368, - 368, 0, 0, 368, 0, 0, 0, 0, 368, 0, - 0, 0, 0, 0, 368, 0, 0, 0, 0, 0, - 368, 0, 368, 0, 0, 0, 0, 368, 368, 0, - 0, 368, 373, 0, 0, 0, 0, 0, 0, 373, - 373, 373, 373, 373, 373, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 373, 373, - 373, 373, 373, 373, 374, 0, 0, 0, 0, 0, - 0, 374, 374, 374, 374, 374, 374, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 374, 374, 374, 374, 374, 374, 375, 0, 0, 0, - 0, 0, 0, 375, 375, 375, 375, 375, 375, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 375, 375, 375, 375, 375, 375, 387, 0, - 0, 0, 0, 0, 0, 387, 387, 387, 387, 387, - 387, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 387, 387, 387, 387, 387, 387, - 388, 0, 0, 0, 0, 0, 0, 388, 388, 388, - 388, 388, 388, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 388, 388, 388, 388, - 388, 388, 389, 0, 0, 0, 0, 0, 0, 389, - - 389, 389, 389, 389, 389, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 389, 389, - 389, 389, 389, 389, 397, 0, 0, 0, 0, 0, - 0, 397, 397, 397, 397, 397, 397, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 397, 397, 397, 397, 397, 397, 398, 0, 0, 0, - 0, 0, 0, 398, 398, 398, 398, 398, 398, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 398, 398, 398, 398, 398, 398, 414, 0, - 0, 0, 0, 0, 0, 414, 414, 414, 414, 414, - 414, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 414, 414, 414, 414, 414, 414, - 426, 0, 0, 0, 0, 0, 0, 426, 426, 426, - 426, 426, 426, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 426, 426, 426, 426, - - 426, 426, 428, 428, 428, 428, 428, 0, 0, 0, - 0, 0, 0, 0, 0, 428, 0, 0, 0, 0, - 0, 428, 0, 0, 0, 0, 0, 0, 428, 428, - 428, 428, 428, 428, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 428, 0, 0, 428, 428, 428, - 428, 428, 428, 437, 437, 437, 437, 437, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 437, 0, 0, 0, 0, 0, 0, 437, - 437, 437, 437, 437, 437, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 437, 437, - 437, 437, 437, 437, 439, 0, 0, 0, 0, 0, - 0, 439, 439, 439, 439, 439, 439, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 439, 439, 439, 439, 439, 439, 446, 0, 0, 0, - 0, 0, 0, 446, 446, 446, 446, 446, 446, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 446, 446, 446, 446, 446, 446, 447, 0, - 0, 0, 0, 0, 0, 447, 447, 447, 447, 447, - 447, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 447, 447, 447, 447, 447, 447, - 452, 0, 0, 0, 0, 0, 0, 452, 452, 452, - 452, 452, 452, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 452, 452, 452, 452, - 452, 452, 453, 0, 0, 0, 0, 0, 0, 453, - - 453, 453, 453, 453, 453, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 453, 453, - 453, 453, 453, 453, 458, 0, 0, 0, 0, 0, - 0, 458, 458, 458, 458, 458, 458, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 458, 458, 458, 458, 458, 458, 459, 0, 0, 0, - 0, 0, 0, 459, 459, 459, 459, 459, 459, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 459, 459, 459, 459, 459, 459, 464, 0, - 0, 0, 0, 0, 0, 464, 464, 464, 464, 464, - 464, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 464, 464, 464, 464, 464, 464, - 479, 0, 0, 479, 479, 479, 479, 479, 479, 479, - 479, 479, 479, 480, 480, 0, 480, 480, 481, 0, - 0, 481, 481, 481, 481, 481, 481, 481, 481, 481, - 481, 482, 482, 0, 482, 482, 483, 0, 0, 483, - - 483, 484, 0, 484, 484, 0, 484, 484, 485, 485, - 485, 485, 485, 485, 485, 485, 485, 485, 486, 486, + 20, 20, 20, 20, 20, 20, 20, 20, 33, 32, + 35, 20, 32, 32, 36, 36, 36, 36, 36, 57, + + 43, 57, 33, 32, 35, 37, 37, 37, 37, 37, + 43, 43, 43, 43, 43, 43, 44, 84, 33, 55, + 32, 35, 55, 55, 57, 46, 44, 44, 44, 44, + 44, 44, 46, 55, 84, 46, 46, 46, 46, 46, + 46, 53, 37, 41, 41, 41, 41, 56, 66, 41, + 72, 53, 53, 53, 53, 53, 53, 70, 147, 86, + 72, 56, 41, 66, 147, 75, 86, 68, 56, 41, + 75, 73, 41, 41, 41, 41, 41, 41, 49, 49, + 49, 49, 68, 74, 74, 70, 73, 75, 63, 49, + 477, 75, 73, 68, 74, 78, 80, 49, 63, 63, + + 63, 63, 63, 63, 49, 83, 80, 49, 49, 49, + 49, 49, 49, 76, 81, 83, 76, 85, 78, 87, + 88, 89, 87, 88, 81, 81, 81, 81, 81, 81, + 93, 80, 85, 102, 108, 89, 90, 90, 90, 90, + 90, 124, 124, 143, 93, 140, 94, 102, 90, 97, + 143, 474, 109, 102, 108, 90, 94, 94, 94, 94, + 94, 94, 90, 97, 96, 90, 90, 90, 90, 90, + 90, 96, 109, 140, 118, 467, 98, 119, 96, 99, + 103, 98, 104, 105, 118, 97, 98, 98, 98, 98, + 98, 98, 119, 99, 103, 107, 104, 105, 120, 118, + + 107, 125, 127, 461, 150, 137, 127, 99, 137, 155, + 104, 150, 155, 120, 148, 125, 103, 105, 112, 125, + 107, 110, 110, 110, 110, 110, 132, 110, 112, 112, + 112, 112, 112, 112, 148, 158, 167, 192, 456, 160, + 110, 158, 157, 192, 167, 132, 159, 110, 160, 162, + 110, 110, 110, 110, 110, 110, 111, 111, 111, 111, + 157, 159, 111, 162, 190, 194, 116, 206, 344, 166, + 169, 190, 194, 344, 206, 111, 116, 116, 116, 116, + 116, 116, 111, 166, 169, 111, 111, 111, 111, 111, + 111, 114, 114, 114, 114, 114, 198, 205, 226, 207, + + 198, 117, 226, 170, 171, 173, 207, 440, 205, 203, + 114, 117, 117, 117, 117, 117, 117, 170, 171, 173, + 114, 114, 114, 114, 114, 114, 121, 121, 121, 121, + 121, 203, 212, 175, 236, 238, 131, 121, 238, 182, + 212, 392, 434, 429, 236, 121, 131, 131, 131, 131, + 131, 131, 121, 175, 182, 121, 121, 121, 121, 121, + 121, 122, 122, 122, 122, 216, 265, 244, 392, 268, + 269, 154, 122, 196, 184, 244, 268, 265, 269, 216, + 122, 154, 154, 154, 154, 154, 154, 122, 184, 196, + 122, 122, 122, 122, 122, 122, 129, 129, 129, 129, + + 129, 184, 276, 202, 340, 307, 161, 204, 307, 309, + 276, 419, 309, 385, 340, 129, 161, 161, 161, 161, + 161, 161, 129, 202, 204, 129, 129, 129, 129, 129, + 129, 152, 152, 152, 152, 152, 232, 165, 172, 229, + 313, 345, 420, 384, 165, 261, 345, 420, 313, 232, + 152, 165, 172, 235, 229, 237, 239, 152, 224, 261, + 152, 152, 152, 152, 152, 152, 163, 163, 163, 163, + 163, 370, 224, 250, 235, 237, 176, 239, 370, 172, + 435, 261, 364, 224, 435, 163, 176, 176, 176, 176, + 176, 176, 177, 250, 251, 163, 163, 163, 163, 163, + + 163, 178, 177, 177, 177, 177, 177, 177, 270, 251, + 272, 178, 178, 178, 178, 178, 178, 180, 180, 180, + 180, 180, 281, 281, 281, 281, 281, 181, 272, 285, + 270, 383, 348, 343, 383, 281, 180, 181, 181, 181, + 181, 181, 181, 183, 285, 332, 180, 180, 180, 180, + 180, 180, 187, 183, 183, 183, 183, 183, 183, 282, + 303, 306, 187, 187, 187, 187, 187, 187, 189, 189, + 189, 189, 189, 283, 283, 283, 283, 283, 199, 282, + 300, 327, 303, 306, 300, 318, 283, 189, 199, 199, + 199, 199, 199, 199, 300, 322, 327, 189, 189, 189, + + 189, 189, 189, 201, 201, 201, 201, 201, 319, 319, + 319, 319, 319, 208, 418, 322, 360, 418, 317, 316, + 326, 319, 201, 208, 208, 208, 208, 208, 208, 209, + 326, 360, 201, 201, 201, 201, 201, 201, 211, 209, + 209, 209, 209, 209, 209, 326, 356, 315, 211, 211, + 211, 211, 211, 211, 215, 215, 215, 215, 215, 218, + 215, 371, 337, 357, 361, 215, 356, 215, 371, 218, + 218, 218, 218, 218, 218, 219, 337, 321, 314, 361, + 215, 220, 321, 357, 366, 219, 219, 219, 219, 219, + 219, 220, 220, 220, 220, 220, 220, 221, 366, 378, + + 337, 366, 321, 222, 381, 407, 378, 221, 221, 221, + 221, 221, 221, 222, 222, 222, 222, 222, 222, 223, + 334, 334, 334, 334, 334, 227, 308, 381, 407, 223, + 223, 223, 223, 223, 223, 227, 227, 227, 227, 227, + 227, 228, 379, 380, 298, 422, 334, 233, 422, 379, + 380, 228, 228, 228, 228, 228, 228, 233, 233, 233, + 233, 233, 233, 234, 338, 338, 338, 338, 338, 241, + 432, 415, 441, 234, 234, 234, 234, 234, 234, 241, + 241, 241, 241, 241, 241, 242, 382, 441, 393, 432, + 338, 243, 415, 382, 393, 242, 242, 242, 242, 242, + + 242, 243, 243, 243, 243, 243, 243, 248, 248, 248, + 248, 248, 405, 248, 293, 390, 394, 395, 248, 405, + 248, 249, 249, 249, 249, 249, 255, 249, 377, 390, + 394, 395, 249, 248, 249, 402, 255, 255, 255, 255, + 255, 255, 377, 396, 404, 403, 402, 249, 253, 253, + 253, 253, 253, 403, 253, 404, 463, 396, 256, 253, + 253, 253, 377, 396, 280, 408, 463, 253, 256, 256, + 256, 256, 256, 256, 253, 257, 408, 253, 253, 253, + 253, 253, 253, 258, 416, 257, 257, 257, 257, 257, + 257, 259, 279, 258, 258, 258, 258, 258, 258, 260, + + 416, 259, 259, 259, 259, 259, 259, 262, 278, 260, + 260, 260, 260, 260, 260, 263, 277, 262, 262, 262, + 262, 262, 262, 266, 271, 263, 263, 263, 263, 263, + 263, 267, 264, 266, 266, 266, 266, 266, 266, 273, + 254, 267, 267, 267, 267, 267, 267, 274, 247, 273, + 273, 273, 273, 273, 273, 275, 406, 274, 274, 274, + 274, 274, 274, 406, 401, 275, 275, 275, 275, 275, + 275, 284, 284, 284, 284, 391, 443, 284, 401, 417, + 391, 431, 246, 391, 431, 287, 287, 287, 287, 287, + 284, 287, 245, 443, 240, 231, 287, 284, 287, 417, + + 284, 284, 284, 284, 284, 284, 286, 286, 286, 286, + 230, 287, 412, 412, 412, 412, 412, 286, 288, 288, + 288, 288, 288, 421, 288, 286, 430, 442, 412, 288, + 421, 288, 286, 430, 450, 286, 286, 286, 286, 286, + 286, 444, 225, 470, 288, 289, 289, 289, 289, 289, + 442, 289, 217, 475, 450, 444, 289, 470, 289, 290, + 290, 290, 290, 290, 294, 290, 448, 475, 462, 433, + 290, 289, 290, 448, 294, 294, 294, 294, 294, 294, + 425, 425, 425, 425, 425, 290, 291, 291, 291, 291, + 291, 433, 291, 425, 455, 462, 296, 291, 214, 291, + + 341, 341, 341, 341, 341, 291, 296, 296, 296, 296, + 296, 296, 291, 213, 455, 291, 291, 291, 291, 291, + 291, 292, 292, 292, 292, 292, 341, 292, 449, 451, + 200, 297, 292, 292, 292, 449, 451, 460, 195, 193, + 292, 297, 297, 297, 297, 297, 297, 292, 299, 191, + 292, 292, 292, 292, 292, 292, 301, 460, 299, 299, + 299, 299, 299, 299, 302, 466, 301, 301, 301, 301, + 301, 301, 304, 188, 302, 302, 302, 302, 302, 302, + 305, 457, 304, 304, 304, 304, 304, 304, 466, 185, + 305, 305, 305, 305, 305, 305, 310, 310, 310, 310, + + 310, 311, 457, 476, 468, 179, 174, 168, 310, 454, + 468, 311, 311, 311, 311, 311, 311, 312, 471, 454, + 164, 473, 310, 153, 476, 471, 473, 312, 312, 312, + 312, 312, 312, 323, 323, 323, 323, 323, 151, 323, + 454, 328, 328, 328, 328, 328, 323, 149, 472, 146, + 145, 144, 328, 142, 328, 472, 141, 139, 331, 323, + 324, 324, 324, 324, 324, 138, 324, 328, 331, 331, + 331, 331, 331, 331, 355, 355, 355, 355, 355, 324, + 355, 365, 365, 365, 365, 365, 324, 355, 136, 324, + 324, 324, 324, 324, 324, 325, 325, 325, 325, 135, + + 355, 325, 133, 130, 128, 333, 126, 365, 115, 367, + 367, 367, 367, 367, 325, 333, 333, 333, 333, 333, + 333, 325, 113, 106, 325, 325, 325, 325, 325, 325, + 329, 329, 329, 329, 329, 367, 95, 82, 79, 77, + 335, 329, 65, 369, 369, 369, 369, 369, 61, 329, + 335, 335, 335, 335, 335, 335, 329, 60, 59, 329, + 329, 329, 329, 329, 329, 330, 330, 330, 330, 369, + 58, 51, 45, 38, 29, 336, 330, 28, 24, 21, + 19, 18, 16, 14, 330, 336, 336, 336, 336, 336, + 336, 330, 339, 7, 330, 330, 330, 330, 330, 330, + + 342, 6, 339, 339, 339, 339, 339, 339, 5, 0, + 342, 342, 342, 342, 342, 342, 346, 346, 346, 346, + 346, 347, 0, 0, 0, 0, 0, 0, 346, 0, + 0, 347, 347, 347, 347, 347, 347, 358, 0, 0, + 0, 0, 346, 0, 0, 0, 0, 358, 358, 358, + 358, 358, 358, 359, 359, 359, 359, 359, 362, 0, + 0, 0, 0, 0, 359, 0, 359, 0, 362, 362, + 362, 362, 362, 362, 363, 0, 0, 368, 0, 359, + 0, 0, 0, 368, 363, 363, 363, 363, 363, 363, + 368, 0, 368, 372, 0, 0, 0, 368, 368, 373, + + 0, 368, 0, 372, 372, 372, 372, 372, 372, 373, + 373, 373, 373, 373, 373, 374, 0, 0, 0, 0, + 0, 375, 0, 0, 0, 374, 374, 374, 374, 374, + 374, 375, 375, 375, 375, 375, 375, 387, 0, 0, + 0, 0, 0, 388, 0, 0, 0, 387, 387, 387, + 387, 387, 387, 388, 388, 388, 388, 388, 388, 389, + 0, 0, 0, 0, 0, 397, 0, 0, 0, 389, + 389, 389, 389, 389, 389, 397, 397, 397, 397, 397, + 397, 398, 0, 0, 0, 0, 0, 399, 0, 0, + 0, 398, 398, 398, 398, 398, 398, 399, 399, 399, + + 399, 399, 399, 400, 400, 400, 400, 400, 0, 0, + 409, 0, 0, 0, 0, 0, 0, 0, 0, 400, + 409, 409, 409, 409, 409, 409, 410, 0, 0, 400, + 411, 411, 411, 411, 411, 0, 410, 410, 410, 410, + 410, 410, 0, 0, 0, 0, 411, 413, 0, 0, + 414, 414, 414, 414, 414, 0, 411, 413, 413, 413, + 413, 413, 413, 414, 423, 423, 423, 423, 423, 0, + 427, 427, 427, 427, 427, 0, 414, 423, 0, 0, + 0, 0, 0, 427, 0, 0, 0, 428, 0, 0, + 423, 424, 424, 424, 424, 424, 427, 428, 428, 428, + + 428, 428, 428, 0, 424, 436, 436, 436, 436, 436, + 424, 0, 0, 0, 0, 0, 0, 424, 436, 0, + 424, 424, 424, 424, 424, 424, 437, 0, 0, 0, + 0, 436, 0, 0, 0, 0, 437, 437, 437, 437, + 437, 437, 438, 438, 438, 438, 438, 445, 0, 0, + 446, 446, 446, 446, 446, 438, 0, 445, 445, 445, + 445, 445, 445, 446, 0, 0, 0, 447, 438, 439, + 439, 439, 439, 439, 0, 0, 446, 447, 447, 447, + 447, 447, 447, 0, 0, 0, 0, 0, 439, 0, + 0, 0, 0, 0, 452, 0, 0, 0, 439, 439, + + 439, 439, 439, 439, 452, 452, 452, 452, 452, 452, + 453, 0, 0, 0, 0, 0, 458, 0, 0, 0, + 453, 453, 453, 453, 453, 453, 458, 458, 458, 458, + 458, 458, 459, 0, 0, 0, 0, 0, 464, 0, + 0, 0, 459, 459, 459, 459, 459, 459, 464, 464, + 464, 464, 464, 464, 465, 0, 0, 0, 0, 0, + 469, 0, 0, 0, 465, 465, 465, 465, 465, 465, + 469, 469, 469, 469, 469, 469, 479, 0, 479, 479, + 479, 479, 479, 479, 479, 479, 479, 480, 480, 0, + 480, 480, 481, 0, 481, 481, 481, 481, 481, 481, + + 481, 481, 481, 482, 482, 0, 482, 482, 483, 0, + 0, 483, 483, 484, 484, 484, 484, 484, 484, 484, + 484, 484, 485, 0, 485, 485, 0, 485, 485, 486, 486, 486, 486, 486, 486, 486, 486, 486, 486, 486, - 486, 488, 488, 0, 488, 488, 489, 489, 489, 489, - 489, 489, 489, 489, 489, 489, 490, 490, 490, 490, - 490, 490, 490, 490, 490, 490, 490, 490, 490, 491, - 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, - 491, 491, 491, 493, 493, 0, 493, 493, 494, 494, - 494, 494, 494, 494, 494, 494, 494, 494, 495, 495, - 0, 495, 495, 496, 496, 496, 496, 496, 496, 496, - - 496, 496, 496, 497, 497, 497, 497, 497, 497, 497, - 497, 497, 497, 498, 498, 498, 500, 500, 500, 500, - 500, 500, 500, 500, 500, 500, 501, 501, 0, 501, - 501, 501, 501, 501, 501, 501, 501, 501, 501, 502, + 487, 487, 487, 487, 487, 487, 487, 487, 487, 488, + 488, 0, 488, 488, 489, 489, 489, 489, 489, 489, + 489, 489, 489, 489, 489, 490, 490, 490, 490, 490, + 490, 490, 490, 490, 490, 490, 490, 491, 491, 492, + 492, 492, 492, 492, 492, 492, 492, 492, 493, 493, + 0, 493, 493, 494, 494, 494, 494, 494, 494, 494, + + 494, 494, 495, 495, 0, 495, 495, 496, 496, 496, + 496, 496, 496, 496, 496, 496, 497, 497, 497, 497, + 497, 497, 497, 497, 497, 498, 498, 498, 498, 498, + 498, 498, 498, 498, 498, 498, 498, 499, 499, 499, + 499, 499, 499, 499, 499, 499, 500, 500, 500, 500, + 500, 500, 500, 500, 500, 501, 501, 501, 0, 501, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, - 502, 502, 503, 503, 503, 503, 503, 503, 503, 503, - 503, 503, 503, 503, 503, 503, 504, 504, 504, 504, - 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, - 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, - 506, 506, 506, 506, 506, 506, 506, 506, 506, 506, - - 507, 507, 507, 507, 508, 0, 0, 508, 508, 508, - 508, 508, 508, 508, 508, 508, 508, 510, 510, 510, - 510, 510, 510, 510, 510, 510, 510, 510, 510, 510, - 510, 512, 512, 512, 512, 513, 513, 513, 513, 513, - 513, 0, 513, 513, 513, 513, 513, 513, 514, 514, - 514, 514, 514, 514, 514, 514, 514, 514, 514, 514, - 514, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 518, 518, 518, 518, 519, - 519, 519, 519, 519, 519, 0, 519, 519, 519, 519, - 519, 519, 520, 0, 0, 520, 520, 520, 520, 520, - - 520, 520, 520, 520, 520, 521, 0, 0, 521, 521, - 521, 521, 521, 521, 521, 521, 521, 521, 522, 522, - 522, 522, 522, 522, 522, 522, 522, 522, 522, 522, - 522, 523, 523, 523, 523, 523, 523, 523, 523, 523, - 523, 523, 523, 523, 525, 525, 0, 525, 525, 526, - 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, - 526, 526, 528, 528, 528, 528, 529, 529, 529, 529, - 529, 529, 529, 529, 529, 529, 529, 529, 529, 530, - 0, 0, 530, 530, 530, 530, 530, 530, 530, 530, - 530, 530, 531, 531, 531, 531, 531, 531, 531, 531, - - 531, 531, 531, 531, 531, 532, 532, 532, 532, 532, - 0, 0, 532, 532, 532, 532, 532, 532, 533, 533, - 533, 533, 533, 533, 533, 533, 533, 533, 533, 533, - 533, 534, 534, 534, 534, 534, 534, 534, 534, 534, - 534, 534, 534, 534, 535, 535, 0, 535, 535, 536, - 536, 536, 536, 536, 536, 536, 536, 536, 536, 536, - 536, 536, 538, 538, 538, 538, 539, 539, 0, 539, - 539, 539, 539, 539, 539, 539, 539, 539, 539, 540, - 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, - 540, 540, 541, 541, 0, 541, 541, 541, 541, 541, - - 541, 541, 541, 541, 541, 542, 542, 542, 542, 542, - 542, 542, 542, 542, 542, 542, 542, 542, 543, 543, - 543, 543, 543, 0, 0, 543, 543, 543, 543, 543, - 543, 546, 546, 546, 546, 0, 0, 0, 0, 546, - 0, 0, 546, 546, 547, 547, 547, 547, 0, 0, - 0, 547, 547, 547, 0, 547, 547, 548, 548, 548, - 548, 548, 548, 548, 548, 548, 548, 549, 549, 549, - 549, 549, 549, 549, 549, 549, 549, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 502, 502, 503, 503, 503, 0, 503, 504, 504, 504, + 504, 0, 504, 504, 504, 504, 504, 504, 505, 505, + 505, 0, 505, 506, 0, 506, 506, 506, 506, 506, + + 506, 506, 506, 506, 507, 0, 507, 507, 507, 507, + 507, 507, 507, 507, 507, 508, 508, 508, 508, 508, + 508, 508, 508, 508, 508, 508, 509, 509, 509, 0, + 509, 510, 510, 510, 510, 510, 510, 510, 510, 510, + 510, 510, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 512, 512, 512, 0, 512, 513, 513, + 513, 0, 0, 0, 513, 0, 0, 513, 513, 514, + 514, 514, 514, 514, 514, 514, 514, 514, 515, 515, + 515, 0, 0, 515, 515, 515, 0, 515, 515, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478 + 478, 478, 478, 478, 478, 478, 478, 478, 478 } ; #line 1 "" @@ -1813,7 +878,7 @@ YY_DECL yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 6578 ); + while ( yy_base[yy_current_state] != 2399 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -2185,7 +1250,7 @@ YY_RULE_SETUP #line 110 "" ECHO; YY_BREAK -#line 2738 "" +#line 1761 "" case YY_STATE_EOF(INITIAL): case YY_END_OF_BUFFER: case YY_STATE_EOF(mediaquery): diff --git a/src/3rdparty/webkit/WebCore/html/HTMLCanvasElement.cpp b/src/3rdparty/webkit/WebCore/html/HTMLCanvasElement.cpp index fb6d9fe..76c3202 100644 --- a/src/3rdparty/webkit/WebCore/html/HTMLCanvasElement.cpp +++ b/src/3rdparty/webkit/WebCore/html/HTMLCanvasElement.cpp @@ -257,6 +257,10 @@ void HTMLCanvasElement::createImageBuffer() const return; m_imageBuffer.set(ImageBuffer::create(size, false).release()); + // The convertLogicalToDevice MaxCanvasArea check should prevent common cases + // where ImageBuffer::create() returns NULL, however we could still be low on memory. + if (!m_imageBuffer) + return; m_imageBuffer->context()->scale(FloatSize(size.width() / unscaledSize.width(), size.height() / unscaledSize.height())); m_imageBuffer->context()->setShadowsIgnoreTransforms(true); } diff --git a/src/3rdparty/webkit/WebCore/platform/qt/DragDataQt.cpp b/src/3rdparty/webkit/WebCore/platform/qt/DragDataQt.cpp index 9d95373..218f7be 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/DragDataQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/qt/DragDataQt.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -126,6 +126,10 @@ String DragData::asURL(String* title) const if (!m_platformDragData) return String(); QList urls = m_platformDragData->urls(); + + if (urls.isEmpty()) + return String(); + return urls.first().toString(); } diff --git a/src/3rdparty/webkit/WebCore/plugins/mac/PluginViewMac.cpp b/src/3rdparty/webkit/WebCore/plugins/mac/PluginViewMac.cpp index e0e178b..1d7d570 100644 --- a/src/3rdparty/webkit/WebCore/plugins/mac/PluginViewMac.cpp +++ b/src/3rdparty/webkit/WebCore/plugins/mac/PluginViewMac.cpp @@ -299,9 +299,6 @@ void PluginView::show() setSelfVisible(true); - if (isParentVisible() && platformPluginWidget()) - platformPluginWidget()->setVisible(true); - Widget::show(); } @@ -311,9 +308,6 @@ void PluginView::hide() setSelfVisible(false); - if (isParentVisible() && platformPluginWidget()) - platformPluginWidget()->setVisible(false); - Widget::hide(); } @@ -345,9 +339,6 @@ void PluginView::setParentVisible(bool visible) return; Widget::setParentVisible(visible); - - if (isSelfVisible() && platformPluginWidget()) - platformPluginWidget()->setVisible(visible); } void PluginView::setNPWindowRect(const IntRect&) diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp index 14288e2..de37383 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp @@ -1095,7 +1095,7 @@ QVariant QWebPage::inputMethodQuery(Qt::InputMethodQuery property) const This enum describes the types of action which can be performed on the web page. Actions only have an effect when they are applicable. The availability of - actions can be be determined by checking \l{QAction::}{isEnabled()} on the + actions can be be determined by checking \l{QAction::}{enabled()} on the action returned by \l{QWebPage::}{action()}. One method of enabling the text editing, cursor movement, and text selection actions -- cgit v0.12 From a93551a2e3e590400b09bc076d3a6883c162b75d Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Mon, 6 Apr 2009 16:18:40 +0200 Subject: compile for non x11 systems Reviewed-by: joerg --- tests/auto/qwidget/tst_qwidget.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index dfd0792..4b41bdb 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -8734,7 +8734,9 @@ void tst_QWidget::toplevelLineEditFocus() QLineEdit w; w.show(); +#ifdef Q_WS_X11 qt_x11_wait_for_window_manager(&w); +#endif QTest::qWait(200); QCOMPARE(QApplication::activeWindow(), &w); -- cgit v0.12 From fc0a71e4b4e4ce1e0f57c6d7be6bd9d935062fc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Mon, 6 Apr 2009 16:22:04 +0200 Subject: Update the autotest to pass again due to a previous behaviuour change. Font propagation changed slightly in some cases due to change 22d472c17167c4ca8df5678842768ab63b7baadd. However, the change is sane - its just the autotest that is not optimal. Task-number: 246215 Reviewed-by: andreas --- .../tst_qgraphicsproxywidget.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp index d1d1857..b99f111 100644 --- a/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp +++ b/tests/auto/qgraphicsproxywidget/tst_qgraphicsproxywidget.cpp @@ -1475,7 +1475,7 @@ void tst_QGraphicsProxyWidget::scrollUpdate() view.paintEventRegion = QRegion(); view.npaints = 0; QTimer::singleShot(0, widget, SLOT(updateScroll())); - QTest::qWait(500); + QTest::qWait(500); QCOMPARE(view.npaints, 2); // QRect(0, 0, 200, 12) is the first update, expanded (-2, -2, 2, 2) // QRect(0, 12, 102, 10) is the scroll update, expanded (-2, -2, 2, 2), @@ -2582,7 +2582,7 @@ void tst_QGraphicsProxyWidget::childPos() { #ifdef Q_OS_IRIX QSKIP("This test is not reliable on IRIX.", SkipAll); -#endif +#endif QFETCH(bool, moveCombo); QFETCH(QPoint, comboPos); QFETCH(QPointF, proxyPos); @@ -2797,6 +2797,7 @@ void tst_QGraphicsProxyWidget::palettePropagation() void tst_QGraphicsProxyWidget::fontPropagation() { // Construct a font with an unlikely setup + QGraphicsScene scene; QFont lineEditFont = QApplication::font("QLineEdit"); QFont font = lineEditFont; font.setPointSize(43); @@ -2805,6 +2806,7 @@ void tst_QGraphicsProxyWidget::fontPropagation() QGraphicsProxyWidget proxy; proxy.setWidget(edit); + scene.addItem(&proxy); EventSpy editSpy(edit); EventSpy proxySpy(&proxy); @@ -2825,6 +2827,7 @@ void tst_QGraphicsProxyWidget::fontPropagation() // Proxy to widget proxy.setFont(font); + QApplication::processEvents(); // wait for QEvent::Polish QVERIFY(proxy.testAttribute(Qt::WA_SetFont)); QCOMPARE(editSpy.counts[QEvent::FontChange], 3); QCOMPARE(proxySpy.counts[QEvent::FontChange], 1); @@ -2893,7 +2896,7 @@ void tst_QGraphicsProxyWidget::createProxyForChildWidget() edit2->setText("QLineEdit 2"); QCheckBox *checkbox = new QCheckBox("QCheckBox"); QVBoxLayout *vlayout = new QVBoxLayout; - + vlayout->addWidget(edit1); vlayout->addWidget(edit2); vlayout->addWidget(checkbox); @@ -2916,7 +2919,7 @@ void tst_QGraphicsProxyWidget::createProxyForChildWidget() QVERIFY(window.graphicsProxyWidget() == 0); QVERIFY(checkbox->graphicsProxyWidget() == 0); - + QGraphicsProxyWidget *windowProxy = scene.addWidget(&window); QGraphicsView view(&scene); view.show(); @@ -2946,10 +2949,10 @@ void tst_QGraphicsProxyWidget::createProxyForChildWidget() QVERIFY(boxProxy->size() == box->size()); QTest::qWait(10); - + QSignalSpy spy(checkbox, SIGNAL(clicked())); - + QTest::mousePress(view.viewport(), Qt::LeftButton, 0, view.mapFromScene(checkboxProxy->mapToScene(QPointF(8,8)))); QTRY_COMPARE(spy.count(), 0); @@ -2958,7 +2961,7 @@ void tst_QGraphicsProxyWidget::createProxyForChildWidget() QTRY_COMPARE(spy.count(), 1); - + boxProxy->setWidget(0); QVERIFY(checkbox->graphicsProxyWidget() == 0); @@ -3006,10 +3009,10 @@ void tst_QGraphicsProxyWidget::actionsContextMenu() widget->addAction(new QAction("item 2", widget)); widget->addAction(new QAction("item 3", widget)); widget->setContextMenuPolicy(Qt::ActionsContextMenu); - + QGraphicsScene scene; scene.addWidget(widget); - + QGraphicsView view(&scene); view.show(); #ifdef Q_WS_X11 -- cgit v0.12 From 003223dcfc1fa884b82085db19d4c4056bf6eaa0 Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Mon, 6 Apr 2009 16:56:36 +0200 Subject: Removed usage of NaN in SVG gradients. The previous change 6c2dd295b2ca2f9125fe072d035a3784ce748718 to remove usage of NaN in SVG gradients was incomplete. This commit should fix that. Task-number: 250146 Reviewed-by: Samuel --- src/svg/qsvghandler.cpp | 6 ++++-- src/svg/qsvgstyle.cpp | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index 18ba71c..433a3ad 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -2587,10 +2587,12 @@ static void parseBaseGradient(QSvgNode *node, if (prop && prop->type() == QSvgStyleProperty::GRADIENT) { QSvgGradientStyle *inherited = static_cast(prop); - if (!inherited->stopLink().isEmpty()) + if (!inherited->stopLink().isEmpty()) { gradProp->setStopLink(inherited->stopLink(), handler->document()); - else + } else { grad->setStops(inherited->qgradient()->stops()); + gradProp->setGradientStopsSet(inherited->gradientStopsSet()); + } matrix = inherited->qmatrix(); } else { diff --git a/src/svg/qsvgstyle.cpp b/src/svg/qsvgstyle.cpp index 4a40bed..b065395 100644 --- a/src/svg/qsvgstyle.cpp +++ b/src/svg/qsvgstyle.cpp @@ -257,7 +257,7 @@ void QSvgGradientStyle::apply(QPainter *p, const QRectF &/*rect*/, QSvgNode *, Q // If the gradient is marked as empty, insert transparent black if (!m_gradientStopsSet) { - m_gradient->setColorAt(0.0, QColor(0, 0, 0, 0)); + m_gradient->setStops(QGradientStops() << QGradientStop(0.0, QColor(0, 0, 0, 0))); m_gradientStopsSet = true; } -- cgit v0.12 From 707012f57bf3abf7ddd829e5752b4e1791250bea Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Fri, 27 Mar 2009 16:53:30 +0100 Subject: Splitted qhttpnetworkconnection* files into individual files (cherry picked from commit fd9b788bd6a99630b06cffee4c9fa9f4c06b0ef1) --- src/network/access/access.pri | 6 + src/network/access/qhttpnetworkconnection.cpp | 1119 +------------------------ src/network/access/qhttpnetworkconnection_p.h | 243 +++--- src/network/access/qhttpnetworkheader.cpp | 123 +++ src/network/access/qhttpnetworkheader_p.h | 111 +++ src/network/access/qhttpnetworkreply.cpp | 663 +++++++++++++++ src/network/access/qhttpnetworkreply_p.h | 226 +++++ src/network/access/qhttpnetworkrequest.cpp | 261 ++++++ src/network/access/qhttpnetworkrequest_p.h | 144 ++++ 9 files changed, 1659 insertions(+), 1237 deletions(-) create mode 100644 src/network/access/qhttpnetworkheader.cpp create mode 100644 src/network/access/qhttpnetworkheader_p.h create mode 100644 src/network/access/qhttpnetworkreply.cpp create mode 100644 src/network/access/qhttpnetworkreply_p.h create mode 100644 src/network/access/qhttpnetworkrequest.cpp create mode 100644 src/network/access/qhttpnetworkrequest_p.h diff --git a/src/network/access/access.pri b/src/network/access/access.pri index 6bcca0c..3269b2e 100644 --- a/src/network/access/access.pri +++ b/src/network/access/access.pri @@ -2,6 +2,9 @@ HEADERS += access/qftp.h \ access/qhttp.h \ + access/qhttpnetworkheader_p.h \ + access/qhttpnetworkrequest_p.h \ + access/qhttpnetworkreply_p.h \ access/qhttpnetworkconnection_p.h \ access/qnetworkaccessmanager.h \ access/qnetworkaccessmanager_p.h \ @@ -27,6 +30,9 @@ HEADERS += access/qftp.h \ SOURCES += access/qftp.cpp \ access/qhttp.cpp \ + access/qhttpnetworkheader.cpp \ + access/qhttpnetworkrequest.cpp \ + access/qhttpnetworkreply.cpp \ access/qhttpnetworkconnection.cpp \ access/qnetworkaccessmanager.cpp \ access/qnetworkaccesscache.cpp \ diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index edb2988..980c0e0 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -45,7 +45,7 @@ #include #include #include -#include + #include #include #include @@ -59,875 +59,9 @@ # include #endif -#ifndef QT_NO_COMPRESS -# include -static const unsigned char gz_magic[2] = {0x1f, 0x8b}; // gzip magic header -// gzip flag byte -#define HEAD_CRC 0x02 // bit 1 set: header CRC present -#define EXTRA_FIELD 0x04 // bit 2 set: extra field present -#define ORIG_NAME 0x08 // bit 3 set: original file name present -#define COMMENT 0x10 // bit 4 set: file comment present -#define RESERVED 0xE0 // bits 5..7: reserved -#define CHUNK 16384 -#endif - -QT_BEGIN_NAMESPACE - -class QHttpNetworkHeaderPrivate : public QSharedData -{ -public: - QUrl url; - QList > fields; - - QHttpNetworkHeaderPrivate(const QUrl &newUrl = QUrl()); - QHttpNetworkHeaderPrivate(const QHttpNetworkHeaderPrivate &other); - inline qint64 contentLength() const; - inline void setContentLength(qint64 length); - - inline QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const; - inline QList headerFieldValues(const QByteArray &name) const; - inline void setHeaderField(const QByteArray &name, const QByteArray &data); - bool operator==(const QHttpNetworkHeaderPrivate &other) const; - -}; - -QHttpNetworkHeaderPrivate::QHttpNetworkHeaderPrivate(const QUrl &newUrl) - :url(newUrl) -{ -} - -QHttpNetworkHeaderPrivate::QHttpNetworkHeaderPrivate(const QHttpNetworkHeaderPrivate &other) - :QSharedData(other) -{ - url = other.url; - fields = other.fields; -} - -qint64 QHttpNetworkHeaderPrivate::contentLength() const -{ - bool ok = false; - QByteArray value = headerField("content-length"); - qint64 length = value.toULongLong(&ok); - if (ok) - return length; - return -1; // the header field is not set -} - -void QHttpNetworkHeaderPrivate::setContentLength(qint64 length) -{ - setHeaderField("Content-Length", QByteArray::number(length)); -} - -QByteArray QHttpNetworkHeaderPrivate::headerField(const QByteArray &name, const QByteArray &defaultValue) const -{ - QList allValues = headerFieldValues(name); - if (allValues.isEmpty()) - return defaultValue; - - QByteArray result; - bool first = true; - foreach (QByteArray value, allValues) { - if (!first) - result += ", "; - first = false; - result += value; - } - return result; -} - -QList QHttpNetworkHeaderPrivate::headerFieldValues(const QByteArray &name) const -{ - QList result; - QByteArray lowerName = name.toLower(); - QList >::ConstIterator it = fields.constBegin(), - end = fields.constEnd(); - for ( ; it != end; ++it) - if (lowerName == it->first.toLower()) - result += it->second; - - return result; -} - -void QHttpNetworkHeaderPrivate::setHeaderField(const QByteArray &name, const QByteArray &data) -{ - QByteArray lowerName = name.toLower(); - QList >::Iterator it = fields.begin(); - while (it != fields.end()) { - if (lowerName == it->first.toLower()) - it = fields.erase(it); - else - ++it; - } - fields.append(qMakePair(name, data)); -} - -bool QHttpNetworkHeaderPrivate::operator==(const QHttpNetworkHeaderPrivate &other) const -{ - return (url == other.url); -} - -// QHttpNetworkRequestPrivate -class QHttpNetworkRequestPrivate : public QHttpNetworkHeaderPrivate -{ -public: - QHttpNetworkRequestPrivate(QHttpNetworkRequest::Operation op, - QHttpNetworkRequest::Priority pri, const QUrl &newUrl = QUrl()); - QHttpNetworkRequestPrivate(const QHttpNetworkRequestPrivate &other); - ~QHttpNetworkRequestPrivate(); - bool operator==(const QHttpNetworkRequestPrivate &other) const; - QByteArray methodName() const; - QByteArray uri(bool throughProxy) const; - - static QByteArray header(const QHttpNetworkRequest &request, bool throughProxy); - - QHttpNetworkRequest::Operation operation; - QHttpNetworkRequest::Priority priority; - mutable QIODevice *data; - bool autoDecompress; -}; - -QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(QHttpNetworkRequest::Operation op, - QHttpNetworkRequest::Priority pri, const QUrl &newUrl) - : QHttpNetworkHeaderPrivate(newUrl), operation(op), priority(pri), data(0), - autoDecompress(false) -{ -} - -QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(const QHttpNetworkRequestPrivate &other) - : QHttpNetworkHeaderPrivate(other) -{ - operation = other.operation; - priority = other.priority; - data = other.data; - autoDecompress = other.autoDecompress; -} - -QHttpNetworkRequestPrivate::~QHttpNetworkRequestPrivate() -{ -} - -bool QHttpNetworkRequestPrivate::operator==(const QHttpNetworkRequestPrivate &other) const -{ - return QHttpNetworkHeaderPrivate::operator==(other) - && (operation == other.operation) - && (data == other.data); -} - -QByteArray QHttpNetworkRequestPrivate::methodName() const -{ - QByteArray ba; - switch (operation) { - case QHttpNetworkRequest::Options: - ba += "OPTIONS"; - break; - case QHttpNetworkRequest::Get: - ba += "GET"; - break; - case QHttpNetworkRequest::Head: - ba += "HEAD"; - break; - case QHttpNetworkRequest::Post: - ba += "POST"; - break; - case QHttpNetworkRequest::Put: - ba += "PUT"; - break; - case QHttpNetworkRequest::Delete: - ba += "DELETE"; - break; - case QHttpNetworkRequest::Trace: - ba += "TRACE"; - break; - case QHttpNetworkRequest::Connect: - ba += "CONNECT"; - break; - default: - break; - } - return ba; -} - -QByteArray QHttpNetworkRequestPrivate::uri(bool throughProxy) const -{ - QUrl::FormattingOptions format(QUrl::RemoveFragment); - - // for POST, query data is send as content - if (operation == QHttpNetworkRequest::Post && !data) - format |= QUrl::RemoveQuery; - // for requests through proxy, the Request-URI contains full url - if (throughProxy) - format |= QUrl::RemoveUserInfo; - else - format |= QUrl::RemoveScheme | QUrl::RemoveAuthority; - QByteArray uri = url.toEncoded(format); - if (uri.isEmpty() || (throughProxy && url.path().isEmpty())) - uri += '/'; - return uri; -} - -QByteArray QHttpNetworkRequestPrivate::header(const QHttpNetworkRequest &request, bool throughProxy) -{ - QByteArray ba = request.d->methodName(); - QByteArray uri = request.d->uri(throughProxy); - ba += " " + uri; - - QString majorVersion = QString::number(request.majorVersion()); - QString minorVersion = QString::number(request.minorVersion()); - ba += " HTTP/" + majorVersion.toLatin1() + "." + minorVersion.toLatin1() + "\r\n"; - - QList > fields = request.header(); - QList >::const_iterator it = fields.constBegin(); - for (; it != fields.constEnd(); ++it) - ba += it->first + ": " + it->second + "\r\n"; - if (request.d->operation == QHttpNetworkRequest::Post) { - // add content type, if not set in the request - if (request.headerField("content-type").isEmpty()) - ba += "Content-Type: application/x-www-form-urlencoded\r\n"; - if (!request.d->data && request.d->url.hasQuery()) { - QByteArray query = request.d->url.encodedQuery(); - ba += "Content-Length: "+ QByteArray::number(query.size()) + "\r\n"; - ba += "\r\n"; - ba += query; - } else { - ba += "\r\n"; - } - } else { - ba += "\r\n"; - } - return ba; -} - -class QHttpNetworkReplyPrivate : public QObjectPrivate, public QHttpNetworkHeaderPrivate -{ -public: - QHttpNetworkReplyPrivate(const QUrl &newUrl = QUrl()); - ~QHttpNetworkReplyPrivate(); - qint64 readStatus(QAbstractSocket *socket); - void parseStatus(const QByteArray &status); - qint64 readHeader(QAbstractSocket *socket); - void parseHeader(const QByteArray &header); - qint64 readBody(QAbstractSocket *socket, QIODevice *out); - bool findChallenge(bool forProxy, QByteArray &challenge) const; - QAuthenticatorPrivate::Method authenticationMethod(bool isProxy) const; - void clear(); - - qint64 transferRaw(QIODevice *in, QIODevice *out, qint64 size); - qint64 transferChunked(QIODevice *in, QIODevice *out); - qint64 getChunkSize(QIODevice *in, qint64 *chunkSize); - - qint64 bytesAvailable() const; - bool isChunked(); - bool connectionCloseEnabled(); - bool isGzipped(); -#ifndef QT_NO_COMPRESS - bool gzipCheckHeader(QByteArray &content, int &pos); - int gunzipBodyPartially(QByteArray &compressed, QByteArray &inflated); -#endif - void removeAutoDecompressHeader(); - - enum ReplyState { - NothingDoneState, - ReadingStatusState, - ReadingHeaderState, - ReadingDataState, - AllDoneState - } state; - - QHttpNetworkRequest request; - int statusCode; - int majorVersion; - int minorVersion; - QString errorString; - QString reasonPhrase; - qint64 bodyLength; - qint64 contentRead; - qint64 totalProgress; - QByteArray fragment; - qint64 currentChunkSize; - qint64 currentChunkRead; - QPointer connection; - bool initInflate; - bool streamEnd; -#ifndef QT_NO_COMPRESS - z_stream inflateStrm; -#endif - bool autoDecompress; - - QByteArray responseData; // uncompressed body - QByteArray compressedData; // compressed body (temporary) - QBuffer requestDataBuffer; - bool requestIsBuffering; - bool requestIsPrepared; -}; - -QHttpNetworkReplyPrivate::QHttpNetworkReplyPrivate(const QUrl &newUrl) - : QHttpNetworkHeaderPrivate(newUrl), state(NothingDoneState), statusCode(100), - majorVersion(0), minorVersion(0), bodyLength(0), contentRead(0), totalProgress(0), - currentChunkSize(0), currentChunkRead(0), connection(0), initInflate(false), - autoDecompress(false), requestIsBuffering(false), requestIsPrepared(false) -{ -} - -QHttpNetworkReplyPrivate::~QHttpNetworkReplyPrivate() -{ -} - -void QHttpNetworkReplyPrivate::clear() -{ - state = NothingDoneState; - statusCode = 100; - bodyLength = 0; - contentRead = 0; - totalProgress = 0; - currentChunkSize = 0; - currentChunkRead = 0; - connection = 0; -#ifndef QT_NO_COMPRESS - if (initInflate) - inflateEnd(&inflateStrm); -#endif - initInflate = false; - streamEnd = false; - autoDecompress = false; - fields.clear(); -} - -// QHttpNetworkReplyPrivate -qint64 QHttpNetworkReplyPrivate::bytesAvailable() const -{ - return (state != ReadingDataState ? 0 : fragment.size()); -} - -bool QHttpNetworkReplyPrivate::isGzipped() -{ - QByteArray encoding = headerField("content-encoding"); - return encoding.toLower() == "gzip"; -} - -void QHttpNetworkReplyPrivate::removeAutoDecompressHeader() -{ - // The header "Content-Encoding = gzip" is retained. - // Content-Length is removed since the actual one send by the server is for compressed data - QByteArray name("content-length"); - QByteArray lowerName = name.toLower(); - QList >::Iterator it = fields.begin(), - end = fields.end(); - while (it != end) { - if (name == it->first.toLower()) { - fields.erase(it); - break; - } - ++it; - } - -} - -bool QHttpNetworkReplyPrivate::findChallenge(bool forProxy, QByteArray &challenge) const -{ - challenge.clear(); - // find out the type of authentication protocol requested. - QByteArray header = forProxy ? "proxy-authenticate" : "www-authenticate"; - // pick the best protocol (has to match parsing in QAuthenticatorPrivate) - QList challenges = headerFieldValues(header); - for (int i = 0; i challenges = headerFieldValues(header); - for (int i = 0; i maxPos) - return ret; - if ((flags & EXTRA_FIELD) && ((pos+2) <= maxPos)) { // skip the extra field - unsigned len = (unsigned)body[++pos]; - len += ((unsigned)body[++pos])<<8; - pos += len; - if (pos > maxPos) - return ret; - } - if ((flags & ORIG_NAME) != 0) { // skip the original file name - while(++pos <= maxPos && body[pos]) {} - } - if ((flags & COMMENT) != 0) { // skip the .gz file comment - while(++pos <= maxPos && body[pos]) {} - } - if ((flags & HEAD_CRC) != 0) { // skip the header crc - pos += 2; - if (pos > maxPos) - return ret; - } - ret = (pos < maxPos); // return failed, if no more bytes left - return ret; -} - -int QHttpNetworkReplyPrivate::gunzipBodyPartially(QByteArray &compressed, QByteArray &inflated) -{ - int ret = Z_DATA_ERROR; - unsigned have; - unsigned char out[CHUNK]; - int pos = -1; - - if (!initInflate) { - // check the header - if (!gzipCheckHeader(compressed, pos)) - return ret; - // allocate inflate state - inflateStrm.zalloc = Z_NULL; - inflateStrm.zfree = Z_NULL; - inflateStrm.opaque = Z_NULL; - inflateStrm.avail_in = 0; - inflateStrm.next_in = Z_NULL; - ret = inflateInit2(&inflateStrm, -MAX_WBITS); - if (ret != Z_OK) - return ret; - initInflate = true; - streamEnd = false; - } - - //remove the header. - compressed.remove(0, pos+1); - // expand until deflate stream ends - inflateStrm.next_in = (unsigned char *)compressed.data(); - inflateStrm.avail_in = compressed.size(); - do { - inflateStrm.avail_out = sizeof(out); - inflateStrm.next_out = out; - ret = inflate(&inflateStrm, Z_NO_FLUSH); - switch (ret) { - case Z_NEED_DICT: - ret = Z_DATA_ERROR; - // and fall through - case Z_DATA_ERROR: - case Z_MEM_ERROR: - inflateEnd(&inflateStrm); - initInflate = false; - return ret; - } - have = sizeof(out) - inflateStrm.avail_out; - inflated.append(QByteArray((const char *)out, have)); - } while (inflateStrm.avail_out == 0); - // clean up and return - if (ret <= Z_ERRNO || ret == Z_STREAM_END) { - inflateEnd(&inflateStrm); - initInflate = false; - } - streamEnd = (ret == Z_STREAM_END); - return ret; -} -#endif - -qint64 QHttpNetworkReplyPrivate::readStatus(QAbstractSocket *socket) -{ - qint64 bytes = 0; - char c; - - while (socket->bytesAvailable()) { - // allow both CRLF & LF (only) line endings - if (socket->peek(&c, 1) == 1 && c == '\n') { - bytes += socket->read(&c, 1); // read the "n" - // remove the CR at the end - if (fragment.endsWith('\r')) { - fragment.truncate(fragment.length()-1); - } - parseStatus(fragment); - state = ReadingHeaderState; - fragment.clear(); // next fragment - break; - } else { - c = 0; - bytes += socket->read(&c, 1); - fragment.append(c); - } - } - return bytes; -} - -void QHttpNetworkReplyPrivate::parseStatus(const QByteArray &status) -{ - const QByteArrayMatcher sp(" "); - int i = sp.indexIn(status); - const QByteArray version = status.mid(0, i); - int j = sp.indexIn(status, i + 1); - const QByteArray code = status.mid(i + 1, j - i - 1); - const QByteArray reason = status.mid(j + 1, status.count() - j); - - const QByteArrayMatcher slash("/"); - int k = slash.indexIn(version); - const QByteArrayMatcher dot("."); - int l = dot.indexIn(version, k); - const QByteArray major = version.mid(k + 1, l - k - 1); - const QByteArray minor = version.mid(l + 1, version.count() - l); - - majorVersion = QString::fromAscii(major.constData()).toInt(); - minorVersion = QString::fromAscii(minor.constData()).toInt(); - statusCode = QString::fromAscii(code.constData()).toInt(); - reasonPhrase = QString::fromAscii(reason.constData()); -} - -qint64 QHttpNetworkReplyPrivate::readHeader(QAbstractSocket *socket) -{ - qint64 bytes = 0; - char crlfcrlf[5]; - crlfcrlf[4] = '\0'; - char c = 0; - bool allHeaders = false; - while (!allHeaders && socket->bytesAvailable()) { - if (socket->peek(&c, 1) == 1 && c == '\n') { - // check for possible header endings. As per HTTP rfc, - // the header endings will be marked by CRLFCRLF. But - // we will allow CRLFLF, LFLF & CRLFCRLF - if (fragment.endsWith("\n\r") || fragment.endsWith('\n')) - allHeaders = true; - } - bytes += socket->read(&c, 1); - fragment.append(c); - } - // we received all headers now parse them - if (allHeaders) { - parseHeader(fragment); - state = ReadingDataState; - fragment.clear(); // next fragment - bodyLength = contentLength(); // cache the length - } - return bytes; -} - -void QHttpNetworkReplyPrivate::parseHeader(const QByteArray &header) -{ - // see rfc2616, sec 4 for information about HTTP/1.1 headers. - // allows relaxed parsing here, accepts both CRLF & LF line endings - const QByteArrayMatcher lf("\n"); - const QByteArrayMatcher colon(":"); - int i = 0; - while (i < header.count()) { - int j = colon.indexIn(header, i); // field-name - if (j == -1) - break; - const QByteArray field = header.mid(i, j - i).trimmed(); - j++; - // any number of LWS is allowed before and after the value - QByteArray value; - do { - i = lf.indexIn(header, j); - if (i == -1) - break; - if (!value.isEmpty()) - value += ' '; - // check if we have CRLF or only LF - bool hasCR = (i && header[i-1] == '\r'); - int length = i -(hasCR ? 1: 0) - j; - value += header.mid(j, length).trimmed(); - j = ++i; - } while (i < header.count() && (header.at(i) == ' ' || header.at(i) == '\t')); - if (i == -1) - break; // something is wrong - - fields.append(qMakePair(field, value)); - } -} - -bool QHttpNetworkReplyPrivate::isChunked() -{ - return headerField("transfer-encoding").toLower().contains("chunked"); -} - -bool QHttpNetworkReplyPrivate::connectionCloseEnabled() -{ - return (headerField("connection").toLower().contains("close") || - headerField("proxy-connection").toLower().contains("close")); -} - -qint64 QHttpNetworkReplyPrivate::readBody(QAbstractSocket *socket, QIODevice *out) -{ - qint64 bytes = 0; - if (isChunked()) { - bytes += transferChunked(socket, out); // chunked transfer encoding (rfc 2616, sec 3.6) - } else if (bodyLength > 0) { // we have a Content-Length - bytes += transferRaw(socket, out, bodyLength - contentRead); - if (contentRead + bytes == bodyLength) - state = AllDoneState; - } else { - bytes += transferRaw(socket, out, socket->bytesAvailable()); - } - if (state == AllDoneState) - socket->readAll(); // Read the rest to clean (CRLF) - contentRead += bytes; - return bytes; -} - -qint64 QHttpNetworkReplyPrivate::transferRaw(QIODevice *in, QIODevice *out, qint64 size) -{ - qint64 bytes = 0; - Q_ASSERT(in); - Q_ASSERT(out); - - int toBeRead = qMin(128*1024, qMin(size, in->bytesAvailable())); - QByteArray raw(toBeRead, 0); - while (size > 0) { - qint64 read = in->read(raw.data(), raw.size()); - if (read == 0) - return bytes; - // ### error checking here - qint64 written = out->write(raw.data(), read); - if (written == 0) - return bytes; - if (read != written) - qDebug() << "### read" << read << "written" << written; - bytes += read; - size -= read; - out->waitForBytesWritten(-1); // throttle - } - return bytes; - -} - -qint64 QHttpNetworkReplyPrivate::transferChunked(QIODevice *in, QIODevice *out) -{ - qint64 bytes = 0; - while (in->bytesAvailable()) { // while we can read from input - // if we are done with the current chunk, get the size of the new chunk - if (currentChunkRead >= currentChunkSize) { - currentChunkSize = 0; - currentChunkRead = 0; - if (bytes) { - char crlf[2]; - bytes += in->read(crlf, 2); // read the "\r\n" after the chunk - } - bytes += getChunkSize(in, ¤tChunkSize); - if (currentChunkSize == -1) - break; - } - // if the chunk size is 0, end of the stream - if (currentChunkSize == 0) { - state = AllDoneState; - break; - } - // otherwise, read data - qint64 readSize = qMin(in->bytesAvailable(), currentChunkSize - currentChunkRead); - QByteArray buffer(readSize, 0); - qint64 read = in->read(buffer.data(), readSize); - bytes += read; - currentChunkRead += read; - qint64 written = out->write(buffer); - Q_UNUSED(written); // Avoid compile warning when building release - Q_ASSERT(read == written); - // ### error checking here - out->waitForBytesWritten(-1); - } - return bytes; -} - -qint64 QHttpNetworkReplyPrivate::getChunkSize(QIODevice *in, qint64 *chunkSize) -{ - qint64 bytes = 0; - char crlf[2]; - *chunkSize = -1; - int bytesAvailable = in->bytesAvailable(); - while (bytesAvailable > bytes) { - qint64 sniffedBytes = in->peek(crlf, 2); - int fragmentSize = fragment.size(); - // check the next two bytes for a "\r\n", skip blank lines - if ((fragmentSize && sniffedBytes == 2 && crlf[0] == '\r' && crlf[1] == '\n') - ||(fragmentSize > 1 && fragment.endsWith('\r') && crlf[0] == '\n')) - { - bytes += in->read(crlf, 1); // read the \r or \n - if (crlf[0] == '\r') - bytes += in->read(crlf, 1); // read the \n - bool ok = false; - // ignore the chunk-extension - fragment = fragment.mid(0, fragment.indexOf(';')).trimmed(); - *chunkSize = fragment.toLong(&ok, 16); - fragment.clear(); - break; // size done - } else { - // read the fragment to the buffer - char c = 0; - bytes += in->read(&c, 1); - fragment.append(c); - } - } - return bytes; -} - -// QHttpNetworkConnectionPrivate - -typedef QPair HttpMessagePair; - -class QHttpNetworkConnectionPrivate : public QObjectPrivate -{ - Q_DECLARE_PUBLIC(QHttpNetworkConnection) -public: - QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt); - ~QHttpNetworkConnectionPrivate(); - void init(); - void connectSignals(QAbstractSocket *socket); - - enum SocketState { - IdleState = 0, // ready to send request - ConnectingState = 1, // connecting to host - WritingState = 2, // writing the data - WaitingState = 4, // waiting for reply - ReadingState = 8, // reading the reply - Wait4AuthState = 0x10, // blocked for send till the current authentication slot is done - BusyState = (ConnectingState|WritingState|WaitingState|ReadingState|Wait4AuthState) - }; - - enum { ChunkSize = 4096 }; - - int indexOf(QAbstractSocket *socket) const; - bool isSocketBusy(QAbstractSocket *socket) const; - bool isSocketWriting(QAbstractSocket *socket) const; - bool isSocketWaiting(QAbstractSocket *socket) const; - bool isSocketReading(QAbstractSocket *socket) const; - - QHttpNetworkReply *queueRequest(const QHttpNetworkRequest &request); - void unqueueRequest(QAbstractSocket *socket); - void prepareRequest(HttpMessagePair &request); - bool sendRequest(QAbstractSocket *socket); - void receiveReply(QAbstractSocket *socket, QHttpNetworkReply *reply); - void resendCurrentRequest(QAbstractSocket *socket); - void closeChannel(int channel); - void copyCredentials(int fromChannel, QAuthenticator *auth, bool isProxy); - - // private slots - void _q_bytesWritten(qint64 bytes); // proceed sending - void _q_readyRead(); // pending data to read - void _q_disconnected(); // disconnected from host - void _q_startNextRequest(); // send the next request from the queue - void _q_restartPendingRequest(); // send the currently blocked request - void _q_connected(); // start sending request - void _q_error(QAbstractSocket::SocketError); // error from socket -#ifndef QT_NO_NETWORKPROXY - void _q_proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth); // from transparent proxy -#endif - void _q_dataReadyReadNoBuffer(); - void _q_dataReadyReadBuffer(); - - void createAuthorization(QAbstractSocket *socket, QHttpNetworkRequest &request); - bool ensureConnection(QAbstractSocket *socket); - QString errorDetail(QNetworkReply::NetworkError errorCode, QAbstractSocket *socket); - void eraseData(QHttpNetworkReply *reply); -#ifndef QT_NO_COMPRESS - bool expand(QAbstractSocket *socket, QHttpNetworkReply *reply, bool dataComplete); -#endif - void bufferData(HttpMessagePair &request); - void removeReply(QHttpNetworkReply *reply); - - QString hostName; - quint16 port; - bool encrypt; - - struct Channel { - QAbstractSocket *socket; - SocketState state; - QHttpNetworkRequest request; // current request - QHttpNetworkReply *reply; // current reply for this request - qint64 written; - qint64 bytesTotal; - bool resendCurrent; - int lastStatus; // last status received on this channel - bool pendingEncrypt; // for https (send after encrypted) - int reconnectAttempts; // maximum 2 reconnection attempts - QAuthenticatorPrivate::Method authMehtod; - QAuthenticatorPrivate::Method proxyAuthMehtod; - QAuthenticator authenticator; - QAuthenticator proxyAuthenticator; -#ifndef QT_NO_OPENSSL - bool ignoreSSLErrors; -#endif - Channel() :state(IdleState), reply(0), written(0), bytesTotal(0), resendCurrent(false), reconnectAttempts(2), - authMehtod(QAuthenticatorPrivate::None), proxyAuthMehtod(QAuthenticatorPrivate::None) -#ifndef QT_NO_OPENSSL - , ignoreSSLErrors(false) -#endif - {} - }; - static const int channelCount; - Channel channels[2]; // maximum of 2 socket connections to the server - bool pendingAuthSignal; // there is an incomplete authentication signal - bool pendingProxyAuthSignal; // there is an incomplete proxy authentication signal - - void appendData(QHttpNetworkReply &reply, const QByteArray &fragment, bool compressed); - qint64 bytesAvailable(const QHttpNetworkReply &reply, bool compressed = false) const; - qint64 read(QHttpNetworkReply &reply, QByteArray &data, qint64 maxSize, bool compressed); - void emitReplyError(QAbstractSocket *socket, QHttpNetworkReply *reply, QNetworkReply::NetworkError errorCode); - bool handleAuthenticateChallenge(QAbstractSocket *socket, QHttpNetworkReply *reply, bool isProxy, bool &resend); - void allDone(QAbstractSocket *socket, QHttpNetworkReply *reply); - void handleStatus(QAbstractSocket *socket, QHttpNetworkReply *reply); - inline bool emitSignals(QHttpNetworkReply *reply); - inline bool expectContent(QHttpNetworkReply *reply); - -#ifndef QT_NO_OPENSSL - void _q_encrypted(); // start sending request (https) - void _q_sslErrors(const QList &errors); // ssl errors from the socket - QSslConfiguration sslConfiguration(const QHttpNetworkReply &reply) const; -#endif -#ifndef QT_NO_NETWORKPROXY - QNetworkProxy networkProxy; -#endif - //The request queues - QList highPriorityQueue; - QList lowPriorityQueue; -}; +QT_BEGIN_NAMESPACE const int QHttpNetworkConnectionPrivate::channelCount = 2; @@ -2150,235 +1284,6 @@ QNetworkProxy QHttpNetworkConnection::transparentProxy() const } #endif -// QHttpNetworkRequest - -QHttpNetworkRequest::QHttpNetworkRequest(const QUrl &url, Operation operation, Priority priority) - : d(new QHttpNetworkRequestPrivate(operation, priority, url)) -{ -} - -QHttpNetworkRequest::QHttpNetworkRequest(const QHttpNetworkRequest &other) - : QHttpNetworkHeader(other), d(other.d) -{ -} - -QHttpNetworkRequest::~QHttpNetworkRequest() -{ -} - -QUrl QHttpNetworkRequest::url() const -{ - return d->url; -} -void QHttpNetworkRequest::setUrl(const QUrl &url) -{ - d->url = url; -} - -qint64 QHttpNetworkRequest::contentLength() const -{ - return d->contentLength(); -} - -void QHttpNetworkRequest::setContentLength(qint64 length) -{ - d->setContentLength(length); -} - -QList > QHttpNetworkRequest::header() const -{ - return d->fields; -} - -QByteArray QHttpNetworkRequest::headerField(const QByteArray &name, const QByteArray &defaultValue) const -{ - return d->headerField(name, defaultValue); -} - -void QHttpNetworkRequest::setHeaderField(const QByteArray &name, const QByteArray &data) -{ - d->setHeaderField(name, data); -} - -QHttpNetworkRequest &QHttpNetworkRequest::operator=(const QHttpNetworkRequest &other) -{ - d = other.d; - return *this; -} - -bool QHttpNetworkRequest::operator==(const QHttpNetworkRequest &other) const -{ - return d->operator==(*other.d); -} - -QHttpNetworkRequest::Operation QHttpNetworkRequest::operation() const -{ - return d->operation; -} - -void QHttpNetworkRequest::setOperation(Operation operation) -{ - d->operation = operation; -} - -QHttpNetworkRequest::Priority QHttpNetworkRequest::priority() const -{ - return d->priority; -} - -void QHttpNetworkRequest::setPriority(Priority priority) -{ - d->priority = priority; -} - -QIODevice *QHttpNetworkRequest::data() const -{ - return d->data; -} - -void QHttpNetworkRequest::setData(QIODevice *data) -{ - d->data = data; -} - -int QHttpNetworkRequest::majorVersion() const -{ - return 1; -} - -int QHttpNetworkRequest::minorVersion() const -{ - return 1; -} - -// QHttpNetworkReply - -QHttpNetworkReply::QHttpNetworkReply(const QUrl &url, QObject *parent) - : QObject(*new QHttpNetworkReplyPrivate(url), parent) -{ -} - -QHttpNetworkReply::~QHttpNetworkReply() -{ - Q_D(QHttpNetworkReply); - if (d->connection) { - d->connection->d_func()->removeReply(this); - } -} - -QUrl QHttpNetworkReply::url() const -{ - return d_func()->url; -} -void QHttpNetworkReply::setUrl(const QUrl &url) -{ - Q_D(QHttpNetworkReply); - d->url = url; -} - -qint64 QHttpNetworkReply::contentLength() const -{ - return d_func()->contentLength(); -} - -void QHttpNetworkReply::setContentLength(qint64 length) -{ - Q_D(QHttpNetworkReply); - d->setContentLength(length); -} - -QList > QHttpNetworkReply::header() const -{ - return d_func()->fields; -} - -QByteArray QHttpNetworkReply::headerField(const QByteArray &name, const QByteArray &defaultValue) const -{ - return d_func()->headerField(name, defaultValue); -} - -void QHttpNetworkReply::setHeaderField(const QByteArray &name, const QByteArray &data) -{ - Q_D(QHttpNetworkReply); - d->setHeaderField(name, data); -} - -void QHttpNetworkReply::parseHeader(const QByteArray &header) -{ - Q_D(QHttpNetworkReply); - d->parseHeader(header); -} - -QHttpNetworkRequest QHttpNetworkReply::request() const -{ - return d_func()->request; -} - -void QHttpNetworkReply::setRequest(const QHttpNetworkRequest &request) -{ - Q_D(QHttpNetworkReply); - d->request = request; -} - -int QHttpNetworkReply::statusCode() const -{ - return d_func()->statusCode; -} - -void QHttpNetworkReply::setStatusCode(int code) -{ - Q_D(QHttpNetworkReply); - d->statusCode = code; -} - -QString QHttpNetworkReply::errorString() const -{ - return d_func()->errorString; -} - -QString QHttpNetworkReply::reasonPhrase() const -{ - return d_func()->reasonPhrase; -} - -void QHttpNetworkReply::setErrorString(const QString &error) -{ - Q_D(QHttpNetworkReply); - d->errorString = error; -} - -int QHttpNetworkReply::majorVersion() const -{ - return d_func()->majorVersion; -} - -int QHttpNetworkReply::minorVersion() const -{ - return d_func()->minorVersion; -} - -qint64 QHttpNetworkReply::bytesAvailable() const -{ - Q_D(const QHttpNetworkReply); - if (d->connection) - return d->connection->d_func()->bytesAvailable(*this); - else - return -1; -} - -QByteArray QHttpNetworkReply::read(qint64 maxSize) -{ - Q_D(QHttpNetworkReply); - QByteArray data; - if (d->connection) - d->connection->d_func()->read(*this, data, maxSize, false); - return data; -} - -bool QHttpNetworkReply::isFinished() const -{ - return d_func()->state == QHttpNetworkReplyPrivate::AllDoneState; -} // SSL support below #ifndef QT_NO_OPENSSL @@ -2433,27 +1338,7 @@ void QHttpNetworkConnection::ignoreSslErrors(int channel) } } -QSslConfiguration QHttpNetworkReply::sslConfiguration() const -{ - Q_D(const QHttpNetworkReply); - if (d->connection) - return d->connection->d_func()->sslConfiguration(*this); - return QSslConfiguration(); -} -void QHttpNetworkReply::setSslConfiguration(const QSslConfiguration &config) -{ - Q_D(QHttpNetworkReply); - if (d->connection) - d->connection->setSslConfiguration(config); -} - -void QHttpNetworkReply::ignoreSslErrors() -{ - Q_D(QHttpNetworkReply); - if (d->connection) - d->connection->ignoreSslErrors(); -} #endif //QT_NO_OPENSSL diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h index 8dbcb3d..09bd459 100644 --- a/src/network/access/qhttpnetworkconnection_p.h +++ b/src/network/access/qhttpnetworkconnection_p.h @@ -56,6 +56,16 @@ #include #include +#include +#include +#include +#include + +#include +#include +#include + + #ifndef QT_NO_HTTP #ifndef QT_NO_OPENSSL @@ -145,144 +155,137 @@ private: #endif }; -class Q_AUTOTEST_EXPORT QHttpNetworkHeader -{ -public: - virtual ~QHttpNetworkHeader() {}; - virtual QUrl url() const = 0; - virtual void setUrl(const QUrl &url) = 0; - virtual int majorVersion() const = 0; - virtual int minorVersion() const = 0; - virtual qint64 contentLength() const = 0; - virtual void setContentLength(qint64 length) = 0; - virtual QList > header() const = 0; - virtual QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const = 0; - virtual void setHeaderField(const QByteArray &name, const QByteArray &data) = 0; -}; +// private classes +typedef QPair HttpMessagePair; + -class QHttpNetworkRequestPrivate; -class Q_AUTOTEST_EXPORT QHttpNetworkRequest: public QHttpNetworkHeader +class QHttpNetworkConnectionPrivate : public QObjectPrivate { + Q_DECLARE_PUBLIC(QHttpNetworkConnection) public: - enum Operation { - Options, - Get, - Head, - Post, - Put, - Delete, - Trace, - Connect + QHttpNetworkConnectionPrivate(const QString &hostName, quint16 port, bool encrypt); + ~QHttpNetworkConnectionPrivate(); + void init(); + void connectSignals(QAbstractSocket *socket); + + enum SocketState { + IdleState = 0, // ready to send request + ConnectingState = 1, // connecting to host + WritingState = 2, // writing the data + WaitingState = 4, // waiting for reply + ReadingState = 8, // reading the reply + Wait4AuthState = 0x10, // blocked for send till the current authentication slot is done + BusyState = (ConnectingState|WritingState|WaitingState|ReadingState|Wait4AuthState) }; - enum Priority { - HighPriority, - NormalPriority, - LowPriority + enum { ChunkSize = 4096 }; + + int indexOf(QAbstractSocket *socket) const; + bool isSocketBusy(QAbstractSocket *socket) const; + bool isSocketWriting(QAbstractSocket *socket) const; + bool isSocketWaiting(QAbstractSocket *socket) const; + bool isSocketReading(QAbstractSocket *socket) const; + + QHttpNetworkReply *queueRequest(const QHttpNetworkRequest &request); + void unqueueRequest(QAbstractSocket *socket); + void prepareRequest(HttpMessagePair &request); + bool sendRequest(QAbstractSocket *socket); + void receiveReply(QAbstractSocket *socket, QHttpNetworkReply *reply); + void resendCurrentRequest(QAbstractSocket *socket); + void closeChannel(int channel); + void copyCredentials(int fromChannel, QAuthenticator *auth, bool isProxy); + + // private slots + void _q_bytesWritten(qint64 bytes); // proceed sending + void _q_readyRead(); // pending data to read + void _q_disconnected(); // disconnected from host + void _q_startNextRequest(); // send the next request from the queue + void _q_restartPendingRequest(); // send the currently blocked request + void _q_connected(); // start sending request + void _q_error(QAbstractSocket::SocketError); // error from socket +#ifndef QT_NO_NETWORKPROXY + void _q_proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth); // from transparent proxy +#endif + void _q_dataReadyReadNoBuffer(); + void _q_dataReadyReadBuffer(); + + void createAuthorization(QAbstractSocket *socket, QHttpNetworkRequest &request); + bool ensureConnection(QAbstractSocket *socket); + QString errorDetail(QNetworkReply::NetworkError errorCode, QAbstractSocket *socket); + void eraseData(QHttpNetworkReply *reply); +#ifndef QT_NO_COMPRESS + bool expand(QAbstractSocket *socket, QHttpNetworkReply *reply, bool dataComplete); +#endif + void bufferData(HttpMessagePair &request); + void removeReply(QHttpNetworkReply *reply); + + QString hostName; + quint16 port; + bool encrypt; + + struct Channel { + QAbstractSocket *socket; + SocketState state; + QHttpNetworkRequest request; // current request + QHttpNetworkReply *reply; // current reply for this request + qint64 written; + qint64 bytesTotal; + bool resendCurrent; + int lastStatus; // last status received on this channel + bool pendingEncrypt; // for https (send after encrypted) + int reconnectAttempts; // maximum 2 reconnection attempts + QAuthenticatorPrivate::Method authMehtod; + QAuthenticatorPrivate::Method proxyAuthMehtod; + QAuthenticator authenticator; + QAuthenticator proxyAuthenticator; +#ifndef QT_NO_OPENSSL + bool ignoreSSLErrors; +#endif + Channel() :state(IdleState), reply(0), written(0), bytesTotal(0), resendCurrent(false), reconnectAttempts(2), + authMehtod(QAuthenticatorPrivate::None), proxyAuthMehtod(QAuthenticatorPrivate::None) +#ifndef QT_NO_OPENSSL + , ignoreSSLErrors(false) +#endif + {} }; - - QHttpNetworkRequest(const QUrl &url = QUrl(), Operation operation = Get, Priority priority = NormalPriority); - QHttpNetworkRequest(const QHttpNetworkRequest &other); - virtual ~QHttpNetworkRequest(); - QHttpNetworkRequest &operator=(const QHttpNetworkRequest &other); - bool operator==(const QHttpNetworkRequest &other) const; - - QUrl url() const; - void setUrl(const QUrl &url); - - int majorVersion() const; - int minorVersion() const; - - qint64 contentLength() const; - void setContentLength(qint64 length); - - QList > header() const; - QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const; - void setHeaderField(const QByteArray &name, const QByteArray &data); - - Operation operation() const; - void setOperation(Operation operation); - - Priority priority() const; - void setPriority(Priority priority); - - QIODevice *data() const; - void setData(QIODevice *data); - -private: - QSharedDataPointer d; - friend class QHttpNetworkRequestPrivate; - friend class QHttpNetworkConnectionPrivate; -}; - -class QHttpNetworkReplyPrivate; -class Q_AUTOTEST_EXPORT QHttpNetworkReply : public QObject, public QHttpNetworkHeader -{ - Q_OBJECT -public: - - explicit QHttpNetworkReply(const QUrl &url = QUrl(), QObject *parent = 0); - virtual ~QHttpNetworkReply(); - - QUrl url() const; - void setUrl(const QUrl &url); - - int majorVersion() const; - int minorVersion() const; - - qint64 contentLength() const; - void setContentLength(qint64 length); - - QList > header() const; - QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const; - void setHeaderField(const QByteArray &name, const QByteArray &data); - void parseHeader(const QByteArray &header); // mainly for testing - - QHttpNetworkRequest request() const; - void setRequest(const QHttpNetworkRequest &request); - - int statusCode() const; - void setStatusCode(int code); - - QString errorString() const; - void setErrorString(const QString &error); - - QString reasonPhrase() const; - - qint64 bytesAvailable() const; - QByteArray read(qint64 maxSize = -1); - - bool isFinished() const; + static const int channelCount; + Channel channels[2]; // maximum of 2 socket connections to the server + bool pendingAuthSignal; // there is an incomplete authentication signal + bool pendingProxyAuthSignal; // there is an incomplete proxy authentication signal + + void appendData(QHttpNetworkReply &reply, const QByteArray &fragment, bool compressed); + qint64 bytesAvailable(const QHttpNetworkReply &reply, bool compressed = false) const; + qint64 read(QHttpNetworkReply &reply, QByteArray &data, qint64 maxSize, bool compressed); + void emitReplyError(QAbstractSocket *socket, QHttpNetworkReply *reply, QNetworkReply::NetworkError errorCode); + bool handleAuthenticateChallenge(QAbstractSocket *socket, QHttpNetworkReply *reply, bool isProxy, bool &resend); + void allDone(QAbstractSocket *socket, QHttpNetworkReply *reply); + void handleStatus(QAbstractSocket *socket, QHttpNetworkReply *reply); + inline bool emitSignals(QHttpNetworkReply *reply); + inline bool expectContent(QHttpNetworkReply *reply); #ifndef QT_NO_OPENSSL - QSslConfiguration sslConfiguration() const; - void setSslConfiguration(const QSslConfiguration &config); - void ignoreSslErrors(); - -Q_SIGNALS: - void sslErrors(const QList &errors); + void _q_encrypted(); // start sending request (https) + void _q_sslErrors(const QList &errors); // ssl errors from the socket + QSslConfiguration sslConfiguration(const QHttpNetworkReply &reply) const; #endif -Q_SIGNALS: - void readyRead(); - void finished(); - void finishedWithError(QNetworkReply::NetworkError errorCode, const QString &detail = QString()); - void headerChanged(); - void dataReadProgress(int done, int total); - void dataSendProgress(int done, int total); +#ifndef QT_NO_NETWORKPROXY + QNetworkProxy networkProxy; +#endif -private: - Q_DECLARE_PRIVATE(QHttpNetworkReply) - friend class QHttpNetworkConnection; - friend class QHttpNetworkConnectionPrivate; + //The request queues + QList highPriorityQueue; + QList lowPriorityQueue; }; + + QT_END_NAMESPACE -Q_DECLARE_METATYPE(QHttpNetworkRequest) +//Q_DECLARE_METATYPE(QHttpNetworkRequest) //Q_DECLARE_METATYPE(QHttpNetworkReply) #endif // QT_NO_HTTP diff --git a/src/network/access/qhttpnetworkheader.cpp b/src/network/access/qhttpnetworkheader.cpp new file mode 100644 index 0000000..6f7f6f7 --- /dev/null +++ b/src/network/access/qhttpnetworkheader.cpp @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qhttpnetworkheader_p.h" + + +QT_BEGIN_NAMESPACE + +QHttpNetworkHeaderPrivate::QHttpNetworkHeaderPrivate(const QUrl &newUrl) + :url(newUrl) +{ +} + +QHttpNetworkHeaderPrivate::QHttpNetworkHeaderPrivate(const QHttpNetworkHeaderPrivate &other) + :QSharedData(other) +{ + url = other.url; + fields = other.fields; +} + +qint64 QHttpNetworkHeaderPrivate::contentLength() const +{ + bool ok = false; + QByteArray value = headerField("content-length"); + qint64 length = value.toULongLong(&ok); + if (ok) + return length; + return -1; // the header field is not set +} + +void QHttpNetworkHeaderPrivate::setContentLength(qint64 length) +{ + setHeaderField("Content-Length", QByteArray::number(length)); +} + +QByteArray QHttpNetworkHeaderPrivate::headerField(const QByteArray &name, const QByteArray &defaultValue) const +{ + QList allValues = headerFieldValues(name); + if (allValues.isEmpty()) + return defaultValue; + + QByteArray result; + bool first = true; + foreach (QByteArray value, allValues) { + if (!first) + result += ", "; + first = false; + result += value; + } + return result; +} + +QList QHttpNetworkHeaderPrivate::headerFieldValues(const QByteArray &name) const +{ + QList result; + QByteArray lowerName = name.toLower(); + QList >::ConstIterator it = fields.constBegin(), + end = fields.constEnd(); + for ( ; it != end; ++it) + if (lowerName == it->first.toLower()) + result += it->second; + + return result; +} + +void QHttpNetworkHeaderPrivate::setHeaderField(const QByteArray &name, const QByteArray &data) +{ + QByteArray lowerName = name.toLower(); + QList >::Iterator it = fields.begin(); + while (it != fields.end()) { + if (lowerName == it->first.toLower()) + it = fields.erase(it); + else + ++it; + } + fields.append(qMakePair(name, data)); +} + +bool QHttpNetworkHeaderPrivate::operator==(const QHttpNetworkHeaderPrivate &other) const +{ + return (url == other.url); +} + + +QT_END_NAMESPACE diff --git a/src/network/access/qhttpnetworkheader_p.h b/src/network/access/qhttpnetworkheader_p.h new file mode 100644 index 0000000..ce538c8 --- /dev/null +++ b/src/network/access/qhttpnetworkheader_p.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QHTTPNETWORKHEADER_H +#define QHTTPNETWORKHEADER_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of the Network Access API. This header file may change from +// version to version without notice, or even be removed. +// +// We mean it. +// +#ifndef QT_NO_HTTP + +QT_BEGIN_NAMESPACE + +#include +#include + +class Q_AUTOTEST_EXPORT QHttpNetworkHeader +{ +public: + virtual ~QHttpNetworkHeader() {}; + virtual QUrl url() const = 0; + virtual void setUrl(const QUrl &url) = 0; + + virtual int majorVersion() const = 0; + virtual int minorVersion() const = 0; + + virtual qint64 contentLength() const = 0; + virtual void setContentLength(qint64 length) = 0; + + virtual QList > header() const = 0; + virtual QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const = 0; + virtual void setHeaderField(const QByteArray &name, const QByteArray &data) = 0; +}; + +class QHttpNetworkHeaderPrivate : public QSharedData +{ +public: + QUrl url; + QList > fields; + + QHttpNetworkHeaderPrivate(const QUrl &newUrl = QUrl()); + QHttpNetworkHeaderPrivate(const QHttpNetworkHeaderPrivate &other); + inline qint64 contentLength() const; + inline void setContentLength(qint64 length); + + inline QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const; + inline QList headerFieldValues(const QByteArray &name) const; + inline void setHeaderField(const QByteArray &name, const QByteArray &data); + bool operator==(const QHttpNetworkHeaderPrivate &other) const; + +}; + + +QT_END_NAMESPACE + + +#endif // QT_NO_HTTP + + +#endif // QHTTPNETWORKHEADER_H + + + + + + diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp new file mode 100644 index 0000000..fe3f6af --- /dev/null +++ b/src/network/access/qhttpnetworkreply.cpp @@ -0,0 +1,663 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qhttpnetworkreply_p.h" +#include "qhttpnetworkconnection_p.h" + +#include + +#ifndef QT_NO_HTTP + +#ifndef QT_NO_OPENSSL +# include +# include +# include +#endif + +QT_BEGIN_NAMESPACE + +QHttpNetworkReply::QHttpNetworkReply(const QUrl &url, QObject *parent) + : QObject(*new QHttpNetworkReplyPrivate(url), parent) +{ +} + +QHttpNetworkReply::~QHttpNetworkReply() +{ + Q_D(QHttpNetworkReply); + if (d->connection) { + d->connection->d_func()->removeReply(this); + } +} + +QUrl QHttpNetworkReply::url() const +{ + return d_func()->url; +} +void QHttpNetworkReply::setUrl(const QUrl &url) +{ + Q_D(QHttpNetworkReply); + d->url = url; +} + +qint64 QHttpNetworkReply::contentLength() const +{ + return d_func()->contentLength(); +} + +void QHttpNetworkReply::setContentLength(qint64 length) +{ + Q_D(QHttpNetworkReply); + d->setContentLength(length); +} + +QList > QHttpNetworkReply::header() const +{ + return d_func()->fields; +} + +QByteArray QHttpNetworkReply::headerField(const QByteArray &name, const QByteArray &defaultValue) const +{ + return d_func()->headerField(name, defaultValue); +} + +void QHttpNetworkReply::setHeaderField(const QByteArray &name, const QByteArray &data) +{ + Q_D(QHttpNetworkReply); + d->setHeaderField(name, data); +} + +void QHttpNetworkReply::parseHeader(const QByteArray &header) +{ + Q_D(QHttpNetworkReply); + d->parseHeader(header); +} + +QHttpNetworkRequest QHttpNetworkReply::request() const +{ + return d_func()->request; +} + +void QHttpNetworkReply::setRequest(const QHttpNetworkRequest &request) +{ + Q_D(QHttpNetworkReply); + d->request = request; +} + +int QHttpNetworkReply::statusCode() const +{ + return d_func()->statusCode; +} + +void QHttpNetworkReply::setStatusCode(int code) +{ + Q_D(QHttpNetworkReply); + d->statusCode = code; +} + +QString QHttpNetworkReply::errorString() const +{ + return d_func()->errorString; +} + +QString QHttpNetworkReply::reasonPhrase() const +{ + return d_func()->reasonPhrase; +} + +void QHttpNetworkReply::setErrorString(const QString &error) +{ + Q_D(QHttpNetworkReply); + d->errorString = error; +} + +int QHttpNetworkReply::majorVersion() const +{ + return d_func()->majorVersion; +} + +int QHttpNetworkReply::minorVersion() const +{ + return d_func()->minorVersion; +} + +qint64 QHttpNetworkReply::bytesAvailable() const +{ + Q_D(const QHttpNetworkReply); + if (d->connection) + return d->connection->d_func()->bytesAvailable(*this); + else + return -1; +} + +QByteArray QHttpNetworkReply::read(qint64 maxSize) +{ + Q_D(QHttpNetworkReply); + QByteArray data; + if (d->connection) + d->connection->d_func()->read(*this, data, maxSize, false); + return data; +} + +bool QHttpNetworkReply::isFinished() const +{ + return d_func()->state == QHttpNetworkReplyPrivate::AllDoneState; +} + + + +QHttpNetworkReplyPrivate::QHttpNetworkReplyPrivate(const QUrl &newUrl) + : QHttpNetworkHeaderPrivate(newUrl), state(NothingDoneState), statusCode(100), + majorVersion(0), minorVersion(0), bodyLength(0), contentRead(0), totalProgress(0), + currentChunkSize(0), currentChunkRead(0), connection(0), initInflate(false), + autoDecompress(false), requestIsBuffering(false), requestIsPrepared(false) +{ +} + +QHttpNetworkReplyPrivate::~QHttpNetworkReplyPrivate() +{ +} + +void QHttpNetworkReplyPrivate::clear() +{ + state = NothingDoneState; + statusCode = 100; + bodyLength = 0; + contentRead = 0; + totalProgress = 0; + currentChunkSize = 0; + currentChunkRead = 0; + connection = 0; +#ifndef QT_NO_COMPRESS + if (initInflate) + inflateEnd(&inflateStrm); +#endif + initInflate = false; + streamEnd = false; + autoDecompress = false; + fields.clear(); +} + +// QHttpNetworkReplyPrivate +qint64 QHttpNetworkReplyPrivate::bytesAvailable() const +{ + return (state != ReadingDataState ? 0 : fragment.size()); +} + +bool QHttpNetworkReplyPrivate::isGzipped() +{ + QByteArray encoding = headerField("content-encoding"); + return encoding.toLower() == "gzip"; +} + +void QHttpNetworkReplyPrivate::removeAutoDecompressHeader() +{ + // The header "Content-Encoding = gzip" is retained. + // Content-Length is removed since the actual one send by the server is for compressed data + QByteArray name("content-length"); + QByteArray lowerName = name.toLower(); + QList >::Iterator it = fields.begin(), + end = fields.end(); + while (it != end) { + if (name == it->first.toLower()) { + fields.erase(it); + break; + } + ++it; + } + +} + +bool QHttpNetworkReplyPrivate::findChallenge(bool forProxy, QByteArray &challenge) const +{ + challenge.clear(); + // find out the type of authentication protocol requested. + QByteArray header = forProxy ? "proxy-authenticate" : "www-authenticate"; + // pick the best protocol (has to match parsing in QAuthenticatorPrivate) + QList challenges = headerFieldValues(header); + for (int i = 0; i challenges = headerFieldValues(header); + for (int i = 0; i maxPos) + return ret; + if ((flags & EXTRA_FIELD) && ((pos+2) <= maxPos)) { // skip the extra field + unsigned len = (unsigned)body[++pos]; + len += ((unsigned)body[++pos])<<8; + pos += len; + if (pos > maxPos) + return ret; + } + if ((flags & ORIG_NAME) != 0) { // skip the original file name + while(++pos <= maxPos && body[pos]) {} + } + if ((flags & COMMENT) != 0) { // skip the .gz file comment + while(++pos <= maxPos && body[pos]) {} + } + if ((flags & HEAD_CRC) != 0) { // skip the header crc + pos += 2; + if (pos > maxPos) + return ret; + } + ret = (pos < maxPos); // return failed, if no more bytes left + return ret; +} + +int QHttpNetworkReplyPrivate::gunzipBodyPartially(QByteArray &compressed, QByteArray &inflated) +{ + int ret = Z_DATA_ERROR; + unsigned have; + unsigned char out[CHUNK]; + int pos = -1; + + if (!initInflate) { + // check the header + if (!gzipCheckHeader(compressed, pos)) + return ret; + // allocate inflate state + inflateStrm.zalloc = Z_NULL; + inflateStrm.zfree = Z_NULL; + inflateStrm.opaque = Z_NULL; + inflateStrm.avail_in = 0; + inflateStrm.next_in = Z_NULL; + ret = inflateInit2(&inflateStrm, -MAX_WBITS); + if (ret != Z_OK) + return ret; + initInflate = true; + streamEnd = false; + } + + //remove the header. + compressed.remove(0, pos+1); + // expand until deflate stream ends + inflateStrm.next_in = (unsigned char *)compressed.data(); + inflateStrm.avail_in = compressed.size(); + do { + inflateStrm.avail_out = sizeof(out); + inflateStrm.next_out = out; + ret = inflate(&inflateStrm, Z_NO_FLUSH); + switch (ret) { + case Z_NEED_DICT: + ret = Z_DATA_ERROR; + // and fall through + case Z_DATA_ERROR: + case Z_MEM_ERROR: + inflateEnd(&inflateStrm); + initInflate = false; + return ret; + } + have = sizeof(out) - inflateStrm.avail_out; + inflated.append(QByteArray((const char *)out, have)); + } while (inflateStrm.avail_out == 0); + // clean up and return + if (ret <= Z_ERRNO || ret == Z_STREAM_END) { + inflateEnd(&inflateStrm); + initInflate = false; + } + streamEnd = (ret == Z_STREAM_END); + return ret; +} +#endif + +qint64 QHttpNetworkReplyPrivate::readStatus(QAbstractSocket *socket) +{ + qint64 bytes = 0; + char c; + + while (socket->bytesAvailable()) { + // allow both CRLF & LF (only) line endings + if (socket->peek(&c, 1) == 1 && c == '\n') { + bytes += socket->read(&c, 1); // read the "n" + // remove the CR at the end + if (fragment.endsWith('\r')) { + fragment.truncate(fragment.length()-1); + } + parseStatus(fragment); + state = ReadingHeaderState; + fragment.clear(); // next fragment + break; + } else { + c = 0; + bytes += socket->read(&c, 1); + fragment.append(c); + } + } + return bytes; +} + +void QHttpNetworkReplyPrivate::parseStatus(const QByteArray &status) +{ + const QByteArrayMatcher sp(" "); + int i = sp.indexIn(status); + const QByteArray version = status.mid(0, i); + int j = sp.indexIn(status, i + 1); + const QByteArray code = status.mid(i + 1, j - i - 1); + const QByteArray reason = status.mid(j + 1, status.count() - j); + + const QByteArrayMatcher slash("/"); + int k = slash.indexIn(version); + const QByteArrayMatcher dot("."); + int l = dot.indexIn(version, k); + const QByteArray major = version.mid(k + 1, l - k - 1); + const QByteArray minor = version.mid(l + 1, version.count() - l); + + majorVersion = QString::fromAscii(major.constData()).toInt(); + minorVersion = QString::fromAscii(minor.constData()).toInt(); + statusCode = QString::fromAscii(code.constData()).toInt(); + reasonPhrase = QString::fromAscii(reason.constData()); +} + +qint64 QHttpNetworkReplyPrivate::readHeader(QAbstractSocket *socket) +{ + qint64 bytes = 0; + char crlfcrlf[5]; + crlfcrlf[4] = '\0'; + char c = 0; + bool allHeaders = false; + while (!allHeaders && socket->bytesAvailable()) { + if (socket->peek(&c, 1) == 1 && c == '\n') { + // check for possible header endings. As per HTTP rfc, + // the header endings will be marked by CRLFCRLF. But + // we will allow CRLFLF, LFLF & CRLFCRLF + if (fragment.endsWith("\n\r") || fragment.endsWith('\n')) + allHeaders = true; + } + bytes += socket->read(&c, 1); + fragment.append(c); + } + // we received all headers now parse them + if (allHeaders) { + parseHeader(fragment); + state = ReadingDataState; + fragment.clear(); // next fragment + bodyLength = contentLength(); // cache the length + } + return bytes; +} + +void QHttpNetworkReplyPrivate::parseHeader(const QByteArray &header) +{ + // see rfc2616, sec 4 for information about HTTP/1.1 headers. + // allows relaxed parsing here, accepts both CRLF & LF line endings + const QByteArrayMatcher lf("\n"); + const QByteArrayMatcher colon(":"); + int i = 0; + while (i < header.count()) { + int j = colon.indexIn(header, i); // field-name + if (j == -1) + break; + const QByteArray field = header.mid(i, j - i).trimmed(); + j++; + // any number of LWS is allowed before and after the value + QByteArray value; + do { + i = lf.indexIn(header, j); + if (i == -1) + break; + if (!value.isEmpty()) + value += ' '; + // check if we have CRLF or only LF + bool hasCR = (i && header[i-1] == '\r'); + int length = i -(hasCR ? 1: 0) - j; + value += header.mid(j, length).trimmed(); + j = ++i; + } while (i < header.count() && (header.at(i) == ' ' || header.at(i) == '\t')); + if (i == -1) + break; // something is wrong + + fields.append(qMakePair(field, value)); + } +} + +bool QHttpNetworkReplyPrivate::isChunked() +{ + return headerField("transfer-encoding").toLower().contains("chunked"); +} + +bool QHttpNetworkReplyPrivate::connectionCloseEnabled() +{ + return (headerField("connection").toLower().contains("close") || + headerField("proxy-connection").toLower().contains("close")); +} + +qint64 QHttpNetworkReplyPrivate::readBody(QAbstractSocket *socket, QIODevice *out) +{ + qint64 bytes = 0; + if (isChunked()) { + bytes += transferChunked(socket, out); // chunked transfer encoding (rfc 2616, sec 3.6) + } else if (bodyLength > 0) { // we have a Content-Length + bytes += transferRaw(socket, out, bodyLength - contentRead); + if (contentRead + bytes == bodyLength) + state = AllDoneState; + } else { + bytes += transferRaw(socket, out, socket->bytesAvailable()); + } + if (state == AllDoneState) + socket->readAll(); // Read the rest to clean (CRLF) + contentRead += bytes; + return bytes; +} + +qint64 QHttpNetworkReplyPrivate::transferRaw(QIODevice *in, QIODevice *out, qint64 size) +{ + qint64 bytes = 0; + Q_ASSERT(in); + Q_ASSERT(out); + + int toBeRead = qMin(128*1024, qMin(size, in->bytesAvailable())); + QByteArray raw(toBeRead, 0); + while (size > 0) { + qint64 read = in->read(raw.data(), raw.size()); + if (read == 0) + return bytes; + // ### error checking here + qint64 written = out->write(raw.data(), read); + if (written == 0) + return bytes; + if (read != written) + qDebug() << "### read" << read << "written" << written; + bytes += read; + size -= read; + out->waitForBytesWritten(-1); // throttle + } + return bytes; + +} + +qint64 QHttpNetworkReplyPrivate::transferChunked(QIODevice *in, QIODevice *out) +{ + qint64 bytes = 0; + while (in->bytesAvailable()) { // while we can read from input + // if we are done with the current chunk, get the size of the new chunk + if (currentChunkRead >= currentChunkSize) { + currentChunkSize = 0; + currentChunkRead = 0; + if (bytes) { + char crlf[2]; + bytes += in->read(crlf, 2); // read the "\r\n" after the chunk + } + bytes += getChunkSize(in, ¤tChunkSize); + if (currentChunkSize == -1) + break; + } + // if the chunk size is 0, end of the stream + if (currentChunkSize == 0) { + state = AllDoneState; + break; + } + // otherwise, read data + qint64 readSize = qMin(in->bytesAvailable(), currentChunkSize - currentChunkRead); + QByteArray buffer(readSize, 0); + qint64 read = in->read(buffer.data(), readSize); + bytes += read; + currentChunkRead += read; + qint64 written = out->write(buffer); + Q_UNUSED(written); // Avoid compile warning when building release + Q_ASSERT(read == written); + // ### error checking here + out->waitForBytesWritten(-1); + } + return bytes; +} + +qint64 QHttpNetworkReplyPrivate::getChunkSize(QIODevice *in, qint64 *chunkSize) +{ + qint64 bytes = 0; + char crlf[2]; + *chunkSize = -1; + int bytesAvailable = in->bytesAvailable(); + while (bytesAvailable > bytes) { + qint64 sniffedBytes = in->peek(crlf, 2); + int fragmentSize = fragment.size(); + // check the next two bytes for a "\r\n", skip blank lines + if ((fragmentSize && sniffedBytes == 2 && crlf[0] == '\r' && crlf[1] == '\n') + ||(fragmentSize > 1 && fragment.endsWith('\r') && crlf[0] == '\n')) + { + bytes += in->read(crlf, 1); // read the \r or \n + if (crlf[0] == '\r') + bytes += in->read(crlf, 1); // read the \n + bool ok = false; + // ignore the chunk-extension + fragment = fragment.mid(0, fragment.indexOf(';')).trimmed(); + *chunkSize = fragment.toLong(&ok, 16); + fragment.clear(); + break; // size done + } else { + // read the fragment to the buffer + char c = 0; + bytes += in->read(&c, 1); + fragment.append(c); + } + } + return bytes; +} + +// SSL support below +#ifndef QT_NO_OPENSSL + +QSslConfiguration QHttpNetworkReply::sslConfiguration() const +{ + Q_D(const QHttpNetworkReply); + if (d->connection) + return d->connection->d_func()->sslConfiguration(*this); + return QSslConfiguration(); +} + +void QHttpNetworkReply::setSslConfiguration(const QSslConfiguration &config) +{ + Q_D(QHttpNetworkReply); + if (d->connection) + d->connection->setSslConfiguration(config); +} + +void QHttpNetworkReply::ignoreSslErrors() +{ + Q_D(QHttpNetworkReply); + if (d->connection) + d->connection->ignoreSslErrors(); +} + + +#endif //QT_NO_OPENSSL + + +QT_END_NAMESPACE + +#endif // QT_NO_HTTP \ No newline at end of file diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h new file mode 100644 index 0000000..9881bb3 --- /dev/null +++ b/src/network/access/qhttpnetworkreply_p.h @@ -0,0 +1,226 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QHTTPNETWORKREPLY_H +#define QHTTPNETWORKREPLY_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of the Network Access API. This header file may change from +// version to version without notice, or even be removed. +// +// We mean it. +// +#ifndef QT_NO_HTTP + +QT_BEGIN_NAMESPACE + +#ifndef QT_NO_COMPRESS +# include +static const unsigned char gz_magic[2] = {0x1f, 0x8b}; // gzip magic header +// gzip flag byte +#define HEAD_CRC 0x02 // bit 1 set: header CRC present +#define EXTRA_FIELD 0x04 // bit 2 set: extra field present +#define ORIG_NAME 0x08 // bit 3 set: original file name present +#define COMMENT 0x10 // bit 4 set: file comment present +#define RESERVED 0xE0 // bits 5..7: reserved +#define CHUNK 16384 +#endif + +#ifndef QT_NO_OPENSSL +# include +# include +#else +# include +#endif + +#include +#include +#include + +#include +#include +#include +#include + +class QHttpNetworkConnection; +class QHttpNetworkRequest; +class QHttpNetworkConnectionPrivate; +class QHttpNetworkReplyPrivate; +class Q_AUTOTEST_EXPORT QHttpNetworkReply : public QObject, public QHttpNetworkHeader +{ + Q_OBJECT +public: + + explicit QHttpNetworkReply(const QUrl &url = QUrl(), QObject *parent = 0); + virtual ~QHttpNetworkReply(); + + QUrl url() const; + void setUrl(const QUrl &url); + + int majorVersion() const; + int minorVersion() const; + + qint64 contentLength() const; + void setContentLength(qint64 length); + + QList > header() const; + QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const; + void setHeaderField(const QByteArray &name, const QByteArray &data); + void parseHeader(const QByteArray &header); // mainly for testing + + QHttpNetworkRequest request() const; + void setRequest(const QHttpNetworkRequest &request); + + int statusCode() const; + void setStatusCode(int code); + + QString errorString() const; + void setErrorString(const QString &error); + + QString reasonPhrase() const; + + qint64 bytesAvailable() const; + QByteArray read(qint64 maxSize = -1); + + bool isFinished() const; + +#ifndef QT_NO_OPENSSL + QSslConfiguration sslConfiguration() const; + void setSslConfiguration(const QSslConfiguration &config); + void ignoreSslErrors(); + +Q_SIGNALS: + void sslErrors(const QList &errors); +#endif + +Q_SIGNALS: + void readyRead(); + void finished(); + void finishedWithError(QNetworkReply::NetworkError errorCode, const QString &detail = QString()); + void headerChanged(); + void dataReadProgress(int done, int total); + void dataSendProgress(int done, int total); + +private: + Q_DECLARE_PRIVATE(QHttpNetworkReply) + friend class QHttpNetworkConnection; + friend class QHttpNetworkConnectionPrivate; +}; + + +class QHttpNetworkReplyPrivate : public QObjectPrivate, public QHttpNetworkHeaderPrivate +{ +public: + QHttpNetworkReplyPrivate(const QUrl &newUrl = QUrl()); + ~QHttpNetworkReplyPrivate(); + qint64 readStatus(QAbstractSocket *socket); + void parseStatus(const QByteArray &status); + qint64 readHeader(QAbstractSocket *socket); + void parseHeader(const QByteArray &header); + qint64 readBody(QAbstractSocket *socket, QIODevice *out); + bool findChallenge(bool forProxy, QByteArray &challenge) const; + QAuthenticatorPrivate::Method authenticationMethod(bool isProxy) const; + void clear(); + + qint64 transferRaw(QIODevice *in, QIODevice *out, qint64 size); + qint64 transferChunked(QIODevice *in, QIODevice *out); + qint64 getChunkSize(QIODevice *in, qint64 *chunkSize); + + qint64 bytesAvailable() const; + bool isChunked(); + bool connectionCloseEnabled(); + bool isGzipped(); +#ifndef QT_NO_COMPRESS + bool gzipCheckHeader(QByteArray &content, int &pos); + int gunzipBodyPartially(QByteArray &compressed, QByteArray &inflated); +#endif + void removeAutoDecompressHeader(); + + enum ReplyState { + NothingDoneState, + ReadingStatusState, + ReadingHeaderState, + ReadingDataState, + AllDoneState + } state; + + QHttpNetworkRequest request; + int statusCode; + int majorVersion; + int minorVersion; + QString errorString; + QString reasonPhrase; + qint64 bodyLength; + qint64 contentRead; + qint64 totalProgress; + QByteArray fragment; + qint64 currentChunkSize; + qint64 currentChunkRead; + QPointer connection; + bool initInflate; + bool streamEnd; +#ifndef QT_NO_COMPRESS + z_stream inflateStrm; +#endif + bool autoDecompress; + + QByteArray responseData; // uncompressed body + QByteArray compressedData; // compressed body (temporary) + QBuffer requestDataBuffer; + bool requestIsBuffering; + bool requestIsPrepared; +}; + + + + +QT_END_NAMESPACE + +//Q_DECLARE_METATYPE(QHttpNetworkReply) + +#endif // QT_NO_HTTP + + +#endif // QHTTPNETWORKREPLY_H \ No newline at end of file diff --git a/src/network/access/qhttpnetworkrequest.cpp b/src/network/access/qhttpnetworkrequest.cpp new file mode 100644 index 0000000..420cb69 --- /dev/null +++ b/src/network/access/qhttpnetworkrequest.cpp @@ -0,0 +1,261 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qhttpnetworkrequest_p.h" + +QT_BEGIN_NAMESPACE + +QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(QHttpNetworkRequest::Operation op, + QHttpNetworkRequest::Priority pri, const QUrl &newUrl) + : QHttpNetworkHeaderPrivate(newUrl), operation(op), priority(pri), data(0), + autoDecompress(false) +{ +} + +QHttpNetworkRequestPrivate::QHttpNetworkRequestPrivate(const QHttpNetworkRequestPrivate &other) + : QHttpNetworkHeaderPrivate(other) +{ + operation = other.operation; + priority = other.priority; + data = other.data; + autoDecompress = other.autoDecompress; +} + +QHttpNetworkRequestPrivate::~QHttpNetworkRequestPrivate() +{ +} + +bool QHttpNetworkRequestPrivate::operator==(const QHttpNetworkRequestPrivate &other) const +{ + return QHttpNetworkHeaderPrivate::operator==(other) + && (operation == other.operation) + && (data == other.data); +} + +QByteArray QHttpNetworkRequestPrivate::methodName() const +{ + QByteArray ba; + switch (operation) { + case QHttpNetworkRequest::Options: + ba += "OPTIONS"; + break; + case QHttpNetworkRequest::Get: + ba += "GET"; + break; + case QHttpNetworkRequest::Head: + ba += "HEAD"; + break; + case QHttpNetworkRequest::Post: + ba += "POST"; + break; + case QHttpNetworkRequest::Put: + ba += "PUT"; + break; + case QHttpNetworkRequest::Delete: + ba += "DELETE"; + break; + case QHttpNetworkRequest::Trace: + ba += "TRACE"; + break; + case QHttpNetworkRequest::Connect: + ba += "CONNECT"; + break; + default: + break; + } + return ba; +} + +QByteArray QHttpNetworkRequestPrivate::uri(bool throughProxy) const +{ + QUrl::FormattingOptions format(QUrl::RemoveFragment); + + // for POST, query data is send as content + if (operation == QHttpNetworkRequest::Post && !data) + format |= QUrl::RemoveQuery; + // for requests through proxy, the Request-URI contains full url + if (throughProxy) + format |= QUrl::RemoveUserInfo; + else + format |= QUrl::RemoveScheme | QUrl::RemoveAuthority; + QByteArray uri = url.toEncoded(format); + if (uri.isEmpty() || (throughProxy && url.path().isEmpty())) + uri += '/'; + return uri; +} + +QByteArray QHttpNetworkRequestPrivate::header(const QHttpNetworkRequest &request, bool throughProxy) +{ + QByteArray ba = request.d->methodName(); + QByteArray uri = request.d->uri(throughProxy); + ba += " " + uri; + + QString majorVersion = QString::number(request.majorVersion()); + QString minorVersion = QString::number(request.minorVersion()); + ba += " HTTP/" + majorVersion.toLatin1() + "." + minorVersion.toLatin1() + "\r\n"; + + QList > fields = request.header(); + QList >::const_iterator it = fields.constBegin(); + for (; it != fields.constEnd(); ++it) + ba += it->first + ": " + it->second + "\r\n"; + if (request.d->operation == QHttpNetworkRequest::Post) { + // add content type, if not set in the request + if (request.headerField("content-type").isEmpty()) + ba += "Content-Type: application/x-www-form-urlencoded\r\n"; + if (!request.d->data && request.d->url.hasQuery()) { + QByteArray query = request.d->url.encodedQuery(); + ba += "Content-Length: "+ QByteArray::number(query.size()) + "\r\n"; + ba += "\r\n"; + ba += query; + } else { + ba += "\r\n"; + } + } else { + ba += "\r\n"; + } + return ba; +} + + +// QHttpNetworkRequest + +QHttpNetworkRequest::QHttpNetworkRequest(const QUrl &url, Operation operation, Priority priority) + : d(new QHttpNetworkRequestPrivate(operation, priority, url)) +{ +} + +QHttpNetworkRequest::QHttpNetworkRequest(const QHttpNetworkRequest &other) + : QHttpNetworkHeader(other), d(other.d) +{ +} + +QHttpNetworkRequest::~QHttpNetworkRequest() +{ +} + +QUrl QHttpNetworkRequest::url() const +{ + return d->url; +} +void QHttpNetworkRequest::setUrl(const QUrl &url) +{ + d->url = url; +} + +qint64 QHttpNetworkRequest::contentLength() const +{ + return d->contentLength(); +} + +void QHttpNetworkRequest::setContentLength(qint64 length) +{ + d->setContentLength(length); +} + +QList > QHttpNetworkRequest::header() const +{ + return d->fields; +} + +QByteArray QHttpNetworkRequest::headerField(const QByteArray &name, const QByteArray &defaultValue) const +{ + return d->headerField(name, defaultValue); +} + +void QHttpNetworkRequest::setHeaderField(const QByteArray &name, const QByteArray &data) +{ + d->setHeaderField(name, data); +} + +QHttpNetworkRequest &QHttpNetworkRequest::operator=(const QHttpNetworkRequest &other) +{ + d = other.d; + return *this; +} + +bool QHttpNetworkRequest::operator==(const QHttpNetworkRequest &other) const +{ + return d->operator==(*other.d); +} + +QHttpNetworkRequest::Operation QHttpNetworkRequest::operation() const +{ + return d->operation; +} + +void QHttpNetworkRequest::setOperation(Operation operation) +{ + d->operation = operation; +} + +QHttpNetworkRequest::Priority QHttpNetworkRequest::priority() const +{ + return d->priority; +} + +void QHttpNetworkRequest::setPriority(Priority priority) +{ + d->priority = priority; +} + +QIODevice *QHttpNetworkRequest::data() const +{ + return d->data; +} + +void QHttpNetworkRequest::setData(QIODevice *data) +{ + d->data = data; +} + +int QHttpNetworkRequest::majorVersion() const +{ + return 1; +} + +int QHttpNetworkRequest::minorVersion() const +{ + return 1; +} + + +QT_END_NAMESPACE + diff --git a/src/network/access/qhttpnetworkrequest_p.h b/src/network/access/qhttpnetworkrequest_p.h new file mode 100644 index 0000000..4e64ca6 --- /dev/null +++ b/src/network/access/qhttpnetworkrequest_p.h @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QHTTPNETWORKREQUEST_H +#define QHTTPNETWORKREQUEST_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of the Network Access API. This header file may change from +// version to version without notice, or even be removed. +// +// We mean it. +// +#ifndef QT_NO_HTTP + +QT_BEGIN_NAMESPACE + +#include + +class QHttpNetworkRequestPrivate; +class Q_AUTOTEST_EXPORT QHttpNetworkRequest: public QHttpNetworkHeader +{ +public: + enum Operation { + Options, + Get, + Head, + Post, + Put, + Delete, + Trace, + Connect + }; + + enum Priority { + HighPriority, + NormalPriority, + LowPriority + }; + + QHttpNetworkRequest(const QUrl &url = QUrl(), Operation operation = Get, Priority priority = NormalPriority); + QHttpNetworkRequest(const QHttpNetworkRequest &other); + virtual ~QHttpNetworkRequest(); + QHttpNetworkRequest &operator=(const QHttpNetworkRequest &other); + bool operator==(const QHttpNetworkRequest &other) const; + + QUrl url() const; + void setUrl(const QUrl &url); + + int majorVersion() const; + int minorVersion() const; + + qint64 contentLength() const; + void setContentLength(qint64 length); + + QList > header() const; + QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const; + void setHeaderField(const QByteArray &name, const QByteArray &data); + + Operation operation() const; + void setOperation(Operation operation); + + Priority priority() const; + void setPriority(Priority priority); + + QIODevice *data() const; + void setData(QIODevice *data); + +private: + QSharedDataPointer d; + friend class QHttpNetworkRequestPrivate; + friend class QHttpNetworkConnectionPrivate; +}; + + +class QHttpNetworkRequestPrivate : public QHttpNetworkHeaderPrivate +{ +public: + QHttpNetworkRequestPrivate(QHttpNetworkRequest::Operation op, + QHttpNetworkRequest::Priority pri, const QUrl &newUrl = QUrl()); + QHttpNetworkRequestPrivate(const QHttpNetworkRequestPrivate &other); + ~QHttpNetworkRequestPrivate(); + bool operator==(const QHttpNetworkRequestPrivate &other) const; + QByteArray methodName() const; + QByteArray uri(bool throughProxy) const; + + static QByteArray header(const QHttpNetworkRequest &request, bool throughProxy); + + QHttpNetworkRequest::Operation operation; + QHttpNetworkRequest::Priority priority; + mutable QIODevice *data; + bool autoDecompress; +}; + + +QT_END_NAMESPACE + +//Q_DECLARE_METATYPE(QHttpNetworkRequest) + +#endif // QT_NO_HTTP + + +#endif // QHTTPNETWORKREQUEST_H \ No newline at end of file -- cgit v0.12 From 9b3de2a229bfd393a13bcf08750c2284f775d8c5 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Mon, 6 Apr 2009 17:03:12 +0200 Subject: De-inlined 2 functions in QHttpNetworkHeader RevBy: Thiago --- src/network/access/qhttpnetworkheader_p.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/access/qhttpnetworkheader_p.h b/src/network/access/qhttpnetworkheader_p.h index ce538c8..306ae85 100644 --- a/src/network/access/qhttpnetworkheader_p.h +++ b/src/network/access/qhttpnetworkheader_p.h @@ -85,8 +85,8 @@ public: QHttpNetworkHeaderPrivate(const QUrl &newUrl = QUrl()); QHttpNetworkHeaderPrivate(const QHttpNetworkHeaderPrivate &other); - inline qint64 contentLength() const; - inline void setContentLength(qint64 length); + qint64 contentLength() const; + void setContentLength(qint64 length); inline QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const; inline QList headerFieldValues(const QByteArray &name) const; -- cgit v0.12 From 1bb9d8fcd59a91751c8d91e2885e2b05eff4d1bb Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Mon, 6 Apr 2009 17:10:26 +0200 Subject: BT: Adjust the colliding mice example to work with coalesced updates. It seems that Cocoa is much more strict about coalesced updates than Carbon ever was. The upshot of this is that some examples that "worked" after a fashion in Carbon, do not exhibit good frame rates with Cocoa. The reason why is that apparently Cocoa will decide to flush to the screen every time a timer fires. If you have a lot of timers that are all dependent on doing on update to the screen, you will get undesirable effects. Thankfully, it is possible to adjust the examples to follow best practices and get a good result. So, we now only do the animation once using QGraphicsScene::advance(). We are also able to make the mice less heavy (no QObject subclass). I've updated the docs and someone on the doc team has kindly volunteered to go through them. Reviewed-by: Andreas --- doc/src/examples/collidingmice-example.qdoc | 39 ++++++++++++++------------- examples/graphicsview/collidingmice/main.cpp | 4 +++ examples/graphicsview/collidingmice/mouse.cpp | 5 ++-- examples/graphicsview/collidingmice/mouse.h | 7 ++--- 4 files changed, 30 insertions(+), 25 deletions(-) diff --git a/doc/src/examples/collidingmice-example.qdoc b/doc/src/examples/collidingmice-example.qdoc index 7ea2ca2..657a204 100644 --- a/doc/src/examples/collidingmice-example.qdoc +++ b/doc/src/examples/collidingmice-example.qdoc @@ -66,7 +66,7 @@ \section1 Mouse Class Definition - The \c mouse class inherits both QObject and QGraphicsItem. The + The \c mouse class inherits from QGraphicsItem. The QGraphicsItem class is the base class for all graphical items in the Graphics View framework, and provides a light-weight foundation for writing your own custom items. @@ -78,14 +78,11 @@ {QGraphicsItem::}{boundingRect()}, which returns an estimate of the area painted by the item, and \l {QGraphicsItem::}{paint()}, which implements the actual painting. In addition, we reimplement - the \l {QGraphicsItem::}{shape()} function to return an accurate + the \l {QGraphicsItem::}{shape()} and \l {QGraphicsItem::}{advance()}. + We reimplement \l {QGraphicsItem::}{shape()} to return an accurate shape of our mouse item; the default implementation simply returns - the item's bounding rectangle. - - The rationale for deriving from QObject in addition to - QGraphicsItem is to be able to animate our items by reimplementing - QObject's \l {QObject::}{timerEvent()} function and use - QObject::startTimer() to generate timer events. + the item's bounding rectangle. We reimplement \l {QGraphicsItem::}{advance()} + to handle the animation so it all happens on one update. \section1 Mouse Class Definition @@ -105,19 +102,18 @@ calling the item's \l {QGraphicsItem::rotate()}{rotate()} function we alter the direction in which the mouse will start moving. - In the end we call QObject's \l {QObject::}{startTimer()} - function, emitting a timer event every 1000/33 millisecond. This - enables us to animate our mouse item using our reimplementation of - the \l {QObject::}{timerEvent()} function; whenever a mouse - receives a timer event it will trigger \l - {QObject::}{timerEvent()}: - + When the QGraphicsScene decides to advance the scene a frame it will call + QGraphicsItem::advance() on each of the items. This enables us to animate + our mouse using our reimplementation of the advance() function. + \snippet examples/graphicsview/collidingmice/mouse.cpp 4 \snippet examples/graphicsview/collidingmice/mouse.cpp 5 \snippet examples/graphicsview/collidingmice/mouse.cpp 6 - First we ensure that the mice stays within a circle with a radius - of 150 pixels. + First, we don't bother doing any advance if the step is 0 since we want to our advance in + the actual advance (advance() is called twice, once with step == 0 indicating that items + are about to advance and with step == 1 for the actual advance). We also ensure that the + mice stays within a circle with a radius of 150 pixels. Note the \l {QGraphicsItem::mapFromScene()}{mapFromScene()} function provided by QGraphicsItem. This function maps a position @@ -275,5 +271,12 @@ In the end, we set the application window's title and size before we enter the main event loop using the QApplication::exec() function. -*/ + Finally, we create a QTimer and connect its timeout() signal to the advance() + slot of the scene. Every time the timer fires, the scene will advance one frame. + We then tell the timer to fire every 1000/33 millisecond. This will + give us a frame rate of 30 frames a second, which is fast enough for most animations. + Doing the animation with a single timer connect to advance the scene ensures that all the + mice are moved at one point and, more importantly, only one update is sent to the screen + after all the mice have moved. +*/ \ No newline at end of file diff --git a/examples/graphicsview/collidingmice/main.cpp b/examples/graphicsview/collidingmice/main.cpp index 4a44481..23c91b0 100644 --- a/examples/graphicsview/collidingmice/main.cpp +++ b/examples/graphicsview/collidingmice/main.cpp @@ -83,6 +83,10 @@ int main(int argc, char **argv) view.resize(400, 300); view.show(); + QTimer timer; + QObject::connect(&timer, SIGNAL(timeout()), &scene, SLOT(advance())); + timer.start(1000 / 33); + return app.exec(); } //! [6] diff --git a/examples/graphicsview/collidingmice/mouse.cpp b/examples/graphicsview/collidingmice/mouse.cpp index 1d10574..bbdb4e3 100644 --- a/examples/graphicsview/collidingmice/mouse.cpp +++ b/examples/graphicsview/collidingmice/mouse.cpp @@ -65,7 +65,6 @@ Mouse::Mouse() color(qrand() % 256, qrand() % 256, qrand() % 256) { rotate(qrand() % (360 * 16)); - startTimer(1000 / 33); } //! [0] @@ -123,8 +122,10 @@ void Mouse::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget * //! [3] //! [4] -void Mouse::timerEvent(QTimerEvent *) +void Mouse::advance(int step) { + if (!step) + return; //! [4] // Don't move too far away //! [5] diff --git a/examples/graphicsview/collidingmice/mouse.h b/examples/graphicsview/collidingmice/mouse.h index 832ea53..c08ce4a 100644 --- a/examples/graphicsview/collidingmice/mouse.h +++ b/examples/graphicsview/collidingmice/mouse.h @@ -43,13 +43,10 @@ #define MOUSE_H #include -#include //! [0] -class Mouse : public QObject, public QGraphicsItem +class Mouse : public QGraphicsItem { - Q_OBJECT - public: Mouse(); @@ -59,7 +56,7 @@ public: QWidget *widget); protected: - void timerEvent(QTimerEvent *event); + void advance(int step); private: qreal angle; -- cgit v0.12 From 041a8ecdb5f11dfc499f8f8f77d85cb63508c093 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Mon, 6 Apr 2009 17:52:58 +0200 Subject: BT: Fixed treeview painting regression on Vista The old code did not split up the frame from the central parts of the itemview selection box correctly. We now draw the edges as border images instead. Previously this would lead to somewhat ugly scaling artifacts for small header sections. Task: 248839 Reviewed-by: ogoffart --- src/gui/styles/qwindowsvistastyle.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/gui/styles/qwindowsvistastyle.cpp b/src/gui/styles/qwindowsvistastyle.cpp index 4c3060d..b14b8b3 100644 --- a/src/gui/styles/qwindowsvistastyle.cpp +++ b/src/gui/styles/qwindowsvistastyle.cpp @@ -801,12 +801,20 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt if (vopt->viewItemPosition == QStyleOptionViewItemV4::OnlyOne || vopt->viewItemPosition == QStyleOptionViewItemV4::Invalid) painter->drawPixmap(pixmapRect.topLeft(), pixmap); - else if (reverse ? rightSection : leftSection) - painter->drawPixmap(pixmapRect, pixmap, srcRect.adjusted(0, 0, -frame, 0)); - else if (reverse ? leftSection : rightSection) - painter->drawPixmap(pixmapRect, pixmap, - srcRect.adjusted(frame, 0, 0, 0)); - else if (vopt->viewItemPosition == QStyleOptionViewItemV4::Middle) + else if (reverse ? rightSection : leftSection){ + painter->drawPixmap(QRect(pixmapRect.topLeft(), + QSize(frame, pixmapRect.height())), pixmap, + QRect(QPoint(0, 0), QSize(frame, pixmapRect.height()))); + painter->drawPixmap(pixmapRect.adjusted(frame, 0, 0, 0), + pixmap, srcRect.adjusted(frame, 0, -frame, 0)); + } else if (reverse ? leftSection : rightSection) { + painter->drawPixmap(QRect(pixmapRect.topRight() - QPoint(frame - 1, 0), + QSize(frame, pixmapRect.height())), pixmap, + QRect(QPoint(pixmapRect.width() - frame, 0), + QSize(frame, pixmapRect.height()))); + painter->drawPixmap(pixmapRect.adjusted(0, 0, -frame, 0), + pixmap, srcRect.adjusted(frame, 0, -frame, 0)); + } else if (vopt->viewItemPosition == QStyleOptionViewItemV4::Middle) painter->drawPixmap(pixmapRect, pixmap, srcRect.adjusted(frame, 0, -frame, 0)); } else { -- cgit v0.12 From 948de0dc991e324cdfb01f2e84a6aadfbf8d737f Mon Sep 17 00:00:00 2001 From: Bill King Date: Mon, 6 Apr 2009 15:49:40 +1000 Subject: Fixes: QSqlTableModel does not handle updates when one of the fields has a NULL value Task-number: 189093 --- src/sql/kernel/qsqldriver.cpp | 11 ++++++++--- tests/auto/qsqldatabase/tst_qsqldatabase.cpp | 28 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/sql/kernel/qsqldriver.cpp b/src/sql/kernel/qsqldriver.cpp index ddebe45..a995005 100644 --- a/src/sql/kernel/qsqldriver.cpp +++ b/src/sql/kernel/qsqldriver.cpp @@ -406,9 +406,14 @@ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName, break; case WhereStatement: if (preparedStatement) { - for (int i = 0; i < rec.count(); ++i) - s.append(escapeIdentifier(rec.fieldName(i), FieldName)).append( - QLatin1String(" = ? AND ")); + for (int i = 0; i < rec.count(); ++i) { + s.append(escapeIdentifier(rec.fieldName(i), FieldName)); + if (rec.isNull(i)) + s.append(QLatin1String(" IS NULL")); + else + s.append(QLatin1String(" = ?")); + s.append(QLatin1String(" AND ")); + } } else { for (i = 0; i < rec.count(); ++i) { s.append(escapeIdentifier(rec.fieldName(i), FieldName)); diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index e10a0ca..51d5267 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -191,6 +191,10 @@ private slots: void sqlite_bindAndFetchUInt_data() { generic_data("QSQLITE3"); } void sqlite_bindAndFetchUInt(); + void sqlStatementUseIsNull_189093_data() { generic_data(); } + void sqlStatementUseIsNull_189093(); + + private: void createTestTables(QSqlDatabase db); void dropTestTables(QSqlDatabase db); @@ -363,6 +367,7 @@ void tst_QSqlDatabase::populateTestTables(QSqlDatabase db) QVERIFY_SQL(q, exec("insert into " + qTableName("qtest") + " (id, t_varchar, t_char, t_numeric) values (1, 'VarChar1', 'Char1', 2.2)")); QVERIFY_SQL(q, exec("insert into " + qTableName("qtest") + " (id, t_varchar, t_char, t_numeric) values (2, 'VarChar2', 'Char2', 3.3)")); QVERIFY_SQL(q, exec("insert into " + qTableName("qtest") + " (id, t_varchar, t_char, t_numeric) values (3, 'VarChar3', 'Char3', 4.4)")); + QVERIFY_SQL(q, exec("insert into " + qTableName("qtest") + " (id, t_varchar, t_char, t_numeric) values (4, 'VarChar4', NULL, NULL)")); } void tst_QSqlDatabase::initTestCase() @@ -2267,5 +2272,28 @@ void tst_QSqlDatabase::db2_valueCacheUpdate() QCOMPARE(c1.toString(), q.value(0).toString()); } +void tst_QSqlDatabase::sqlStatementUseIsNull_189093() +{ + // NULL = NULL is unknow, the sqlStatment must use IS NULL + QFETCH(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + // select a record with NULL value + QSqlQuery q(QString::null, db); + QVERIFY_SQL(q, exec("select * from " + qTableName("qtest") + " where id = 4")); + QVERIFY_SQL(q, next()); + + QSqlDriver *driver = db.driver(); + QVERIFY(driver); + + QString preparedStatment = driver->sqlStatement(QSqlDriver::WhereStatement, QString("qtest"), q.record(), true); + QCOMPARE(preparedStatment.count("IS NULL", Qt::CaseInsensitive), 2); + + QString statment = driver->sqlStatement(QSqlDriver::WhereStatement, QString("qtest"), q.record(), false); + QCOMPARE(statment.count("IS NULL", Qt::CaseInsensitive), 2); +} + + QTEST_MAIN(tst_QSqlDatabase) #include "tst_qsqldatabase.moc" -- cgit v0.12 From 6393b9fa8474b7b9e86319f54477cba9bec65d11 Mon Sep 17 00:00:00 2001 From: Bill King Date: Tue, 7 Apr 2009 07:45:10 +1000 Subject: Make compile when Qt3Support is turned off --- tests/auto/qsqldatabase/tst_qsqldatabase.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index 51d5267..8dede12 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -1050,6 +1050,7 @@ void tst_QSqlDatabase::recordMySQL() int minor = tst_Databases::getMySqlVersion( db ).section( QChar('.'), 1, 1 ).toInt(); int revision = tst_Databases::getMySqlVersion( db ).section( QChar('.'), 2, 2 ).toInt(); +#ifdef QT3_SUPPORT /* The below is broken in mysql below 5.0.15 see http://dev.mysql.com/doc/refman/5.0/en/binary-varbinary.html specifically: Before MySQL 5.0.15, the pad value is space. Values are right-padded @@ -1059,6 +1060,7 @@ void tst_QSqlDatabase::recordMySQL() bin10 = FieldDef("binary(10)", QVariant::ByteArray, QByteArray(Q3CString("123abc "))); varbin10 = FieldDef("varbinary(10)", QVariant::ByteArray, QByteArray(Q3CString("123abcv "))); } +#endif static QDateTime dt(QDate::currentDate(), QTime(1, 2, 3, 0)); static const FieldDef fieldDefs[] = { -- cgit v0.12 From 3b68e5157e103dec536d5aaff508c1751f20c62e Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 6 Apr 2009 16:24:41 -0700 Subject: Don't use uninitialized caps If flags does not contain DSDESC_CAPS caps might very well be uninitialized. Make sure to properly deal with this situation. Reviewed-by: Donald --- src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index fd6f48a..39a2d48 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -218,8 +218,12 @@ IDirectFBSurface* QDirectFBScreen::createDFBSurface(const DFBSurfaceDescription if (d_ptr->videoonly && !(desc->flags & DSDESC_PREALLOCATED)) { // Add the video only capability. This means the surface will be created in video ram DFBSurfaceDescription voDesc = *desc; - voDesc.caps = DFBSurfaceCapabilities(voDesc.caps | DSCAPS_VIDEOONLY); - voDesc.flags = DFBSurfaceDescriptionFlags(voDesc.flags | DSDESC_CAPS); + if (!(voDesc.flags & DSDESC_CAPS)) { + voDesc.caps = DSCAPS_VIDEOONLY; + voDesc.flags = DFBSurfaceDescriptionFlags(voDesc.flags | DSDESC_CAPS); + } else { + voDesc.caps = DFBSurfaceCapabilities(voDesc.caps | DSCAPS_VIDEOONLY); + } result = d_ptr->dfb->CreateSurface(d_ptr->dfb, &voDesc, &newSurface); } -- cgit v0.12 From 723eea029f98b802563c0bc06ba82ff741e1ac73 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Tue, 7 Apr 2009 10:55:31 +1000 Subject: Move QT_BEGIN_NAMESPACE to after the usual Qt header includes QT_BEGIN_NAMESPACE is not defined until qglobal.h is included, but some of the QtNetwork headers were listing it before. Reviewed-by: Ian Walters --- src/network/access/qhttpnetworkheader_p.h | 4 ++-- src/network/access/qhttpnetworkreply_p.h | 6 +++--- src/network/access/qhttpnetworkrequest_p.h | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/network/access/qhttpnetworkheader_p.h b/src/network/access/qhttpnetworkheader_p.h index 306ae85..3052309 100644 --- a/src/network/access/qhttpnetworkheader_p.h +++ b/src/network/access/qhttpnetworkheader_p.h @@ -54,11 +54,11 @@ // #ifndef QT_NO_HTTP -QT_BEGIN_NAMESPACE - #include #include +QT_BEGIN_NAMESPACE + class Q_AUTOTEST_EXPORT QHttpNetworkHeader { public: diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h index 9881bb3..21f4116 100644 --- a/src/network/access/qhttpnetworkreply_p.h +++ b/src/network/access/qhttpnetworkreply_p.h @@ -54,8 +54,6 @@ // #ifndef QT_NO_HTTP -QT_BEGIN_NAMESPACE - #ifndef QT_NO_COMPRESS # include static const unsigned char gz_magic[2] = {0x1f, 0x8b}; // gzip magic header @@ -84,6 +82,8 @@ static const unsigned char gz_magic[2] = {0x1f, 0x8b}; // gzip magic header #include #include +QT_BEGIN_NAMESPACE + class QHttpNetworkConnection; class QHttpNetworkRequest; class QHttpNetworkConnectionPrivate; @@ -223,4 +223,4 @@ QT_END_NAMESPACE #endif // QT_NO_HTTP -#endif // QHTTPNETWORKREPLY_H \ No newline at end of file +#endif // QHTTPNETWORKREPLY_H diff --git a/src/network/access/qhttpnetworkrequest_p.h b/src/network/access/qhttpnetworkrequest_p.h index 4e64ca6..d18e116 100644 --- a/src/network/access/qhttpnetworkrequest_p.h +++ b/src/network/access/qhttpnetworkrequest_p.h @@ -54,10 +54,10 @@ // #ifndef QT_NO_HTTP -QT_BEGIN_NAMESPACE - #include +QT_BEGIN_NAMESPACE + class QHttpNetworkRequestPrivate; class Q_AUTOTEST_EXPORT QHttpNetworkRequest: public QHttpNetworkHeader { @@ -141,4 +141,4 @@ QT_END_NAMESPACE #endif // QT_NO_HTTP -#endif // QHTTPNETWORKREQUEST_H \ No newline at end of file +#endif // QHTTPNETWORKREQUEST_H -- cgit v0.12 From 0002b0285269f69648a7eede33a1d9df5fab8c53 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 6 Apr 2009 18:20:28 -0700 Subject: Fix up some QT_...NO_PALETTE codepaths Make sure we create the surface from the converted image and not the original one. Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 39a2d48..dd147cf 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -171,7 +171,7 @@ IDirectFBSurface* QDirectFBScreen::createDFBSurface(const QImage &img, SurfaceCr } #endif #ifndef QT_NO_DIRECTFB_PALETTE - if (img.numColors() != 0) + if (img.numColors() != 0 && surface) QDirectFBScreen::setSurfaceColorTable(surface, img); #endif return surface; @@ -261,19 +261,21 @@ IDirectFBSurface *QDirectFBScreen::copyToDFBSurface(const QImage &img, #ifdef QT_NO_DIRECTFB_PREALLOCATED || image.format() != pixmapFormat #endif +#ifdef QT_NO_DIRECTFB_PALETTE + || image.numColors() != 0 +#endif ) { image = image.convertToFormat(pixmapFormat); } - - IDirectFBSurface *dfbSurface = createDFBSurface(img.size(), pixmapFormat, options); + IDirectFBSurface *dfbSurface = createDFBSurface(image.size(), pixmapFormat, options); if (!dfbSurface) { qWarning("QDirectFBPixmapData::fromImage() Couldn't create surface"); return 0; } #ifndef QT_NO_DIRECTFB_PREALLOCATED - IDirectFBSurface *imgSurface = createDFBSurface(img, DontTrackSurface); + IDirectFBSurface *imgSurface = createDFBSurface(image, DontTrackSurface); if (!imgSurface) { qWarning("QDirectFBPixmapData::fromImage()"); QDirectFBScreen::releaseDFBSurface(dfbSurface); -- cgit v0.12 From fb7275161fa646c76cf47dfc8eb41e9356639e70 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 6 Apr 2009 18:41:58 -0700 Subject: Pens can have brushes DirectFB can only handle cases where the pen's brush is Qt::SolidPattern Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 3b6ea80..d0a9dc6 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -367,7 +367,9 @@ void QDirectFBPaintEnginePrivate::setPen(const QPen &p) { pen = p; simplePen = (pen.style() == Qt::NoPen) || - (pen.style() == Qt::SolidLine && !antialiased + (pen.style() == Qt::SolidLine + && !antialiased + && (pen.brush().style() == Qt::SolidPattern) && (pen.widthF() <= 1 && !matrixScale)); } -- cgit v0.12 From 5fb7752ff93b31635e64fa321917749744cc9db6 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 6 Apr 2009 18:51:52 -0700 Subject: Make sure RGB32 workaround works for windows Need to set forceRaster to true if the window surface is RGB32. Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp index ef208af..ec108c4 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp @@ -111,6 +111,7 @@ void QDirectFBSurface::createWindow() dfbSurface->Release(dfbSurface); dfbWindow->GetSurface(dfbWindow, &dfbSurface); + forceRaster = (dfbSurface && QDirectFBScreen::getImageFormat(dfbSurface) == QImage::Format_RGB32); } #endif // QT_NO_DIRECTFB_WM @@ -143,6 +144,7 @@ void QDirectFBSurface::setGeometry(const QRect &rect, const QRegion &mask) IDirectFBSurface *primarySurface = screen->dfbSurface(); Q_ASSERT(primarySurface); result = primarySurface->GetSubSurface(primarySurface, &r, &dfbSurface); + forceRaster = (dfbSurface && QDirectFBScreen::getImageFormat(dfbSurface) == QImage::Format_RGB32); } else { #ifdef QT_NO_DIRECTFB_WM if (isResize) { @@ -164,6 +166,7 @@ void QDirectFBSurface::setGeometry(const QRect &rect, const QRegion &mask) QDirectFBScreen::initSurfaceDescriptionPixelFormat(&description, QDirectFBScreen::instance()->pixelFormat()); dfbSurface = QDirectFBScreen::instance()->createDFBSurface(&description, false); + forceRaster = (dfbSurface && QDirectFBScreen::getImageFormat(dfbSurface) == QImage::Format_RGB32); } else { Q_ASSERT(dfbSurface); } -- cgit v0.12 From 80d83e72fca6a60ca9cfec8bfa37a82087c931a9 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Tue, 31 Mar 2009 18:10:26 -0700 Subject: Make windows the right formats and videoonly CreateWindow gives you more control over how windows are created. Make sure to specify that they're in the same format as the primary surface and that they're in video memory if this is supported. Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp index ec108c4..15c2f7c 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp @@ -98,10 +98,19 @@ void QDirectFBSurface::createWindow() if (!layer) qFatal("QDirectFBWindowSurface: Unable to get primary display layer!"); - DFBWindowDescription description; - description.caps = DFBWindowCapabilities(DWCAPS_NODECORATION | - DWCAPS_ALPHACHANNEL); - description.flags = DWDESC_CAPS; + DFBWindowDescription description; + description.caps = DFBWindowCapabilities(DWCAPS_NODECORATION); + description.flags = DFBWindowDescriptionFlags(DWDESC_CAPS + |DWDESC_SURFACE_CAPS + |DWDESC_PIXELFORMAT); + + description.surface_caps = DSCAPS_NONE; + if (QDirectFBScreen::instance()->preferVideoOnly()) + description.surface_caps = DFBSurfaceCapabilities(description.surface_caps|DSCAPS_VIDEOONLY); + const QImage::Format format = QDirectFBScreen::instance()->pixelFormat(); + description.pixelformat = QDirectFBScreen::getSurfacePixelFormat(format); + if (QDirectFBScreen::isPremultiplied(format)) + description.surface_caps = DFBSurfaceCapabilities(DSCAPS_PREMULTIPLIED|description.caps); DFBResult result = layer->CreateWindow(layer, &description, &dfbWindow); if (result != DFB_OK) @@ -111,7 +120,7 @@ void QDirectFBSurface::createWindow() dfbSurface->Release(dfbSurface); dfbWindow->GetSurface(dfbWindow, &dfbSurface); - forceRaster = (dfbSurface && QDirectFBScreen::getImageFormat(dfbSurface) == QImage::Format_RGB32); + forceRaster = (format == QImage::Format_RGB32); } #endif // QT_NO_DIRECTFB_WM -- cgit v0.12 From 5a0b19a4559fa83e77cc6c6cd05fc492e692b667 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 6 Apr 2009 19:18:58 -0700 Subject: Make sure to dirty clip in setState For an example of something that breaks without this fix show a spinbox in plastique style. The clip is never removed. Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index d0a9dc6..4732c65 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -909,8 +909,7 @@ void QDirectFBPaintEngine::setState(QPainterState *s) { Q_D(QDirectFBPaintEngine); QRasterPaintEngine::setState(s); - if (d->surface) - d->updateClip(); + d->setClipDirty(); d->setPen(state()->pen); d->setBrush(state()->brush); d->setOpacity(state()->opacity); -- cgit v0.12 From cab39df3deb99aba7aa71a397055a2ec742921f4 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Tue, 7 Apr 2009 12:32:04 +1000 Subject: Make OpenGL/ES 1.1 CommonLite and OpenGL/ES 1.0 builds work Reviewed-by: trustme --- src/opengl/qgl_cl_p.h | 2 +- src/opengl/qglframebufferobject.cpp | 4 ++++ src/opengl/qglpixelbuffer_egl.cpp | 8 +++++-- src/opengl/qpaintengine_opengl.cpp | 44 ++++++++++++++++++------------------- src/opengl/qwindowsurface_gl.cpp | 4 ++++ 5 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/opengl/qgl_cl_p.h b/src/opengl/qgl_cl_p.h index e514ff5..c05a7d7 100644 --- a/src/opengl/qgl_cl_p.h +++ b/src/opengl/qgl_cl_p.h @@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE inline void glTexParameterf (GLenum target, GLenum pname, GLfloat param) { - glTexParameterx(target, pname, param); + glTexParameterx(target, pname, FLOAT2X(param)); } inline void glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index fb22272..c362b7e 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -48,6 +48,10 @@ #include #include +#ifdef QT_OPENGL_ES_1_CL +#include "qgl_cl_p.h" +#endif + QT_BEGIN_NAMESPACE extern QImage qt_gl_read_framebuffer(const QSize&, bool, bool); diff --git a/src/opengl/qglpixelbuffer_egl.cpp b/src/opengl/qglpixelbuffer_egl.cpp index 964efa2..5390fd1 100644 --- a/src/opengl/qglpixelbuffer_egl.cpp +++ b/src/opengl/qglpixelbuffer_egl.cpp @@ -47,6 +47,10 @@ #include #include +#ifdef QT_OPENGL_ES_1_CL +#include "qgl_cl_p.h" +#endif + QT_BEGIN_NAMESPACE #ifdef EGL_BIND_TO_TEXTURE_RGBA @@ -188,8 +192,8 @@ GLuint QGLPixelBuffer::generateDynamicTexture() const glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, d->req_size.width(), d->req_size.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, 0); else glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, d->req_size.width(), d->req_size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); return texture; #else return 0; diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index 976a021..88fd379 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -1983,7 +1983,7 @@ public: void QOpenGLTrapezoidToArrayTessellator::addTrap(const Trapezoid &trap) { // On OpenGL ES we convert the trap to 2 triangles -#ifndef QT_OPENGL_ES_1 +#ifndef QT_OPENGL_ES if (size > allocated - 8) { #else if (size > allocated - 12) { @@ -1994,31 +1994,31 @@ void QOpenGLTrapezoidToArrayTessellator::addTrap(const Trapezoid &trap) QGLTrapezoid t = toGLTrapezoid(trap); -#ifndef QT_OPENGL_ES_1 - vertices[size++] = t.topLeftX; - vertices[size++] = t.top; - vertices[size++] = t.topRightX; - vertices[size++] = t.top; - vertices[size++] = t.bottomRightX; - vertices[size++] = t.bottom; - vertices[size++] = t.bottomLeftX; - vertices[size++] = t.bottom; +#ifndef QT_OPENGL_ES + vertices[size++] = f2vt(t.topLeftX); + vertices[size++] = f2vt(t.top); + vertices[size++] = f2vt(t.topRightX); + vertices[size++] = f2vt(t.top); + vertices[size++] = f2vt(t.bottomRightX); + vertices[size++] = f2vt(t.bottom); + vertices[size++] = f2vt(t.bottomLeftX); + vertices[size++] = f2vt(t.bottom); #else // First triangle - vertices[size++] = t.topLeftX; - vertices[size++] = t.top; - vertices[size++] = t.topRightX; - vertices[size++] = t.top; - vertices[size++] = t.bottomRightX; - vertices[size++] = t.bottom; + vertices[size++] = f2vt(t.topLeftX); + vertices[size++] = f2vt(t.top); + vertices[size++] = f2vt(t.topRightX); + vertices[size++] = f2vt(t.top); + vertices[size++] = f2vt(t.bottomRightX); + vertices[size++] = f2vt(t.bottom); // Second triangle - vertices[size++] = t.bottomLeftX; - vertices[size++] = t.bottom; - vertices[size++] = t.topLeftX; - vertices[size++] = t.top; - vertices[size++] = t.bottomRightX; - vertices[size++] = t.bottom; + vertices[size++] = f2vt(t.bottomLeftX); + vertices[size++] = f2vt(t.bottom); + vertices[size++] = f2vt(t.topLeftX); + vertices[size++] = f2vt(t.top); + vertices[size++] = f2vt(t.bottomRightX); + vertices[size++] = f2vt(t.bottom); #endif } diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index 3dd3064..837ccf2 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -76,6 +76,10 @@ #define GLX_SAMPLES_ARB 100001 #endif +#ifdef QT_OPENGL_ES_1_CL +#include "qgl_cl_p.h" +#endif + QT_BEGIN_NAMESPACE // -- cgit v0.12 From 7d2593c767d6006ec123cb4564071dbc7948a3fc Mon Sep 17 00:00:00 2001 From: Ian Walters Date: Tue, 7 Apr 2009 12:59:44 +1000 Subject: Remove inline keywords, fix compile bug The compile under OS-X was failing due to unfound symbols. Given that the implementation of these functions is not in the header file, they should not have inline keywords. Removing the inline keywords allowed compilation to succeed. Reviewed-by: Rhys Weatherley --- src/network/access/qhttpnetworkheader_p.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/network/access/qhttpnetworkheader_p.h b/src/network/access/qhttpnetworkheader_p.h index 3052309..4e62352 100644 --- a/src/network/access/qhttpnetworkheader_p.h +++ b/src/network/access/qhttpnetworkheader_p.h @@ -88,9 +88,9 @@ public: qint64 contentLength() const; void setContentLength(qint64 length); - inline QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const; - inline QList headerFieldValues(const QByteArray &name) const; - inline void setHeaderField(const QByteArray &name, const QByteArray &data); + QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const; + QList headerFieldValues(const QByteArray &name) const; + void setHeaderField(const QByteArray &name, const QByteArray &data); bool operator==(const QHttpNetworkHeaderPrivate &other) const; }; -- cgit v0.12 From 018edd573eac026f861e97ffab611b4eeb059830 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 6 Apr 2009 20:10:01 -0700 Subject: Clean up surface creation code Use the intended functions for surface creation. Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index 9f5c055..6857d96 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -144,15 +144,11 @@ void QDirectFBPixmapData::fill(const QColor &color) Q_ASSERT(dfbSurface); if (color.alpha() < 255 && !hasAlphaChannel()) { - DFBSurfaceDescription description; - description.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH | - DSDESC_HEIGHT | - DSDESC_PIXELFORMAT); - dfbSurface->GetSize(dfbSurface, &description.width, &description.height); - QDirectFBScreen::initSurfaceDescriptionPixelFormat(&description, screen->alphaPixmapFormat()); - screen->releaseDFBSurface(dfbSurface); // release old surface - - dfbSurface = screen->createDFBSurface(&description, QDirectFBScreen::TrackSurface); + + QSize size; + dfbSurface->GetSize(dfbSurface, &size.rwidth(), &size.rheight()); + screen->releaseDFBSurface(dfbSurface); + dfbSurface = screen->createDFBSurface(size, screen->alphaPixmapFormat(), QDirectFBScreen::TrackSurface); forceRaster = false; setSerialNumber(++global_ser_no); if (!dfbSurface) { -- cgit v0.12 From f70dcb0ed48bb393d3e7ed8941e98f1e52fff80e Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 6 Apr 2009 20:25:12 -0700 Subject: Improve QDirectFBPixmapData::transformed Make sure we keep retain alpha if there is one in the source. Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index 6857d96..ee60302 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -231,13 +231,22 @@ QPixmap QDirectFBPixmapData::transformed(const QTransform &transform, return QPixmap(); QDirectFBPixmapData *data = new QDirectFBPixmapData(QPixmapData::PixmapType); - data->resize(size.width(), size.height()); - - IDirectFBSurface *dest = data->dfbSurface; - dest->SetBlittingFlags(dest, DSBLIT_NOFX); + QImage::Format format = screen->pixelFormat(); + DFBSurfaceBlittingFlags flags = DSBLIT_NOFX; + if (hasAlphaChannel()) { + flags = DSBLIT_BLEND_ALPHACHANNEL; + format = screen->alphaPixmapFormat(); + } + data->dfbSurface = screen->createDFBSurface(size, + format, + QDirectFBScreen::TrackSurface); + if (flags & DSBLIT_BLEND_ALPHACHANNEL) { + data->dfbSurface->Clear(data->dfbSurface, 0, 0, 0, 0); + } + data->dfbSurface->SetBlittingFlags(data->dfbSurface, flags); const DFBRectangle destRect = { 0, 0, size.width(), size.height() }; - dest->StretchBlit(dest, dfbSurface, 0, &destRect); + data->dfbSurface->StretchBlit(data->dfbSurface, dfbSurface, 0, &destRect); return QPixmap(data); } -- cgit v0.12 From 3eb0951fa7664e39c74df8edfca51c2a1199209b Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 6 Apr 2009 20:28:38 -0700 Subject: Improve QDirectFBPixmapData::copy Make sure we retain the alpha channel of the original surface. Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index ee60302..9df3051 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -109,7 +109,8 @@ void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect) } IDirectFBSurface *src = static_cast(data)->directFBSurface(); - const QImage::Format format = (data->hasAlphaChannel() + const bool hasAlpha = data->hasAlphaChannel(); + const QImage::Format format = (hasAlpha ? QDirectFBScreen::instance()->alphaPixmapFormat() : QDirectFBScreen::instance()->pixelFormat()); @@ -122,7 +123,12 @@ void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect) } forceRaster = (format == QImage::Format_RGB32); - dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX); + if (hasAlpha) { + dfbSurface->Clear(dfbSurface, 0, 0, 0, 0); + dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_BLEND_ALPHACHANNEL); + } else { + dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX); + } const DFBRectangle blitRect = { rect.x(), rect.y(), rect.width(), rect.height() }; DFBResult result = dfbSurface->Blit(dfbSurface, src, &blitRect, 0, 0); -- cgit v0.12 From 6ee9fd3cdb932dd8d7a2ad6a5ac61300aefc1058 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 6 Apr 2009 22:16:13 -0700 Subject: Make sure to set blitting flags Need to set blitting flags before blitting from a surface with alpha channel. Otherwise alpha areas become white. For some reason setting the porterduff to DSPD_SRC does not fix this. Reviewed-by: TrustMe --- .../gfxdrivers/directfb/qdirectfbpixmap.cpp | 23 +++------------------ .../gfxdrivers/directfb/qdirectfbscreen.cpp | 24 +++++++++++++++++----- src/plugins/gfxdrivers/directfb/qdirectfbscreen.h | 21 +++++++++++++++++++ 3 files changed, 43 insertions(+), 25 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index 9df3051..923025a 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -187,30 +187,13 @@ bool QDirectFBPixmapData::hasAlphaChannel() const { if (!serialNumber()) return false; + DFBSurfacePixelFormat format; + dfbSurface->GetPixelFormat(dfbSurface, &format); + return QDirectFBScreen::hasAlpha(format); // We don't need to ask DFB for this really. Can just keep track // of what image format this has. It should always have either // QDirectFBScreen::alphaPixmapFormat() or QScreen::pixelFormat() - - DFBSurfacePixelFormat format; - dfbSurface->GetPixelFormat(dfbSurface, &format); - switch (format) { - case DSPF_ARGB1555: - case DSPF_ARGB: - case DSPF_LUT8: - case DSPF_AiRGB: - case DSPF_A1: - case DSPF_ARGB2554: - case DSPF_ARGB4444: - case DSPF_AYUV: - case DSPF_A4: - case DSPF_ARGB1666: - case DSPF_ARGB6666: - case DSPF_LUT2: - return true; - default: - return false; - } } QPixmap QDirectFBPixmapData::transformed(const QTransform &transform, diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index dd147cf..bbb0678 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -185,7 +185,15 @@ IDirectFBSurface *QDirectFBScreen::copyDFBSurface(IDirectFBSurface *src, QSize size; src->GetSize(src, &size.rwidth(), &size.rheight()); IDirectFBSurface *surface = createDFBSurface(size, format, options); - surface->SetBlittingFlags(surface, DSBLIT_NOFX); + DFBSurfacePixelFormat dspf; + src->GetPixelFormat(src, &dspf); + DFBSurfaceBlittingFlags flags = QDirectFBScreen::hasAlpha(dspf) + ? DSBLIT_BLEND_ALPHACHANNEL + : DSBLIT_NOFX; + if (flags & DSBLIT_BLEND_ALPHACHANNEL) + surface->Clear(surface, 0, 0, 0, 0); + + surface->SetBlittingFlags(surface, flags); surface->Blit(surface, src, 0, 0, 0); surface->ReleaseSource(surface); // ??? Is this always right? return surface; @@ -281,10 +289,16 @@ IDirectFBSurface *QDirectFBScreen::copyToDFBSurface(const QImage &img, QDirectFBScreen::releaseDFBSurface(dfbSurface); return 0; } + Q_ASSERT(imgSurface); - DFBResult result; - dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX); - result = dfbSurface->Blit(dfbSurface, imgSurface, 0, 0, 0); + DFBSurfaceBlittingFlags flags = img.hasAlphaChannel() + ? DSBLIT_BLEND_ALPHACHANNEL + : DSBLIT_NOFX; + if (flags & DSBLIT_BLEND_ALPHACHANNEL) + dfbSurface->Clear(dfbSurface, 0, 0, 0, 0); + + dfbSurface->SetBlittingFlags(dfbSurface, flags); + DFBResult result = dfbSurface->Blit(dfbSurface, imgSurface, 0, 0, 0); if (result != DFB_OK) DirectFBError("QDirectFBPixmapData::fromImage()", result); dfbSurface->ReleaseSource(dfbSurface); @@ -370,7 +384,7 @@ DFBSurfacePixelFormat QDirectFBScreen::getSurfacePixelFormat(QImage::Format form }; } -static inline bool isPremultiplied(IDirectFBSurface *surface) +static inline bool isPremultiplied(IDirectFBSurface *surface) { Q_ASSERT(surface); DFBSurfaceCapabilities caps; diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h index a1e93c6..f394ac1 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h @@ -119,6 +119,7 @@ public: static QImage::Format getImageFormat(IDirectFBSurface *surface); static bool initSurfaceDescriptionPixelFormat(DFBSurfaceDescription *description, QImage::Format format); static inline bool isPremultiplied(QImage::Format format); + static inline bool hasAlpha(DFBSurfacePixelFormat format); QImage::Format alphaPixmapFormat() const; #ifndef QT_NO_DIRECTFB_PALETTE @@ -151,6 +152,26 @@ inline bool QDirectFBScreen::isPremultiplied(QImage::Format format) return false; } +inline bool QDirectFBScreen::hasAlpha(DFBSurfacePixelFormat format) +{ + switch (format) { + case DSPF_ARGB1555: + case DSPF_ARGB: + case DSPF_LUT8: + case DSPF_AiRGB: + case DSPF_A1: + case DSPF_ARGB2554: + case DSPF_ARGB4444: + case DSPF_AYUV: + case DSPF_A4: + case DSPF_ARGB1666: + case DSPF_ARGB6666: + case DSPF_LUT2: + return true; + default: + return false; + } +} QT_END_HEADER -- cgit v0.12 From 7b72b28464b4ffba6b39cbb863731202dd922064 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 6 Apr 2009 22:18:18 -0700 Subject: Cleanup. This function is no longer used. Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index bbb0678..cb40935 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -384,16 +384,6 @@ DFBSurfacePixelFormat QDirectFBScreen::getSurfacePixelFormat(QImage::Format form }; } -static inline bool isPremultiplied(IDirectFBSurface *surface) -{ - Q_ASSERT(surface); - DFBSurfaceCapabilities caps; - const DFBResult result = surface->GetCapabilities(surface, &caps); - Q_ASSERT(result == DFB_OK); - Q_UNUSED(result); - return caps & DSCAPS_PREMULTIPLIED; -} - QImage::Format QDirectFBScreen::getImageFormat(IDirectFBSurface *surface) { DFBSurfacePixelFormat format; -- cgit v0.12 From 13e3bd76869c0e9be2408b0928b87565aa48ae3d Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 6 Apr 2009 22:23:01 -0700 Subject: Optimize fillRects/fillRegion This is not X11. There's no need to create another structure to hold the DFB rectangles. Verified by DirectFB expert. Reviewed-by: TrustMe --- .../gfxdrivers/directfb/qdirectfbpaintengine.cpp | 28 ++++------------------ 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 4732c65..a93bbf7 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -558,43 +558,25 @@ void QDirectFBPaintEnginePrivate::fillRegion(const QRegion ®ion) const { const QVector rects = region.rects(); const int n = rects.size(); - QVarLengthArray dfbRects(n); - - for (int i = 0; i < n; ++i) { - const QRect r = rects.at(i); - dfbRects[i].x = r.x(); - dfbRects[i].y = r.y(); - dfbRects[i].w = r.width(); - dfbRects[i].h = r.height(); - - } - surface->FillRectangles(surface, dfbRects.data(), n); + fillRects(rects.constData(), n); } void QDirectFBPaintEnginePrivate::fillRects(const QRect *rects, int n) const { - QVarLengthArray dfbRects(n); for (int i = 0; i < n; ++i) { const QRect r = transform.mapRect(rects[i]); - dfbRects[i].x = r.x(); - dfbRects[i].y = r.y(); - dfbRects[i].w = r.width(); - dfbRects[i].h = r.height(); + surface->FillRectangle(surface, r.x(), r.y(), + r.width(), r.height()); } - surface->FillRectangles(surface, dfbRects.data(), n); } void QDirectFBPaintEnginePrivate::fillRects(const QRectF *rects, int n) const { - QVarLengthArray dfbRects(n); for (int i = 0; i < n; ++i) { const QRect r = transform.mapRect(rects[i]).toRect(); - dfbRects[i].x = r.x(); - dfbRects[i].y = r.y(); - dfbRects[i].w = r.width(); - dfbRects[i].h = r.height(); + surface->FillRectangle(surface, r.x(), r.y(), + r.width(), r.height()); } - surface->FillRectangles(surface, dfbRects.data(), n); } void QDirectFBPaintEnginePrivate::drawRects(const QRect *rects, int n) const -- cgit v0.12 From bf3fdc3f6697cfaec689e8422b6c43cfe49bf9b4 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 6 Apr 2009 22:34:05 -0700 Subject: Optimize bytesPerLine further If we're asking for the stride it's very likely the next thing we'll do is ask for the bits() so there's no good reason to unlock it again. In the raster buffer case memory() will be called just before bytesPerLine() so the code won't be hit but it's still the right thing to do. Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp index edbfa7d..2a2ef5c 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp @@ -110,7 +110,6 @@ int QDirectFBPaintDevice::bytesPerLine() const QDirectFBPaintDevice* that = const_cast(this); that->lockDirectFB(); Q_ASSERT(bpl != -1); - that->unlockDirectFB(); } return bpl; } -- cgit v0.12 From 3923604b4390e613000f4c2b00db9e0a954f92ed Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 6 Apr 2009 22:45:07 -0700 Subject: Better QDirectFBPixmapData::toImage() This is essentially a return to the earlier version of toImage(). Use a preallocated surface that operates on the returned image to do the conversion. If this causes drawing bugs it is likely a bug in the directfb driver and can be worked around by compiling with QT_NO_DIRECTFB_PREALLOCATED. Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index 923025a..45f0710 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -245,6 +245,17 @@ QImage QDirectFBPixmapData::toImage() const if (!dfbSurface) return QImage(); +#ifndef QT_NO_DIRECTFB_PREALLOCATED + QImage ret(size(), QDirectFBScreen::getImageFormat(dfbSurface)); + if (IDirectFBSurface *imgSurface = screen->createDFBSurface(ret, QDirectFBScreen::DontTrackSurface)) { + imgSurface->SetBlittingFlags(imgSurface, hasAlphaChannel() ? DSBLIT_BLEND_ALPHACHANNEL : DSBLIT_NOFX); + imgSurface->Blit(imgSurface, dfbSurface, 0, 0, 0); + imgSurface->ReleaseSource(imgSurface); + imgSurface->Release(imgSurface); + return ret; + } +#endif + QDirectFBPixmapData *that = const_cast(this); const QImage *img = that->buffer(); return img->copy(); -- cgit v0.12 From fd4a62bfc18006b3c29918a65b60d9bacf22c9c0 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 6 Apr 2009 22:52:12 -0700 Subject: Call ReleaseSource where appropriate DirectFB caches the last source surface in the target surface after a Blit. This can cause a surface to be kept around longer than desired since the caching increases the ref-count. Unless it's likely that the blit will happen again soon we Release the source. Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp | 2 ++ src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 3 ++- src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index 45f0710..c4144bd 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -132,6 +132,7 @@ void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect) const DFBRectangle blitRect = { rect.x(), rect.y(), rect.width(), rect.height() }; DFBResult result = dfbSurface->Blit(dfbSurface, src, &blitRect, 0, 0); + dfbSurface->ReleaseSource(dfbSurface); if (result != DFB_OK) { DirectFBError("QDirectFBPixmapData::copy()", result); setSerialNumber(0); @@ -236,6 +237,7 @@ QPixmap QDirectFBPixmapData::transformed(const QTransform &transform, const DFBRectangle destRect = { 0, 0, size.width(), size.height() }; data->dfbSurface->StretchBlit(data->dfbSurface, dfbSurface, 0, &destRect); + data->dfbSurface->ReleaseSource(data->dfbSurface); return QPixmap(data); } diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index cb40935..4ae64f7 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -195,7 +195,7 @@ IDirectFBSurface *QDirectFBScreen::copyDFBSurface(IDirectFBSurface *src, surface->SetBlittingFlags(surface, flags); surface->Blit(surface, src, 0, 0, 0); - surface->ReleaseSource(surface); // ??? Is this always right? + surface->ReleaseSource(surface); return surface; } @@ -1093,6 +1093,7 @@ void QDirectFBScreen::compose(const QRegion ®ion) blit(surface->image(), offset, r); } } + d_ptr->dfbSurface->ReleaseSource(d_ptr->dfbSurface); } // Normally, when using DirectFB to compose the windows (I.e. when diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp index 15c2f7c..592ad47 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp @@ -262,7 +262,7 @@ bool QDirectFBSurface::scroll(const QRegion ®ion, int dx, int dy) dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX); dfbSurface->BatchBlit(dfbSurface, dfbSurface, dfbRects.data(), dfbPoints.data(), n); - + dfbSurface->ReleaseSource(dfbSurface); return true; } -- cgit v0.12 From 79adaaf479bfe2e5c252c7aad20db7d04d315444 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 6 Apr 2009 22:55:22 -0700 Subject: Code cleanup. QDirectFBPaintDevice's know their screen. No need to use instance() in these cases. Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp | 10 +++++----- src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index c4144bd..35ab859 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -71,9 +71,9 @@ void QDirectFBPixmapData::resize(int width, int height) return; } - dfbSurface = QDirectFBScreen::instance()->createDFBSurface(QSize(width, height), - screen->pixelFormat(), - QDirectFBScreen::TrackSurface); + dfbSurface = screen->createDFBSurface(QSize(width, height), + screen->pixelFormat(), + QDirectFBScreen::TrackSurface); forceRaster = (screen->pixelFormat() == QImage::Format_RGB32); if (!dfbSurface) { setSerialNumber(0); @@ -111,8 +111,8 @@ void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect) IDirectFBSurface *src = static_cast(data)->directFBSurface(); const bool hasAlpha = data->hasAlphaChannel(); const QImage::Format format = (hasAlpha - ? QDirectFBScreen::instance()->alphaPixmapFormat() - : QDirectFBScreen::instance()->pixelFormat()); + ? screen->alphaPixmapFormat() + : screen->pixelFormat()); dfbSurface = screen->createDFBSurface(rect.size(), format, QDirectFBScreen::TrackSurface); diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp index 592ad47..28b1e52 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp @@ -105,9 +105,9 @@ void QDirectFBSurface::createWindow() |DWDESC_PIXELFORMAT); description.surface_caps = DSCAPS_NONE; - if (QDirectFBScreen::instance()->preferVideoOnly()) + if (screen->preferVideoOnly()) description.surface_caps = DFBSurfaceCapabilities(description.surface_caps|DSCAPS_VIDEOONLY); - const QImage::Format format = QDirectFBScreen::instance()->pixelFormat(); + const QImage::Format format = screen->pixelFormat(); description.pixelformat = QDirectFBScreen::getSurfacePixelFormat(format); if (QDirectFBScreen::isPremultiplied(format)) description.surface_caps = DFBSurfaceCapabilities(DSCAPS_PREMULTIPLIED|description.caps); @@ -173,8 +173,8 @@ void QDirectFBSurface::setGeometry(const QRect &rect, const QRegion &mask) description.width = rect.width(); description.height = rect.height(); QDirectFBScreen::initSurfaceDescriptionPixelFormat(&description, - QDirectFBScreen::instance()->pixelFormat()); - dfbSurface = QDirectFBScreen::instance()->createDFBSurface(&description, false); + screen->pixelFormat()); + dfbSurface = screen->createDFBSurface(&description, false); forceRaster = (dfbSurface && QDirectFBScreen::getImageFormat(dfbSurface) == QImage::Format_RGB32); } else { Q_ASSERT(dfbSurface); -- cgit v0.12 From d3a4c7314ad7694361f510beeadcc012daf7992b Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 6 Apr 2009 23:02:20 -0700 Subject: Approriate warning with incompatible options QT_NO_DIRECTFB_LAYER doesn't work unless QT_NO_DIRECTFB_WM also is defined. Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp index 28b1e52..8140860 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp @@ -94,6 +94,9 @@ bool QDirectFBSurface::isValid() const #ifndef QT_NO_DIRECTFB_WM void QDirectFBSurface::createWindow() { +#ifdef QT_NO_DIRECTFB_LAYER +#warning QT_NO_DIRECTFB_LAYER requires QT_NO_DIRECTFB_WM +#else IDirectFBDisplayLayer *layer = screen->dfbDisplayLayer(); if (!layer) qFatal("QDirectFBWindowSurface: Unable to get primary display layer!"); @@ -121,6 +124,7 @@ void QDirectFBSurface::createWindow() dfbWindow->GetSurface(dfbWindow, &dfbSurface); forceRaster = (format == QImage::Format_RGB32); +#endif } #endif // QT_NO_DIRECTFB_WM -- cgit v0.12 From d821e3288c3f3dee0c4591e6fc64114511559680 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 6 Apr 2009 23:05:02 -0700 Subject: Kill some warnings Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp index 8140860..4b8fe0a 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp @@ -334,6 +334,12 @@ inline bool isWidgetOpaque(const QWidget *w) void QDirectFBSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &offset) { + Q_UNUSED(widget); +#ifdef QT_NO_DIRECTFB_WM + Q_UNUSED(region); + Q_UNUSED(offset); +#endif + QWidget *win = window(); // hw: make sure opacity information is updated before compositing -- cgit v0.12 From 470d87ac503debe3bead80628044d176479975eb Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Mon, 30 Mar 2009 15:21:59 +0200 Subject: Fixes: Make drawPixmap slightly more optimal for QPaintEngineEx RevBy: Samuel --- src/gui/painting/qpainter.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index fe6cc69..b2f0ac4 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -5155,9 +5155,6 @@ void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm) Q_D(QPainter); - if (!d->engine || pm.isNull()) - return; - #ifndef QT_NO_DEBUG qt_painter_thread_test(d->device->devType(), "drawPixmap()"); #endif @@ -5167,12 +5164,18 @@ void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm) return; } + if (!d->engine) + return; + qreal x = p.x(); qreal y = p.y(); int w = pm.width(); int h = pm.height(); + if (w <= 0) + return; + // Emulate opaque background for bitmaps if (d->state->bgMode == Qt::OpaqueMode && pm.isQBitmap()) { fillRect(QRectF(x, y, w, h), d->state->bgBrush.color()); -- cgit v0.12 From 7666940bc4a20c3db98ef8cefd4cd0196cf9a437 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Mon, 30 Mar 2009 16:25:54 +0200 Subject: Fixes: Make drawPixmap as fast as drawImage on rasterR RevBy: Samuel Details: The IMAGE_FROM_PIXMAP has to be doing a local copy or something, because it is sure not fast... --- src/gui/painting/qpaintengine_raster.cpp | 100 +++++++++++++++++++++---------- src/gui/painting/qpaintengine_raster_p.h | 2 +- 2 files changed, 68 insertions(+), 34 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 6dd5682..addd63d 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -2355,11 +2355,6 @@ void QRasterPaintEngine::strokePolygonCosmetic(const QPoint *points, int pointCo } } -#define IMAGE_FROM_PIXMAP(pixmap) \ - pixmap.data->classId() == QPixmapData::RasterClass \ - ? ((QRasterPixmapData *) pixmap.data)->image \ - : pixmap.toImage() - /*! \internal */ @@ -2368,16 +2363,33 @@ void QRasterPaintEngine::drawPixmap(const QPointF &pos, const QPixmap &pixmap) #ifdef QT_DEBUG_DRAW qDebug() << " - QRasterPaintEngine::drawPixmap(), pos=" << pos << " pixmap=" << pixmap.size() << "depth=" << pixmap.depth(); #endif - if (pixmap.depth() == 1) { - Q_D(QRasterPaintEngine); - QRasterPaintEngineState *s = state(); - if (s->matrix.type() <= QTransform::TxTranslate) { - drawBitmap(pos + QPointF(s->matrix.dx(), s->matrix.dy()), pixmap, &s->penData); + + if (pixmap.data->classId() == QPixmapData::RasterClass) { + const QImage &image = ((QRasterPixmapData *) pixmap.data)->image; + if (image.depth() == 1) { + Q_D(QRasterPaintEngine); + QRasterPaintEngineState *s = state(); + if (s->matrix.type() <= QTransform::TxTranslate) { + drawBitmap(pos + QPointF(s->matrix.dx(), s->matrix.dy()), image, &s->penData); + } else { + drawImage(pos, d->rasterBuffer->colorizeBitmap(image, s->pen.color())); + } } else { - drawImage(pos, d->rasterBuffer->colorizeBitmap(IMAGE_FROM_PIXMAP(pixmap), s->pen.color())); + QRasterPaintEngine::drawImage(pos, image); } } else { - QRasterPaintEngine::drawImage(pos, IMAGE_FROM_PIXMAP(pixmap)); + const QImage image = pixmap.toImage(); + if (pixmap.depth() == 1) { + Q_D(QRasterPaintEngine); + QRasterPaintEngineState *s = state(); + if (s->matrix.type() <= QTransform::TxTranslate) { + drawBitmap(pos + QPointF(s->matrix.dx(), s->matrix.dy()), image, &s->penData); + } else { + drawImage(pos, d->rasterBuffer->colorizeBitmap(image, s->pen.color())); + } + } else { + QRasterPaintEngine::drawImage(pos, image); + } } } @@ -2390,22 +2402,40 @@ void QRasterPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pixmap, cons qDebug() << " - QRasterPaintEngine::drawPixmap(), r=" << r << " sr=" << sr << " pixmap=" << pixmap.size() << "depth=" << pixmap.depth(); #endif - Q_D(QRasterPaintEngine); - QRasterPaintEngineState *s = state(); - - if (pixmap.depth() == 1) { - if (s->matrix.type() <= QTransform::TxTranslate - && r.size() == sr.size() - && r.size() == pixmap.size()) { - ensurePen(); - drawBitmap(r.topLeft() + QPointF(s->matrix.dx(), s->matrix.dy()), pixmap, &s->penData); - return; + if (pixmap.data->classId() == QPixmapData::RasterClass) { + const QImage &image = ((QRasterPixmapData *) pixmap.data)->image; + if (image.depth() == 1) { + Q_D(QRasterPaintEngine); + QRasterPaintEngineState *s = state(); + if (s->matrix.type() <= QTransform::TxTranslate + && r.size() == sr.size() + && r.size() == pixmap.size()) { + ensurePen(); + drawBitmap(r.topLeft() + QPointF(s->matrix.dx(), s->matrix.dy()), image, &s->penData); + return; + } else { + drawImage(r, d->rasterBuffer->colorizeBitmap(image, s->pen.color()), sr); + } } else { - drawImage(r, d->rasterBuffer->colorizeBitmap(IMAGE_FROM_PIXMAP(pixmap), - s->pen.color()), sr); + drawImage(r, image, sr); } } else { - drawImage(r, IMAGE_FROM_PIXMAP(pixmap), sr); + const QImage image = pixmap.toImage(); + if (image.depth() == 1) { + Q_D(QRasterPaintEngine); + QRasterPaintEngineState *s = state(); + if (s->matrix.type() <= QTransform::TxTranslate + && r.size() == sr.size() + && r.size() == pixmap.size()) { + ensurePen(); + drawBitmap(r.topLeft() + QPointF(s->matrix.dx(), s->matrix.dy()), image, &s->penData); + return; + } else { + drawImage(r, d->rasterBuffer->colorizeBitmap(image, s->pen.color()), sr); + } + } else { + drawImage(r, image, sr); + } } } @@ -2614,10 +2644,15 @@ void QRasterPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, QRasterPaintEngineState *s = state(); QImage image; - if (pixmap.depth() == 1) - image = d->rasterBuffer->colorizeBitmap(IMAGE_FROM_PIXMAP(pixmap), s->pen.color()); - else - image = IMAGE_FROM_PIXMAP(pixmap); + + if (pixmap.data->classId() == QPixmapData::RasterClass) { + image = ((QRasterPixmapData *) pixmap.data)->image; + } else { + image = pixmap.toImage(); + } + + if (image.depth() == 1) + image = d->rasterBuffer->colorizeBitmap(image, s->pen.color()); if (s->matrix.type() > QTransform::TxTranslate) { QTransform copy = s->matrix; @@ -3650,14 +3685,13 @@ void QRasterPaintEngine::drawBufferSpan(const uint *buffer, int bufsize, } #endif // Q_WS_QWS -void QRasterPaintEngine::drawBitmap(const QPointF &pos, const QPixmap &pm, QSpanData *fg) +void QRasterPaintEngine::drawBitmap(const QPointF &pos, const QImage &image, QSpanData *fg) { Q_ASSERT(fg); if (!fg->blend) return; Q_D(QRasterPaintEngine); - const QImage image = IMAGE_FROM_PIXMAP(pm); Q_ASSERT(image.depth() == 1); const int spanCount = 256; @@ -3665,8 +3699,8 @@ void QRasterPaintEngine::drawBitmap(const QPointF &pos, const QPixmap &pm, QSpan int n = 0; // Boundaries - int w = pm.width(); - int h = pm.height(); + int w = image.width(); + int h = image.height(); int ymax = qMin(qRound(pos.y() + h), d->rasterBuffer->height()); int ymin = qMax(qRound(pos.y()), 0); int xmax = qMin(qRound(pos.x() + w), d->rasterBuffer->width()); diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h index 0f8060a..26a2b3f 100644 --- a/src/gui/painting/qpaintengine_raster_p.h +++ b/src/gui/painting/qpaintengine_raster_p.h @@ -256,7 +256,7 @@ private: void init(); void fillRect(const QRectF &rect, QSpanData *data); - void drawBitmap(const QPointF &pos, const QPixmap &image, QSpanData *fill); + void drawBitmap(const QPointF &pos, const QImage &image, QSpanData *fill); void drawCachedGlyphs(const QPointF &p, const QTextItemInt &ti); -- cgit v0.12 From b78d46626aa3fd34009063fc0d870cf528119af5 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 1 Apr 2009 10:11:40 +0200 Subject: Fixes: Calling repaint() during a top-level resize RevBy: bnilsen Task: 249394 Details: When going through the backingstore a repaint in a toplevel resize should just discard the repaint() as it will repaint shortly after anyway. This is in line with the implementation of update(). --- src/gui/kernel/qwidget.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index f92d660..669c7a1 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -9417,11 +9417,13 @@ void QWidget::repaint(const QRect &rect) if (!isVisible() || !updatesEnabled() || rect.isEmpty()) return; - QTLWExtra *tlwExtra = !d->paintOnScreen() ? window()->d_func()->maybeTopData() : 0; - if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) { - tlwExtra->inRepaint = true; - tlwExtra->backingStore->markDirty(rect, this, true); - tlwExtra->inRepaint = false; + if (hasBackingStoreSupport()) { + QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); + if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) { + tlwExtra->inRepaint = true; + tlwExtra->backingStore->markDirty(rect, this, true); + tlwExtra->inRepaint = false; + } } else { d->repaint_sys(rect); } @@ -9444,11 +9446,13 @@ void QWidget::repaint(const QRegion &rgn) if (!isVisible() || !updatesEnabled() || rgn.isEmpty()) return; - QTLWExtra *tlwExtra = !d->paintOnScreen() ? window()->d_func()->maybeTopData() : 0; - if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) { - tlwExtra->inRepaint = true; - tlwExtra->backingStore->markDirty(rgn, this, true); - tlwExtra->inRepaint = false; + if (hasBackingStoreSupport()) { + QTLWExtra *tlwExtra = window()->d_func()->maybeTopData(); + if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore) { + tlwExtra->inRepaint = true; + tlwExtra->backingStore->markDirty(rgn, this, true); + tlwExtra->inRepaint = false; + } } else { d->repaint_sys(rgn); } -- cgit v0.12 From e0560bcaa3703fafccc21dd709731341a123a0e4 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Thu, 2 Apr 2009 11:27:57 +0200 Subject: Works around a crash in q3richtext. Full fix will potentially break other code and is thus avoided Task-number: 248992 Reviewed-by: Trond --- src/qt3support/text/q3richtext.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qt3support/text/q3richtext.cpp b/src/qt3support/text/q3richtext.cpp index c058e37..e508001 100644 --- a/src/qt3support/text/q3richtext.cpp +++ b/src/qt3support/text/q3richtext.cpp @@ -4895,7 +4895,8 @@ void Q3TextParagraph::drawString(QPainter &painter, const QString &str, int star bool extendRight = false; bool extendLeft = false; bool selWrap = (real_selEnd == length()-1 && n && n->hasSelection(it.key())); - if (selWrap || this->str->at(real_selEnd).lineStart) { + if (selWrap + || ((real_selEnd < this->str->length()) && this->str->at(real_selEnd).lineStart)) { extendRight = (fullSelectionWidth != 0); if (!extendRight && !rightToLeft) tmpw += painter.fontMetrics().width(QLatin1Char(' ')); -- cgit v0.12 From 974680679b03c668ffce87bd50b5dacf44b0fa22 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Fri, 3 Apr 2009 11:16:40 +0200 Subject: Adds a few \warnings to the docs on do-not-use-for-performance-reasons Reviewed-by: Trond --- src/gui/graphicsview/qgraphicsproxywidget.cpp | 8 ++++++-- src/gui/image/qimage.cpp | 12 +++++++++++- src/gui/image/qpixmap.cpp | 18 ++++++++++++++++-- src/gui/painting/qpainter.cpp | 10 ++++++++++ 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsproxywidget.cpp b/src/gui/graphicsview/qgraphicsproxywidget.cpp index 1d2721b..e660879 100644 --- a/src/gui/graphicsview/qgraphicsproxywidget.cpp +++ b/src/gui/graphicsview/qgraphicsproxywidget.cpp @@ -177,6 +177,10 @@ QT_BEGIN_NAMESPACE while the widget is embedded. In this state, the widget may differ slightly in behavior from when it is not embedded. + \warning This class is provided for convenience when bridging + QWidgets and QGraphicsItems, it should not be used for + high-performance scenarios. + \sa QGraphicsScene::addWidget(), QGraphicsWidget */ @@ -1033,7 +1037,7 @@ void QGraphicsProxyWidget::dragMoveEvent(QGraphicsSceneDragDropEvent *event) if (receiver != d->dragDropWidget) { // Try to enter before we leave QDragEnterEvent dragEnter(receiverPos, event->possibleActions(), event->mimeData(), event->buttons(), event->modifiers()); - dragEnter.setDropAction(event->proposedAction()); + dragEnter.setDropAction(event->proposedAction()); QApplication::sendEvent(receiver, &dragEnter); event->setAccepted(dragEnter.isAccepted()); event->setDropAction(dragEnter.dropAction()); @@ -1431,7 +1435,7 @@ int QGraphicsProxyWidget::type() const Creates a proxy widget for the given \a child of the widget contained in this proxy. - + This function makes it possible to aquire proxies for non top-level widgets. For instance, you can embed a dialog, and then transform only one of its widgets. diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index dc236e4..6945ef8 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -114,7 +114,7 @@ Q_GUI_EXPORT _qt_image_cleanup_hook qt_image_cleanup_hook = 0; typedef void (*_qt_image_cleanup_hook_64)(qint64); Q_GUI_EXPORT _qt_image_cleanup_hook_64 qt_image_cleanup_hook_64 = 0; -static QImage rotated90(const QImage &src); +static QImage rotated90(const QImage &src);= static QImage rotated180(const QImage &src); static QImage rotated270(const QImage &src); @@ -3607,6 +3607,9 @@ int QImage::pixelIndex(int x, int y) const If the \a position is not valid, the results are undefined. + \warning This function is expensive when used for massive pixel + manipulations. + \sa setPixel(), valid(), {QImage#Pixel Manipulation}{Pixel Manipulation} */ @@ -5581,6 +5584,8 @@ bool QImage::isDetached() const Use one of the composition mods in QPainter::CompositionMode instead. + \warning This function is expensive. + \sa alphaChannel(), {QImage#Image Transformations}{Image Transformations}, {QImage#Image Formats}{Image Formats} */ @@ -5663,6 +5668,11 @@ void QImage::setAlphaChannel(const QImage &alphaChannel) \l{QPixmap::}{alphaChannel()}, which works in the same way as this function on QPixmaps. + Most usecases for this function can be replaced with QPainter and + using composition modes. + + \warning This is an expensive function. + \sa setAlphaChannel(), hasAlphaChannel(), {QPixmap#Pixmap Information}{Pixmap}, {QImage#Image Transformations}{Image Transformations} diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 8684a1b..efb8260 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -674,7 +674,7 @@ void QPixmap::resize_helper(const QSize &s) pixels black. The effect of this function is undefined when the pixmap is being painted on. - This is potentially an expensive operation. + \warning This is potentially an expensive operation. \sa mask(), {QPixmap#Pixmap Transformations}{Pixmap Transformations}, QBitmap @@ -1380,6 +1380,12 @@ void QPixmap::deref() If the given \a size is empty, this function returns a null pixmap. + + In some cases it can be more beneficial to draw the pixmap to a + painter with a scale set rather than scaling the pixmap. This is + the case when the painter is for instance based on OpenGL or when + the scale factor changes rapidly. + \sa isNull(), {QPixmap#Pixmap Transformations}{Pixmap Transformations} @@ -1751,6 +1757,10 @@ int QPixmap::metric(PaintDeviceMetric metric) const The effect of this function is undefined when the pixmap is being painted on. + \warning This is potentially an expensive operation. Most usecases + for this function are covered by QPainter and compositionModes + which will normally execute faster. + \sa alphaChannel(), {QPixmap#Pixmap Transformations}{Pixmap Transformations} */ @@ -1793,6 +1803,9 @@ void QPixmap::setAlphaChannel(const QPixmap &alphaChannel) \image alphachannelimage.png The pixmap and channelImage QPixmaps + \warning This is an expensive operation. The alpha channel of the + pixmap is extracted dynamically from the pixeldata. + \sa setAlphaChannel(), {QPixmap#Pixmap Information}{Pixmap Information} */ @@ -1814,7 +1827,8 @@ QPaintEngine *QPixmap::paintEngine() const Extracts a bitmap mask from the pixmap's alphachannel. - This is potentially an expensive operation. + \warning This is potentially an expensive operation. The mask of + the pixmap is extracted dynamically from the pixeldata. \sa setMask(), {QPixmap#Pixmap Information}{Pixmap Information} */ diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index b2f0ac4..2beb8c2 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -2371,6 +2371,11 @@ void QPainter::setClipping(bool enable) Returns the currently set clip region. Note that the clip region is given in logical coordinates. + \warning QPainter does not store the combined clip explicitly as + this is handled by the underlying QPaintEngine, so the path is + recreated on demand and transformed to the current logical + coordinate system. This is potentially an expensive operation. + \sa setClipRegion(), clipPath(), setClipping() */ @@ -2486,6 +2491,11 @@ extern QPainterPath qt_regionToPath(const QRegion ®ion); Returns the currently clip as a path. Note that the clip path is given in logical coordinates. + \warning QPainter does not store the combined clip explicitly as + this is handled by the underlying QPaintEngine, so the path is + recreated on demand and transformed to the current logical + coordinate system. This is potentially an expensive operation. + \sa setClipPath(), clipRegion(), setClipping() */ QPainterPath QPainter::clipPath() const -- cgit v0.12 From 640f2c732c6fd76866cd7e601a9140dbe7849e6f Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Mon, 6 Apr 2009 17:18:22 +0200 Subject: BT: Fix regression when tooltips dissappear suddenly in Unified toolbar QWidget::childAt() makes some assumptions about its children (they are all contained in its geometry). This does not hold up when using the unified toolbar because the toolbar ends up in the "non-client" area. So, when dispatching an enter/leave event in tooltip show, we end up dispatching to the wrong widgets and that results in the tooltip cleverly thinking that it needs to hide itself because we've left the widget that needs the tooltip. I've special cased this by just having a "native" mapFromParent() that is only called for on the mac, though there is nothing that is limiting this from being called on other platfroms. Also QWidget::mapFromParent() probably needs to be looked at at some point. Task-number: 248048 Reviewed-by: Richard Moe Gustavsen --- src/gui/kernel/qt_mac_p.h | 1 + src/gui/kernel/qwidget.cpp | 24 ++++++++++++++++++++++-- src/gui/kernel/qwidget_mac.mm | 14 ++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qt_mac_p.h b/src/gui/kernel/qt_mac_p.h index 3aec23f..e65492d 100644 --- a/src/gui/kernel/qt_mac_p.h +++ b/src/gui/kernel/qt_mac_p.h @@ -233,6 +233,7 @@ extern QPaintDevice *qt_mac_safe_pdev; //qapplication_mac.cpp extern OSWindowRef qt_mac_window_for(const QWidget*); //qwidget_mac.mm extern OSViewRef qt_mac_nativeview_for(const QWidget *); //qwidget_mac.mm +extern QPoint qt_mac_nativeMapFromParent(const QWidget *child, const QPoint &pt); //qwidget_mac.mm #ifdef check # undef check diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 669c7a1..31fed5e 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -66,6 +66,7 @@ #ifdef Q_WS_MAC # include "qt_mac_p.h" # include "qt_cocoa_helpers_mac_p.h" +# include "qmainwindow.h" #endif #if defined(Q_WS_QWS) # include "qwsdisplay_qws.h" @@ -8966,17 +8967,36 @@ QWidget *QWidget::childAt(const QPoint &p) const QWidget *QWidgetPrivate::childAt_helper(const QPoint &p, bool ignoreChildrenInDestructor) const { Q_Q(const QWidget); - if (!q->rect().contains(p)) +#ifdef Q_WS_MAC + bool includeFrame = q->isWindow() && qobject_cast(q) + && static_cast(q)->unifiedTitleAndToolBarOnMac(); +#endif + + if ( +#ifdef Q_WS_MAC + !includeFrame && +#endif + !q->rect().contains(p)) return 0; + for (int i = children.size(); i > 0 ;) { --i; QWidget *w = qobject_cast(children.at(i)); - if (w && !w->isWindow() && !w->isHidden() && w->geometry().contains(p)) { + if (w && !w->isWindow() && !w->isHidden() + && (w->geometry().contains(p) +#ifdef Q_WS_MAC + || (includeFrame && w->geometry().contains(qt_mac_nativeMapFromParent(w, p))) +#endif + )) { if (ignoreChildrenInDestructor && w->data->in_destructor) continue; if (w->testAttribute(Qt::WA_TransparentForMouseEvents)) continue; QPoint childPoint = w->mapFromParent(p); +#ifdef Q_WS_MAC + if (includeFrame && !w->geometry().contains(p)) + childPoint = qt_mac_nativeMapFromParent(w, p); +#endif if (QWidget *t = w->d_func()->childAt_helper(childPoint, ignoreChildrenInDestructor)) return t; // if WMouseNoMask is set the widget mask is ignored, if diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index f2a532f..5432c55 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -3274,6 +3274,20 @@ void QWidgetPrivate::show_sys() qt_event_request_window_change(q); } + +QPoint qt_mac_nativeMapFromParent(const QWidget *child, const QPoint &pt) +{ +#ifndef QT_MAC_USE_COCOA + CGPoint nativePoint = CGPointMake(pt.x(), pt.y()); + HIViewConvertPoint(&nativePoint, qt_mac_nativeview_for(child->parentWidget()), + qt_mac_nativeview_for(child)); +#else + NSPoint nativePoint = [qt_mac_nativeview_for(child) convertPoint:NSMakePoint(pt.x(), pt.y()) fromView:qt_mac_nativeview_for(child->parentWidget())]; +#endif + return QPoint(nativePoint.x, nativePoint.y); +} + + void QWidgetPrivate::hide_sys() { Q_Q(QWidget); -- cgit v0.12 From d2b10ebfa77a78687389d08627ab0b14cf48fb21 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Tue, 7 Apr 2009 09:28:20 +0200 Subject: Compile. Looks like a typo. Reviewed-by: Bradley T. Hughes --- src/gui/image/qimage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 6945ef8..c7a20db 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -114,7 +114,7 @@ Q_GUI_EXPORT _qt_image_cleanup_hook qt_image_cleanup_hook = 0; typedef void (*_qt_image_cleanup_hook_64)(qint64); Q_GUI_EXPORT _qt_image_cleanup_hook_64 qt_image_cleanup_hook_64 = 0; -static QImage rotated90(const QImage &src);= +static QImage rotated90(const QImage &src); static QImage rotated180(const QImage &src); static QImage rotated270(const QImage &src); -- cgit v0.12 From e60d3622607cbf1b3583a205fc9e3e019a555b45 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Tue, 7 Apr 2009 07:42:30 +0200 Subject: QLocalSocket will disconnect 30 seconds after a successful delayed connect When the connection is established, the socket notifier is deleted, but not the connection timer, so the opened connection will be closed after 30 seconds. Task-number: none Reviewed-by: Andreas Reviewed-by: Thiago --- src/network/socket/qlocalsocket_p.h | 1 + src/network/socket/qlocalsocket_unix.cpp | 28 +++++++++++++++------------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/network/socket/qlocalsocket_p.h b/src/network/socket/qlocalsocket_p.h index dd48d0a..781d3da 100644 --- a/src/network/socket/qlocalsocket_p.h +++ b/src/network/socket/qlocalsocket_p.h @@ -192,6 +192,7 @@ public: void _q_error(QAbstractSocket::SocketError newError); void _q_connectToSocket(); void _q_abortConnectionAttempt(); + void cancelDelayedConnect(); QSocketNotifier *delayConnect; QTimer *connectTimer; int connectingSocket; diff --git a/src/network/socket/qlocalsocket_unix.cpp b/src/network/socket/qlocalsocket_unix.cpp index a375e9b..38643f1 100644 --- a/src/network/socket/qlocalsocket_unix.cpp +++ b/src/network/socket/qlocalsocket_unix.cpp @@ -322,11 +322,8 @@ void QLocalSocketPrivate::_q_connectToSocket() } // connected! - if (delayConnect) { - delayConnect->setEnabled(false); - delete delayConnect; - delayConnect = 0; - } + cancelDelayedConnect(); + serverName = connectingName; fullServerName = connectingPathName; if (unixSocket.setSocketDescriptor(connectingSocket, @@ -373,6 +370,18 @@ void QLocalSocketPrivate::_q_abortConnectionAttempt() q->close(); } +void QLocalSocketPrivate::cancelDelayedConnect() +{ + if (delayConnect) { + delayConnect->setEnabled(false); + delete delayConnect; + delayConnect = 0; + connectTimer->stop(); + delete connectTimer; + connectTimer = 0; + } +} + quintptr QLocalSocket::socketDescriptor() const { Q_D(const QLocalSocket); @@ -419,14 +428,7 @@ void QLocalSocket::close() { Q_D(QLocalSocket); d->unixSocket.close(); - if (d->delayConnect) { - d->delayConnect->setEnabled(false); - delete d->delayConnect; - d->delayConnect = 0; - d->connectTimer->stop(); - delete d->connectTimer; - d->connectTimer = 0; - } + d->cancelDelayedConnect(); if (d->connectingSocket != -1) ::close(d->connectingSocket); d->connectingSocket = -1; -- cgit v0.12 From b9d6ecc1dbe5791fec6fb06de3be06186b485420 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Tue, 7 Apr 2009 09:51:31 +0200 Subject: BT: Compile without QT3SUPPORT Reviewed-by: ogoffart --- src/gui/styles/qgtkstyle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index 6354ce7..b569b5c 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -2634,7 +2634,7 @@ void QGtkStyle::drawControl(ControlElement element, QColor disabledTextColor = QColor(gdkDText.red>>8, gdkDText.green>>8, gdkDText.blue>>8); if (resolve_mask & (1 << QPalette::ButtonText)) { textColor = option->palette.buttonText().color(); - disabledTextColor = option->palette.brush(QPalette::Disabled, QPalette::ButtonText);; + disabledTextColor = option->palette.brush(QPalette::Disabled, QPalette::ButtonText).color(); } QColor highlightedTextColor = QColor(gdkHText.red>>8, gdkHText.green>>8, gdkHText.blue>>8); -- cgit v0.12 From 730b936b53633891e2b8c505a3ff4c93209e7ae8 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 6 Apr 2009 17:06:28 +0200 Subject: fix QMAKE_VAR_FIRST_ expansion in compiler flags doesn't seem to be a terribly popular feature, given that nobody noticed this yet ... --- qmake/generators/makefile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 3e5452e..67e5bfb 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -1492,7 +1492,7 @@ MakefileGenerator::replaceExtraCompilerVariables(const QString &orig_var, const val += project->values(varname); } if(val.isEmpty() && var.startsWith(QLatin1String("QMAKE_VAR_FIRST_"))) { - const QString varname = var.mid(12); + const QString varname = var.mid(16); val += project->first(varname); } -- cgit v0.12 From 3279b07302fde0eb14f9b197c9ad2e14d512817e Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 6 Apr 2009 19:39:03 +0200 Subject: make shadow builds with default moc/ui dirs work again append the source dir to the include path, but only after the dirs with the generated files. this seems to have worked before only accidentally: the unqualified default dirs were expanded to the source dir instead of the build dir, but the build dir is added implicitly by default, so things magically worked. now that we qualify the moc/ui dirs, projects relying on the strange side effect suddenly break. we should probably add the source dir to the include path by default, but this coupling to uic/moc is closer to the historical behavior and thus should be safer. Reviewed-by: mariusSO --- mkspecs/features/include_source_dir.prf | 1 + mkspecs/features/moc.prf | 7 +++++++ mkspecs/features/uic.prf | 7 +++++++ 3 files changed, 15 insertions(+) create mode 100644 mkspecs/features/include_source_dir.prf diff --git a/mkspecs/features/include_source_dir.prf b/mkspecs/features/include_source_dir.prf new file mode 100644 index 0000000..8794998 --- /dev/null +++ b/mkspecs/features/include_source_dir.prf @@ -0,0 +1 @@ +!equals(_PRO_FILE_PWD_, $$OUT_PWD):INCLUDEPATH *= . diff --git a/mkspecs/features/moc.prf b/mkspecs/features/moc.prf index f1dcf37..f18d462 100644 --- a/mkspecs/features/moc.prf +++ b/mkspecs/features/moc.prf @@ -66,6 +66,13 @@ win32:moc_dir_short ~= s,^.:,/, contains(moc_dir_short, ^[/\\\\].*):INCLUDEPATH += $$MOC_DIR else:INCLUDEPATH += $$OUT_PWD/$$MOC_DIR +# Backwards compatibility: Make shadow builds with default MOC_DIR work +# if the user did not add the source dir explicitly. +equals(MOC_DIR, .) { + CONFIG -= include_source_dir + CONFIG = include_source_dir $$CONFIG +} + #auto depend on moc unix:!no_mocdepend { moc_source.depends += $$first(QMAKE_MOC) diff --git a/mkspecs/features/uic.prf b/mkspecs/features/uic.prf index c7b1686..0c7fb1b 100644 --- a/mkspecs/features/uic.prf +++ b/mkspecs/features/uic.prf @@ -39,6 +39,13 @@ win32:ui_dir_short ~= s,^.:,/, contains(ui_dir_short, ^[/\\\\].*):INCLUDEPATH += $$UI_HEADERS_DIR else:INCLUDEPATH += $$OUT_PWD/$$UI_HEADERS_DIR +# Backwards compatibility: Make shadow builds with default UI_DIR work +# if the user did not add the source dir explicitly. +equals(UI_DIR, .) { + CONFIG -= include_source_dir + CONFIG = include_source_dir $$CONFIG +} + uic3 { isEmpty(FORMS3) { UIC3_FORMS = FORMS -- cgit v0.12 From d8f76432c3937690c37972136c02a5a264bc941f Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 7 Apr 2009 11:26:12 +0200 Subject: qmake: additional compiler options were written twice into vcproj files In the function initCompilerTool we handled QMAKE_CXXFLAGS twice for every configuration (debug / release). The call of parseOptions before the if clause is enough. Reviewed-by: mariusSO --- qmake/generators/win32/msvc_vcproj.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 08159b0..8901289 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -1030,7 +1030,6 @@ void VcprojGenerator::initCompilerTool() conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS")); if(project->isActiveConfig("debug")){ // Debug version - conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS")); conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_DEBUG")); if((projectTarget == Application) || (projectTarget == StaticLib)) conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_MT_DBG")); @@ -1038,7 +1037,6 @@ void VcprojGenerator::initCompilerTool() conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_MT_DLLDBG")); } else { // Release version - conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS")); conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_RELEASE")); conf.compiler.PreprocessorDefinitions += "QT_NO_DEBUG"; conf.compiler.PreprocessorDefinitions += "NDEBUG"; -- cgit v0.12 From 467b23fcff9f25a14abf051edfb2373c36172fc9 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Tue, 7 Apr 2009 12:14:22 +0200 Subject: Fixes missing hover on QListView in Vista We did not enable hover on list view item views. This is inconsistent with how QTreeView works as well as different from how native icon views behave. Reviewed-by: Prasanth Ullattil Task number: 242519 --- src/gui/styles/qwindowsvistastyle.cpp | 3 +++ src/gui/styles/qwindowsvistastyle_p.h | 1 + 2 files changed, 4 insertions(+) diff --git a/src/gui/styles/qwindowsvistastyle.cpp b/src/gui/styles/qwindowsvistastyle.cpp index b14b8b3..013ca1e 100644 --- a/src/gui/styles/qwindowsvistastyle.cpp +++ b/src/gui/styles/qwindowsvistastyle.cpp @@ -2396,6 +2396,9 @@ void QWindowsVistaStyle::polish(QWidget *widget) else if (QTreeView *tree = qobject_cast (widget)) { tree->viewport()->setAttribute(Qt::WA_Hover); } + else if (QListView *list = qobject_cast (widget)) { + list->viewport()->setAttribute(Qt::WA_Hover); + } } /*! diff --git a/src/gui/styles/qwindowsvistastyle_p.h b/src/gui/styles/qwindowsvistastyle_p.h index 877bc50..cef2b71 100644 --- a/src/gui/styles/qwindowsvistastyle_p.h +++ b/src/gui/styles/qwindowsvistastyle_p.h @@ -76,6 +76,7 @@ #include #include #include +#include #include #include #include -- cgit v0.12 From c1c30037292711f0fb05677e77ed2eb2112eca78 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 7 Apr 2009 12:50:32 +0200 Subject: Fixes: WDestructiveClose flag and the new WindowCancelButtonHint have the same value -> crash on SetTitle() Task: 242484 RevBy: mauricek AutoTest: Details: Since we do not respect binary compatibility on Windows CE we just change the enum --- src/corelib/global/qnamespace.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index fb7fa0c..a519f4a 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -280,9 +280,7 @@ public: WindowStaysOnTopHint = 0x00040000, // reserved for Qt3Support: // WMouseNoMask = 0x00080000, - WindowOkButtonHint = 0x00080000, // WDestructiveClose = 0x00100000, - WindowCancelButtonHint = 0x00100000, // WStaticContents = 0x00200000, // WGroupLeader = 0x00400000, // WShowModal = 0x00800000, @@ -291,7 +289,9 @@ public: WindowStaysOnBottomHint = 0x04000000, WindowCloseButtonHint = 0x08000000, MacWindowToolBarButtonHint = 0x10000000, - BypassGraphicsProxyWidget = 0x20000000 + BypassGraphicsProxyWidget = 0x20000000, + WindowOkButtonHint = 0x00080000, + WindowCancelButtonHint = 0x00100000 #ifdef QT3_SUPPORT , -- cgit v0.12 From a6ab4f638a63755a601b61141fa7730d5ac6e793 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Tue, 7 Apr 2009 13:16:28 +0200 Subject: Adjust comments Someone messed up the whitespace on this comment. --- src/gui/widgets/qcocoamenu_mac.mm | 67 ++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/src/gui/widgets/qcocoamenu_mac.mm b/src/gui/widgets/qcocoamenu_mac.mm index c92dfc0..64da141 100644 --- a/src/gui/widgets/qcocoamenu_mac.mm +++ b/src/gui/widgets/qcocoamenu_mac.mm @@ -1,41 +1,41 @@ /**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) + ** Contact: Qt Software Information (qt-info@nokia.com) ** ** This file is part of the QtGui module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ + ** No Commercial Usage + ** This file contains pre-release code and may not be distributed. + ** You may use this file in accordance with the terms and conditions + ** contained in the either Technology Preview License Agreement or the + ** Beta Release License Agreement. + ** + ** GNU Lesser General Public License Usage + ** Alternatively, this file may be used under the terms of the GNU Lesser + ** General Public License version 2.1 as published by the Free Software + ** Foundation and appearing in the file LICENSE.LGPL included in the + ** packaging of this file. Please review the following information to + ** ensure the GNU Lesser General Public License version 2.1 requirements + ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. + ** + ** In addition, as a special exception, Nokia gives you certain + ** additional rights. These rights are described in the Nokia Qt LGPL + ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this + ** package. + ** + ** GNU General Public License Usage + ** Alternatively, this file may be used under the terms of the GNU + ** General Public License version 3.0 as published by the Free Software + ** Foundation and appearing in the file LICENSE.GPL included in the + ** packaging of this file. Please review the following information to + ** ensure the GNU General Public License version 3.0 requirements will be + ** met: http://www.gnu.org/copyleft/gpl.html. + ** + ** If you are unsure which license is appropriate for your use, please + ** contact the sales department at qt-sales@nokia.com. + ** $QT_END_LICENSE$ ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. @@ -134,8 +134,9 @@ QT_END_NAMESPACE // If it does, then we will first send the key sequence to the QWidget that has focus // since (in Qt's eyes) it needs to a chance at the key event first. If the widget // accepts the key event, we then return YES, but set the target and action to be nil, - // which means that the action should not be triggered. In every other case we return - // NO, which means that Cocoa can do as it pleases (i.e., fire the menu action). + // which means that the action should not be triggered, and instead dispatch the event ourselves. + // In every other case we return NO, which means that Cocoa can do as it pleases + // (i.e., fire the menu action). NSMenuItem *whichItem; if ([self hasShortcut:menu forKey:[event characters] -- cgit v0.12 From acff913a6287ad50b0ac782d817d51072ccb479c Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Tue, 7 Apr 2009 13:17:05 +0200 Subject: BT: Send the keyevent after we send the shortcutoverride in menu In our Cocoa menu we check if we need to send the key event to the qwidget before the menu has a chance at it, because logically in Qt, the key event should go to the widget and not the menubar first (a bit different than what happens on the mac). The way to determine this is to send a shortcut override event and see if it accepts it. If it does, that means we should just send it the key event. Previously we were sending the shortcut override, but not following through on the key event because we thought (however foolishly). That returning "YES" but not setting an action would somehow forward the event (it doesn't). There still seems to be some problems if you have a Dvorak-QWERTY+CWD layout, but this probably needs to be dealt with at the key mapper level. Reviewed-by: Prasanth Ullattil --- src/gui/widgets/qcocoamenu_mac.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/widgets/qcocoamenu_mac.mm b/src/gui/widgets/qcocoamenu_mac.mm index 64da141..bae270a 100644 --- a/src/gui/widgets/qcocoamenu_mac.mm +++ b/src/gui/widgets/qcocoamenu_mac.mm @@ -161,6 +161,7 @@ QT_END_NAMESPACE if (accel_ev.isAccepted()) { *target = nil; *action = nil; + [qt_mac_nativeview_for(widget) keyDown:event]; return YES; } } -- cgit v0.12 From 179fafcc370c907a6070c7150695d446255e68d1 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 7 Apr 2009 13:19:11 +0200 Subject: BT: QFileDialog: A folder with a name containing diacritic is disabled on Mac OS X - cocoa The filename as NSString that we get from Cocoa does not have the correct file system encoding. This means that certain characters are implemented differently than what e.g. QFile::encoded returns. This fix normalizes the string from cocoa before using it. Task-number: 249928 Reviewed-by: Trenton Schulz --- src/gui/dialogs/qfiledialog_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/dialogs/qfiledialog_mac.mm b/src/gui/dialogs/qfiledialog_mac.mm index 4c13d01..90af9fc 100644 --- a/src/gui/dialogs/qfiledialog_mac.mm +++ b/src/gui/dialogs/qfiledialog_mac.mm @@ -278,7 +278,7 @@ QT_USE_NAMESPACE { Q_UNUSED(sender); QString qtFileName = QT_PREPEND_NAMESPACE(qt_mac_NSStringToQString)(filename); - QFileInfo info(qtFileName); + QFileInfo info(qtFileName.normalized(QT_PREPEND_NAMESPACE(QString::NormalizationForm_C))); QString path = info.absolutePath(); if (path != *mLastFilterCheckPath){ *mLastFilterCheckPath = path; -- cgit v0.12 From 3934e698b00e5ee89cd3b2b4474bc50a4947a174 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Tue, 7 Apr 2009 13:55:31 +0200 Subject: Wrong merge after 6e13559503040963c28dd8f5b6881e3a2b9d5596. Do not update the cache's exposed list if the entire cache is already exposed. Makes tst_QGraphicsItem::cacheMode pass again. Reviewed-by: Andreas --- src/gui/graphicsview/qgraphicsitem.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 0f39263..742b711 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -3998,14 +3998,14 @@ void QGraphicsItem::update(const QRectF &rect) return; if (CacheMode(d_ptr->cacheMode) != NoCache) { - QGraphicsItemCache *cache = d_ptr->maybeExtraItemCache(); - if (!cache || cache->allExposed) - return; - if (rect.isNull()) { - cache->allExposed = true; - cache->exposed.clear(); - } else { - cache->exposed.append(rect); + QGraphicsItemCache *cache = d_ptr->extraItemCache(); + if (!cache->allExposed) { + if (rect.isNull()) { + cache->allExposed = true; + cache->exposed.clear(); + } else { + cache->exposed.append(rect); + } } } -- cgit v0.12 From ca2d62f97f991d042a781d9d7bd0dbda910e1d04 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Tue, 7 Apr 2009 10:59:41 +0200 Subject: Drag cursor is not updated when modifier keys are pressed/released in the Cocoa Builds. The drag move events were compressed based only on the position of the cursor. It has to be based on both position and the "drag operation" in native event. Reviewed-by: nrc --- src/gui/kernel/qcocoaview_mac.mm | 6 ++++-- src/gui/kernel/qt_mac_p.h | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 19367d1..9b581c5 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -300,11 +300,13 @@ extern "C" { NSPoint windowPoint = [sender draggingLocation]; NSPoint globalPoint = [[sender draggingDestinationWindow] convertBaseToScreen:windowPoint]; NSPoint localPoint = [self convertPoint:windowPoint fromView:nil]; + NSDragOperation nsActions = [sender draggingSourceOperationMask]; QPoint posDrag(localPoint.x, localPoint.y); - if (qt_mac_mouse_inside_answer_rect(posDrag)) + if (qt_mac_mouse_inside_answer_rect(posDrag) + && QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastOperation) == nsActions) return QT_PREPEND_NAMESPACE(qt_mac_mapDropActions)(QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastAction)); // send drag move event to the widget - NSDragOperation nsActions = [sender draggingSourceOperationMask]; + QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastOperation) = nsActions; Qt::DropActions qtAllowed = QT_PREPEND_NAMESPACE(qt_mac_mapNSDragOperations)(nsActions); QMimeData *mimeData = dropData; if (QDragManager::self()->source()) diff --git a/src/gui/kernel/qt_mac_p.h b/src/gui/kernel/qt_mac_p.h index e65492d..ca995dc 100644 --- a/src/gui/kernel/qt_mac_p.h +++ b/src/gui/kernel/qt_mac_p.h @@ -250,11 +250,13 @@ struct QMacDndAnswerRecord { Qt::KeyboardModifiers modifiers; Qt::MouseButtons buttons; Qt::DropAction lastAction; + unsigned int lastOperation; void clear() { rect = QRect(); modifiers = Qt::NoModifier; buttons = Qt::NoButton; lastAction = Qt::IgnoreAction; + lastOperation = 0; } }; extern QMacDndAnswerRecord qt_mac_dnd_answer_rec; -- cgit v0.12 From c5b0197611ebb3279b3426aca275458477edb42d Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Tue, 7 Apr 2009 14:15:39 +0200 Subject: My changelog for 4.5.1 --- dist/changes-4.5.1 | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index 1d2286e..de4eef7 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -33,9 +33,25 @@ Third party components * Library * **************************************************************************** +- QAbstractSocket + * [192037] Emit disconnected only if we were connected before + +- QAuthenticator + * [237979] fix implemenation of md5-sess + +- QFileInfo + * [205244] return valid file info also for relative UNC paths + +- QHttp + * [208445] cancel request upon receiving unknown authentication method + - QSharedPointer * [246843] Fixed a crash caused by using QSharedPointer in global statics +- QSSlSocket + * [245668] set also protocol, verifyMode and verifyDepth in + setSslConfiguration() + **************************************************************************** * Database Drivers * **************************************************************************** -- cgit v0.12 From 1562ae67a1be7a16e1e2f6a5c40528da61e40cec Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 7 Apr 2009 14:34:05 +0200 Subject: compile fix with namespaces --- src/gui/graphicsview/qgraphicsitem.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 742b711..26fc485 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -3713,7 +3713,7 @@ void QGraphicsItemPrivate::fullUpdateHelper(bool childrenOnly, bool maybeDirtyCl dirtyChildren = 1; } -static inline bool allChildrenCombineOpacity(QGraphicsItem *parent) +static inline bool allChildrenCombineOpacityHelper(QGraphicsItem *parent) { Q_ASSERT(parent); if (parent->flags() & QGraphicsItem::ItemDoesntPropagateOpacityToChildren) @@ -3732,11 +3732,11 @@ void QGraphicsItemPrivate::updateEffectiveOpacity() Q_Q(QGraphicsItem); if (parent) { resolveEffectiveOpacity(parent->effectiveOpacity()); - parent->d_ptr->allChildrenCombineOpacity = ::allChildrenCombineOpacity(parent); + parent->d_ptr->allChildrenCombineOpacity = allChildrenCombineOpacityHelper(parent); } else { resolveEffectiveOpacity(1.0); } - allChildrenCombineOpacity = ::allChildrenCombineOpacity(q); + allChildrenCombineOpacity = allChildrenCombineOpacityHelper(q); } /*! -- cgit v0.12 From 0ea43e7d28815c133e8029f3d966871a10fef8e0 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 7 Apr 2009 14:55:04 +0200 Subject: Fixes: mediaobject autotest for windows ce (waveout) RevBy: Joerg AutoTest: mediaobject Details: Since our wave files on Windows CE are very short (memory) we actually land up in the PausedState when playback is finished --- tests/auto/mediaobject/tst_mediaobject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/mediaobject/tst_mediaobject.cpp b/tests/auto/mediaobject/tst_mediaobject.cpp index 96589b7..e0275de 100644 --- a/tests/auto/mediaobject/tst_mediaobject.cpp +++ b/tests/auto/mediaobject/tst_mediaobject.cpp @@ -787,7 +787,7 @@ void tst_MediaObject::setMediaAndPlay() QSignalSpy totalTimeChangedSignalSpy(m_media, SIGNAL(totalTimeChanged(qint64))); QVERIFY(m_media->currentSource().type() != MediaSource::Invalid); Phonon::State state = m_media->state(); - QVERIFY(state == Phonon::StoppedState || state == Phonon::PlayingState); + QVERIFY(state == Phonon::StoppedState || state == Phonon::PlayingState || Phonon::PausedState); m_media->setCurrentSource(m_url); // before calling play() we better make sure that if play() finishes very fast that we don't get // called again -- cgit v0.12 From 9904f77b26d3b75f8ed53e82c14ff8e9baf710dc Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 7 Apr 2009 15:04:31 +0200 Subject: BT: compilefix for Qt in namespace RevBy: mauricek Details: using prefix qt_ instead of ::global namespace --- src/gui/graphicsview/qgraphicsitem.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 9d320b7..b520a3f 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -3707,7 +3707,7 @@ void QGraphicsItemPrivate::fullUpdateHelper(bool childrenOnly, bool maybeDirtyCl dirtyChildren = 1; } -static inline bool allChildrenCombineOpacity(QGraphicsItem *parent) +static inline bool qt_allChildrenCombineOpacity(QGraphicsItem *parent) { Q_ASSERT(parent); if (parent->flags() & QGraphicsItem::ItemDoesntPropagateOpacityToChildren) @@ -3726,11 +3726,11 @@ void QGraphicsItemPrivate::updateEffectiveOpacity() Q_Q(QGraphicsItem); if (parent) { resolveEffectiveOpacity(parent->effectiveOpacity()); - parent->d_ptr->allChildrenCombineOpacity = ::allChildrenCombineOpacity(parent); + parent->d_ptr->allChildrenCombineOpacity = qt_allChildrenCombineOpacity(parent); } else { resolveEffectiveOpacity(1.0); } - allChildrenCombineOpacity = ::allChildrenCombineOpacity(q); + allChildrenCombineOpacity = qt_allChildrenCombineOpacity(q); } /*! -- cgit v0.12 From de007bd2a20a141aefe901408512c806879a2387 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 7 Apr 2009 15:03:11 +0200 Subject: fix tap-and-hold checkbox problem for Windows CE Symptom: checkboxes didn't get checked if you press, hold for some seconds and then release the mouse or stylus. In QAbstractButton we reacted on the contextMenuEvent that gets sent if the system recognizes the context menu gesture (tap and hold) and did call setDown(false). This change has been done because buttons in tool bars stayed in the down state when displaying the context menu with this gesture. I've now moved the handling of this to qtoolbar.cpp. Task-number: 246619 Reviewed-by: thartman --- src/gui/widgets/qabstractbutton.cpp | 9 --------- src/gui/widgets/qabstractbutton.h | 3 --- src/gui/widgets/qtoolbar.cpp | 11 +++++++++++ 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/gui/widgets/qabstractbutton.cpp b/src/gui/widgets/qabstractbutton.cpp index 330a7f8..61ed0ea 100644 --- a/src/gui/widgets/qabstractbutton.cpp +++ b/src/gui/widgets/qabstractbutton.cpp @@ -1248,15 +1248,6 @@ void QAbstractButton::timerEvent(QTimerEvent *e) } } -#if defined(Q_OS_WINCE) && !defined(QT_NO_CONTEXTMENU) -/*! \reimp */ -void QAbstractButton::contextMenuEvent(QContextMenuEvent *e) -{ - e->ignore(); - setDown(false); -} -#endif - /*! \reimp */ void QAbstractButton::focusInEvent(QFocusEvent *e) { diff --git a/src/gui/widgets/qabstractbutton.h b/src/gui/widgets/qabstractbutton.h index 6503a56..f0cbb05 100644 --- a/src/gui/widgets/qabstractbutton.h +++ b/src/gui/widgets/qabstractbutton.h @@ -143,9 +143,6 @@ protected: void focusOutEvent(QFocusEvent *e); void changeEvent(QEvent *e); void timerEvent(QTimerEvent *e); -#ifdef Q_OS_WINCE - void contextMenuEvent(QContextMenuEvent *e); -#endif #ifdef QT3_SUPPORT public: diff --git a/src/gui/widgets/qtoolbar.cpp b/src/gui/widgets/qtoolbar.cpp index 85d6ea2..1babb6d 100644 --- a/src/gui/widgets/qtoolbar.cpp +++ b/src/gui/widgets/qtoolbar.cpp @@ -1153,6 +1153,17 @@ bool QToolBar::event(QEvent *event) if (d->mouseMoveEvent(static_cast(event))) return true; break; +#ifdef Q_OS_WINCE + case QEvent::ContextMenu: + { + QContextMenuEvent* contextMenuEvent = static_cast(event); + QWidget* child = childAt(contextMenuEvent->pos()); + QAbstractButton* button = qobject_cast(child); + if (button) + button->setDown(false); + } + break; +#endif case QEvent::Leave: if (d->state != 0 && d->state->dragging) { #ifdef Q_OS_WIN -- cgit v0.12 From f6cefda2c038c68883f535bb86ac297e2a4f5407 Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Tue, 7 Apr 2009 15:32:21 +0200 Subject: Added copyright headers for the new QWS keymap handling files Also removed the old obsolete qkbpc101_qws files. Somehow this removal got lost in the rebase before the keyboard handler refactoring commit. Reviewed-by: TrustMe --- src/gui/embedded/qkbd_defaultmap_qws_p.h | 52 ++++ src/gui/embedded/qkbd_qws_p.h | 52 ++++ src/gui/embedded/qkbdlinuxinput_qws.cpp | 4 +- src/gui/embedded/qkbdpc101_qws.cpp | 485 ------------------------------- src/gui/embedded/qkbdpc101_qws.h | 95 ------ src/gui/embedded/qkbdtty_qws.cpp | 4 +- tools/kmap2qmap/main.cpp | 41 +++ 7 files changed, 149 insertions(+), 584 deletions(-) delete mode 100644 src/gui/embedded/qkbdpc101_qws.cpp delete mode 100644 src/gui/embedded/qkbdpc101_qws.h diff --git a/src/gui/embedded/qkbd_defaultmap_qws_p.h b/src/gui/embedded/qkbd_defaultmap_qws_p.h index 34ce69e..0d6d77d 100644 --- a/src/gui/embedded/qkbd_defaultmap_qws_p.h +++ b/src/gui/embedded/qkbd_defaultmap_qws_p.h @@ -1,6 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #ifndef QWSKEYBOARDHANDLER_DEFAULTMAP_H #define QWSKEYBOARDHANDLER_DEFAULTMAP_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + const QWSKeyboard::Mapping QWSKbPrivate::s_keymap_default[] = { { 1, 0xffff, 0x01000000, 0x00, 0x00, 0x0000 }, { 2, 0x0031, 0x00000031, 0x00, 0x00, 0x0000 }, diff --git a/src/gui/embedded/qkbd_qws_p.h b/src/gui/embedded/qkbd_qws_p.h index f7dcdaf..3224da2 100644 --- a/src/gui/embedded/qkbd_qws_p.h +++ b/src/gui/embedded/qkbd_qws_p.h @@ -1,6 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #ifndef QWSKEYBOARD_P_H #define QWSKEYBOARD_P_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + #include namespace QWSKeyboard { diff --git a/src/gui/embedded/qkbdlinuxinput_qws.cpp b/src/gui/embedded/qkbdlinuxinput_qws.cpp index d04b09f..1ef2696 100644 --- a/src/gui/embedded/qkbdlinuxinput_qws.cpp +++ b/src/gui/embedded/qkbdlinuxinput_qws.cpp @@ -105,9 +105,9 @@ QWSLinuxInputKbPrivate::QWSLinuxInputKbPrivate(QWSLinuxInputKeyboardHandler *h, QStringList args = device.split(QLatin1Char(':')); foreach (const QString &arg, args) { - if (arg.startsWith(QLatin1String("repeat_delay="))) + if (arg.startsWith(QLatin1String("repeat-delay="))) repeat_delay = arg.mid(13).toInt(); - else if (arg.startsWith(QLatin1String("repeat_rate="))) + else if (arg.startsWith(QLatin1String("repeat-rate="))) repeat_rate = arg.mid(12).toInt(); else if (arg.startsWith(QLatin1String("/dev/"))) dev = arg; diff --git a/src/gui/embedded/qkbdpc101_qws.cpp b/src/gui/embedded/qkbdpc101_qws.cpp deleted file mode 100644 index 3173645..0000000 --- a/src/gui/embedded/qkbdpc101_qws.cpp +++ /dev/null @@ -1,485 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qkbdpc101_qws.h" - -#ifndef QT_NO_QWS_KEYBOARD - -#include "qscreen_qws.h" -#include "qwindowsystem_qws.h" -#include "qnamespace.h" -#include "qapplication.h" - -#include -#include -#include -#include -#include -#include - -#ifdef Q_OS_LINUX -#include -#include -#endif - -QT_BEGIN_NAMESPACE - -static const QWSKeyMap pc101KeyM[] = { - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, - { Qt::Key_Escape, 27 , 27 , 0xffff }, - { Qt::Key_1, '1' , '!' , 0xffff }, - { Qt::Key_2, '2' , '@' , 0xffff }, - { Qt::Key_3, '3' , '#' , 0xffff }, - { Qt::Key_4, '4' , '$' , 0xffff }, - { Qt::Key_5, '5' , '%' , 0xffff }, - { Qt::Key_6, '6' , '^' , 0xffff }, - { Qt::Key_7, '7' , '&' , 0xffff }, - { Qt::Key_8, '8' , '*' , 0xffff }, - { Qt::Key_9, '9' , '(' , 0xffff }, // 10 - { Qt::Key_0, '0' , ')' , 0xffff }, - { Qt::Key_Minus, '-' , '_' , 0xffff }, - { Qt::Key_Equal, '=' , '+' , 0xffff }, - { Qt::Key_Backspace, 8 , 8 , 0xffff }, - { Qt::Key_Tab, 9 , 9 , 0xffff }, - { Qt::Key_Q, 'q' , 'Q' , 'Q'-64 }, - { Qt::Key_W, 'w' , 'W' , 'W'-64 }, - { Qt::Key_E, 'e' , 'E' , 'E'-64 }, - { Qt::Key_R, 'r' , 'R' , 'R'-64 }, - { Qt::Key_T, 't' , 'T' , 'T'-64 }, // 20 - { Qt::Key_Y, 'y' , 'Y' , 'Y'-64 }, - { Qt::Key_U, 'u' , 'U' , 'U'-64 }, - { Qt::Key_I, 'i' , 'I' , 'I'-64 }, - { Qt::Key_O, 'o' , 'O' , 'O'-64 }, - { Qt::Key_P, 'p' , 'P' , 'P'-64 }, - { Qt::Key_BraceLeft, '[' , '{' , 0xffff }, - { Qt::Key_BraceRight, ']' , '}' , 0xffff }, - { Qt::Key_Return, 13 , 13 , 0xffff }, - { Qt::Key_Control, 0xffff , 0xffff , 0xffff }, - { Qt::Key_A, 'a' , 'A' , 'A'-64 }, // 30 - { Qt::Key_S, 's' , 'S' , 'S'-64 }, - { Qt::Key_D, 'd' , 'D' , 'D'-64 }, - { Qt::Key_F, 'f' , 'F' , 'F'-64 }, - { Qt::Key_G, 'g' , 'G' , 'G'-64 }, - { Qt::Key_H, 'h' , 'H' , 'H'-64 }, - { Qt::Key_J, 'j' , 'J' , 'J'-64 }, - { Qt::Key_K, 'k' , 'K' , 'K'-64 }, - { Qt::Key_L, 'l' , 'L' , 'L'-64 }, - { Qt::Key_Semicolon, ';' , ':' , 0xffff }, - { Qt::Key_Apostrophe, '\'' , '"' , 0xffff }, // 40 - { Qt::Key_QuoteLeft, '`' , '~' , 0xffff }, - { Qt::Key_Shift, 0xffff , 0xffff , 0xffff }, - { Qt::Key_Backslash, '\\' , '|' , 0xffff }, - { Qt::Key_Z, 'z' , 'Z' , 'Z'-64 }, - { Qt::Key_X, 'x' , 'X' , 'X'-64 }, - { Qt::Key_C, 'c' , 'C' , 'C'-64 }, - { Qt::Key_V, 'v' , 'V' , 'V'-64 }, - { Qt::Key_B, 'b' , 'B' , 'B'-64 }, - { Qt::Key_N, 'n' , 'N' , 'N'-64 }, - { Qt::Key_M, 'm' , 'M' , 'M'-64 }, // 50 - { Qt::Key_Comma, ',' , '<' , 0xffff }, - { Qt::Key_Period, '.' , '>' , 0xffff }, - { Qt::Key_Slash, '/' , '?' , 0xffff }, - { Qt::Key_Shift, 0xffff , 0xffff , 0xffff }, - { Qt::Key_Asterisk, '*' , '*' , 0xffff }, - { Qt::Key_Alt, 0xffff , 0xffff , 0xffff }, - { Qt::Key_Space, ' ' , ' ' , 0xffff }, - { Qt::Key_CapsLock, 0xffff , 0xffff , 0xffff }, - { Qt::Key_F1, 0xffff , 0xffff , 0xffff }, - { Qt::Key_F2, 0xffff , 0xffff , 0xffff }, // 60 - { Qt::Key_F3, 0xffff , 0xffff , 0xffff }, - { Qt::Key_F4, 0xffff , 0xffff , 0xffff }, - { Qt::Key_F5, 0xffff , 0xffff , 0xffff }, - { Qt::Key_F6, 0xffff , 0xffff , 0xffff }, - { Qt::Key_F7, 0xffff , 0xffff , 0xffff }, - { Qt::Key_F8, 0xffff , 0xffff , 0xffff }, - { Qt::Key_F9, 0xffff , 0xffff , 0xffff }, - { Qt::Key_F10, 0xffff , 0xffff , 0xffff }, - { Qt::Key_NumLock, 0xffff , 0xffff , 0xffff }, - { Qt::Key_ScrollLock, 0xffff , 0xffff , 0xffff }, // 70 - { Qt::Key_7, '7' , '7' , 0xffff }, - { Qt::Key_8, '8' , '8' , 0xffff }, - { Qt::Key_9, '9' , '9' , 0xffff }, - { Qt::Key_Minus, '-' , '-' , 0xffff }, - { Qt::Key_4, '4' , '4' , 0xffff }, - { Qt::Key_5, '5' , '5' , 0xffff }, - { Qt::Key_6, '6' , '6' , 0xffff }, - { Qt::Key_Plus, '+' , '+' , 0xffff }, - { Qt::Key_1, '1' , '1' , 0xffff }, - { Qt::Key_2, '2' , '2' , 0xffff }, // 80 - { Qt::Key_3, '3' , '3' , 0xffff }, - { Qt::Key_0, '0' , '0' , 0xffff }, - { Qt::Key_Period, '.' , '.' , 0xffff }, - { Qt::Key_SysReq, 0xffff , 0xffff , 0xffff }, - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, - { Qt::Key_Less, '<' , '>' , 0xffff }, - { Qt::Key_F11, 0xffff , 0xffff , 0xffff }, - { Qt::Key_F12, 0xffff , 0xffff , 0xffff }, - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 90 - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, - { Qt::Key_Enter, 13 , 13 , 0xffff }, - { Qt::Key_Control, 0xffff , 0xffff , 0xffff }, - { Qt::Key_Slash, '/' , '/' , 0xffff }, - { Qt::Key_SysReq, 0xffff , 0xffff , 0xffff }, - { Qt::Key_Meta, 0xffff , 0xffff , 0xffff }, // 100 - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // break - { Qt::Key_Home, 0xffff , 0xffff , 0xffff }, - { Qt::Key_Up, 0xffff , 0xffff , 0xffff }, - { Qt::Key_PageUp, 0xffff , 0xffff , 0xffff }, - { Qt::Key_Left, 0xffff , 0xffff , 0xffff }, - { Qt::Key_Right, 0xffff , 0xffff , 0xffff }, - { Qt::Key_End, 0xffff , 0xffff , 0xffff }, - { Qt::Key_Down, 0xffff , 0xffff , 0xffff }, - { Qt::Key_PageDown, 0xffff , 0xffff , 0xffff }, - { Qt::Key_Insert, 0xffff , 0xffff , 0xffff }, // 110 - { Qt::Key_Delete, 0xffff , 0xffff , 0xffff }, - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // macro - { Qt::Key_F13, 0xffff , 0xffff , 0xffff }, - { Qt::Key_F14, 0xffff , 0xffff , 0xffff }, - { Qt::Key_Help, 0xffff , 0xffff , 0xffff }, - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // do - { Qt::Key_F17, 0xffff , 0xffff , 0xffff }, - { Qt::Key_Plus, '+' , '-' , 0xffff }, - { Qt::Key_Pause, 0xffff , 0xffff , 0xffff }, - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, - { 0, 0xffff , 0xffff , 0xffff } -}; - -static const int keyMSize = sizeof(pc101KeyM)/sizeof(QWSKeyMap)-1; - -//=========================================================================== - -// -// PC-101 type keyboards -// - -/*! - \class QWSPC101KeyboardHandler - \ingroup qws - - \internal -*/ - -QWSPC101KeyboardHandler::QWSPC101KeyboardHandler(const QString&) -{ - shift = false; - alt = false; - ctrl = false; - extended = 0; - prevuni = 0; - prevkey = 0; - caps = false; -#if defined(QT_QWS_IPAQ) - // iPAQ Action Key has ScanCode 0x60: 0x60|0x80 = 0xe0 == extended mode 1 ! - ipaq_return_pressed = false; -#endif -} - -QWSPC101KeyboardHandler::~QWSPC101KeyboardHandler() -{ -} - -const QWSKeyMap *QWSPC101KeyboardHandler::keyMap() const -{ - return pc101KeyM; -} - -void QWSPC101KeyboardHandler::doKey(uchar code) -{ - - int keyCode = Qt::Key_unknown; - bool release = false; - int keypad = 0; - bool softwareRepeat = false; - -#ifndef QT_QWS_USE_KEYCODES - // extended? - if (code == 224 -#if defined(QT_QWS_IPAQ) - && !ipaq_return_pressed -#endif - ) { - extended = 1; - return; - } else if (code == 225) { - extended = 2; - return; - } -#endif - - if (code & 0x80) { - release = true; - code &= 0x7f; - } - -#ifndef QT_QWS_USE_KEYCODES - if (extended == 1) { - switch (code) { - case 72: - keyCode = Qt::Key_Up; - break; - case 75: - keyCode = Qt::Key_Left; - break; - case 77: - keyCode = Qt::Key_Right; - break; - case 80: - keyCode = Qt::Key_Down; - break; - case 82: - keyCode = Qt::Key_Insert; - break; - case 71: - keyCode = Qt::Key_Home; - break; - case 73: - keyCode = Qt::Key_PageUp; - break; - case 83: - keyCode = Qt::Key_Delete; - break; - case 79: - keyCode = Qt::Key_End; - break; - case 81: - keyCode = Qt::Key_PageDown; - break; - case 28: - keyCode = Qt::Key_Enter; - break; - case 53: - keyCode = Qt::Key_Slash; - break; - case 0x1d: - keyCode = Qt::Key_Control; - break; - case 0x2a: - keyCode = Qt::Key_Print; - break; - case 0x38: - keyCode = Qt::Key_Alt; - break; - case 0x5b: - keyCode = Qt::Key_Super_L; - break; - case 0x5c: - keyCode = Qt::Key_Super_R; - break; - case 0x5d: - keyCode = Qt::Key_Menu; - break; -#if 0 - default: - qDebug("extended1 code %x release %d", code, release); - break; -#endif - } - } else if (extended == 2) { - switch (code) { - case 0x1d: - return; - case 0x45: - keyCode = Qt::Key_Pause; - break; - } - } else -#endif - { - if (code < keyMSize) { - keyCode = pc101KeyM[code].key_code; - } - -#if defined(QT_QWS_IPAQ) || defined(QT_QWS_EBX) - softwareRepeat = true; - - switch (code) { - case 0x7a: case 0x7b: case 0x7c: case 0x7d: - keyCode = code - 0x7a + Qt::Key_F9; - softwareRepeat = false; - break; - case 0x79: - keyCode = Qt::Key_SysReq; - softwareRepeat = false; - break; - case 0x78: -# ifdef QT_QWS_IPAQ - keyCode = Qt::Key_F24; // record -# else - keyCode = Qt::Key_Escape; -# endif - softwareRepeat = false; - break; - case 0x60: - keyCode = Qt::Key_Return; -# ifdef QT_QWS_IPAQ - ipaq_return_pressed = !release; -# endif - break; - case 0x67: - keyCode = Qt::Key_Right; - break; - case 0x69: - keyCode = Qt::Key_Up; - break; - case 0x6a: - keyCode = Qt::Key_Down; - break; - case 0x6c: - keyCode = Qt::Key_Left; - break; - } - - if (qt_screen->isTransformed() - && keyCode >= Qt::Key_Left && keyCode <= Qt::Key_Down) - { - keyCode = transformDirKey(keyCode); - } -#endif - /* - Translate shift+Qt::Key_Tab to Qt::Key_Backtab - */ - if ((keyCode == Qt::Key_Tab) && shift) - keyCode = Qt::Key_Backtab; - } - -#ifndef QT_QWS_USE_KEYCODES - /* - Qt::Keypad consists of extended keys 53 and 28, - and non-extended keys 55 and 71 through 83. - */ - if ((extended == 1) ? (code == 53 || code == 28) : - (code == 55 || (code >= 71 && code <= 83))) -#else - if (code == 55 || code >= 71 && code <= 83 || code == 96 - || code == 98 || code == 118) -#endif - { - keypad = Qt::KeypadModifier; - } - - // Ctrl-Alt-Backspace exits qws - if (ctrl && alt && keyCode == Qt::Key_Backspace) { - qApp->quit(); - } - - if (keyCode == Qt::Key_Alt) { - alt = !release; - } else if (keyCode == Qt::Key_Control) { - ctrl = !release; - } else if (keyCode == Qt::Key_Shift) { - shift = !release; - } else if (keyCode == Qt::Key_CapsLock && release) { - caps = !caps; -#if defined(Q_OS_LINUX) - char leds; - ioctl(0, KDGETLED, &leds); - leds = leds & ~LED_CAP; - if (caps) leds |= LED_CAP; - ioctl(0, KDSETLED, leds); -#endif - } - if (keyCode != Qt::Key_unknown) { - bool bAlt = alt; - bool bCtrl = ctrl; - bool bShift = shift; - int unicode = 0; - if (code < keyMSize) { - if (!extended) { - bool bCaps = shift || - (caps ? QChar(keyMap()[code].unicode).isLetter() : false); - if (bCtrl) - unicode = keyMap()[code].ctrl_unicode ? keyMap()[code].ctrl_unicode : 0xffff; - else if (bCaps) - unicode = keyMap()[code].shift_unicode ? keyMap()[code].shift_unicode : 0xffff; - else - unicode = keyMap()[code].unicode ? keyMap()[code].unicode : 0xffff; -#ifndef QT_QWS_USE_KEYCODES - } else if (extended==1) { - if (code == 53) - unicode = '/'; -#endif - } - } - - modifiers = 0; - if (bAlt) modifiers |= Qt::AltModifier; - if (bCtrl) modifiers |= Qt::ControlModifier; - if (bShift) modifiers |= Qt::ShiftModifier; - if (keypad) modifiers |= Qt::KeypadModifier; - - // looks wrong -- WWA - bool repeat = false; - if (prevuni == unicode && prevkey == keyCode && !release) - repeat = true; - - processKeyEvent(unicode, keyCode, modifiers, !release, repeat); - - if (!release) { - prevuni = unicode; - prevkey = keyCode; - } else { - prevkey = prevuni = 0; - } - } - - if (softwareRepeat && !release) - beginAutoRepeat(prevuni, prevkey, modifiers); - else - endAutoRepeat(); - - extended = 0; -} - -QT_END_NAMESPACE - -#endif // QT_NO_QWS_KEYBOARD diff --git a/src/gui/embedded/qkbdpc101_qws.h b/src/gui/embedded/qkbdpc101_qws.h deleted file mode 100644 index f9f0104..0000000 --- a/src/gui/embedded/qkbdpc101_qws.h +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QKBDPC101_QWS_H -#define QKBDPC101_QWS_H - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -#ifndef QT_NO_QWS_KEYBOARD - -#ifndef QT_NO_QWS_KBD_PC101 - -struct QWSKeyMap { - uint key_code; - ushort unicode; - ushort shift_unicode; - ushort ctrl_unicode; -}; - -class QWSPC101KeyboardHandler : public QWSKeyboardHandler -{ -public: - explicit QWSPC101KeyboardHandler(const QString&); - virtual ~QWSPC101KeyboardHandler(); - - virtual void doKey(uchar scancode); - virtual const QWSKeyMap *keyMap() const; - -protected: - bool shift; - bool alt; - bool ctrl; - bool caps; -#if defined(QT_QWS_IPAQ) - uint ipaq_return_pressed:1; -#endif - uint extended:2; - Qt::KeyboardModifiers modifiers; - int prevuni; - int prevkey; -}; - -#endif // QT_NO_QWS_KBD_PC101 - -#endif // QT_NO_QWS_KEYBOARD - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QKBDPC101_QWS_H diff --git a/src/gui/embedded/qkbdtty_qws.cpp b/src/gui/embedded/qkbdtty_qws.cpp index 8311ba7..5c0dec8 100644 --- a/src/gui/embedded/qkbdtty_qws.cpp +++ b/src/gui/embedded/qkbdtty_qws.cpp @@ -122,9 +122,9 @@ QWSTtyKbPrivate::QWSTtyKbPrivate(QWSTtyKeyboardHandler *h, const QString &device QStringList args = device.split(QLatin1Char(':')); foreach (const QString &arg, args) { - if (arg.startsWith(QLatin1String("repeat_delay="))) + if (arg.startsWith(QLatin1String("repeat-delay="))) repeat_delay = arg.mid(13).toInt(); - else if (arg.startsWith(QLatin1String("repeat_rate="))) + else if (arg.startsWith(QLatin1String("repeat-rate="))) repeat_rate = arg.mid(12).toInt(); else if (arg.startsWith(QLatin1String("/dev/"))) dev = arg; diff --git a/tools/kmap2qmap/main.cpp b/tools/kmap2qmap/main.cpp index 5e80b23..b518392 100644 --- a/tools/kmap2qmap/main.cpp +++ b/tools/kmap2qmap/main.cpp @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #include #include -- cgit v0.12 From 773c4d326c24f8db12ab58e379bd223ce1126d72 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Tue, 7 Apr 2009 15:30:12 +0200 Subject: BT: Prevent a crash in Designer when quiting when in the filter edit. Gah, my original change (f5ef0eb1a6543abdd29e07c23de7fa1128f6d623) had its heart in the right place, but it seems that it can cause crashes on closing where we refuse to give up the first responder and we end up with a dangling pointer. This lets that case happen (when we have no focus widget and are setting a nil first responder, there's no reason to stop that, but it refuses to do that when we do have a focus widget. Hopefully we don't get in a situation where our focus widget gets out of sync. Reviewed-by: Prasanth Ullattil --- src/gui/kernel/qcocoapanel_mac.mm | 5 +++-- src/gui/kernel/qcocoawindow_mac.mm | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qcocoapanel_mac.mm b/src/gui/kernel/qcocoapanel_mac.mm index c17b30c..95e20af 100644 --- a/src/gui/kernel/qcocoapanel_mac.mm +++ b/src/gui/kernel/qcocoapanel_mac.mm @@ -157,10 +157,11 @@ QT_USE_NAMESPACE [self release]; } - - (BOOL)makeFirstResponder:(NSResponder *)responder { - if (responder == nil) + // For some reason Cocoa wants to flip the first responder + // when Qt doesn't want to, sorry, but "No" :-) + if (responder == nil && qApp->focusWidget()) return NO; return [super makeFirstResponder:responder]; } diff --git a/src/gui/kernel/qcocoawindow_mac.mm b/src/gui/kernel/qcocoawindow_mac.mm index ba121cd..e7b76a7 100644 --- a/src/gui/kernel/qcocoawindow_mac.mm +++ b/src/gui/kernel/qcocoawindow_mac.mm @@ -182,7 +182,9 @@ extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview. - (BOOL)makeFirstResponder:(NSResponder *)responder { - if (responder == nil) + // For some reason Cocoa wants to flip the first responder + // when Qt doesn't want to, sorry, but "No" :-) + if (responder == nil && qApp->focusWidget()) return NO; return [super makeFirstResponder:responder]; } -- cgit v0.12 From c451bec89869bb12b2a2937581df331443795dba Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Tue, 7 Apr 2009 15:48:13 +0200 Subject: Add -qconfig support for non QWS builds. There are customers using X11 on embedded systems, so make it possible to use -qconfig for those builds too. Reviewed-by: Paul Olav Tvete --- configure | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/configure b/configure index f87f79c..35fbd2d 100755 --- a/configure +++ b/configure @@ -830,14 +830,15 @@ while [ "$#" -gt 0 ]; do ;; #Qt style options that pass an argument -qconfig) - if [ "$PLATFORM_QWS" = "yes" ]; then - CFG_QCONFIG="$VAL" - VAR=`echo $1 | sed "s,^-\(.*\),\1,"` - shift - VAL=$1 - else - UNKNOWN_ARG=yes + if [ "$PLATFORM_QWS" != "yes" ]; then + echo + echo "WARNING: -qconfig is only tested and supported on Qt for Embedded Linux." + echo fi + CFG_QCONFIG="$VAL" + VAR=`echo $1 | sed "s,^-\(.*\),\1,"` + shift + VAL=$1 ;; -prefix|-docdir|-headerdir|-plugindir|-datadir|-libdir|-bindir|-translationdir|-sysconfdir|-examplesdir|-demosdir|-depths|-make|-nomake|-platform|-xplatform|-buildkey|-sdk|-arch|-host-arch|-mysql_config) VAR=`echo $1 | sed "s,^-\(.*\),\1,"` -- cgit v0.12 From baf61b32cf4aa554ee3dbb4a22b99e854d5ebd34 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Thu, 26 Feb 2009 11:14:12 +0100 Subject: Optimize QGraphicsItem::map(To|From)Parent(const QPainterPath) Now that we have QPainterPath::translate, we can use that instead of itemTransform()/map(To|From)Scene, which lowers the number of QTransform operations involved. Reviewd-by: Andreas --- src/gui/graphicsview/qgraphicsitem.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 26fc485..c8a4a14 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -4587,7 +4587,9 @@ QPainterPath QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPainterP */ QPainterPath QGraphicsItem::mapToParent(const QPainterPath &path) const { - return d_ptr->parent ? itemTransform(d_ptr->parent).map(path) : mapToScene(path); + QPainterPath p(path); + p.translate(d_ptr->pos); + return d_ptr->hasTransform ? transform().map(p) : p; } /*! @@ -4802,9 +4804,9 @@ QPainterPath QGraphicsItem::mapFromItem(const QGraphicsItem *item, const QPainte */ QPainterPath QGraphicsItem::mapFromParent(const QPainterPath &path) const { - if (d_ptr->parent) - return d_ptr->parent->itemTransform(this).map(path); - return mapFromScene(path); + QPainterPath p(path); + p.translate(-d_ptr->pos); + return d_ptr->hasTransform ? transform().inverted().map(p) : p; } /*! -- cgit v0.12 From fde7f3d03782c801901f511131458d6fcb1021a5 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sun, 29 Mar 2009 21:47:53 +0200 Subject: Add an internal qIsFuzzyNull(double) method The method can help to avoid many calls to the rather expensive qFuzzyCompare in the cases where we compare a number against 0 or 1. --- src/corelib/global/qglobal.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 672862a..28b9d08 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1706,6 +1706,22 @@ static inline bool qFuzzyCompare(float p1, float p2) return (qAbs(p1 - p2) <= 0.00001f * qMin(qAbs(p1), qAbs(p2))); } +/*! + \internal +*/ +static inline bool qIsFuzzyNull(double d) +{ + return qAbs(d) <= 0.000000000001; +} + +/*! + \internal +*/ +static inline bool qIsFuzzyNull(float f) +{ + return qAbs(f) <= 0.00001f; +} + /* This function tests a double for a null value. It doesn't check whether the actual value is 0 or close to 0, but whether -- cgit v0.12 From 6f93983dcce291f66d42e844f1d12bd4a59b046b Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 30 Mar 2009 20:44:39 +0200 Subject: Optimise QMatrix and QTransform Add some private inline constructors and do inlining other places. All test still pass. --- src/gui/painting/qmatrix.cpp | 63 ++++++++----- src/gui/painting/qmatrix.h | 18 +++- src/gui/painting/qtransform.cpp | 198 ++++++++++++++++++++++++++++------------ src/gui/painting/qtransform.h | 30 +++++- 4 files changed, 220 insertions(+), 89 deletions(-) diff --git a/src/gui/painting/qmatrix.cpp b/src/gui/painting/qmatrix.cpp index 4439d52..31abcad 100644 --- a/src/gui/painting/qmatrix.cpp +++ b/src/gui/painting/qmatrix.cpp @@ -208,9 +208,13 @@ QT_BEGIN_NAMESPACE */ QMatrix::QMatrix() + : _m11(1.) + , _m12(0.) + , _m21(0.) + , _m22(1.) + , _dx(0.) + , _dy(0.) { - _m11 = _m22 = 1.0; - _m12 = _m21 = _dx = _dy = 0.0; } /*! @@ -220,12 +224,14 @@ QMatrix::QMatrix() \sa setMatrix() */ -QMatrix::QMatrix(qreal m11, qreal m12, qreal m21, qreal m22, - qreal dx, qreal dy) +QMatrix::QMatrix(qreal m11, qreal m12, qreal m21, qreal m22, qreal dx, qreal dy) + : _m11(m11) + , _m12(m12) + , _m21(m21) + , _m22(m22) + , _dx(dx) + , _dy(dy) { - _m11 = m11; _m12 = m12; - _m21 = m21; _m22 = m22; - _dx = dx; _dy = dy; } @@ -233,8 +239,13 @@ QMatrix::QMatrix(qreal m11, qreal m12, qreal m21, qreal m22, Constructs a matrix that is a copy of the given \a matrix. */ QMatrix::QMatrix(const QMatrix &matrix) + : _m11(matrix._m11) + , _m12(matrix._m12) + , _m21(matrix._m21) + , _m22(matrix._m22) + , _dx(matrix._dx) + , _dy(matrix._dy) { - *this = matrix; } /*! @@ -249,12 +260,14 @@ QMatrix::QMatrix(const QMatrix &matrix) \sa QMatrix() */ -void QMatrix::setMatrix(qreal m11, qreal m12, qreal m21, qreal m22, - qreal dx, qreal dy) +void QMatrix::setMatrix(qreal m11, qreal m12, qreal m21, qreal m22, qreal dx, qreal dy) { - _m11 = m11; _m12 = m12; - _m21 = m21; _m22 = m22; - _dx = dx; _dy = dy; + _m11 = m11; + _m12 = m12; + _m21 = m21; + _m22 = m22; + _dx = dx; + _dy = dy; } @@ -968,18 +981,17 @@ QMatrix QMatrix::inverted(bool *invertible) const if (determinant == 0.0) { if (invertible) *invertible = false; // singular matrix - QMatrix defaultMatrix; - return defaultMatrix; + return QMatrix(true); } else { // invertible matrix if (invertible) *invertible = true; qreal dinv = 1.0/determinant; - QMatrix imatrix((_m22*dinv), (-_m12*dinv), - (-_m21*dinv), (_m11*dinv), - ((_m21*_dy - _m22*_dx)*dinv), - ((_m12*_dx - _m11*_dy)*dinv)); - return imatrix; + return QMatrix((_m22*dinv), (-_m12*dinv), + (-_m21*dinv), (_m11*dinv), + ((_m21*_dy - _m22*_dx)*dinv), + ((_m12*_dx - _m11*_dy)*dinv), + true); } } @@ -1054,9 +1066,14 @@ QMatrix &QMatrix::operator *=(const QMatrix &m) QMatrix QMatrix::operator *(const QMatrix &m) const { - QMatrix result = *this; - result *= m; - return result; + qreal tm11 = _m11*m._m11 + _m12*m._m21; + qreal tm12 = _m11*m._m12 + _m12*m._m22; + qreal tm21 = _m21*m._m11 + _m22*m._m21; + qreal tm22 = _m21*m._m12 + _m22*m._m22; + + qreal tdx = _dx*m._m11 + _dy*m._m21 + m._dx; + qreal tdy = _dx*m._m12 + _dy*m._m22 + m._dy; + return QMatrix(tm11, tm12, tm21, tm22, tdx, tdy, true); } /*! diff --git a/src/gui/painting/qmatrix.h b/src/gui/painting/qmatrix.h index bf53c32..1b6bd6d 100644 --- a/src/gui/painting/qmatrix.h +++ b/src/gui/painting/qmatrix.h @@ -121,6 +121,20 @@ public: #endif private: + inline QMatrix(bool) + : _m11(1.) + , _m12(0.) + , _m21(0.) + , _m22(1.) + , _dx(0.) + , _dy(0.) {} + inline QMatrix(qreal m11, qreal m12, qreal m21, qreal m22, qreal dx, qreal dy, bool) + : _m11(m11) + , _m12(m12) + , _m21(m21) + , _m22(m22) + , _dx(dx) + , _dy(dy) {} friend class QTransform; qreal _m11, _m12; qreal _m21, _m22; @@ -147,8 +161,8 @@ Q_GUI_EXPORT QPainterPath operator *(const QPainterPath &p, const QMatrix &m); inline bool QMatrix::isIdentity() const { - return qFuzzyCompare(_m11, 1) && qFuzzyCompare(_m22, 1) && qFuzzyCompare(_m12 + 1, 1) - && qFuzzyCompare(_m21 + 1, 1) && qFuzzyCompare(_dx + 1, 1) && qFuzzyCompare(_dy + 1, 1); + return qIsFuzzyNull(_m11 - 1) && qIsFuzzyNull(_m22 - 1) && qIsFuzzyNull(_m12) + && qIsFuzzyNull(_m21) && qIsFuzzyNull(_dx) && qIsFuzzyNull(_dy); } /***************************************************************************** diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp index b25146d..6c37ab6 100644 --- a/src/gui/painting/qtransform.cpp +++ b/src/gui/painting/qtransform.cpp @@ -238,11 +238,11 @@ QT_BEGIN_NAMESPACE \sa reset() */ QTransform::QTransform() - : m_13(0), m_23(0), m_33(1) + : affine(true) + , m_13(0), m_23(0), m_33(1) , m_type(TxNone) , m_dirty(TxNone) { - } /*! @@ -256,12 +256,11 @@ QTransform::QTransform() QTransform::QTransform(qreal h11, qreal h12, qreal h13, qreal h21, qreal h22, qreal h23, qreal h31, qreal h32, qreal h33) - : affine(h11, h12, h21, h22, h31, h32), - m_13(h13), m_23(h23), m_33(h33) + : affine(h11, h12, h21, h22, h31, h32, true) + , m_13(h13), m_23(h23), m_33(h33) , m_type(TxNone) , m_dirty(TxProject) { - } /*! @@ -273,12 +272,11 @@ QTransform::QTransform(qreal h11, qreal h12, qreal h13, */ QTransform::QTransform(qreal h11, qreal h12, qreal h21, qreal h22, qreal dx, qreal dy) - : affine(h11, h12, h21, h22, dx, dy), - m_13(0), m_23(0), m_33(1) + : affine(h11, h12, h21, h22, dx, dy, true) + , m_13(0), m_23(0), m_33(1) , m_type(TxNone) , m_dirty(TxShear) { - } /*! @@ -289,12 +287,11 @@ QTransform::QTransform(qreal h11, qreal h12, qreal h21, and 1 respectively. */ QTransform::QTransform(const QMatrix &mtx) - : affine(mtx), + : affine(mtx._m11, mtx._m12, mtx._m21, mtx._m22, mtx._dx, mtx._dy, true), m_13(0), m_23(0), m_33(1) , m_type(TxNone) , m_dirty(TxShear) { - } /*! @@ -317,7 +314,7 @@ QTransform QTransform::adjoint() const return QTransform(h11, h12, h13, h21, h22, h23, - h31, h32, h33); + h31, h32, h33, true); } /*! @@ -327,7 +324,7 @@ QTransform QTransform::transposed() const { QTransform t(affine._m11, affine._m21, affine._dx, affine._m12, affine._m22, affine._dy, - m_13, m_23, m_33); + m_13, m_23, m_33, true); t.m_type = m_type; t.m_dirty = m_dirty; return t; @@ -345,11 +342,10 @@ QTransform QTransform::transposed() const */ QTransform QTransform::inverted(bool *invertible) const { - QTransform invert; + QTransform invert(true); bool inv = true; - qreal det; - switch(type()) { + switch(inline_type()) { case TxNone: break; case TxTranslate: @@ -357,11 +353,11 @@ QTransform QTransform::inverted(bool *invertible) const invert.affine._dy = -affine._dy; break; case TxScale: - inv = !qFuzzyCompare(affine._m11 + 1, 1); - inv &= !qFuzzyCompare(affine._m22 + 1, 1); + inv = !qIsFuzzyNull(affine._m11); + inv &= !qIsFuzzyNull(affine._m22); if (inv) { - invert.affine._m11 = 1 / affine._m11; - invert.affine._m22 = 1 / affine._m22; + invert.affine._m11 = 1. / affine._m11; + invert.affine._m22 = 1. / affine._m22; invert.affine._dx = -affine._dx * invert.affine._m11; invert.affine._dy = -affine._dy * invert.affine._m22; } @@ -372,8 +368,8 @@ QTransform QTransform::inverted(bool *invertible) const break; default: // general case - det = determinant(); - inv = !qFuzzyCompare(det + 1, 1); + qreal det = determinant(); + inv = !qIsFuzzyNull(det); if (inv) invert = adjoint() / det; break; @@ -397,12 +393,12 @@ QTransform QTransform::inverted(bool *invertible) const \sa setMatrix() */ -QTransform & QTransform::translate(qreal dx, qreal dy) +QTransform &QTransform::translate(qreal dx, qreal dy) { if (dx == 0 && dy == 0) return *this; - switch(type()) { + switch(inline_type()) { case TxNone: affine._dx = dx; affine._dy = dy; @@ -437,7 +433,7 @@ QTransform & QTransform::translate(qreal dx, qreal dy) */ QTransform QTransform::fromTranslate(qreal dx, qreal dy) { - QTransform transform(1, 0, 0, 1, dx, dy); + QTransform transform(1, 0, 0, 0, 1, 0, dx, dy, 1, true); if (dx == 0 && dy == 0) transform.m_dirty = TxNone; else @@ -456,7 +452,7 @@ QTransform & QTransform::scale(qreal sx, qreal sy) if (sx == 1 && sy == 1) return *this; - switch(type()) { + switch(inline_type()) { case TxNone: case TxTranslate: affine._m11 = sx; @@ -489,8 +485,8 @@ QTransform & QTransform::scale(qreal sx, qreal sy) */ QTransform QTransform::fromScale(qreal sx, qreal sy) { - QTransform transform(sx, 0, 0, sy, 0, 0); - if (sx == 1 && sy == 1) + QTransform transform(sx, 0, 0, 0, sy, 0, 0, 0, 1, true); + if (sx == 1. && sy == 1.) transform.m_dirty = TxNone; else transform.m_dirty = TxScale; @@ -505,7 +501,7 @@ QTransform QTransform::fromScale(qreal sx, qreal sy) */ QTransform & QTransform::shear(qreal sh, qreal sv) { - switch(type()) { + switch(inline_type()) { case TxNone: case TxTranslate: affine._m12 = sv; @@ -574,7 +570,7 @@ QTransform & QTransform::rotate(qreal a, Qt::Axis axis) } if (axis == Qt::ZAxis) { - switch(type()) { + switch(inline_type()) { case TxNone: case TxTranslate: affine._m11 = cosa; @@ -646,7 +642,7 @@ QTransform & QTransform::rotateRadians(qreal a, Qt::Axis axis) qreal cosa = qCos(a); if (axis == Qt::ZAxis) { - switch(type()) { + switch(inline_type()) { case TxNone: case TxTranslate: affine._m11 = cosa; @@ -730,11 +726,11 @@ bool QTransform::operator!=(const QTransform &o) const */ QTransform & QTransform::operator*=(const QTransform &o) { - const TransformationType otherType = o.type(); + const TransformationType otherType = o.inline_type(); if (otherType == TxNone) return *this; - const TransformationType thisType = type(); + const TransformationType thisType = inline_type(); if (thisType == TxNone) return operator=(o); @@ -812,9 +808,77 @@ QTransform & QTransform::operator*=(const QTransform &o) */ QTransform QTransform::operator*(const QTransform &m) const { - QTransform result = *this; - result *= m; - return result; + const TransformationType otherType = m.inline_type(); + if (otherType == TxNone) + return *this; + + const TransformationType thisType = inline_type(); + if (thisType == TxNone) + return m; + + QTransform t(true); + TransformationType type = qMax(thisType, otherType); + switch(type) { + case TxNone: + break; + case TxTranslate: + t.affine._dx = affine._dx + m.affine._dx; + t.affine._dy += affine._dy + m.affine._dy; + break; + case TxScale: + { + qreal m11 = affine._m11*m.affine._m11; + qreal m22 = affine._m22*m.affine._m22; + + qreal m31 = affine._dx*m.affine._m11 + m.affine._dx; + qreal m32 = affine._dy*m.affine._m22 + m.affine._dy; + + t.affine._m11 = m11; + t.affine._m22 = m22; + t.affine._dx = m31; t.affine._dy = m32; + break; + } + case TxRotate: + case TxShear: + { + qreal m11 = affine._m11*m.affine._m11 + affine._m12*m.affine._m21; + qreal m12 = affine._m11*m.affine._m12 + affine._m12*m.affine._m22; + + qreal m21 = affine._m21*m.affine._m11 + affine._m22*m.affine._m21; + qreal m22 = affine._m21*m.affine._m12 + affine._m22*m.affine._m22; + + qreal m31 = affine._dx*m.affine._m11 + affine._dy*m.affine._m21 + m.affine._dx; + qreal m32 = affine._dx*m.affine._m12 + affine._dy*m.affine._m22 + m.affine._dy; + + t.affine._m11 = m11; t.affine._m12 = m12; + t.affine._m21 = m21; t.affine._m22 = m22; + t.affine._dx = m31; t.affine._dy = m32; + break; + } + case TxProject: + { + qreal m11 = affine._m11*m.affine._m11 + affine._m12*m.affine._m21 + m_13*m.affine._dx; + qreal m12 = affine._m11*m.affine._m12 + affine._m12*m.affine._m22 + m_13*m.affine._dy; + qreal m13 = affine._m11*m.m_13 + affine._m12*m.m_23 + m_13*m.m_33; + + qreal m21 = affine._m21*m.affine._m11 + affine._m22*m.affine._m21 + m_23*m.affine._dx; + qreal m22 = affine._m21*m.affine._m12 + affine._m22*m.affine._m22 + m_23*m.affine._dy; + qreal m23 = affine._m21*m.m_13 + affine._m22*m.m_23 + m_23*m.m_33; + + qreal m31 = affine._dx*m.affine._m11 + affine._dy*m.affine._m21 + m_33*m.affine._dx; + qreal m32 = affine._dx*m.affine._m12 + affine._dy*m.affine._m22 + m_33*m.affine._dy; + qreal m33 = affine._dx*m.m_13 + affine._dy*m.m_23 + m_33*m.m_33; + + t.affine._m11 = m11; t.affine._m12 = m12; t.m_13 = m13; + t.affine._m21 = m21; t.affine._m22 = m22; t.m_23 = m23; + t.affine._dx = m31; t.affine._dy = m32; t.m_33 = m33; + } + } + + t.m_dirty = type; + t.m_type = type; + + return t; } /*! @@ -976,7 +1040,7 @@ QPoint QTransform::map(const QPoint &p) const qreal x = 0, y = 0; - TransformationType t = type(); + TransformationType t = inline_type(); switch(t) { case TxNone: x = fx; @@ -1027,7 +1091,7 @@ QPointF QTransform::map(const QPointF &p) const qreal x = 0, y = 0; - TransformationType t = type(); + TransformationType t = inline_type(); switch(t) { case TxNone: x = fx; @@ -1098,7 +1162,7 @@ QLine QTransform::map(const QLine &l) const qreal x1 = 0, y1 = 0, x2 = 0, y2 = 0; - TransformationType t = type(); + TransformationType t = inline_type(); switch(t) { case TxNone: x1 = fx1; @@ -1157,7 +1221,7 @@ QLineF QTransform::map(const QLineF &l) const qreal x1 = 0, y1 = 0, x2 = 0, y2 = 0; - TransformationType t = type(); + TransformationType t = inline_type(); switch(t) { case TxNone: x1 = fx1; @@ -1245,7 +1309,7 @@ static QPolygonF mapProjective(const QTransform &transform, const QPolygonF &pol */ QPolygonF QTransform::map(const QPolygonF &a) const { - TransformationType t = type(); + TransformationType t = inline_type(); if (t <= TxTranslate) return a.translated(affine._dx, affine._dy); @@ -1275,7 +1339,7 @@ QPolygonF QTransform::map(const QPolygonF &a) const */ QPolygon QTransform::map(const QPolygon &a) const { - TransformationType t = type(); + TransformationType t = inline_type(); if (t <= TxTranslate) return a.translated(qRound(affine._dx), qRound(affine._dy)); @@ -1320,7 +1384,7 @@ extern QPainterPath qt_regionToPath(const QRegion ®ion); */ QRegion QTransform::map(const QRegion &r) const { - TransformationType t = type(); + TransformationType t = inline_type(); if (t == TxNone) return r; if (t == TxTranslate) { @@ -1343,7 +1407,7 @@ struct QHomogeneousCoordinate QHomogeneousCoordinate(qreal x_, qreal y_, qreal w_) : x(x_), y(y_), w(w_) {} const QPointF toPoint() const { - qreal iw = 1 / w; + qreal iw = 1. / w; return QPointF(x * iw, y * iw); } }; @@ -1481,7 +1545,7 @@ static QPainterPath mapProjective(const QTransform &transform, const QPainterPat */ QPainterPath QTransform::map(const QPainterPath &path) const { - TransformationType t = type(); + TransformationType t = inline_type(); if (t == TxNone || path.isEmpty()) return path; @@ -1526,7 +1590,7 @@ QPainterPath QTransform::map(const QPainterPath &path) const */ QPolygon QTransform::mapToPolygon(const QRect &rect) const { - TransformationType t = type(); + TransformationType t = inline_type(); QPolygon a(4); qreal x[4] = { 0, 0, 0, 0 }, y[4] = { 0, 0, 0, 0 }; @@ -1700,7 +1764,7 @@ void QTransform::setMatrix(qreal m11, qreal m12, qreal m13, QRect QTransform::mapRect(const QRect &rect) const { - TransformationType t = type(); + TransformationType t = inline_type(); if (t <= TxTranslate) return rect.translated(qRound(affine._dx), qRound(affine._dy)); @@ -1771,7 +1835,7 @@ QRect QTransform::mapRect(const QRect &rect) const */ QRectF QTransform::mapRect(const QRectF &rect) const { - TransformationType t = type(); + TransformationType t = inline_type(); if (t <= TxTranslate) return rect.translated(affine._dx, affine._dy); @@ -1846,7 +1910,7 @@ QRectF QTransform::mapRect(const QRectF &rect) const */ void QTransform::map(qreal x, qreal y, qreal *tx, qreal *ty) const { - TransformationType t = type(); + TransformationType t = inline_type(); MAP(x, y, *tx, *ty); } @@ -1860,7 +1924,7 @@ void QTransform::map(qreal x, qreal y, qreal *tx, qreal *ty) const */ void QTransform::map(int x, int y, int *tx, int *ty) const { - TransformationType t = type(); + TransformationType t = inline_type(); qreal fx = 0, fy = 0; MAP(x, y, fx, fy); *tx = qRound(fx); @@ -1889,25 +1953,41 @@ const QMatrix &QTransform::toAffine() const */ QTransform::TransformationType QTransform::type() const { - if (m_dirty >= m_type) { - if (m_dirty > TxShear && (!qFuzzyCompare(m_13 + 1, 1) || !qFuzzyCompare(m_23 + 1, 1))) + if(m_dirty == TxNone || m_dirty < m_type) + return static_cast(m_type); + + switch (static_cast(m_dirty)) { + case TxProject: + if (!qIsFuzzyNull(m_13) || !qIsFuzzyNull(m_23) || !qIsFuzzyNull(m_33 - 1)) { m_type = TxProject; - else if (m_dirty > TxScale && (!qFuzzyCompare(affine._m12 + 1, 1) || !qFuzzyCompare(affine._m21 + 1, 1))) { + break; + } + case TxShear: + case TxRotate: + if (!qIsFuzzyNull(affine._m12) || !qIsFuzzyNull(affine._m21)) { const qreal dot = affine._m11 * affine._m12 + affine._m21 * affine._m22; - if (qFuzzyCompare(dot + 1, 1)) + if (qIsFuzzyNull(dot)) m_type = TxRotate; else m_type = TxShear; - } else if (m_dirty > TxTranslate && (!qFuzzyCompare(affine._m11, 1) || !qFuzzyCompare(affine._m22, 1) || !qFuzzyCompare(m_33, 1))) + break; + } + case TxScale: + if (!qIsFuzzyNull(affine._m11 - 1) || !qIsFuzzyNull(affine._m22 - 1)) { m_type = TxScale; - else if (m_dirty > TxNone && (!qFuzzyCompare(affine._dx + 1, 1) || !qFuzzyCompare(affine._dy + 1, 1))) + break; + } + case TxTranslate: + if (!qIsFuzzyNull(affine._dx) || !qIsFuzzyNull(affine._dy)) { m_type = TxTranslate; - else - m_type = TxNone; - - m_dirty = TxNone; + break; + } + case TxNone: + m_type = TxNone; + break; } + m_dirty = TxNone; return static_cast(m_type); } diff --git a/src/gui/painting/qtransform.h b/src/gui/painting/qtransform.h index c76409b..2d6c889 100644 --- a/src/gui/painting/qtransform.h +++ b/src/gui/painting/qtransform.h @@ -159,6 +159,19 @@ public: static QTransform fromScale(qreal dx, qreal dy); private: + inline QTransform(qreal h11, qreal h12, qreal h13, + qreal h21, qreal h22, qreal h23, + qreal h31, qreal h32, qreal h33, bool) + : affine(h11, h12, h21, h22, h31, h32, true) + , m_13(h13), m_23(h23), m_33(h33) + , m_type(TxNone) + , m_dirty(TxProject) {} + inline QTransform(bool) + : affine(true) + , m_13(0), m_23(0), m_33(1) + , m_type(TxNone) + , m_dirty(TxNone) {} + inline TransformationType inline_type() const; QMatrix affine; qreal m_13; qreal m_23; @@ -173,18 +186,25 @@ private: Q_DECLARE_TYPEINFO(QTransform, Q_MOVABLE_TYPE); /******* inlines *****/ +inline QTransform::TransformationType QTransform::inline_type() const +{ + if (m_dirty == TxNone) + return static_cast(m_type); + return type(); +} + inline bool QTransform::isAffine() const { - return type() < TxProject; + return inline_type() < TxProject; } inline bool QTransform::isIdentity() const { - return type() == TxNone; + return inline_type() == TxNone; } inline bool QTransform::isInvertible() const { - return !qFuzzyCompare(determinant() + 1, 1); + return !qIsFuzzyNull(determinant()); } inline bool QTransform::isScaling() const @@ -193,12 +213,12 @@ inline bool QTransform::isScaling() const } inline bool QTransform::isRotating() const { - return type() >= TxRotate; + return inline_type() >= TxRotate; } inline bool QTransform::isTranslating() const { - return type() >= TxTranslate; + return inline_type() >= TxTranslate; } inline qreal QTransform::determinant() const -- cgit v0.12 From a10b39a1884c97e62fbe599358ea6a8fb900c528 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Tue, 31 Mar 2009 16:42:18 +0200 Subject: Use qIsFuzzyNull rather than qFuzzyCompare qIsFuzzyNull is much cheaper than qFuzzyCompare, and in this case qIsFuzzyNull will do the trick. --- src/gui/graphicsview/qgraphicsitem.cpp | 8 ++++---- src/gui/graphicsview/qgraphicsitem_p.h | 2 +- src/gui/graphicsview/qgraphicsscene.cpp | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index c8a4a14..5c29e9c 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1904,11 +1904,11 @@ void QGraphicsItem::setOpacity(qreal opacity) newOpacity = qBound(0.0, newOpacity, 1.0); // No change? Done. - if (qFuzzyCompare(newOpacity, this->opacity())) + if (qIsFuzzyNull(newOpacity - this->opacity())) return; // Assign local opacity. - if (qFuzzyCompare(newOpacity, qreal(1.0))) { + if (qIsFuzzyNull(newOpacity - 1)) { // Opaque, unset opacity. d_ptr->hasOpacity = 0; d_ptr->unsetExtra(QGraphicsItemPrivate::ExtraOpacity); @@ -3763,7 +3763,7 @@ void QGraphicsItemPrivate::resolveEffectiveOpacity(qreal parentEffectiveOpacity) } // Set this item's resolved opacity. - if (qFuzzyCompare(myEffectiveOpacity, qreal(1.0))) { + if (qIsFuzzyNull(myEffectiveOpacity - 1)) { // Opaque, unset effective opacity. hasEffectiveOpacity = 0; unsetExtra(ExtraEffectiveOpacity); @@ -5846,7 +5846,7 @@ static void qt_graphicsItem_highlightSelected( QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option) { const QRectF murect = painter->transform().mapRect(QRectF(0, 0, 1, 1)); - if (qFuzzyCompare(qMax(murect.width(), murect.height()) + 1, 1)) + if (qIsFuzzyNull(qMax(murect.width(), murect.height()))) return; const QRectF mbrect = painter->transform().mapRect(item->boundingRect()); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index f738cf1..77db691 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -269,7 +269,7 @@ public: void updateCachedClipPathFromSetPosHelper(const QPointF &newPos); inline bool isFullyTransparent() const - { return hasEffectiveOpacity && qFuzzyCompare(q_func()->effectiveOpacity() + 1, qreal(1.0)); } + { return hasEffectiveOpacity && qIsFuzzyNull(q_func()->effectiveOpacity()); } inline bool childrenCombineOpacity() const { return allChildrenCombineOpacity || children.isEmpty(); } diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 7948caf..0439847 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4618,7 +4618,7 @@ static void _q_paintItem(QGraphicsItem *item, QPainter *painter, ? proxy->widget()->windowOpacity() : 1.0; const qreal oldPainterOpacity = painter->opacity(); - if (qFuzzyCompare(windowOpacity + 1, qreal(1.0))) + if (qIsFuzzyNull(windowOpacity)) return; // Set new painter opacity. if (windowOpacity < 1.0) @@ -5258,7 +5258,7 @@ void QGraphicsScene::itemUpdated(QGraphicsItem *item, const QRectF &rect) // Deliver the actual update. if (!d->updateAll) { if (d->views.isEmpty() || ((d->connectedSignals & d->changedSignalMask) && !item->d_ptr->itemIsUntransformable() - && qFuzzyCompare(item->boundingRegionGranularity(), qreal(0.0)))) { + && qIsFuzzyNull(item->boundingRegionGranularity()))) { // This block of code is kept for compatibility. Since 4.5, by default // QGraphicsView does not connect the signal and we use the below // method of delivering updates. -- cgit v0.12 From 37c72476fc444d3089075473cb4e9aa42ed64694 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Thu, 2 Apr 2009 14:48:13 +0200 Subject: Disable mouse tracking in QGraphicsView if possible. We don't need mouse tracking unless there are items in the scene that either accept hover events or have a cursor set. This cut-off is extremely efficient in the common case since all items ignore hover events and use the standard cursor by default. We no longer dig for items and do lots of intersection and calculating just for fun :-) We even get rid of the overhead of 2 x QCoreApplication::sendEvent! The next step is to optimize the items(*) functions to simply check for hasCursor()/acceptsHoverEvents() before we do complex checks like intersects/collidesWithPath() etc. Auto test included. Reviewed-by: Andreas --- src/gui/graphicsview/qgraphicsitem.cpp | 10 ++- src/gui/graphicsview/qgraphicsscene.cpp | 24 ++++++ src/gui/graphicsview/qgraphicsscene_p.h | 3 + src/gui/graphicsview/qgraphicsview.cpp | 27 ++++++- src/gui/graphicsview/qgraphicswidget.cpp | 5 ++ tests/auto/qgraphicsview/tst_qgraphicsview.cpp | 101 ++++++++++++++++++++++++- 6 files changed, 167 insertions(+), 3 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 5c29e9c..b8ff5b4 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1421,7 +1421,9 @@ void QGraphicsItem::setCursor(const QCursor &cursor) d_ptr->setExtra(QGraphicsItemPrivate::ExtraCursor, qVariantValue(cursorVariant)); d_ptr->hasCursor = 1; if (d_ptr->scene) { + d_ptr->scene->d_func()->allItemsUseDefaultCursor = false; foreach (QGraphicsView *view, d_ptr->scene->views()) { + view->viewport()->setMouseTracking(true); // Note: Some of this logic is duplicated in QGraphicsView's mouse events. if (view->underMouse()) { foreach (QGraphicsItem *itemUnderCursor, view->items(view->mapFromGlobal(QCursor::pos()))) { @@ -2053,7 +2055,13 @@ bool QGraphicsItem::acceptsHoverEvents() const */ void QGraphicsItem::setAcceptHoverEvents(bool enabled) { + if (d_ptr->acceptsHover == quint32(enabled)) + return; d_ptr->acceptsHover = quint32(enabled); + if (d_ptr->acceptsHover && d_ptr->scene && d_ptr->scene->d_func()->allItemsIgnoreHoverEvents) { + d_ptr->scene->d_func()->allItemsIgnoreHoverEvents = false; + d_ptr->scene->d_func()->enableMouseTrackingOnViews(); + } } /*! @@ -2063,7 +2071,7 @@ void QGraphicsItem::setAcceptHoverEvents(bool enabled) */ void QGraphicsItem::setAcceptsHoverEvents(bool enabled) { - d_ptr->acceptsHover = quint32(enabled); + setAcceptHoverEvents(enabled); } /*! diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 0439847..e885238 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -351,6 +351,8 @@ QGraphicsScenePrivate::QGraphicsScenePrivate() dragDropItem(0), enterWidget(0), lastDropAction(Qt::IgnoreAction), + allItemsIgnoreHoverEvents(true), + allItemsUseDefaultCursor(true), painterStateProtection(true), sortCacheEnabled(false), updatingSortCache(false), @@ -1047,6 +1049,12 @@ void QGraphicsScenePrivate::clearKeyboardGrabber() ungrabKeyboard(keyboardGrabberItems.first()); } +void QGraphicsScenePrivate::enableMouseTrackingOnViews() +{ + foreach (QGraphicsView *view, views) + view->viewport()->setMouseTracking(true); +} + /*! Returns all items for the screen position in \a event. */ @@ -2763,6 +2771,8 @@ void QGraphicsScene::clear() d->lastItemCount = 0; d->bspTree.clear(); d->largestUntransformableItem = QRectF(); + d->allItemsIgnoreHoverEvents = true; + d->allItemsUseDefaultCursor = true; } /*! @@ -2927,6 +2937,17 @@ void QGraphicsScene::addItem(QGraphicsItem *item) ++d->selectionChanging; int oldSelectedItemSize = d->selectedItems.size(); + // Enable mouse tracking if the item accepts hover events or has a cursor set. + if (d->allItemsIgnoreHoverEvents && d->itemAcceptsHoverEvents_helper(item)) { + d->allItemsIgnoreHoverEvents = false; + d->enableMouseTrackingOnViews(); + } + if (d->allItemsUseDefaultCursor && item->hasCursor()) { + d->allItemsUseDefaultCursor = false; + if (d->allItemsIgnoreHoverEvents) // already enabled otherwise + d->enableMouseTrackingOnViews(); + } + // Update selection lists if (item->isSelected()) d->selectedItems << item; @@ -4219,6 +4240,9 @@ bool QGraphicsScenePrivate::itemAcceptsHoverEvents_helper(const QGraphicsItem *i */ bool QGraphicsScenePrivate::dispatchHoverEvent(QGraphicsSceneHoverEvent *hoverEvent) { + if (allItemsIgnoreHoverEvents) + return false; + // Find the first item that accepts hover events, reusing earlier // calculated data is possible. if (cachedItemsUnderMouse.isEmpty()) { diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 8af8b28..9ace725 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -168,6 +168,9 @@ public: Qt::DropAction lastDropAction; QList cachedItemsUnderMouse; QList hoverItems; + bool allItemsIgnoreHoverEvents; + bool allItemsUseDefaultCursor; + void enableMouseTrackingOnViews(); QMap mouseGrabberButtonDownPos; QMap mouseGrabberButtonDownScenePos; QMap mouseGrabberButtonDownScreenPos; diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index b41dc66..797c895 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -587,6 +587,10 @@ void QGraphicsViewPrivate::mouseMoveEventHandler(QMouseEvent *event) return; if (!scene) return; + if (scene->d_func()->allItemsIgnoreHoverEvents && scene->d_func()->allItemsUseDefaultCursor + && !event->buttons()) { // forward event to the scene if something is pressed. + return; // No need to process this event further. + } QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseMove); mouseEvent.setWidget(q->viewport()); @@ -614,6 +618,16 @@ void QGraphicsViewPrivate::mouseMoveEventHandler(QMouseEvent *event) } #ifndef QT_NO_CURSOR + // If all the items ignore hover events, we don't look-up any items + // in QGraphicsScenePrivate::dispatchHoverEvent, hence the + // cachedItemsUnderMouse list will be empty. We therefore do the look-up + // for cursor items here if not all items use the default cursor. + if (scene->d_func()->allItemsIgnoreHoverEvents && !scene->d_func()->allItemsUseDefaultCursor + && scene->d_func()->cachedItemsUnderMouse.isEmpty()) { + scene->d_func()->cachedItemsUnderMouse = scene->d_func()->itemsAtPosition(mouseEvent.screenPos(), + mouseEvent.scenePos(), + mouseEvent.widget()); + } // Find the topmost item under the mouse with a cursor. foreach (QGraphicsItem *item, scene->d_func()->cachedItemsUnderMouse) { if (item->hasCursor()) { @@ -1688,6 +1702,12 @@ void QGraphicsView::setScene(QGraphicsScene *scene) d->recalculateContentSize(); d->lastCenterPoint = sceneRect().center(); d->keepLastCenterPoint = true; + // We are only interested in mouse tracking if items accept + // hover events or use non-default cursors. + if (!d->scene->d_func()->allItemsIgnoreHoverEvents + || !d->scene->d_func()->allItemsUseDefaultCursor) { + d->viewport->setMouseTracking(true); + } } else { d->recalculateContentSize(); } @@ -2799,7 +2819,12 @@ void QGraphicsView::setupViewport(QWidget *widget) widget->setAutoFillBackground(true); } - widget->setMouseTracking(true); + // We are only interested in mouse tracking if items + // accept hover events or use non-default cursors. + if (d->scene && (!d->scene->d_func()->allItemsIgnoreHoverEvents + || !d->scene->d_func()->allItemsUseDefaultCursor)) { + widget->setMouseTracking(true); + } widget->setAcceptDrops(acceptDrops()); } diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index 7f02fb9..2e7d82a 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -1635,6 +1635,11 @@ void QGraphicsWidget::setWindowFlags(Qt::WindowFlags wFlags) else d->scene->d_func()->addPopup(this); } + + if (d->scene && d->scene->d_func()->allItemsIgnoreHoverEvents && d->hasDecoration()) { + d->scene->d_func()->allItemsIgnoreHoverEvents = false; + d->scene->d_func()->enableMouseTrackingOnViews(); + } } /*! diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp index 412c6c5..6b3a9d4 100644 --- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp @@ -191,6 +191,7 @@ private slots: void scrollAfterResize_data(); void scrollAfterResize(); void centerOnDirtyItem(); + void mouseTracking(); // task specific tests below me void task172231_untransformableItems(); @@ -2515,7 +2516,8 @@ void tst_QGraphicsView::replayMouseMove() // One mouse event should be translated into one scene event. for (int i = 0; i < 3; ++i) { - sendMouseMove(view.viewport(), view.viewport()->rect().center()); + sendMouseMove(view.viewport(), view.viewport()->rect().center(), + Qt::LeftButton, Qt::MouseButtons(Qt::LeftButton)); QCOMPARE(viewSpy.count(), i + 1); QCOMPARE(sceneSpy.count(), i + 1); } @@ -2705,6 +2707,7 @@ void tst_QGraphicsView::task186827_deleteReplayedItem() MouseMoveCounter view; view.setScene(&scene); view.show(); + view.viewport()->setMouseTracking(true); #ifdef Q_WS_X11 qt_x11_wait_for_window_manager(&view); #endif @@ -3048,6 +3051,102 @@ void tst_QGraphicsView::centerOnDirtyItem() QCOMPARE(before, after); } +void tst_QGraphicsView::mouseTracking() +{ + // Mouse tracking should only be automatically enabled if items either accept hover events + // or have a cursor set. We never disable mouse tracking if it is already enabled. + + { // Make sure mouse tracking is disabled by default. + QGraphicsScene scene(-10000, -10000, 20000, 20000); + QGraphicsView view(&scene); + QVERIFY(!view.viewport()->hasMouseTracking()); + } + + { // Make sure we don't disable mouse tracking in setupViewport/setScene. + QGraphicsView view; + QWidget *viewport = new QWidget; + viewport->setMouseTracking(true); + view.setViewport(viewport); + QVERIFY(viewport->hasMouseTracking()); + + QGraphicsScene scene(-10000, -10000, 20000, 20000); + view.setScene(&scene); + QVERIFY(viewport->hasMouseTracking()); + } + + // Make sure we enable mouse tracking when having items that accept hover events. + { + // Adding an item to the scene after the scene is set on the view. + QGraphicsScene scene(-10000, -10000, 20000, 20000); + QGraphicsView view(&scene); + + QGraphicsRectItem *item = new QGraphicsRectItem(10, 10, 10, 10); + item->setAcceptHoverEvents(true); + scene.addItem(item); + QVERIFY(view.viewport()->hasMouseTracking()); + } + { + // Adding an item to the scene before the scene is set on the view. + QGraphicsScene scene(-10000, -10000, 20000, 20000); + QGraphicsRectItem *item = new QGraphicsRectItem(10, 10, 10, 10); + item->setAcceptHoverEvents(true); + scene.addItem(item); + + QGraphicsView view(&scene); + QVERIFY(view.viewport()->hasMouseTracking()); + } + { + // QGraphicsWidget implicitly accepts hover if it has window decoration. + QGraphicsScene scene(-10000, -10000, 20000, 20000); + QGraphicsView view(&scene); + + QGraphicsWidget *widget = new QGraphicsWidget; + scene.addItem(widget); + QVERIFY(!view.viewport()->hasMouseTracking()); + // Enable window decoraton. + widget->setWindowFlags(Qt::Window | Qt::WindowTitleHint); + QVERIFY(view.viewport()->hasMouseTracking()); + } + + // Make sure we enable mouse tracking when having items with a cursor set. + { + // Adding an item to the scene after the scene is set on the view. + QGraphicsScene scene(-10000, -10000, 20000, 20000); + QGraphicsView view(&scene); + + QGraphicsRectItem *item = new QGraphicsRectItem(10, 10, 10, 10); + item->setCursor(Qt::CrossCursor); + scene.addItem(item); + QVERIFY(view.viewport()->hasMouseTracking()); + } + { + // Adding an item to the scene before the scene is set on the view. + QGraphicsScene scene(-10000, -10000, 20000, 20000); + QGraphicsRectItem *item = new QGraphicsRectItem(10, 10, 10, 10); + item->setCursor(Qt::CrossCursor); + scene.addItem(item); + + QGraphicsView view(&scene); + QVERIFY(view.viewport()->hasMouseTracking()); + } + + // Make sure we propagate mouse tracking to all views. + { + QGraphicsScene scene(-10000, -10000, 20000, 20000); + QGraphicsView view1(&scene); + QGraphicsView view2(&scene); + QGraphicsView view3(&scene); + + QGraphicsRectItem *item = new QGraphicsRectItem(10, 10, 10, 10); + item->setCursor(Qt::CrossCursor); + scene.addItem(item); + + QVERIFY(view1.viewport()->hasMouseTracking()); + QVERIFY(view2.viewport()->hasMouseTracking()); + QVERIFY(view3.viewport()->hasMouseTracking()); + } +} + QTEST_MAIN(tst_QGraphicsView) #include "tst_qgraphicsview.moc" #endif -- cgit v0.12 From 35c26d696cbff269d551c012a212c09692dd6f6b Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Tue, 7 Apr 2009 16:37:08 +0200 Subject: Bt: Fix regression in the Embedded dialogs example We had to revert an earlier fix since it obviously did not work correctly. However since we do not really need to propagate the palette on the viewContainer _before_ it is created, we can simply avoid the issue alltogether as it would happen because we implicitly added a child widget during the polish of the combo box. Reviewed-by: nrc --- demos/embeddeddialogs/customproxy.cpp | 11 +++++++++-- src/gui/widgets/qcombobox.cpp | 24 +++++++++++++----------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/demos/embeddeddialogs/customproxy.cpp b/demos/embeddeddialogs/customproxy.cpp index 56a0548..ed2fc76 100644 --- a/demos/embeddeddialogs/customproxy.cpp +++ b/demos/embeddeddialogs/customproxy.cpp @@ -111,8 +111,15 @@ bool CustomProxy::sceneEventFilter(QGraphicsItem *watched, QEvent *event) QVariant CustomProxy::itemChange(GraphicsItemChange change, const QVariant &value) { - if (change == ItemChildRemovedChange) - removeSceneEventFilter(this); + if (change == ItemChildAddedChange || change == ItemChildRemovedChange) { + QGraphicsItem *item = qVariantValue(value); + if (change == ItemChildAddedChange) { + item->setCacheMode(ItemCoordinateCache); + item->installSceneEventFilter(this); + } else { + item->removeSceneEventFilter(this); + } + } return QGraphicsProxyWidget::itemChange(change, value); } diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp index 09a51fe..b9dbc62 100644 --- a/src/gui/widgets/qcombobox.cpp +++ b/src/gui/widgets/qcombobox.cpp @@ -2572,19 +2572,21 @@ void QComboBox::changeEvent(QEvent *e) hidePopup(); break; case QEvent::PaletteChange: { - QStyleOptionComboBox opt; - initStyleOption(&opt); + if (d->container) { + QStyleOptionComboBox opt; + initStyleOption(&opt); #ifndef QT_NO_MENU - if (style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, this)) { - QMenu menu; - menu.ensurePolished(); - d->viewContainer()->setPalette(menu.palette()); - d->viewContainer()->setWindowOpacity(menu.windowOpacity()); - } else + if (style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, this)) { + QMenu menu; + menu.ensurePolished(); + d->viewContainer()->setPalette(menu.palette()); + d->viewContainer()->setWindowOpacity(menu.windowOpacity()); + } else #endif - { - d->viewContainer()->setPalette(palette()); - d->viewContainer()->setWindowOpacity(1.0); + { + d->viewContainer()->setPalette(palette()); + d->viewContainer()->setWindowOpacity(1.0); + } } break; } -- cgit v0.12 From 76608a9c51f4cd5309a5fec1af40c4d80089adf5 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 7 Apr 2009 17:05:45 +0200 Subject: Fix compilation if SSL is not enabled. Using #ifndef QT_NO_OPENSSL without first #include'ing something will never work. Which means we always include qsslsocket.h. The problem is: if OpenSSL isn't enabled, then that file is a no-op and we never include qabstractsocket.h. Reviewed-by: Markus Goetz --- src/network/access/qhttpnetworkreply_p.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h index 21f4116..c17c65c 100644 --- a/src/network/access/qhttpnetworkreply_p.h +++ b/src/network/access/qhttpnetworkreply_p.h @@ -66,12 +66,10 @@ static const unsigned char gz_magic[2] = {0x1f, 0x8b}; // gzip magic header #define CHUNK 16384 #endif -#ifndef QT_NO_OPENSSL -# include -# include -#else -# include -#endif +#include +// it's safe to include these even if SSL support is not enabled +#include +#include #include #include -- cgit v0.12 From 18af4dfaabb4c3281abf2c2da575ced8dda672f1 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 7 Apr 2009 17:19:47 +0200 Subject: Fixes: Support for OpenGL ES 2.0 in configure.exe (Windows CE) RevBy: Joerg Details: -opengl-es-2 option for configure.exe --- tools/configure/configureapp.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 8c0dc39..df583a6 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -675,6 +675,9 @@ void Configure::parseCmdLine() } else if ( configCmdLine.at(i) == "-opengl-es-cl" ) { dictionary[ "OPENGL" ] = "yes"; dictionary[ "OPENGL_ES_CL" ] = "yes"; + } else if ( configCmdLine.at(i) == "-opengl-es-2" ) { + dictionary[ "OPENGL" ] = "yes"; + dictionary[ "OPENGL_ES_2" ] = "yes"; } // Databases ------------------------------------------------ else if( configCmdLine.at(i) == "-qt-sql-mysql" ) @@ -1632,6 +1635,7 @@ bool Configure::displayHelp() desc( "-signature ", "Use file for signing the target project"); desc("OPENGL_ES_CM", "no", "-opengl-es-cm", "Enable support for OpenGL ES Common"); desc("OPENGL_ES_CL", "no", "-opengl-es-cl", "Enable support for OpenGL ES Common Lite"); + desc("OPENGL_ES_2", "no", "-opengl-es-2", "Enable support for OpenGL ES 2.0"); desc("DIRECTSHOW", "no", "-phonon-wince-ds9", "Enable Phonon Direct Show 9 backend for Windows CE"); return true; @@ -1785,6 +1789,8 @@ bool Configure::checkAvailability(const QString &part) available = (dictionary[ "ARCHITECTURE" ] == "windowsce"); else if (part == "OPENGL_ES_CL") available = (dictionary[ "ARCHITECTURE" ] == "windowsce"); + else if (part == "OPENGL_ES_2") + available = (dictionary[ "ARCHITECTURE" ] == "windowsce"); else if (part == "DIRECTSHOW") available = (dictionary[ "ARCHITECTURE" ] == "windowsce"); else if (part == "SSE2") @@ -2264,6 +2270,10 @@ void Configure::generateOutputVars() qtConfig += "opengles1"; } + if ( dictionary["OPENGL_ES_2"] == "yes" ) { + qtConfig += "opengles2"; + } + if ( dictionary["OPENGL_ES_CL"] == "yes" ) { qtConfig += "opengles1cl"; } @@ -2664,9 +2674,11 @@ void Configure::generateConfigfiles() if(dictionary["SCRIPTTOOLS"] == "no") qconfigList += "QT_NO_SCRIPTTOOLS"; if(dictionary["OPENGL_ES_CM"] == "yes" || - dictionary["OPENGL_ES_CL"] == "yes") qconfigList += "QT_OPENGL_ES"; + dictionary["OPENGL_ES_CL"] == "yes" || + dictionary["OPENGL_ES_2"] == "yes") qconfigList += "QT_OPENGL_ES"; if(dictionary["OPENGL_ES_CM"] == "yes") qconfigList += "QT_OPENGL_ES_1"; + if(dictionary["OPENGL_ES_2"] == "yes") qconfigList += "QT_OPENGL_ES_2"; if(dictionary["OPENGL_ES_CL"] == "yes") qconfigList += "QT_OPENGL_ES_1_CL"; if(dictionary["SQL_MYSQL"] == "yes") qconfigList += "QT_SQL_MYSQL"; -- cgit v0.12 From 5d6b7757eebc76018eedd2fdfb5135df7b5cb460 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Tue, 7 Apr 2009 08:19:52 -0700 Subject: Make sure to clear surface in toImage It seems DirectFB doesn't preserve alpha value of a blit unless BLEND is specified and if it is we need to Clear to transparent first. Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index 35ab859..a20b66a 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -250,7 +250,12 @@ QImage QDirectFBPixmapData::toImage() const #ifndef QT_NO_DIRECTFB_PREALLOCATED QImage ret(size(), QDirectFBScreen::getImageFormat(dfbSurface)); if (IDirectFBSurface *imgSurface = screen->createDFBSurface(ret, QDirectFBScreen::DontTrackSurface)) { - imgSurface->SetBlittingFlags(imgSurface, hasAlphaChannel() ? DSBLIT_BLEND_ALPHACHANNEL : DSBLIT_NOFX); + if (hasAlphaChannel()) { + imgSurface->SetBlittingFlags(imgSurface, DSBLIT_BLEND_ALPHACHANNEL); + imgSurface->Clear(imgSurface, 0, 0, 0, 0); + } else { + imgSurface->SetBlittingFlags(imgSurface, DSBLIT_NOFX); + } imgSurface->Blit(imgSurface, dfbSurface, 0, 0, 0); imgSurface->ReleaseSource(imgSurface); imgSurface->Release(imgSurface); -- cgit v0.12 From 3568aeef72bec8333650eb2200b12eba8fac1b71 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 7 Apr 2009 16:59:01 +0200 Subject: compile with aCC --- tools/linguist/shared/translatormessage.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/linguist/shared/translatormessage.h b/tools/linguist/shared/translatormessage.h index 7d31925..9f847b0 100644 --- a/tools/linguist/shared/translatormessage.h +++ b/tools/linguist/shared/translatormessage.h @@ -195,12 +195,12 @@ struct TranslatorMessagePtr { Q_DECLARE_TYPEINFO(TranslatorMessagePtr, Q_MOVABLE_TYPE); -static inline int qHash(TranslatorMessagePtr tmp) +inline int qHash(TranslatorMessagePtr tmp) { return qHash(*tmp.ptr); } -static inline bool operator==(TranslatorMessagePtr tmp1, TranslatorMessagePtr tmp2) +inline bool operator==(TranslatorMessagePtr tmp1, TranslatorMessagePtr tmp2) { return *tmp1.ptr == *tmp2.ptr; } -- cgit v0.12 From f63976b7c5fd512c00442efd5cb9afb0b3707388 Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Fri, 1 Aug 2008 00:37:56 +0200 Subject: The QT_NO_SHAREDMEMORY define was checked a bit too late Reviewed-By: Harald Fernengel --- src/corelib/kernel/qsharedmemory_unix.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/corelib/kernel/qsharedmemory_unix.cpp b/src/corelib/kernel/qsharedmemory_unix.cpp index 487c653..cd248dc 100644 --- a/src/corelib/kernel/qsharedmemory_unix.cpp +++ b/src/corelib/kernel/qsharedmemory_unix.cpp @@ -47,12 +47,9 @@ #include #include -#include - -QT_BEGIN_NAMESPACE - #ifndef QT_NO_SHAREDMEMORY +#include #include #include #include @@ -61,6 +58,8 @@ QT_BEGIN_NAMESPACE #include #include +QT_BEGIN_NAMESPACE + QSharedMemoryPrivate::QSharedMemoryPrivate() : QObjectPrivate(), memory(0), size(0), error(QSharedMemory::NoError), #ifndef QT_NO_SYSTEMSEMAPHORE -- cgit v0.12 From 2553bde1b24091ef4076d0512709b6657750000e Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Tue, 7 Apr 2009 12:47:04 -0700 Subject: Make flipflags work a little better. Make it more flexible. This patch allows people to use DFB without DSFLIP_BLIT. Also, before this patch the flip= options weren't really used for anything. Reviewed-by: TrustMe --- .../gfxdrivers/directfb/qdirectfbscreen.cpp | 20 ++++++----- .../gfxdrivers/directfb/qdirectfbsurface.cpp | 40 ++++++++++++++-------- src/plugins/gfxdrivers/directfb/qdirectfbsurface.h | 5 +-- 3 files changed, 41 insertions(+), 24 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 4ae64f7..a62c846 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -85,7 +85,7 @@ public: }; QDirectFBScreenPrivate::QDirectFBScreenPrivate(QDirectFBScreen* screen) - : QWSGraphicsSystem(screen), dfb(0), dfbSurface(0), flipFlags(DSFLIP_BLIT) + : QWSGraphicsSystem(screen), dfb(0), dfbSurface(0), flipFlags(DSFLIP_NONE) #ifndef QT_NO_DIRECTFB_LAYER , dfbLayer(0) #endif @@ -710,7 +710,7 @@ int QDirectFBScreen::depth(DFBSurfacePixelFormat format) void QDirectFBScreenPrivate::setFlipFlags(const QStringList &args) { - QRegExp flipRegexp(QLatin1String("^flip=([\\w,]+)$")); + QRegExp flipRegexp(QLatin1String("^flip=([\\w,]*)$")); int index = args.indexOf(flipRegexp); if (index >= 0) { const QStringList flips = flipRegexp.cap(1).split(QLatin1Char(','), @@ -729,6 +729,8 @@ void QDirectFBScreenPrivate::setFlipFlags(const QStringList &args) qWarning("QDirectFBScreen: Unknown flip argument: %s", qPrintable(flip)); } + } else { + flipFlags = DFBSurfaceFlipFlags(DSFLIP_BLIT); } } @@ -994,19 +996,21 @@ void QDirectFBScreen::blank(bool on) QWSWindowSurface* QDirectFBScreen::createSurface(QWidget *widget) const { #ifdef QT_NO_DIRECTFB_WM - if (QApplication::type() == QApplication::GuiServer) - return new QDirectFBSurface(const_cast(this), widget); - else + if (QApplication::type() == QApplication::GuiServer) { + return new QDirectFBSurface(d_ptr->flipFlags, const_cast(this), widget); + } else { return QScreen::createSurface(widget); + } #else - return new QDirectFBSurface(const_cast(this), widget); + return new QDirectFBSurface(d_ptr->flipFlags, const_cast(this), widget); #endif } QWSWindowSurface* QDirectFBScreen::createSurface(const QString &key) const { - if (key == QLatin1String("directfb")) - return new QDirectFBSurface(const_cast(this)); + if (key == QLatin1String("directfb")) { + return new QDirectFBSurface(d_ptr->flipFlags, const_cast(this)); + } return QScreen::createSurface(key); } diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp index 4b8fe0a..f5626c8 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp @@ -50,12 +50,13 @@ //#define QT_DIRECTFB_DEBUG_SURFACES 1 -QDirectFBSurface::QDirectFBSurface(QDirectFBScreen* scr) +QDirectFBSurface::QDirectFBSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen* scr) : QDirectFBPaintDevice(scr) #ifndef QT_NO_DIRECTFB_WM , dfbWindow(0) #endif , engine(0) + , flipFlags(flip) { setSurfaceFlags(Opaque | Buffered); #ifdef QT_DIRECTFB_TIMING @@ -64,12 +65,13 @@ QDirectFBSurface::QDirectFBSurface(QDirectFBScreen* scr) #endif } -QDirectFBSurface::QDirectFBSurface(QDirectFBScreen* scr, QWidget *widget) +QDirectFBSurface::QDirectFBSurface(DFBSurfaceFlipFlags flip, QDirectFBScreen *scr, QWidget *widget) : QWSWindowSurface(widget), QDirectFBPaintDevice(scr) #ifndef QT_NO_DIRECTFB_WM , dfbWindow(0) #endif , engine(0) + , flipFlags(flip) { onscreen = widget->testAttribute(Qt::WA_PaintOnScreen); if (onscreen) @@ -244,7 +246,7 @@ void QDirectFBSurface::setPermanentState(const QByteArray &state) bool QDirectFBSurface::scroll(const QRegion ®ion, int dx, int dy) { - if (!dfbSurface) + if (!dfbSurface || !(flipFlags & DSFLIP_BLIT)) return false; const QVector rects = region.rects(); @@ -362,21 +364,31 @@ void QDirectFBSurface::flush(QWidget *widget, const QRegion ®ion, } #endif #ifndef QT_NO_DIRECTFB_WM - if (region.numRects() > 1) { - const QVector rects = region.rects(); - for (int i=0; iFlip(dfbSurface, 0, DFBSurfaceFlipFlags(flipFlags)); + } else { + if (region.numRects() > 1) { + const QVector rects = region.rects(); + DFBSurfaceFlipFlags tmpFlags = flipFlags; + if (flipFlags & DSFLIP_WAIT) + tmpFlags = DFBSurfaceFlipFlags(flipFlags & ~DSFLIP_WAIT); + for (int i=0; iFlip(dfbSurface, &dfbReg, + i + 1 < rects.size() + ? tmpFlags + : flipFlags); + } + } else { + const QRect r = region.boundingRect(); const DFBRegion dfbReg = { r.x() + offset.x(), r.y() + offset.y(), r.x() + r.width() + offset.x(), r.y() + r.height() + offset.y() }; - dfbSurface->Flip(dfbSurface, &dfbReg, DSFLIP_ONSYNC); + dfbSurface->Flip(dfbSurface, &dfbReg, flipFlags); } - } else { - const QRect r = region.boundingRect(); - const DFBRegion dfbReg = { r.x() + offset.x(), r.y() + offset.y(), - r.x() + r.width() + offset.x(), - r.y() + r.height() + offset.y() }; - dfbSurface->Flip(dfbSurface, &dfbReg, DSFLIP_ONSYNC); } #endif #ifdef QT_DIRECTFB_TIMING diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.h b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.h index 9e2791c..ab4145d 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.h @@ -61,8 +61,8 @@ QT_MODULE(Gui) class QDirectFBSurface: public QWSWindowSurface, public QDirectFBPaintDevice { public: - QDirectFBSurface(QDirectFBScreen* scr); - QDirectFBSurface(QDirectFBScreen* scr, QWidget *widget); + QDirectFBSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen* scr); + QDirectFBSurface(DFBSurfaceFlipFlags flipFlags, QDirectFBScreen* scr, QWidget *widget); ~QDirectFBSurface(); bool isValid() const; @@ -99,6 +99,7 @@ private: bool onscreen; QList bufferImages; + DFBSurfaceFlipFlags flipFlags; #ifdef QT_DIRECTFB_TIMING int frames; QTime timer; -- cgit v0.12 From b818bf2d67e4e5f3f3a01eeb0c0de37a4cd33b50 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Tue, 7 Apr 2009 15:01:46 -0700 Subject: Work around RGB32 issue in solidFill Drawing operations with DirectFB in RGB32 changes the alpha byte to 0. This doesn't play well with QRasterEngine. See 5fb7752ff93b31635e64fa321917749744cc9db6 and 34059fba55816496d2570b3306ac2b631b12a5c6 Reviewed-by: TrustMe --- .../gfxdrivers/directfb/qdirectfbscreen.cpp | 37 +++++++++++++--------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index a62c846..bf9864a 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -1182,21 +1182,29 @@ void QDirectFBScreen::solidFill(const QColor &color, const QRegion ®ion) if (region.isEmpty()) return; - const QVector rects = region.rects(); - QVarLengthArray dfbRects(rects.size()); - for (int i = 0; i < rects.size(); ++i) { - const QRect r = rects.at(i); - dfbRects[i].x = r.x(); - dfbRects[i].y = r.y(); - dfbRects[i].w = r.width(); - dfbRects[i].h = r.height(); + if (QDirectFBScreen::getImageFormat(d_ptr->dfbSurface) == QImage::Format_RGB32) { + uchar *mem; + int bpl; + d_ptr->dfbSurface->Lock(d_ptr->dfbSurface, DSLF_WRITE, (void**)&mem, &bpl); + QImage img(mem, w, h, bpl, QImage::Format_RGB32); + QPainter p(&img); + p.setBrush(color); + p.setPen(Qt::NoPen); + const QVector rects = region.rects(); + p.drawRects(rects.constData(), rects.size()); + p.end(); + d_ptr->dfbSurface->Unlock(d_ptr->dfbSurface); + } else { + d_ptr->dfbSurface->SetColor(d_ptr->dfbSurface, + color.red(), color.green(), color.blue(), + color.alpha()); + const QVector rects = region.rects(); + for (int i=0; idfbSurface->FillRectangle(d_ptr->dfbSurface, + r.x(), r.y(), r.width(), r.height()); + } } - - d_ptr->dfbSurface->SetColor(d_ptr->dfbSurface, - color.red(), color.green(), color.blue(), - color.alpha()); - d_ptr->dfbSurface->FillRectangles(d_ptr->dfbSurface, dfbRects.data(), - dfbRects.size()); } QImage::Format QDirectFBScreen::alphaPixmapFormat() const @@ -1204,7 +1212,6 @@ QImage::Format QDirectFBScreen::alphaPixmapFormat() const return d_ptr->alphaPixmapFormat; } - bool QDirectFBScreen::initSurfaceDescriptionPixelFormat(DFBSurfaceDescription *description, QImage::Format format) { -- cgit v0.12 From 06c19716bd9c5974743775de7aa702271b3ab435 Mon Sep 17 00:00:00 2001 From: Bill King Date: Wed, 8 Apr 2009 09:53:53 +1000 Subject: Fixes: Memory leak in DB2 driver Looks like they were using the old QPtrVector in qt3, and didn't quite handle the porting correctly. Reviewed-by: Lincoln Ramsay --- src/sql/drivers/db2/qsql_db2.cpp | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/src/sql/drivers/db2/qsql_db2.cpp b/src/sql/drivers/db2/qsql_db2.cpp index 69383f7..a6be435 100644 --- a/src/sql/drivers/db2/qsql_db2.cpp +++ b/src/sql/drivers/db2/qsql_db2.cpp @@ -87,8 +87,19 @@ public: {} ~QDB2ResultPrivate() { - for (int i = 0; i < valueCache.count(); ++i) + emptyValueCache(); + } + void clearValueCache() + { + for (int i = 0; i < valueCache.count(); ++i) { delete valueCache[i]; + valueCache[i] = NULL; + } + } + void emptyValueCache() + { + clearValueCache(); + valueCache.clear(); } const QDB2DriverPrivate* dp; @@ -544,7 +555,7 @@ bool QDB2Result::reset (const QString& query) SQLRETURN r; d->recInf.clear(); - d->valueCache.clear(); + d->emptyValueCache(); if (!qMakeStatement(d, isForwardOnly())) return false; @@ -567,7 +578,7 @@ bool QDB2Result::reset (const QString& query) } else { setSelect(false); } - d->valueCache.resize(count); + d->valueCache.resize(count, NULL); setActive(true); return true; } @@ -579,7 +590,7 @@ bool QDB2Result::prepare(const QString& query) SQLRETURN r; d->recInf.clear(); - d->valueCache.clear(); + d->emptyValueCache(); if (!qMakeStatement(d, isForwardOnly())) return false; @@ -607,7 +618,7 @@ bool QDB2Result::exec() SQLRETURN r; d->recInf.clear(); - d->valueCache.clear(); + d->emptyValueCache(); if (!qMakeStatement(d, isForwardOnly(), false)) return false; @@ -810,7 +821,7 @@ bool QDB2Result::exec() setSelect(false); } setActive(true); - d->valueCache.resize(count); + d->valueCache.resize(count, NULL); //get out parameters if (!hasOutValues()) @@ -858,7 +869,7 @@ bool QDB2Result::fetch(int i) return false; if (i == at()) return true; - d->valueCache.fill(0); + d->clearValueCache(); int actualIdx = i + 1; if (actualIdx <= 0) { setAt(QSql::BeforeFirstRow); @@ -887,7 +898,7 @@ bool QDB2Result::fetch(int i) bool QDB2Result::fetchNext() { SQLRETURN r; - d->valueCache.fill(0); + d->clearValueCache(); r = SQLFetchScroll(d->hStmt, SQL_FETCH_NEXT, 0); @@ -907,7 +918,7 @@ bool QDB2Result::fetchFirst() return false; if (isForwardOnly()) return fetchNext(); - d->valueCache.fill(0); + d->clearValueCache(); SQLRETURN r; r = SQLFetchScroll(d->hStmt, SQL_FETCH_FIRST, @@ -923,7 +934,7 @@ bool QDB2Result::fetchFirst() bool QDB2Result::fetchLast() { - d->valueCache.fill(0); + d->clearValueCache(); int i = at(); if (i == QSql::AfterLastRow) { @@ -1101,7 +1112,7 @@ bool QDB2Result::nextResult() setActive(false); setAt(QSql::BeforeFirstRow); d->recInf.clear(); - d->valueCache.clear(); + d->emptyValueCache(); setSelect(false); SQLRETURN r = SQLMoreResults(d->hStmt); @@ -1119,7 +1130,7 @@ bool QDB2Result::nextResult() for (int i = 0; i < fieldCount; ++i) d->recInf.append(qMakeFieldInfo(d, i)); - d->valueCache.resize(fieldCount); + d->valueCache.resize(fieldCount, NULL); setActive(true); return true; -- cgit v0.12 From a83faaf1bedfd321c4fc759156369d2f86fbbbed Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Tue, 7 Apr 2009 16:16:22 +1000 Subject: Remove fixed-point support from math3d The main use case for fixed-point support is to build large arrays of vertices. This can be handled using qvertextype or something similar at higher levels. So it isn't worth risking numerical instability in the core classes. Reviewed-by: trustme --- src/gui/math3d/math3d.pri | 5 - src/gui/math3d/qfixedpt.cpp | 711 --------------------- src/gui/math3d/qfixedpt.h | 551 ---------------- src/gui/math3d/qgenericmatrix.h | 22 +- src/gui/math3d/qmath3dglobal.h | 102 --- src/gui/math3d/qmath3dutil.cpp | 194 ------ src/gui/math3d/qmath3dutil_p.h | 96 --- src/gui/math3d/qmatrix4x4.cpp | 374 ++++++----- src/gui/math3d/qmatrix4x4.h | 177 +++-- src/gui/math3d/qquaternion.cpp | 33 +- src/gui/math3d/qquaternion.h | 49 +- src/gui/math3d/qvector2d.cpp | 9 +- src/gui/math3d/qvector2d.h | 34 +- src/gui/math3d/qvector3d.cpp | 8 +- src/gui/math3d/qvector3d.h | 41 +- src/gui/math3d/qvector4d.cpp | 12 +- src/gui/math3d/qvector4d.h | 46 +- tests/auto/math3d/math3d.pro | 3 +- tests/auto/math3d/qfixedpt/qfixedpt.pro | 2 - tests/auto/math3d/qfixedpt/tst_qfixedpt.cpp | 643 ------------------- tests/auto/math3d/qmatrixnxn/tst_qmatrixnxn.cpp | 83 +-- .../math3d/qmatrixnxn_fixed/qmatrixnxn_fixed.pro | 8 - tests/auto/math3d/qquaternion/tst_qquaternion.cpp | 18 - .../math3d/qquaternion_fixed/qquaternion_fixed.pro | 8 - tests/auto/math3d/qvectornd/tst_qvectornd.cpp | 18 - .../math3d/qvectornd_fixed/qvectornd_fixed.pro | 8 - tests/auto/math3d/shared/math3dincludes.cpp | 54 -- tests/auto/math3d/shared/math3dincludes.h | 35 - 28 files changed, 391 insertions(+), 2953 deletions(-) delete mode 100644 src/gui/math3d/qfixedpt.cpp delete mode 100644 src/gui/math3d/qfixedpt.h delete mode 100644 src/gui/math3d/qmath3dglobal.h delete mode 100644 src/gui/math3d/qmath3dutil.cpp delete mode 100644 src/gui/math3d/qmath3dutil_p.h delete mode 100644 tests/auto/math3d/qfixedpt/qfixedpt.pro delete mode 100644 tests/auto/math3d/qfixedpt/tst_qfixedpt.cpp delete mode 100644 tests/auto/math3d/qmatrixnxn_fixed/qmatrixnxn_fixed.pro delete mode 100644 tests/auto/math3d/qquaternion_fixed/qquaternion_fixed.pro delete mode 100644 tests/auto/math3d/qvectornd_fixed/qvectornd_fixed.pro delete mode 100644 tests/auto/math3d/shared/math3dincludes.cpp diff --git a/src/gui/math3d/math3d.pri b/src/gui/math3d/math3d.pri index 581adbd..e4dd53a 100644 --- a/src/gui/math3d/math3d.pri +++ b/src/gui/math3d/math3d.pri @@ -1,8 +1,5 @@ HEADERS += \ - math3d/qfixedpt.h \ math3d/qgenericmatrix.h \ - math3d/qmath3dglobal.h \ - math3d/qmath3dutil_p.h \ math3d/qmatrix4x4.h \ math3d/qquaternion.h \ math3d/qvector2d.h \ @@ -10,9 +7,7 @@ HEADERS += \ math3d/qvector4d.h SOURCES += \ - math3d/qfixedpt.cpp \ math3d/qgenericmatrix.cpp \ - math3d/qmath3dutil.cpp \ math3d/qmatrix4x4.cpp \ math3d/qquaternion.cpp \ math3d/qvector2d.cpp \ diff --git a/src/gui/math3d/qfixedpt.cpp b/src/gui/math3d/qfixedpt.cpp deleted file mode 100644 index 93f2150..0000000 --- a/src/gui/math3d/qfixedpt.cpp +++ /dev/null @@ -1,711 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the $MODULE$ of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qfixedpt.h" - -QT_BEGIN_NAMESPACE - -/*! - \internal - Returns the fixed-point square root of \a value. -*/ -qint64 qt_math3d_fixed_sqrt(qint64 value) -{ - qint64 result = 0; - qint64 bit = ((qint64)1) << 62; - while (bit > value) - bit >>= 2; - while (bit != 0) { - if (value >= (result + bit)) { - value -= result + bit; - result += (bit << 1); - } - result >>= 1; - bit >>= 2; - } - return result; -} - -/*! - \class QFixedPt - \brief The QFixedPt class represents fixed-point numbers within a 32-bit integer with a configurable precision. - - The template parameter is the number of bits of precision after - the decimal point. For example, QFixedPt<5> indicates that there - are 27 bits before the decimal point, and 5 bits of precision after - the decimal point. -*/ - -/*! - \fn QFixedPt::QFixedPt() - - Constructs a default fixed-point number. The initial value - is undefined. -*/ - -/*! - \fn QFixedPt::QFixedPt(int value) - - Constructs a fixed-point number from the integer \a value. -*/ - -/*! - \fn QFixedPt::QFixedPt(qreal value) - - Constructs a fixed-point number from the floating-point \a value. -*/ - -/*! - \fn QFixedPt& QFixedPt::operator=(int value) - - Assigns the integer \a value to this fixed-point variable. -*/ - -/*! - \fn QFixedPt& QFixedPt::operator=(qreal value) - - Assigns the floating-point \a value to this fixed-point variable. -*/ - -/*! - \fn int QFixedPt::bits() const - - Returns the raw bits that represent the fixed-point value of this object. - - \sa setBits() -*/ - -/*! - \fn void QFixedPt::setBits(int value) - - Sets the raw bits that represent the fixed-point value of - this object to \a value. - - \sa bits() -*/ - -#if !defined(QT_NO_MEMBER_TEMPLATES) || defined(Q_QDOC) - -/*! - \fn QFixedPt QFixedPt::toPrecision() const - - Returns this fixed-point number, converted to the new fixed-point - precision Prec. - - \sa qFixedPtToPrecision() -*/ - -#endif - -/*! - \fn QFixedPt qFixedPtToPrecision(const QFixedPt& value) - - Returns the fixed-point number \a value, converted to the new fixed-point - precision Prec. - - \sa QFixedPt::toPrecision() -*/ - -/*! - \fn QFixedPt& QFixedPt::operator+=(const QFixedPt& value) - - Adds \a value to this fixed-point number. -*/ - -/*! - \fn QFixedPt& QFixedPt::operator+=(int value) - - Adds an integer \a value to this fixed-point number. -*/ - -/*! - \fn QFixedPt& QFixedPt::operator+=(qreal value) - - Adds a floating-point \a value to this fixed-point number. -*/ - -/*! - \fn QFixedPt& QFixedPt::operator-=(const QFixedPt& value) - - Subtracts \a value from this fixed-point number. -*/ - -/*! - \fn QFixedPt& QFixedPt::operator-=(int value) - - Subtracts an integer \a value from this fixed-point number. -*/ - -/*! - \fn QFixedPt& QFixedPt::operator-=(qreal value) - - Subtracts a floating-point \a value from this fixed-point number. -*/ - -/*! - \fn QFixedPt& QFixedPt::operator*=(const QFixedPt& value) - - Multiplies this fixed-point number by \a value. -*/ - -/*! - \fn QFixedPt& QFixedPt::operator*=(int value) - - Multiplies this fixed-point number by an integer \a value. -*/ - -/*! - \fn QFixedPt& QFixedPt::operator*=(qreal value) - - Multiplies this fixed-point number by a floating-point \a value. -*/ - -/*! - \fn QFixedPt& QFixedPt::operator/=(const QFixedPt& value) - - Divides this fixed-point number by \a value. Division by zero - will result in zero. -*/ - -/*! - \fn QFixedPt& QFixedPt::operator/=(int value) - - Divides this fixed-point number by an integer \a value. Division - by zero will result in zero. -*/ - -/*! - \fn QFixedPt& QFixedPt::operator/=(qreal value) - - Divides this fixed-point number by a floating-point \a value. Division - by zero will result in zero. -*/ - -/*! - \fn QFixedPt& QFixedPt::operator<<=(int value) - - Shifts this fixed-point number left by \a value bits. -*/ - -/*! - \fn QFixedPt& QFixedPt::operator>>=(int value) - - Shifts this fixed-point number right by \a value bits. -*/ - -/*! - \fn QFixedPt QFixedPt::operator<<(int value) const - - Returns the result of shifting this fixed-point number - left by \a value bits. -*/ - -/*! - \fn QFixedPt QFixedPt::operator>>(int value) const - - Returns the result of shifting this fixed-point number - right by \a value bits. -*/ - -/*! - \fn bool QFixedPt::operator==(const QFixedPt& value) const - - Returns true if this fixed-point number is equal to \a value; - false otherwise. -*/ - -/*! - \fn bool operator==(const QFixedPt& v1, int v2) - \relates QFixedPt - - Returns true if \a v1 is equal to \a v2; false otherwise. -*/ - -/*! - \fn bool operator==(int v1, const QFixedPt& v2) - \relates QFixedPt - - Returns true if \a v1 is equal to \a v2; false otherwise. -*/ - -/*! - \fn bool operator==(const QFixedPt& v1, qreal v2) - \relates QFixedPt - - Returns true if \a v1 is equal to \a v2; false otherwise. -*/ - -/*! - \fn bool operator==(qreal v1, const QFixedPt& v2) - \relates QFixedPt - - Returns true if \a v1 is equal to \a v2; false otherwise. -*/ - -/*! - \fn bool QFixedPt::operator!=(const QFixedPt& value) const - - Returns true if this fixed-point number is not equal to \a value; - false otherwise. -*/ - -/*! - \fn bool operator!=(const QFixedPt& v1, int v2) - \relates QFixedPt - - Returns true if \a v1 is not equal to \a v2; false otherwise. -*/ - -/*! - \fn bool operator!=(int v1, const QFixedPt& v2) - \relates QFixedPt - - Returns true if \a v1 is not equal to \a v2; false otherwise. -*/ - -/*! - \fn bool operator!=(const QFixedPt& v1, qreal v2) - \relates QFixedPt - - Returns true if \a v1 is not equal to \a v2; false otherwise. -*/ - -/*! - \fn bool operator!=(qreal v1, const QFixedPt& v2) - \relates QFixedPt - - Returns true if \a v1 is not equal to \a v2; false otherwise. -*/ - -/*! - \fn bool QFixedPt::operator<=(const QFixedPt& value) const - - Returns true if this fixed-point number is less than or equal to - \a value; false otherwise. -*/ - -/*! - \fn bool operator<=(const QFixedPt& v1, int v2) - \relates QFixedPt - - Returns true if \a v1 is less than or equal to \a v2; false otherwise. -*/ - -/*! - \fn bool operator<=(int v1, const QFixedPt& v2) - \relates QFixedPt - - Returns true if \a v1 is less than or equal to \a v2; false otherwise. -*/ - -/*! - \fn bool operator<=(const QFixedPt& v1, qreal v2) - \relates QFixedPt - - Returns true if \a v1 is less than or equal to \a v2; false otherwise. -*/ - -/*! - \fn bool operator<=(qreal v1, const QFixedPt& v2) - \relates QFixedPt - - Returns true if \a v1 is less than or equal to \a v2; false otherwise. -*/ - -/*! - \fn bool QFixedPt::operator<(const QFixedPt& value) const - - Returns true if this fixed-point number is less than \a value; - false otherwise. -*/ - -/*! - \fn bool operator<(const QFixedPt& v1, int v2) - \relates QFixedPt - - Returns true if \a v1 is less than \a v2; false otherwise. -*/ - -/*! - \fn bool operator<(int v1, const QFixedPt& v2) - \relates QFixedPt - - Returns true if \a v1 is less than \a v2; false otherwise. -*/ - -/*! - \fn bool operator<(const QFixedPt& v1, qreal v2) - \relates QFixedPt - - Returns true if \a v1 is less than \a v2; false otherwise. -*/ - -/*! - \fn bool operator<(qreal v1, const QFixedPt& v2) - \relates QFixedPt - - Returns true if \a v1 is less than \a v2; false otherwise. -*/ - -/*! - \fn bool QFixedPt::operator>=(const QFixedPt& value) const - - Returns true if this fixed-point number is greater than or equal to - \a value; false otherwise. -*/ - -/*! - \fn bool operator>=(const QFixedPt& v1, int v2) - \relates QFixedPt - - Returns true if \a v1 is greater than or equal to \a v2; false otherwise. -*/ - -/*! - \fn bool operator>=(int v1, const QFixedPt& v2) - \relates QFixedPt - - Returns true if \a v1 is greater than or equal to \a v2; false otherwise. -*/ - -/*! - \fn bool operator>=(const QFixedPt& v1, qreal v2) - \relates QFixedPt - - Returns true if \a v1 is greater than or equal to \a v2; false otherwise. -*/ - -/*! - \fn bool operator>=(qreal v1, const QFixedPt& v2) - \relates QFixedPt - - Returns true if \a v1 is greater than or equal to \a v2; false otherwise. -*/ - -/*! - \fn bool QFixedPt::operator>(const QFixedPt& value) const - - Returns true if this fixed-point number is greater than \a value; - false otherwise. -*/ - -/*! - \fn bool operator>(const QFixedPt& v1, int v2) - \relates QFixedPt - - Returns true if \a v1 is greater than \a v2; false otherwise. -*/ - -/*! - \fn bool operator>(int v1, const QFixedPt& v2) - \relates QFixedPt - - Returns true if \a v1 is greater than \a v2; false otherwise. -*/ - -/*! - \fn bool operator>(const QFixedPt& v1, qreal v2) - \relates QFixedPt - - Returns true if \a v1 is greater than \a v2; false otherwise. -*/ - -/*! - \fn bool operator>(qreal v1, const QFixedPt& v2) - \relates QFixedPt - - Returns true if \a v1 is greater than \a v2; false otherwise. -*/ - -/*! - \fn QFixedPt QFixedPt::operator+(const QFixedPt& value) const - - Returns the result of adding this fixed-point number and \a value. -*/ - -/*! - \fn QFixedPt QFixedPt::operator+(int value) const - - Returns the result of adding this fixed-point number and \a value. -*/ - -/*! - \fn QFixedPt QFixedPt::operator+(qreal value) const - - Returns the result of adding this fixed-point number and \a value. -*/ - -/*! - \fn QFixedPt operator+(int v1, const QFixedPt& v2) - \relates QFixedPt - - Returns the result of adding \a v1 and \a v2. -*/ - -/*! - \fn QFixedPt operator+(qreal v1, const QFixedPt& v2) - \relates QFixedPt - - Returns the result of adding \a v1 and \a v2. -*/ - -/*! - \fn QFixedPt QFixedPt::operator-(const QFixedPt& value) const - - Returns the result of subtracting \a value from this fixed-point number. -*/ - -/*! - \fn QFixedPt QFixedPt::operator-(int value) const - - Returns the result of subtracting \a value from this fixed-point number. -*/ - -/*! - \fn QFixedPt QFixedPt::operator-(qreal value) const - - Returns the result of subtracting \a value from this fixed-point number. -*/ - -/*! - \fn QFixedPt operator-(int v1, const QFixedPt& v2) - \relates QFixedPt - - Returns the result of subtracting \a v2 from \a v1. -*/ - -/*! - \fn QFixedPt operator-(qreal v1, const QFixedPt& v2) - \relates QFixedPt - - Returns the result of subtracting \a v2 from \a v1. -*/ - -/*! - \fn QFixedPt QFixedPt::operator*(const QFixedPt& value) const - - Returns the result of multiplying this fixed-point number by \a value. -*/ - -/*! - \fn QFixedPt QFixedPt::operator*(int value) const - - Returns the result of multiplying this fixed-point number by \a value. -*/ - -/*! - \fn QFixedPt QFixedPt::operator*(qreal value) const - - Returns the result of multiplying this fixed-point number by \a value. -*/ - -/*! - \fn QFixedPt operator*(int v1, const QFixedPt& v2) - \relates QFixedPt - - Returns the result of multiplying \a v1 by \a v2. -*/ - -/*! - \fn QFixedPt operator*(qreal v1, const QFixedPt& v2) - \relates QFixedPt - - Returns the result of multiplying \a v1 by \a v2. -*/ - -/*! - \fn QFixedPt QFixedPt::operator/(const QFixedPt& value) const - - Returns the result of dividing this fixed-point number by \a value. - Division by zero will result in zero. -*/ - -/*! - \fn QFixedPt QFixedPt::operator/(int value) const - - Returns the result of dividing this fixed-point number by \a value. - Division by zero will result in zero. -*/ - -/*! - \fn QFixedPt QFixedPt::operator/(qreal value) const - - Returns the result of dividing this fixed-point number by \a value. - Division by zero will result in zero. -*/ - -/*! - \fn QFixedPt operator/(int v1, const QFixedPt& v2) - \relates QFixedPt - - Returns the result of dividing \a v1 by \a v2. Division by zero will - result in zero. -*/ - -/*! - \fn QFixedPt operator/(qreal v1, const QFixedPt& v2) - \relates QFixedPt - - Returns the result of dividing \a v1 by \a v2. Division by zero will - result in zero. -*/ - -/*! - \fn QFixedPt QFixedPt::operator-() const - - Returns the negation of this fixed-point number. -*/ - -/*! - \fn QFixedPt QFixedPt::sqrt() const - - Returns the square root of this fixed-point number. - - \sa sqrtF() -*/ - -/*! - \fn qreal QFixedPt::sqrtF() const - - Return the square root of this fixed-point number as a - floating-point value. - - \sa sqrt() -*/ - -/*! - \fn QFixedPt QFixedPt::round() const - - Returns this fixed-point number, rounded to the nearest integer. - - \sa floor(), ceil(), truncate() -*/ - -/*! - \fn QFixedPt QFixedPt::floor() const; - - Returns the largest integer that is less than or equal to - this fixed-point number. - - \sa round(), ceil(), truncate() -*/ - -/*! - \fn QFixedPt QFixedPt::ceil() const - - Returns the smallest integer that is greater than or equal to - this fixed-point number. - - \sa round(), floor(), truncate() -*/ - -/*! - \fn int QFixedPt::truncate() const - - Returns this fixed-point number with the bits after the - decimal point truncated. - - \sa round(), floor(), ceil() -*/ - -/*! - \fn int QFixedPt::toInt() const - - Returns this fixed-point number, rounded to the nearest integer. - - \sa toReal() -*/ - -/*! - \fn qreal QFixedPt::toReal() const - - Returns this fixed-point number as a floating-point value. - - \sa toInt() -*/ - -/*! - \fn int qCeil(const QFixedPt& value) - \relates QFixedPt - - Returns the smallest integer that is greater than or equal to - \a value. - - \sa qFloor(), qRound(), QFixedPt::ceil() -*/ - -/*! - \fn int qFloor(const QFixedPt& value) - \relates QFixedPt - - Returns the largest integer that is less than or equal to - \a value. - - \sa qCeil(), qRound(), QFixedPt::floor() -*/ - -/*! - \fn int qRound(const QFixedPt& value) - \relates QFixedPt - - Returns \a value, rounded to the nearest integer. - - \sa qCeil(), qFloor(), QFixedPt::round() -*/ - -/*! - \fn bool qFuzzyCompare(const QFixedPt& v1, const QFixedPt& v2, int compareBits) - \relates QFixedPt - - Returns true if \a v1 is almost equal to \a v2; false otherwise. - The \a compareBits parameter specifies the number of bits of precision - that should be considered relevant when performing the comparison. - By default, \a compareBits is PrecBits / 4. -*/ - -/*! - \fn bool qIsNull(const QFixedPt& v) - \relates QFixedPt - - Returns true if \a v is zero; false otherwise. -*/ - -QT_END_NAMESPACE diff --git a/src/gui/math3d/qfixedpt.h b/src/gui/math3d/qfixedpt.h deleted file mode 100644 index 142f62f..0000000 --- a/src/gui/math3d/qfixedpt.h +++ /dev/null @@ -1,551 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the $MODULE$ of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QFIXEDPT_H -#define QFIXEDPT_H - -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -Q_GUI_EXPORT qint64 qt_math3d_fixed_sqrt(qint64 value); - -// Should be called QFixed or QFixedPoint, but both of those -// are already in use in src/gui/painting/qfixed_p.h. -template -class QFixedPt -{ -public: - inline QFixedPt() {} // Deliberately not initialized - don't change this. - inline QFixedPt(int value) : val(value << PrecBits) {} - inline QFixedPt(qreal value) : val(int(value * (1 << PrecBits))) {} - - inline QFixedPt& operator=(int value) - { val = value << PrecBits; return *this; } - inline QFixedPt& operator=(qreal value) - { val = int(value * (1 << PrecBits)); return *this; } - - inline int bits() const { return val; } - inline void setBits(int value) { val = value; } - -#if !defined(QT_NO_MEMBER_TEMPLATES) || defined(Q_QDOC) - template - inline QFixedPt toPrecision() const - { - QFixedPt result; - if (Prec < PrecBits) - result.setBits(shiftRight(val, (PrecBits - Prec))); - else - result.setBits(shiftLeft(val, (Prec - PrecBits))); - return result; - } -#endif - - inline QFixedPt& operator+=(const QFixedPt& value) - { val += value.val; return *this; } - inline QFixedPt& operator+=(int value) - { val += (value << PrecBits); return *this; } - inline QFixedPt& operator+=(qreal value) - { val += int(value * (1 << PrecBits)); return *this; } - - inline QFixedPt& operator-=(const QFixedPt& value) - { val -= value.val; return *this; } - inline QFixedPt& operator-=(int value) - { val -= (value << PrecBits); return *this; } - inline QFixedPt& operator-=(qreal value) - { val -= int(value * (1 << PrecBits)); return *this; } - - inline QFixedPt& operator*=(const QFixedPt& value) - { val = mul(val, value.val); return *this; } - inline QFixedPt& operator*=(int value) - { val = mul(val, (value << PrecBits)); return *this; } - inline QFixedPt& operator*=(qreal value) - { val = mul(val, int(value * (1 << PrecBits))); return *this; } - - inline QFixedPt& operator/=(const QFixedPt& value) - { val = div(val, value.val); return *this; } - inline QFixedPt& operator/=(int value) - { val = div(val, (value << PrecBits)); return *this; } - inline QFixedPt& operator/=(qreal value) - { val = div(val, int(value * (1 << PrecBits))); return *this; } - - inline QFixedPt& operator<<=(int value) - { val <<= value; return *this; } - inline QFixedPt& operator>>=(int value) - { val >>= value; return *this; } - - inline QFixedPt operator<<(int value) const - { QFixedPt result; result.val = val << value; return result; } - inline QFixedPt operator>>(int value) const - { QFixedPt result; result.val = val >> value; return result; } - - inline bool operator==(const QFixedPt& value) const - { return val == value.val; } - inline bool operator!=(const QFixedPt& value) const - { return val != value.val; } - inline bool operator<=(const QFixedPt& value) const - { return val <= value.val; } - inline bool operator<(const QFixedPt& value) const - { return val < value.val; } - inline bool operator>=(const QFixedPt& value) const - { return val >= value.val; } - inline bool operator>(const QFixedPt& value) const - { return val > value.val; } - - inline QFixedPt operator+(const QFixedPt& value) const - { QFixedPt result; - result.val = val + value.val; return result; } - inline QFixedPt operator+(int value) const - { QFixedPt result; - result.val = val + (value << PrecBits); return result; } - inline QFixedPt operator+(qreal value) const - { QFixedPt result; - result.val = val + int(value * (1 << PrecBits)); return result; } - - inline QFixedPt operator-(const QFixedPt& value) const - { QFixedPt result; - result.val = val - value.val; return result; } - inline QFixedPt operator-(int value) const - { QFixedPt result; - result.val = val - (value << PrecBits); return result; } - inline QFixedPt operator-(qreal value) const - { QFixedPt result; - result.val = val - int(value * (1 << PrecBits)); return result; } - - inline QFixedPt operator*(const QFixedPt& value) const - { QFixedPt result; - result.val = mul(val, value.val); return result; } - inline QFixedPt operator*(int value) const - { QFixedPt result; - result.val = mul(val, (value << PrecBits)); return result; } - inline QFixedPt operator*(qreal value) const - { QFixedPt result; - result.val = mul(val, int(value * (1 << PrecBits))); return result; } - - inline QFixedPt operator/(const QFixedPt& value) const - { QFixedPt result; - result.val = div(val, value.val); return result; } - inline QFixedPt operator/(int value) const - { QFixedPt result; - result.val = div(val, (value << PrecBits)); return result; } - inline QFixedPt operator/(qreal value) const - { QFixedPt result; - result.val = div(val, int(value * (1 << PrecBits))); return result; } - - inline QFixedPt operator-() const - { QFixedPt result; result.val = -val; return result; } - - inline QFixedPt sqrt() const; - inline qreal sqrtF() const; - inline QFixedPt round() const; - inline QFixedPt floor() const; - inline QFixedPt ceil() const; - inline int truncate() const { return val >> PrecBits; } - - inline int toInt() const { return (val + (1 << (PrecBits - 1))) >> PrecBits; } - inline qreal toReal() const { return qreal(val) / qreal(1 << PrecBits); } - -#if !defined(Q_NO_TEMPLATE_FRIENDS) - template - friend QFixedPt operator/(int v1, const QFixedPt& v2); - template - friend QFixedPt operator/(qreal v1, const QFixedPt& v2); - -private: -#endif - int val; - - inline static int mul(int v1, int v2) - { - return int((qint64(v1) * qint64(v2)) >> PrecBits); - } - - inline static int div(int v1, int v2) - { - if (v2) - return int((qint64(v1) << PrecBits) / qint64(v2)); - else - return 0; - } - - // These are used by toPrecision() to avoid a silly gcc compiler warning - // related to negative shift values that will never actually be used. - inline static int shiftRight(int val, int shift) - { - return val >> shift; - } - inline static int shiftLeft(int val, int shift) - { - return val << shift; - } - -#if !defined(Q_NO_TEMPLATE_FRIENDS) - template - friend QFixedPt qFixedPtToPrecision(const QFixedPt& value); -#endif -}; - -template -inline bool operator==(const QFixedPt& v1, int v2) -{ - return v1.bits() == (v2 << PrecBits); -} - -template -inline bool operator==(int v1, const QFixedPt& v2) -{ - return (v1 << PrecBits) == v2.bits(); -} - -template -inline bool operator==(const QFixedPt& v1, qreal v2) -{ - return v1.bits() == int(v2 * (1 << PrecBits)); -} - -template -inline bool operator==(qreal v1, const QFixedPt& v2) -{ - return int(v1 * (1 << PrecBits)) == v2.bits(); -} - -template -inline bool operator!=(const QFixedPt& v1, int v2) -{ - return v1.bits() != (v2 << PrecBits); -} - -template -inline bool operator!=(int v1, const QFixedPt& v2) -{ - return (v1 << PrecBits) != v2.bits(); -} - -template -inline bool operator!=(const QFixedPt& v1, qreal v2) -{ - return v1.bits() != int(v2 * (1 << PrecBits)); -} - -template -inline bool operator!=(qreal v1, const QFixedPt& v2) -{ - return int(v1 * (1 << PrecBits)) != v2.bits(); -} - -template -inline bool operator<=(const QFixedPt& v1, int v2) -{ - return v1.bits() <= (v2 << PrecBits); -} - -template -inline bool operator<=(int v1, const QFixedPt& v2) -{ - return (v1 << PrecBits) <= v2.bits(); -} - -template -inline bool operator<=(const QFixedPt& v1, qreal v2) -{ - return v1.bits() <= int(v2 * (1 << PrecBits)); -} - -template -inline bool operator<=(qreal v1, const QFixedPt& v2) -{ - return int(v1 * (1 << PrecBits)) <= v2.bits(); -} - -template -inline bool operator<(const QFixedPt& v1, int v2) -{ - return v1.bits() < (v2 << PrecBits); -} - -template -inline bool operator<(int v1, const QFixedPt& v2) -{ - return (v1 << PrecBits) < v2.bits(); -} - -template -inline bool operator<(const QFixedPt& v1, qreal v2) -{ - return v1.bits() < int(v2 * (1 << PrecBits)); -} - -template -inline bool operator<(qreal v1, const QFixedPt& v2) -{ - return int(v1 * (1 << PrecBits)) < v2.bits(); -} - -template -inline bool operator>=(const QFixedPt& v1, int v2) -{ - return v1.bits() >= (v2 << PrecBits); -} - -template -inline bool operator>=(int v1, const QFixedPt& v2) -{ - return (v1 << PrecBits) >= v2.bits(); -} - -template -inline bool operator>=(const QFixedPt& v1, qreal v2) -{ - return v1.bits() >= int(v2 * (1 << PrecBits)); -} - -template -inline bool operator>=(qreal v1, const QFixedPt& v2) -{ - return int(v1 * (1 << PrecBits)) >= v2.bits(); -} - -template -inline bool operator>(const QFixedPt& v1, int v2) -{ - return v1.bits() > (v2 << PrecBits); -} - -template -inline bool operator>(int v1, const QFixedPt& v2) -{ - return (v1 << PrecBits) > v2.bits(); -} - -template -inline bool operator>(const QFixedPt& v1, qreal v2) -{ - return v1.bits() > int(v2 * (1 << PrecBits)); -} - -template -inline bool operator>(qreal v1, const QFixedPt& v2) -{ - return int(v1 * (1 << PrecBits)) > v2.bits(); -} - -template -inline QFixedPt operator+(int v1, const QFixedPt& v2) -{ - return v2 + v1; -} - -template -inline QFixedPt operator+(qreal v1, const QFixedPt& v2) -{ - return v2 + v1; -} - -template -inline QFixedPt operator-(int v1, const QFixedPt& v2) -{ - return -(v2 - v1); -} - -template -inline QFixedPt operator-(qreal v1, const QFixedPt& v2) -{ - return -(v2 - v1); -} - -template -inline QFixedPt operator*(int v1, const QFixedPt& v2) -{ - return v2 * v1; -} - -template -inline QFixedPt operator*(qreal v1, const QFixedPt& v2) -{ - return v2 * v1; -} - -template -inline QFixedPt operator/(int v1, const QFixedPt& v2) -{ - QFixedPt result; - result.val = QFixedPt::div(v1 << PrecBits, v2.val); - return result; -} - -template -inline QFixedPt operator/(qreal v1, const QFixedPt& v2) -{ - QFixedPt result; - result.val = QFixedPt::div(int(v1 * (1 << PrecBits)), v2.val); - return result; -} - -template -inline QFixedPt QFixedPt::sqrt() const -{ - QFixedPt result; - result.val = int(qt_math3d_fixed_sqrt - (qint64(val) << (PrecBits * 2)) >> (PrecBits / 2)); - return result; -} - -template -inline qreal QFixedPt::sqrtF() const -{ - return qt_math3d_fixed_sqrt - (qint64(val) << (PrecBits * 2)) / (qreal)(1 << (PrecBits + (PrecBits / 2))); -} - -template -inline QFixedPt QFixedPt::round() const -{ - QFixedPt result; - result.val = (val + (1 << (PrecBits - 1))) & ~((1 << PrecBits) - 1); - return result; -} - -template -inline QFixedPt QFixedPt::floor() const -{ - QFixedPt result; - result.val = val & ~((1 << PrecBits) - 1); - return result; -} - -template -inline QFixedPt QFixedPt::ceil() const -{ - QFixedPt result; - result.val = (val + (1 << PrecBits) - 1) & ~((1 << PrecBits) - 1); - return result; -} - -template -inline int qCeil(const QFixedPt& value) -{ - return value.ceil().bits() >> PrecBits; -} - -template -inline int qFloor(const QFixedPt& value) -{ - return value.floor().bits() >> PrecBits; -} - -template -inline int qRound(const QFixedPt& value) -{ - return value.round().bits() >> PrecBits; -} - -template -inline bool qFuzzyCompare(const QFixedPt& v1, const QFixedPt& v2, int compareBits = (PrecBits / 4)) -{ - return ((v1.bits() ^ v2.bits()) & ~((1 << compareBits) - 1)) == 0; -} - -template -inline bool qIsNull(const QFixedPt& v) -{ - return v.bits() == 0; -} - -template -QFixedPt qFixedPtToPrecision(const QFixedPt& value) -{ - QFixedPt result; - if (Prec < PrecBits) - result.setBits(QFixedPt::shiftRight(value.bits(), (PrecBits - Prec))); - else - result.setBits(QFixedPt::shiftLeft(value.bits(), (Prec - PrecBits))); - return result; -} - -template -inline QDebug &operator<<(QDebug &dbg, const QFixedPt &f) -{ - return dbg << f.toReal(); -} - -Q_DECLARE_TYPEINFO(QFixedPt<0>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<1>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<2>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<3>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<4>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<5>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<6>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<7>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<8>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<9>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<10>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<11>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<12>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<13>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<14>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<15>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<16>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<17>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<18>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<19>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<20>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<21>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<22>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<23>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<24>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<25>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<26>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<27>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<28>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<29>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<30>, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QFixedPt<31>, Q_PRIMITIVE_TYPE); - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/gui/math3d/qgenericmatrix.h b/src/gui/math3d/qgenericmatrix.h index dbeaaf3..d0b22de 100644 --- a/src/gui/math3d/qgenericmatrix.h +++ b/src/gui/math3d/qgenericmatrix.h @@ -42,8 +42,8 @@ #ifndef QGENERICMATRIX_H #define QGENERICMATRIX_H -#include #include +#include QT_BEGIN_HEADER @@ -134,7 +134,7 @@ template Q_INLINE_TEMPLATE T QGenericMatrix::operator()(int row, int column) const { Q_ASSERT(row >= 0 && row < M && column >= 0 && column < N); - return qt_math3d_convert(m[column][row]); + return T(m[column][row]); } template @@ -323,18 +323,18 @@ Q_OUTOFLINE_TEMPLATE void QGenericMatrix::toValueArray(T *value { for (int col = 0; col < N; ++col) for (int row = 0; row < M; ++row) - values[row * N + col] = qt_math3d_convert(m[col][row]); + values[row * N + col] = T(m[col][row]); } // Define aliases for the useful variants of QGenericMatrix. -typedef QGenericMatrix<2, 2, qreal, qrealinner> QMatrix2x2; -typedef QGenericMatrix<2, 3, qreal, qrealinner> QMatrix2x3; -typedef QGenericMatrix<2, 4, qreal, qrealinner> QMatrix2x4; -typedef QGenericMatrix<3, 2, qreal, qrealinner> QMatrix3x2; -typedef QGenericMatrix<3, 3, qreal, qrealinner> QMatrix3x3; -typedef QGenericMatrix<3, 4, qreal, qrealinner> QMatrix3x4; -typedef QGenericMatrix<4, 2, qreal, qrealinner> QMatrix4x2; -typedef QGenericMatrix<4, 3, qreal, qrealinner> QMatrix4x3; +typedef QGenericMatrix<2, 2, qreal, float> QMatrix2x2; +typedef QGenericMatrix<2, 3, qreal, float> QMatrix2x3; +typedef QGenericMatrix<2, 4, qreal, float> QMatrix2x4; +typedef QGenericMatrix<3, 2, qreal, float> QMatrix3x2; +typedef QGenericMatrix<3, 3, qreal, float> QMatrix3x3; +typedef QGenericMatrix<3, 4, qreal, float> QMatrix3x4; +typedef QGenericMatrix<4, 2, qreal, float> QMatrix4x2; +typedef QGenericMatrix<4, 3, qreal, float> QMatrix4x3; #ifndef QT_NO_DEBUG_STREAM diff --git a/src/gui/math3d/qmath3dglobal.h b/src/gui/math3d/qmath3dglobal.h deleted file mode 100644 index c2f7184..0000000 --- a/src/gui/math3d/qmath3dglobal.h +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the $MODULE$ of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QMATH3DGLOBAL_H -#define QMATH3DGLOBAL_H - -#include -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -// Detect the presence of a fixed-point OpenGL implementation. -#if defined(QT_OPENGL_ES_1_CL) || defined(QT_NO_GL_FLOAT) -#ifndef QT_GL_FIXED_PREFERRED -#define QT_GL_FIXED_PREFERRED 1 -#endif -#endif - -// QT_GL_FIXED_PREFERRED indicates that fixed-point should be -// preferred over floating-point for operations requiring high performance. -// -// qreal is the floating-point type that should be used in -// user-visible functions. qrealinner is used internally where -// values may be stored as either floating-point or fixed-point. -// qrealinner will typically be the same size as GLfloat or GLfixed. -#if defined(QT_GL_FIXED_PREFERRED) -typedef QFixedPt<16> qrealinner; -#else -typedef float qrealinner; -#endif - -// Explicit conversion operator, primarily for converting from -// fixed point back to floating-point. This is safer than -// declaring conversion operators in the QFixedPt class. -template -T1 qt_math3d_convert(T2 v) -{ - return T1(v); -} -template <> -inline float qt_math3d_convert< float, QFixedPt<16> >(QFixedPt<16> v) -{ - return float(v.toReal()); -} -template <> -inline double qt_math3d_convert< double, QFixedPt<16> >(QFixedPt<16> v) -{ - return double(v.toReal()); -} -template <> -inline int qt_math3d_convert< int, QFixedPt<16> >(QFixedPt<16> v) -{ - return v.toInt(); -} - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/gui/math3d/qmath3dutil.cpp b/src/gui/math3d/qmath3dutil.cpp deleted file mode 100644 index ad84162..0000000 --- a/src/gui/math3d/qmath3dutil.cpp +++ /dev/null @@ -1,194 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the $MODULE$ of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qmath3dutil_p.h" - -QT_BEGIN_NAMESPACE - -#ifdef QT_GL_FIXED_PREFERRED - -// The table that follows was automatically generated by the following code: -// -//#include -//#include -// -//int main() -//{ -// double angle; -// int count = 0; -// for (angle = 0.0; angle < 360.0; angle += 1.0) { -// if ((count % 4) == 0) -// printf(" "); -// printf(" qf2vt(%f)", sin(angle * M_PI / 180.0)); -// ++count; -// if (count != 360) -// printf(","); -// if ((count % 4) == 0) -// printf("\n"); -// } -// return 0; -//} - -#define qf2vt(x) (int((x) * 65536.0)) - -static int const sinTable[360] = { - qf2vt(0.000000), qf2vt(0.017452), qf2vt(0.034899), qf2vt(0.052336), - qf2vt(0.069756), qf2vt(0.087156), qf2vt(0.104528), qf2vt(0.121869), - qf2vt(0.139173), qf2vt(0.156434), qf2vt(0.173648), qf2vt(0.190809), - qf2vt(0.207912), qf2vt(0.224951), qf2vt(0.241922), qf2vt(0.258819), - qf2vt(0.275637), qf2vt(0.292372), qf2vt(0.309017), qf2vt(0.325568), - qf2vt(0.342020), qf2vt(0.358368), qf2vt(0.374607), qf2vt(0.390731), - qf2vt(0.406737), qf2vt(0.422618), qf2vt(0.438371), qf2vt(0.453990), - qf2vt(0.469472), qf2vt(0.484810), qf2vt(0.500000), qf2vt(0.515038), - qf2vt(0.529919), qf2vt(0.544639), qf2vt(0.559193), qf2vt(0.573576), - qf2vt(0.587785), qf2vt(0.601815), qf2vt(0.615661), qf2vt(0.629320), - qf2vt(0.642788), qf2vt(0.656059), qf2vt(0.669131), qf2vt(0.681998), - qf2vt(0.694658), qf2vt(0.707107), qf2vt(0.719340), qf2vt(0.731354), - qf2vt(0.743145), qf2vt(0.754710), qf2vt(0.766044), qf2vt(0.777146), - qf2vt(0.788011), qf2vt(0.798636), qf2vt(0.809017), qf2vt(0.819152), - qf2vt(0.829038), qf2vt(0.838671), qf2vt(0.848048), qf2vt(0.857167), - qf2vt(0.866025), qf2vt(0.874620), qf2vt(0.882948), qf2vt(0.891007), - qf2vt(0.898794), qf2vt(0.906308), qf2vt(0.913545), qf2vt(0.920505), - qf2vt(0.927184), qf2vt(0.933580), qf2vt(0.939693), qf2vt(0.945519), - qf2vt(0.951057), qf2vt(0.956305), qf2vt(0.961262), qf2vt(0.965926), - qf2vt(0.970296), qf2vt(0.974370), qf2vt(0.978148), qf2vt(0.981627), - qf2vt(0.984808), qf2vt(0.987688), qf2vt(0.990268), qf2vt(0.992546), - qf2vt(0.994522), qf2vt(0.996195), qf2vt(0.997564), qf2vt(0.998630), - qf2vt(0.999391), qf2vt(0.999848), qf2vt(1.000000), qf2vt(0.999848), - qf2vt(0.999391), qf2vt(0.998630), qf2vt(0.997564), qf2vt(0.996195), - qf2vt(0.994522), qf2vt(0.992546), qf2vt(0.990268), qf2vt(0.987688), - qf2vt(0.984808), qf2vt(0.981627), qf2vt(0.978148), qf2vt(0.974370), - qf2vt(0.970296), qf2vt(0.965926), qf2vt(0.961262), qf2vt(0.956305), - qf2vt(0.951057), qf2vt(0.945519), qf2vt(0.939693), qf2vt(0.933580), - qf2vt(0.927184), qf2vt(0.920505), qf2vt(0.913545), qf2vt(0.906308), - qf2vt(0.898794), qf2vt(0.891007), qf2vt(0.882948), qf2vt(0.874620), - qf2vt(0.866025), qf2vt(0.857167), qf2vt(0.848048), qf2vt(0.838671), - qf2vt(0.829038), qf2vt(0.819152), qf2vt(0.809017), qf2vt(0.798636), - qf2vt(0.788011), qf2vt(0.777146), qf2vt(0.766044), qf2vt(0.754710), - qf2vt(0.743145), qf2vt(0.731354), qf2vt(0.719340), qf2vt(0.707107), - qf2vt(0.694658), qf2vt(0.681998), qf2vt(0.669131), qf2vt(0.656059), - qf2vt(0.642788), qf2vt(0.629320), qf2vt(0.615661), qf2vt(0.601815), - qf2vt(0.587785), qf2vt(0.573576), qf2vt(0.559193), qf2vt(0.544639), - qf2vt(0.529919), qf2vt(0.515038), qf2vt(0.500000), qf2vt(0.484810), - qf2vt(0.469472), qf2vt(0.453990), qf2vt(0.438371), qf2vt(0.422618), - qf2vt(0.406737), qf2vt(0.390731), qf2vt(0.374607), qf2vt(0.358368), - qf2vt(0.342020), qf2vt(0.325568), qf2vt(0.309017), qf2vt(0.292372), - qf2vt(0.275637), qf2vt(0.258819), qf2vt(0.241922), qf2vt(0.224951), - qf2vt(0.207912), qf2vt(0.190809), qf2vt(0.173648), qf2vt(0.156434), - qf2vt(0.139173), qf2vt(0.121869), qf2vt(0.104528), qf2vt(0.087156), - qf2vt(0.069756), qf2vt(0.052336), qf2vt(0.034899), qf2vt(0.017452), - qf2vt(0.000000), qf2vt(-0.017452), qf2vt(-0.034899), qf2vt(-0.052336), - qf2vt(-0.069756), qf2vt(-0.087156), qf2vt(-0.104528), qf2vt(-0.121869), - qf2vt(-0.139173), qf2vt(-0.156434), qf2vt(-0.173648), qf2vt(-0.190809), - qf2vt(-0.207912), qf2vt(-0.224951), qf2vt(-0.241922), qf2vt(-0.258819), - qf2vt(-0.275637), qf2vt(-0.292372), qf2vt(-0.309017), qf2vt(-0.325568), - qf2vt(-0.342020), qf2vt(-0.358368), qf2vt(-0.374607), qf2vt(-0.390731), - qf2vt(-0.406737), qf2vt(-0.422618), qf2vt(-0.438371), qf2vt(-0.453990), - qf2vt(-0.469472), qf2vt(-0.484810), qf2vt(-0.500000), qf2vt(-0.515038), - qf2vt(-0.529919), qf2vt(-0.544639), qf2vt(-0.559193), qf2vt(-0.573576), - qf2vt(-0.587785), qf2vt(-0.601815), qf2vt(-0.615661), qf2vt(-0.629320), - qf2vt(-0.642788), qf2vt(-0.656059), qf2vt(-0.669131), qf2vt(-0.681998), - qf2vt(-0.694658), qf2vt(-0.707107), qf2vt(-0.719340), qf2vt(-0.731354), - qf2vt(-0.743145), qf2vt(-0.754710), qf2vt(-0.766044), qf2vt(-0.777146), - qf2vt(-0.788011), qf2vt(-0.798636), qf2vt(-0.809017), qf2vt(-0.819152), - qf2vt(-0.829038), qf2vt(-0.838671), qf2vt(-0.848048), qf2vt(-0.857167), - qf2vt(-0.866025), qf2vt(-0.874620), qf2vt(-0.882948), qf2vt(-0.891007), - qf2vt(-0.898794), qf2vt(-0.906308), qf2vt(-0.913545), qf2vt(-0.920505), - qf2vt(-0.927184), qf2vt(-0.933580), qf2vt(-0.939693), qf2vt(-0.945519), - qf2vt(-0.951057), qf2vt(-0.956305), qf2vt(-0.961262), qf2vt(-0.965926), - qf2vt(-0.970296), qf2vt(-0.974370), qf2vt(-0.978148), qf2vt(-0.981627), - qf2vt(-0.984808), qf2vt(-0.987688), qf2vt(-0.990268), qf2vt(-0.992546), - qf2vt(-0.994522), qf2vt(-0.996195), qf2vt(-0.997564), qf2vt(-0.998630), - qf2vt(-0.999391), qf2vt(-0.999848), qf2vt(-1.000000), qf2vt(-0.999848), - qf2vt(-0.999391), qf2vt(-0.998630), qf2vt(-0.997564), qf2vt(-0.996195), - qf2vt(-0.994522), qf2vt(-0.992546), qf2vt(-0.990268), qf2vt(-0.987688), - qf2vt(-0.984808), qf2vt(-0.981627), qf2vt(-0.978148), qf2vt(-0.974370), - qf2vt(-0.970296), qf2vt(-0.965926), qf2vt(-0.961262), qf2vt(-0.956305), - qf2vt(-0.951057), qf2vt(-0.945519), qf2vt(-0.939693), qf2vt(-0.933580), - qf2vt(-0.927184), qf2vt(-0.920505), qf2vt(-0.913545), qf2vt(-0.906308), - qf2vt(-0.898794), qf2vt(-0.891007), qf2vt(-0.882948), qf2vt(-0.874620), - qf2vt(-0.866025), qf2vt(-0.857167), qf2vt(-0.848048), qf2vt(-0.838671), - qf2vt(-0.829038), qf2vt(-0.819152), qf2vt(-0.809017), qf2vt(-0.798636), - qf2vt(-0.788011), qf2vt(-0.777146), qf2vt(-0.766044), qf2vt(-0.754710), - qf2vt(-0.743145), qf2vt(-0.731354), qf2vt(-0.719340), qf2vt(-0.707107), - qf2vt(-0.694658), qf2vt(-0.681998), qf2vt(-0.669131), qf2vt(-0.656059), - qf2vt(-0.642788), qf2vt(-0.629320), qf2vt(-0.615661), qf2vt(-0.601815), - qf2vt(-0.587785), qf2vt(-0.573576), qf2vt(-0.559193), qf2vt(-0.544639), - qf2vt(-0.529919), qf2vt(-0.515038), qf2vt(-0.500000), qf2vt(-0.484810), - qf2vt(-0.469472), qf2vt(-0.453990), qf2vt(-0.438371), qf2vt(-0.422618), - qf2vt(-0.406737), qf2vt(-0.390731), qf2vt(-0.374607), qf2vt(-0.358368), - qf2vt(-0.342020), qf2vt(-0.325568), qf2vt(-0.309017), qf2vt(-0.292372), - qf2vt(-0.275637), qf2vt(-0.258819), qf2vt(-0.241922), qf2vt(-0.224951), - qf2vt(-0.207912), qf2vt(-0.190809), qf2vt(-0.173648), qf2vt(-0.156434), - qf2vt(-0.139173), qf2vt(-0.121869), qf2vt(-0.104528), qf2vt(-0.087156), - qf2vt(-0.069756), qf2vt(-0.052336), qf2vt(-0.034899), qf2vt(-0.017452) -}; - -void qt_math3d_sincos(qreal angle, qrealinner *s, qrealinner *c) -{ - if (angle == qFloor(angle)) { - // The angle is an integer number of degrees, so look up the results. - int a = (int)angle; - if (a >= 0) - a = (a % 360); - else - a = 360 - (-a % 360); - s->setBits(sinTable[a]); - c->setBits(sinTable[(a + 90) % 360]); - } else { - qreal a = angle * M_PI / 180.0f; - *s = qSin(a); - *c = qCos(a); - } -} - -#else - -void qt_math3d_sincos(qreal angle, qrealinner *s, qrealinner *c) -{ - qreal a = angle * M_PI / 180.0f; - *s = qSin(a); - *c = qCos(a); -} - -#endif - -QT_END_NAMESPACE diff --git a/src/gui/math3d/qmath3dutil_p.h b/src/gui/math3d/qmath3dutil_p.h deleted file mode 100644 index fa4c156..0000000 --- a/src/gui/math3d/qmath3dutil_p.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the $MODULE$ of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QMATH3DUTIL_P_H -#define QMATH3DUTIL_P_H - -#include -#include - -QT_BEGIN_NAMESPACE - -#ifdef QT_GL_FIXED_PREFERRED -#define qvtsqrt(x) ((x).sqrtF()) -#else -#define qvtsqrt(x) qSqrt((x)) -#endif - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -void qt_math3d_sincos(qreal degrees, qrealinner *s, qrealinner *c); - -#ifdef QT_GL_FIXED_PREFERRED - -inline qrealinner qf2vt_round(qreal x) -{ - QFixedPt<16> result; - if (x >= 0.0f) - result.setBits(int(x * 65536.0f + 0.5f)); - else - result.setBits(int(x * 65536.0f - 0.5f)); - return result; -} - -// Helper macros for computing dot products without losing precision. -// In fixed-point mode, a 64-bit intermediate result is used. -#define qvtmul64(x,y) ((qint64((x).bits())) * (qint64((y).bits()))) -#define qvtsqrt64(x) \ - (qt_math3d_fixed_sqrt((x) << 16) / (qreal)(1 << 24)) -#define qvtdot64(x) ((x) / (qreal)(((qint64)1) << 32)) - -#else - -inline qrealinner qf2vt_round(qreal x) -{ - return x; -} - -#define qvtmul64(x,y) ((x) * (y)) -#define qvtsqrt64(x) (qvtsqrt((x))) -#define qvtdot64(x) ((x)) - -#endif - -QT_END_NAMESPACE - -#endif diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp index bcb3066..c2873e0 100644 --- a/src/gui/math3d/qmatrix4x4.cpp +++ b/src/gui/math3d/qmatrix4x4.cpp @@ -40,7 +40,6 @@ ****************************************************************************/ #include "qmatrix4x4.h" -#include "qmath3dutil_p.h" #include #include #include @@ -106,7 +105,7 @@ QMatrix4x4::QMatrix4x4(const qreal *values) #if !defined(QT_NO_MEMBER_TEMPLATES) || defined(Q_QDOC) /*! - \fn QMatrix4x4::QMatrix4x4(const QGenericMatrix& matrix) + \fn QMatrix4x4::QMatrix4x4(const QGenericMatrix& matrix) Constructs a 4x4 matrix from the left-most 4 columns and top-most 4 rows of \a matrix. If \a matrix has less than 4 columns or rows, @@ -117,7 +116,7 @@ QMatrix4x4::QMatrix4x4(const qreal *values) */ /*! - \fn QGenericMatrix QMatrix4x4::toGenericMatrix() const + \fn QGenericMatrix QMatrix4x4::toGenericMatrix() const Constructs a NxM generic matrix from the left-most N columns and top-most M rows of this 4x4 matrix. If N or M is greater than 4, @@ -130,7 +129,7 @@ QMatrix4x4::QMatrix4x4(const qreal *values) #endif /*! - \fn QMatrix4x4 qGenericMatrixToMatrix4x4(const QGenericMatrix& matrix) + \fn QMatrix4x4 qGenericMatrixToMatrix4x4(const QGenericMatrix& matrix) \relates QMatrix4x4 Returns a 4x4 matrix constructed from the left-most 4 columns and @@ -142,7 +141,7 @@ QMatrix4x4::QMatrix4x4(const qreal *values) */ /*! - \fn QGenericMatrix qGenericMatrixFromMatrix4x4(const QMatrix4x4& matrix) + \fn QGenericMatrix qGenericMatrixFromMatrix4x4(const QMatrix4x4& matrix) \relates QMatrix4x4 Returns a NxM generic matrix constructed from the left-most N columns @@ -156,7 +155,7 @@ QMatrix4x4::QMatrix4x4(const qreal *values) /*! \internal */ -QMatrix4x4::QMatrix4x4(const qrealinner *values, int cols, int rows) +QMatrix4x4::QMatrix4x4(const float *values, int cols, int rows) { for (int col = 0; col < 4; ++col) { for (int row = 0; row < 4; ++row) { @@ -244,7 +243,7 @@ QMatrix4x4::QMatrix4x4(const QTransform& transform) */ /*! - \fn qrealinner& QMatrix4x4::operator()(int row, int column) + \fn float& QMatrix4x4::operator()(int row, int column) Returns a reference to the element at position (\a row, \a column) in this matrix so that the element can be assigned to. @@ -316,8 +315,8 @@ QMatrix4x4::QMatrix4x4(const QTransform& transform) // | A B C | // M = | D E F | det(M) = A * (EI - HF) - B * (DI - GF) + C * (DH - GE) // | G H I | -static inline qrealinner matrixDet3 - (const qrealinner m[4][4], int col0, int col1, int col2, +static inline float matrixDet3 + (const float m[4][4], int col0, int col1, int col2, int row0, int row1, int row2) { return m[col0][row0] * @@ -332,9 +331,9 @@ static inline qrealinner matrixDet3 } // Calculate the determinant of a 4x4 matrix. -static inline qrealinner matrixDet4(const qrealinner m[4][4]) +static inline float matrixDet4(const float m[4][4]) { - qrealinner det; + float det; det = m[0][0] * matrixDet3(m, 1, 2, 3, 1, 2, 3); det -= m[1][0] * matrixDet3(m, 0, 2, 3, 1, 2, 3); det += m[2][0] * matrixDet3(m, 0, 1, 3, 1, 2, 3); @@ -347,7 +346,7 @@ static inline qrealinner matrixDet4(const qrealinner m[4][4]) */ qreal QMatrix4x4::determinant() const { - return qt_math3d_convert(matrixDet4(m)); + return qreal(matrixDet4(m)); } /*! @@ -386,13 +385,13 @@ QMatrix4x4 QMatrix4x4::inverted(bool *invertible) const QMatrix4x4 inv(1); // The "1" says to not load the identity. - qrealinner det = matrixDet4(m); + float det = matrixDet4(m); if (det == 0.0f) { if (invertible) *invertible = false; return QMatrix4x4(); } - det = qrealinner(1.0f) / det; + det = 1.0f / det; inv.m[0][0] = matrixDet3(m, 1, 2, 3, 1, 2, 3) * det; inv.m[0][1] = -matrixDet3(m, 0, 2, 3, 1, 2, 3) * det; @@ -434,18 +433,18 @@ QMatrix3x3 QMatrix4x4::normalMatrix() const } else if (flagBits == Scale || flagBits == (Translation | Scale)) { if (m[0][0] == 0.0f || m[1][1] == 0.0f || m[2][2] == 0.0f) return inv; - inv.data()[0] = qrealinner(1.0f) / m[0][0]; - inv.data()[4] = qrealinner(1.0f) / m[1][1]; - inv.data()[8] = qrealinner(1.0f) / m[2][2]; + inv.data()[0] = 1.0f / m[0][0]; + inv.data()[4] = 1.0f / m[1][1]; + inv.data()[8] = 1.0f / m[2][2]; return inv; } - qrealinner det = matrixDet3(m, 0, 1, 2, 0, 1, 2); + float det = matrixDet3(m, 0, 1, 2, 0, 1, 2); if (det == 0.0f) return inv; - det = qrealinner(1.0f) / det; + det = 1.0f / det; - qrealinner *invm = inv.data(); + float *invm = inv.data(); // Invert and transpose in a single step. invm[0 + 0 * 3] = (m[1][1] * m[2][2] - m[2][1] * m[1][2]) * det; @@ -507,23 +506,22 @@ QMatrix4x4 QMatrix4x4::transposed() const */ QMatrix4x4& QMatrix4x4::operator/=(qreal divisor) { - qrealinner d(divisor); - m[0][0] /= d; - m[0][1] /= d; - m[0][2] /= d; - m[0][3] /= d; - m[1][0] /= d; - m[1][1] /= d; - m[1][2] /= d; - m[1][3] /= d; - m[2][0] /= d; - m[2][1] /= d; - m[2][2] /= d; - m[2][3] /= d; - m[3][0] /= d; - m[3][1] /= d; - m[3][2] /= d; - m[3][3] /= d; + m[0][0] /= divisor; + m[0][1] /= divisor; + m[0][2] /= divisor; + m[0][3] /= divisor; + m[1][0] /= divisor; + m[1][1] /= divisor; + m[1][2] /= divisor; + m[1][3] /= divisor; + m[2][0] /= divisor; + m[2][1] /= divisor; + m[2][2] /= divisor; + m[2][3] /= divisor; + m[3][0] /= divisor; + m[3][1] /= divisor; + m[3][2] /= divisor; + m[3][3] /= divisor; flagBits = General; return *this; } @@ -665,23 +663,22 @@ QMatrix4x4& QMatrix4x4::operator/=(qreal divisor) QMatrix4x4 operator/(const QMatrix4x4& matrix, qreal divisor) { QMatrix4x4 m(1); // The "1" says to not load the identity. - qrealinner d(divisor); - m.m[0][0] = matrix.m[0][0] / d; - m.m[0][1] = matrix.m[0][1] / d; - m.m[0][2] = matrix.m[0][2] / d; - m.m[0][3] = matrix.m[0][3] / d; - m.m[1][0] = matrix.m[1][0] / d; - m.m[1][1] = matrix.m[1][1] / d; - m.m[1][2] = matrix.m[1][2] / d; - m.m[1][3] = matrix.m[1][3] / d; - m.m[2][0] = matrix.m[2][0] / d; - m.m[2][1] = matrix.m[2][1] / d; - m.m[2][2] = matrix.m[2][2] / d; - m.m[2][3] = matrix.m[2][3] / d; - m.m[3][0] = matrix.m[3][0] / d; - m.m[3][1] = matrix.m[3][1] / d; - m.m[3][2] = matrix.m[3][2] / d; - m.m[3][3] = matrix.m[3][3] / d; + m.m[0][0] = matrix.m[0][0] / divisor; + m.m[0][1] = matrix.m[0][1] / divisor; + m.m[0][2] = matrix.m[0][2] / divisor; + m.m[0][3] = matrix.m[0][3] / divisor; + m.m[1][0] = matrix.m[1][0] / divisor; + m.m[1][1] = matrix.m[1][1] / divisor; + m.m[1][2] = matrix.m[1][2] / divisor; + m.m[1][3] = matrix.m[1][3] / divisor; + m.m[2][0] = matrix.m[2][0] / divisor; + m.m[2][1] = matrix.m[2][1] / divisor; + m.m[2][2] = matrix.m[2][2] / divisor; + m.m[2][3] = matrix.m[2][3] / divisor; + m.m[3][0] = matrix.m[3][0] / divisor; + m.m[3][1] = matrix.m[3][1] / divisor; + m.m[3][2] = matrix.m[3][2] / divisor; + m.m[3][3] = matrix.m[3][3] / divisor; return m; } @@ -703,9 +700,9 @@ QMatrix4x4 operator/(const QMatrix4x4& matrix, qreal divisor) */ QMatrix4x4& QMatrix4x4::scale(const QVector3D& vector) { - qrealinner vx = vector.xp; - qrealinner vy = vector.yp; - qrealinner vz = vector.zp; + float vx = vector.xp; + float vy = vector.yp; + float vz = vector.zp; if (flagBits == Identity) { m[0][0] = vx; m[1][1] = vy; @@ -749,9 +746,9 @@ QMatrix4x4& QMatrix4x4::scale(const QVector3D& vector) */ QMatrix4x4& QMatrix4x4::scale(qreal x, qreal y, qreal z) { - qrealinner vx(x); - qrealinner vy(y); - qrealinner vz(z); + float vx(x); + float vy(y); + float vz(z); if (flagBits == Identity) { m[0][0] = vx; m[1][1] = vy; @@ -794,34 +791,33 @@ QMatrix4x4& QMatrix4x4::scale(qreal x, qreal y, qreal z) */ QMatrix4x4& QMatrix4x4::scale(qreal factor) { - qrealinner f(factor); if (flagBits == Identity) { - m[0][0] = f; - m[1][1] = f; - m[2][2] = f; + m[0][0] = factor; + m[1][1] = factor; + m[2][2] = factor; flagBits = Scale; } else if (flagBits == Scale || flagBits == (Scale | Translation)) { - m[0][0] *= f; - m[1][1] *= f; - m[2][2] *= f; + m[0][0] *= factor; + m[1][1] *= factor; + m[2][2] *= factor; } else if (flagBits == Translation) { - m[0][0] = f; - m[1][1] = f; - m[2][2] = f; + m[0][0] = factor; + m[1][1] = factor; + m[2][2] = factor; flagBits |= Scale; } else { - m[0][0] *= f; - m[0][1] *= f; - m[0][2] *= f; - m[0][3] *= f; - m[1][0] *= f; - m[1][1] *= f; - m[1][2] *= f; - m[1][3] *= f; - m[2][0] *= f; - m[2][1] *= f; - m[2][2] *= f; - m[2][3] *= f; + m[0][0] *= factor; + m[0][1] *= factor; + m[0][2] *= factor; + m[0][3] *= factor; + m[1][0] *= factor; + m[1][1] *= factor; + m[1][2] *= factor; + m[1][3] *= factor; + m[2][0] *= factor; + m[2][1] *= factor; + m[2][2] *= factor; + m[2][3] *= factor; flagBits = General; } return *this; @@ -836,9 +832,9 @@ QMatrix4x4& QMatrix4x4::scale(qreal factor) */ QMatrix4x4& QMatrix4x4::translate(const QVector3D& vector) { - qrealinner vx = vector.xp; - qrealinner vy = vector.yp; - qrealinner vz = vector.zp; + float vx = vector.xp; + float vy = vector.yp; + float vz = vector.zp; if (flagBits == Identity) { m[3][0] = vx; m[3][1] = vy; @@ -882,9 +878,9 @@ QMatrix4x4& QMatrix4x4::translate(const QVector3D& vector) */ QMatrix4x4& QMatrix4x4::translate(qreal x, qreal y, qreal z) { - qrealinner vx(x); - qrealinner vy(y); - qrealinner vz(z); + float vx(x); + float vy(y); + float vz(z); if (flagBits == Identity) { m[3][0] = vx; m[3][1] = vy; @@ -931,6 +927,10 @@ QMatrix4x4& QMatrix4x4::rotate(qreal angle, const QVector3D& vector) #endif +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + /*! \overload @@ -942,8 +942,10 @@ QMatrix4x4& QMatrix4x4::rotate(qreal angle, const QVector3D& vector) QMatrix4x4& QMatrix4x4::rotate(qreal angle, qreal x, qreal y, qreal z) { QMatrix4x4 m(1); // The "1" says to not load the identity. - qrealinner c, s, ic; - qt_math3d_sincos(angle, &s, &c); + qreal a = angle * M_PI / 180.0f; + qreal c = qCos(a); + qreal s = qSin(a); + qreal ic; bool quick = false; if (x == 0.0f) { if (y == 0.0f) { @@ -993,27 +995,24 @@ QMatrix4x4& QMatrix4x4::rotate(qreal angle, qreal x, qreal y, qreal z) quick = true; } if (!quick) { - qrealinner vx(x); - qrealinner vy(y); - qrealinner vz(z); - qrealinner len(qvtsqrt(vx * vx + vy * vy + vz * vz)); + qreal len = qSqrt(x * x + y * y + z * z); if (len != 0) { - vx /= len; - vy /= len; - vz /= len; + x /= len; + y /= len; + z /= len; } ic = 1.0f - c; - m.m[0][0] = vx * vx * ic + c; - m.m[1][0] = vx * vy * ic - vz * s; - m.m[2][0] = vx * vz * ic + vy * s; + m.m[0][0] = x * x * ic + c; + m.m[1][0] = x * y * ic - z * s; + m.m[2][0] = x * z * ic + y * s; m.m[3][0] = 0.0f; - m.m[0][1] = vy * vx * ic + vz * s; - m.m[1][1] = vy * vy * ic + c; - m.m[2][1] = vy * vz * ic - vx * s; + m.m[0][1] = y * x * ic + z * s; + m.m[1][1] = y * y * ic + c; + m.m[2][1] = y * z * ic - x * s; m.m[3][1] = 0.0f; - m.m[0][2] = vx * vz * ic - vy * s; - m.m[1][2] = vy * vz * ic + vx * s; - m.m[2][2] = vz * vz * ic + c; + m.m[0][2] = x * z * ic - y * s; + m.m[1][2] = y * z * ic + x * s; + m.m[2][2] = z * z * ic + c; m.m[3][2] = 0.0f; m.m[0][3] = 0.0f; m.m[1][3] = 0.0f; @@ -1043,15 +1042,15 @@ QMatrix4x4& QMatrix4x4::rotate(const QQuaternion& quaternion) // Algorithm from: // http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q54 QMatrix4x4 m(1); - qrealinner xx = quaternion.xp * quaternion.xp; - qrealinner xy = quaternion.xp * quaternion.yp; - qrealinner xz = quaternion.xp * quaternion.zp; - qrealinner xw = quaternion.xp * quaternion.wp; - qrealinner yy = quaternion.yp * quaternion.yp; - qrealinner yz = quaternion.yp * quaternion.zp; - qrealinner yw = quaternion.yp * quaternion.wp; - qrealinner zz = quaternion.zp * quaternion.zp; - qrealinner zw = quaternion.zp * quaternion.wp; + float xx = quaternion.xp * quaternion.xp; + float xy = quaternion.xp * quaternion.yp; + float xz = quaternion.xp * quaternion.zp; + float xw = quaternion.xp * quaternion.wp; + float yy = quaternion.yp * quaternion.yp; + float yz = quaternion.yp * quaternion.zp; + float yw = quaternion.yp * quaternion.wp; + float zz = quaternion.zp * quaternion.zp; + float zw = quaternion.zp * quaternion.wp; m.m[0][0] = 1.0f - 2 * (yy + zz); m.m[1][0] = 2 * (xy - zw); m.m[2][0] = 2 * (xz + yw); @@ -1137,33 +1136,33 @@ QMatrix4x4& QMatrix4x4::ortho(qreal left, qreal right, qreal bottom, qreal top, // which will be more efficient to modify with further // transformations than producing a "General" matrix. translate(QVector3D - (qf2vt_round(-(left + right) / width), - qf2vt_round(-(top + bottom) / invheight), + (-(left + right) / width, + -(top + bottom) / invheight, 0.0f, 1)); scale(QVector3D - (qf2vt_round(2.0f / width), - qf2vt_round(2.0f / invheight), + (2.0f / width, + 2.0f / invheight, -1.0f, 1)); return *this; } #endif QMatrix4x4 m(1); - m.m[0][0] = qf2vt_round(2.0f / width); - m.m[1][0] = qf2vt_round(0.0f); - m.m[2][0] = qf2vt_round(0.0f); - m.m[3][0] = qf2vt_round(-(left + right) / width); - m.m[0][1] = qf2vt_round(0.0f); - m.m[1][1] = qf2vt_round(2.0f / invheight); - m.m[2][1] = qf2vt_round(0.0f); - m.m[3][1] = qf2vt_round(-(top + bottom) / invheight); - m.m[0][2] = qf2vt_round(0.0f); - m.m[1][2] = qf2vt_round(0.0f); - m.m[2][2] = qf2vt_round(-2.0f / clip); - m.m[3][2] = qf2vt_round(-(nearPlane + farPlane) / clip); - m.m[0][3] = qf2vt_round(0.0f); - m.m[1][3] = qf2vt_round(0.0f); - m.m[2][3] = qf2vt_round(0.0f); - m.m[3][3] = qf2vt_round(1.0f); + m.m[0][0] = 2.0f / width; + m.m[1][0] = 0.0f; + m.m[2][0] = 0.0f; + m.m[3][0] = -(left + right) / width; + m.m[0][1] = 0.0f; + m.m[1][1] = 2.0f / invheight; + m.m[2][1] = 0.0f; + m.m[3][1] = -(top + bottom) / invheight; + m.m[0][2] = 0.0f; + m.m[1][2] = 0.0f; + m.m[2][2] = -2.0f / clip; + m.m[3][2] = -(nearPlane + farPlane) / clip; + m.m[0][3] = 0.0f; + m.m[1][3] = 0.0f; + m.m[2][3] = 0.0f; + m.m[3][3] = 1.0f; // Apply the projection. *this *= m; @@ -1189,22 +1188,22 @@ QMatrix4x4& QMatrix4x4::frustum(qreal left, qreal right, qreal bottom, qreal top qreal width = right - left; qreal invheight = top - bottom; qreal clip = farPlane - nearPlane; - m.m[0][0] = qf2vt_round(2.0f * nearPlane / width); - m.m[1][0] = qf2vt_round(0.0f); - m.m[2][0] = qf2vt_round((left + right) / width); - m.m[3][0] = qf2vt_round(0.0f); - m.m[0][1] = qf2vt_round(0.0f); - m.m[1][1] = qf2vt_round(2.0f * nearPlane / invheight); - m.m[2][1] = qf2vt_round((top + bottom) / invheight); - m.m[3][1] = qf2vt_round(0.0f); - m.m[0][2] = qf2vt_round(0.0f); - m.m[1][2] = qf2vt_round(0.0f); - m.m[2][2] = qf2vt_round(-(nearPlane + farPlane) / clip); - m.m[3][2] = qf2vt_round(-(2.0f * nearPlane * farPlane) / clip); - m.m[0][3] = qf2vt_round(0.0f); - m.m[1][3] = qf2vt_round(0.0f); - m.m[2][3] = qf2vt_round(-1.0f); - m.m[3][3] = qf2vt_round(0.0f); + m.m[0][0] = 2.0f * nearPlane / width; + m.m[1][0] = 0.0f; + m.m[2][0] = (left + right) / width; + m.m[3][0] = 0.0f; + m.m[0][1] = 0.0f; + m.m[1][1] = 2.0f * nearPlane / invheight; + m.m[2][1] = (top + bottom) / invheight; + m.m[3][1] = 0.0f; + m.m[0][2] = 0.0f; + m.m[1][2] = 0.0f; + m.m[2][2] = -(nearPlane + farPlane) / clip; + m.m[3][2] = -2.0f * nearPlane * farPlane / clip; + m.m[0][3] = 0.0f; + m.m[1][3] = 0.0f; + m.m[2][3] = -1.0f; + m.m[3][3] = 0.0f; // Apply the projection. *this *= m; @@ -1234,22 +1233,22 @@ QMatrix4x4& QMatrix4x4::perspective(qreal angle, qreal aspect, qreal nearPlane, return *this; qreal cotan = qCos(radians) / sine; qreal clip = farPlane - nearPlane; - m.m[0][0] = qf2vt_round(cotan / aspect); - m.m[1][0] = qf2vt_round(0.0f); - m.m[2][0] = qf2vt_round(0.0f); - m.m[3][0] = qf2vt_round(0.0f); - m.m[0][1] = qf2vt_round(0.0f); - m.m[1][1] = qf2vt_round(cotan); - m.m[2][1] = qf2vt_round(0.0f); - m.m[3][1] = qf2vt_round(0.0f); - m.m[0][2] = qf2vt_round(0.0f); - m.m[1][2] = qf2vt_round(0.0f); - m.m[2][2] = qf2vt_round(-(nearPlane + farPlane) / clip); - m.m[3][2] = qf2vt_round(-(2.0f * nearPlane * farPlane) / clip); - m.m[0][3] = qf2vt_round(0.0f); - m.m[1][3] = qf2vt_round(0.0f); - m.m[2][3] = qf2vt_round(-1.0f); - m.m[3][3] = qf2vt_round(0.0f); + m.m[0][0] = cotan / aspect; + m.m[1][0] = 0.0f; + m.m[2][0] = 0.0f; + m.m[3][0] = 0.0f; + m.m[0][1] = 0.0f; + m.m[1][1] = cotan; + m.m[2][1] = 0.0f; + m.m[3][1] = 0.0f; + m.m[0][2] = 0.0f; + m.m[1][2] = 0.0f; + m.m[2][2] = -(nearPlane + farPlane) / clip; + m.m[3][2] = -(2.0f * nearPlane * farPlane) / clip; + m.m[0][3] = 0.0f; + m.m[1][3] = 0.0f; + m.m[2][3] = -1.0f; + m.m[3][3] = 0.0f; // Apply the projection. *this *= m; @@ -1339,7 +1338,7 @@ void QMatrix4x4::toValueArray(qreal *values) const { for (int row = 0; row < 4; ++row) for (int col = 0; col < 4; ++col) - values[row * 4 + col] = qt_math3d_convert(m[col][row]); + values[row * 4 + col] = qreal(m[col][row]); } /*! @@ -1351,12 +1350,9 @@ void QMatrix4x4::toValueArray(qreal *values) const */ QMatrix QMatrix4x4::toAffine() const { - return QMatrix(qt_math3d_convert(m[0][0]), - qt_math3d_convert(m[0][1]), - qt_math3d_convert(m[1][0]), - qt_math3d_convert(m[1][1]), - qt_math3d_convert(m[3][0]), - qt_math3d_convert(m[3][1])); + return QMatrix(qreal(m[0][0]), qreal(m[0][1]), + qreal(m[1][0]), qreal(m[1][1]), + qreal(m[3][0]), qreal(m[3][1])); } /*! @@ -1368,15 +1364,9 @@ QMatrix QMatrix4x4::toAffine() const */ QTransform QMatrix4x4::toTransform() const { - return QTransform(qt_math3d_convert(m[0][0]), - qt_math3d_convert(m[0][1]), - qt_math3d_convert(m[0][3]), - qt_math3d_convert(m[1][0]), - qt_math3d_convert(m[1][1]), - qt_math3d_convert(m[1][3]), - qt_math3d_convert(m[3][0]), - qt_math3d_convert(m[3][1]), - qt_math3d_convert(m[3][3])); + return QTransform(qreal(m[0][0]), qreal(m[0][1]), qreal(m[0][3]), + qreal(m[1][0]), qreal(m[1][1]), qreal(m[1][3]), + qreal(m[3][0]), qreal(m[3][1]), qreal(m[3][3])); } /*! @@ -1442,7 +1432,7 @@ QTransform QMatrix4x4::toTransform() const */ /*! - \fn qrealinner *QMatrix4x4::data() + \fn float *QMatrix4x4::data() Returns a pointer to the raw data of this matrix. This is indended for use with raw GL functions. @@ -1451,7 +1441,7 @@ QTransform QMatrix4x4::toTransform() const */ /*! - \fn const qrealinner *QMatrix4x4::data() const + \fn const float *QMatrix4x4::data() const Returns a constant pointer to the raw data of this matrix. This is indended for use with raw GL functions. @@ -1460,7 +1450,7 @@ QTransform QMatrix4x4::toTransform() const */ /*! - \fn const qrealinner *QMatrix4x4::constData() const + \fn const float *QMatrix4x4::constData() const Returns a constant pointer to the raw data of this matrix. This is indended for use with raw GL functions. @@ -1519,8 +1509,8 @@ void QMatrix4x4::extractAxisRotation(qreal &angle, QVector3D &axis) const { // Orientation is dependent on the upper 3x3 matrix; subtract the // homogeneous scaling element from the trace of the 4x4 matrix - qrealinner tr = m[0][0] + m[1][1] + m[2][2]; - qreal cosa = qt_math3d_convert(0.5f * (tr - 1.0f)); + float tr = m[0][0] + m[1][1] + m[2][2]; + qreal cosa = qreal(0.5f * (tr - 1.0f)); angle = acos(cosa) * 180.0f / M_PI; // Any axis will work if r is zero (means no rotation) @@ -1540,11 +1530,11 @@ void QMatrix4x4::extractAxisRotation(qreal &angle, QVector3D &axis) const } // rads == PI - qrealinner tmp; + float tmp; // r00 is maximum if ((m[0][0] >= m[2][2]) && (m[0][0] >= m[1][1])) { - axis.xp = 0.5f * qvtsqrt(m[0][0] - m[1][1] - m[2][2] + 1.0f); + axis.xp = 0.5f * qSqrt(m[0][0] - m[1][1] - m[2][2] + 1.0f); tmp = 0.5f / axis.x(); axis.yp = m[1][0] * tmp; axis.zp = m[2][0] * tmp; @@ -1552,7 +1542,7 @@ void QMatrix4x4::extractAxisRotation(qreal &angle, QVector3D &axis) const // r11 is maximum if ((m[1][1] >= m[2][2]) && (m[1][1] >= m[0][0])) { - axis.yp = 0.5f * qvtsqrt(m[1][1] - m[0][0] - m[2][2] + 1.0f); + axis.yp = 0.5f * qSqrt(m[1][1] - m[0][0] - m[2][2] + 1.0f); tmp = 0.5f / axis.y(); axis.xp = tmp * m[1][0]; axis.zp = tmp * m[2][1]; @@ -1560,7 +1550,7 @@ void QMatrix4x4::extractAxisRotation(qreal &angle, QVector3D &axis) const // r22 is maximum if ((m[2][2] >= m[1][1]) && (m[2][2] >= m[0][0])) { - axis.zp = 0.5f * qvtsqrt(m[2][2] - m[0][0] - m[1][1] + 1.0f); + axis.zp = 0.5f * qSqrt(m[2][2] - m[0][0] - m[1][1] + 1.0f); tmp = 0.5f / axis.z(); axis.xp = m[2][0]*tmp; axis.yp = m[2][1]*tmp; diff --git a/src/gui/math3d/qmatrix4x4.h b/src/gui/math3d/qmatrix4x4.h index 6428b20..2b485c1 100644 --- a/src/gui/math3d/qmatrix4x4.h +++ b/src/gui/math3d/qmatrix4x4.h @@ -70,14 +70,14 @@ public: qreal m41, qreal m42, qreal m43, qreal m44); #if !defined(QT_NO_MEMBER_TEMPLATES) || defined(Q_QDOC) template - explicit QMatrix4x4(const QGenericMatrix& matrix); + explicit QMatrix4x4(const QGenericMatrix& matrix); #endif - QMatrix4x4(const qrealinner *values, int cols, int rows); + QMatrix4x4(const float *values, int cols, int rows); QMatrix4x4(const QTransform& transform); QMatrix4x4(const QMatrix& matrix); inline qreal operator()(int row, int column) const; - inline qrealinner& operator()(int row, int column); + inline float& operator()(int row, int column); inline QVector4D column(int index) const; inline void setColumn(int index, const QVector4D& value); @@ -171,12 +171,12 @@ public: #if !defined(QT_NO_MEMBER_TEMPLATES) || defined(Q_QDOC) template - QGenericMatrix toGenericMatrix() const; + QGenericMatrix toGenericMatrix() const; #endif - inline qrealinner *data(); - inline const qrealinner *data() const { return m[0]; } - inline const qrealinner *constData() const { return m[0]; } + inline float *data(); + inline const float *data() const { return m[0]; } + inline const float *constData() const { return m[0]; } void inferSpecialType(); @@ -185,7 +185,7 @@ public: #endif private: - qrealinner m[4][4]; // Column-major order to match OpenGL. + float m[4][4]; // Column-major order to match OpenGL. int flagBits; // Flag bits from the enum below. enum { @@ -219,9 +219,9 @@ inline QMatrix4x4::QMatrix4x4 template Q_INLINE_TEMPLATE QMatrix4x4::QMatrix4x4 - (const QGenericMatrix& matrix) + (const QGenericMatrix& matrix) { - const qrealinner *values = matrix.constData(); + const float *values = matrix.constData(); for (int col = 0; col < 4; ++col) { for (int row = 0; row < 4; ++row) { if (col < N && row < M) @@ -236,10 +236,10 @@ Q_INLINE_TEMPLATE QMatrix4x4::QMatrix4x4 } template -QGenericMatrix QMatrix4x4::toGenericMatrix() const +QGenericMatrix QMatrix4x4::toGenericMatrix() const { - QGenericMatrix result; - qrealinner *values = result.data(); + QGenericMatrix result; + float *values = result.data(); for (int col = 0; col < N; ++col) { for (int row = 0; row < M; ++row) { if (col < 4 && row < 4) @@ -258,10 +258,10 @@ QGenericMatrix QMatrix4x4::toGenericMatrix() const inline qreal QMatrix4x4::operator()(int row, int column) const { Q_ASSERT(row >= 0 && row < 4 && column >= 0 && column < 4); - return qt_math3d_convert(m[column][row]); + return qreal(m[column][row]); } -inline qrealinner& QMatrix4x4::operator()(int row, int column) +inline float& QMatrix4x4::operator()(int row, int column) { Q_ASSERT(row >= 0 && row < 4 && column >= 0 && column < 4); flagBits = General; @@ -420,23 +420,22 @@ inline QMatrix4x4& QMatrix4x4::operator*=(const QMatrix4x4& other) inline QMatrix4x4& QMatrix4x4::operator*=(qreal factor) { - qrealinner f(factor); - m[0][0] *= f; - m[0][1] *= f; - m[0][2] *= f; - m[0][3] *= f; - m[1][0] *= f; - m[1][1] *= f; - m[1][2] *= f; - m[1][3] *= f; - m[2][0] *= f; - m[2][1] *= f; - m[2][2] *= f; - m[2][3] *= f; - m[3][0] *= f; - m[3][1] *= f; - m[3][2] *= f; - m[3][3] *= f; + m[0][0] *= factor; + m[0][1] *= factor; + m[0][2] *= factor; + m[0][3] *= factor; + m[1][0] *= factor; + m[1][1] *= factor; + m[1][2] *= factor; + m[1][3] *= factor; + m[2][0] *= factor; + m[2][1] *= factor; + m[2][2] *= factor; + m[2][3] *= factor; + m[3][0] *= factor; + m[3][1] *= factor; + m[3][2] *= factor; + m[3][3] *= factor; flagBits = General; return *this; } @@ -604,7 +603,7 @@ inline QMatrix4x4 operator*(const QMatrix4x4& m1, const QMatrix4x4& m2) inline QVector3D operator*(const QVector3D& vector, const QMatrix4x4& matrix) { - qrealinner x, y, z, w; + float x, y, z, w; x = vector.xp * matrix.m[0][0] + vector.yp * matrix.m[0][1] + vector.zp * matrix.m[0][2] + @@ -629,7 +628,7 @@ inline QVector3D operator*(const QVector3D& vector, const QMatrix4x4& matrix) inline QVector3D operator*(const QMatrix4x4& matrix, const QVector3D& vector) { - qrealinner x, y, z, w; + float x, y, z, w; x = vector.xp * matrix.m[0][0] + vector.yp * matrix.m[1][0] + vector.zp * matrix.m[2][0] + @@ -658,7 +657,7 @@ inline QVector3D operator*(const QMatrix4x4& matrix, const QVector3D& vector) inline QVector4D operator*(const QVector4D& vector, const QMatrix4x4& matrix) { - qrealinner x, y, z, w; + float x, y, z, w; x = vector.xp * matrix.m[0][0] + vector.yp * matrix.m[0][1] + vector.zp * matrix.m[0][2] + @@ -680,7 +679,7 @@ inline QVector4D operator*(const QVector4D& vector, const QMatrix4x4& matrix) inline QVector4D operator*(const QMatrix4x4& matrix, const QVector4D& vector) { - qrealinner x, y, z, w; + float x, y, z, w; x = vector.xp * matrix.m[0][0] + vector.yp * matrix.m[1][0] + vector.zp * matrix.m[2][0] + @@ -704,8 +703,8 @@ inline QVector4D operator*(const QMatrix4x4& matrix, const QVector4D& vector) inline QPoint operator*(const QPoint& point, const QMatrix4x4& matrix) { - qrealinner xin, yin; - qrealinner x, y, w; + float xin, yin; + float x, y, w; xin = point.x(); yin = point.y(); x = xin * matrix.m[0][0] + @@ -725,8 +724,8 @@ inline QPoint operator*(const QPoint& point, const QMatrix4x4& matrix) inline QPointF operator*(const QPointF& point, const QMatrix4x4& matrix) { - qrealinner xin, yin; - qrealinner x, y, w; + float xin, yin; + float x, y, w; xin = point.x(); yin = point.y(); x = xin * matrix.m[0][0] + @@ -739,18 +738,16 @@ inline QPointF operator*(const QPointF& point, const QMatrix4x4& matrix) yin * matrix.m[3][1] + matrix.m[3][3]; if (w == 1.0f) { - return QPointF(qt_math3d_convert(x), - qt_math3d_convert(y)); + return QPointF(qreal(x), qreal(y)); } else { - return QPointF(qt_math3d_convert(x / w), - qt_math3d_convert(y / w)); + return QPointF(qreal(x / w), qreal(y / w)); } } inline QPoint operator*(const QMatrix4x4& matrix, const QPoint& point) { - qrealinner xin, yin; - qrealinner x, y, w; + float xin, yin; + float x, y, w; xin = point.x(); yin = point.y(); x = xin * matrix.m[0][0] + @@ -770,8 +767,8 @@ inline QPoint operator*(const QMatrix4x4& matrix, const QPoint& point) inline QPointF operator*(const QMatrix4x4& matrix, const QPointF& point) { - qrealinner xin, yin; - qrealinner x, y, w; + float xin, yin; + float x, y, w; xin = point.x(); yin = point.y(); x = xin * matrix.m[0][0] + @@ -784,11 +781,9 @@ inline QPointF operator*(const QMatrix4x4& matrix, const QPointF& point) yin * matrix.m[1][3] + matrix.m[3][3]; if (w == 1.0f) { - return QPointF(qt_math3d_convert(x), - qt_math3d_convert(y)); + return QPointF(qreal(x), qreal(y)); } else { - return QPointF(qt_math3d_convert(x / w), - qt_math3d_convert(y / w)); + return QPointF(qreal(x / w), qreal(y / w)); } } @@ -817,46 +812,44 @@ inline QMatrix4x4 operator-(const QMatrix4x4& matrix) inline QMatrix4x4 operator*(qreal factor, const QMatrix4x4& matrix) { QMatrix4x4 m(1); - qrealinner f(factor); - m.m[0][0] = matrix.m[0][0] * f; - m.m[0][1] = matrix.m[0][1] * f; - m.m[0][2] = matrix.m[0][2] * f; - m.m[0][3] = matrix.m[0][3] * f; - m.m[1][0] = matrix.m[1][0] * f; - m.m[1][1] = matrix.m[1][1] * f; - m.m[1][2] = matrix.m[1][2] * f; - m.m[1][3] = matrix.m[1][3] * f; - m.m[2][0] = matrix.m[2][0] * f; - m.m[2][1] = matrix.m[2][1] * f; - m.m[2][2] = matrix.m[2][2] * f; - m.m[2][3] = matrix.m[2][3] * f; - m.m[3][0] = matrix.m[3][0] * f; - m.m[3][1] = matrix.m[3][1] * f; - m.m[3][2] = matrix.m[3][2] * f; - m.m[3][3] = matrix.m[3][3] * f; + m.m[0][0] = matrix.m[0][0] * factor; + m.m[0][1] = matrix.m[0][1] * factor; + m.m[0][2] = matrix.m[0][2] * factor; + m.m[0][3] = matrix.m[0][3] * factor; + m.m[1][0] = matrix.m[1][0] * factor; + m.m[1][1] = matrix.m[1][1] * factor; + m.m[1][2] = matrix.m[1][2] * factor; + m.m[1][3] = matrix.m[1][3] * factor; + m.m[2][0] = matrix.m[2][0] * factor; + m.m[2][1] = matrix.m[2][1] * factor; + m.m[2][2] = matrix.m[2][2] * factor; + m.m[2][3] = matrix.m[2][3] * factor; + m.m[3][0] = matrix.m[3][0] * factor; + m.m[3][1] = matrix.m[3][1] * factor; + m.m[3][2] = matrix.m[3][2] * factor; + m.m[3][3] = matrix.m[3][3] * factor; return m; } inline QMatrix4x4 operator*(const QMatrix4x4& matrix, qreal factor) { QMatrix4x4 m(1); - qrealinner f(factor); - m.m[0][0] = matrix.m[0][0] * f; - m.m[0][1] = matrix.m[0][1] * f; - m.m[0][2] = matrix.m[0][2] * f; - m.m[0][3] = matrix.m[0][3] * f; - m.m[1][0] = matrix.m[1][0] * f; - m.m[1][1] = matrix.m[1][1] * f; - m.m[1][2] = matrix.m[1][2] * f; - m.m[1][3] = matrix.m[1][3] * f; - m.m[2][0] = matrix.m[2][0] * f; - m.m[2][1] = matrix.m[2][1] * f; - m.m[2][2] = matrix.m[2][2] * f; - m.m[2][3] = matrix.m[2][3] * f; - m.m[3][0] = matrix.m[3][0] * f; - m.m[3][1] = matrix.m[3][1] * f; - m.m[3][2] = matrix.m[3][2] * f; - m.m[3][3] = matrix.m[3][3] * f; + m.m[0][0] = matrix.m[0][0] * factor; + m.m[0][1] = matrix.m[0][1] * factor; + m.m[0][2] = matrix.m[0][2] * factor; + m.m[0][3] = matrix.m[0][3] * factor; + m.m[1][0] = matrix.m[1][0] * factor; + m.m[1][1] = matrix.m[1][1] * factor; + m.m[1][2] = matrix.m[1][2] * factor; + m.m[1][3] = matrix.m[1][3] * factor; + m.m[2][0] = matrix.m[2][0] * factor; + m.m[2][1] = matrix.m[2][1] * factor; + m.m[2][2] = matrix.m[2][2] * factor; + m.m[2][3] = matrix.m[2][3] * factor; + m.m[3][0] = matrix.m[3][0] * factor; + m.m[3][1] = matrix.m[3][1] * factor; + m.m[3][2] = matrix.m[3][2] * factor; + m.m[3][3] = matrix.m[3][3] * factor; return m; } @@ -934,7 +927,7 @@ inline QRectF QMatrix4x4::mapRect(const QRectF& rect) const return QRectF(QPointF(xmin, ymin), QPointF(xmax, ymax)); } -inline qrealinner *QMatrix4x4::data() +inline float *QMatrix4x4::data() { // We have to assume that the caller will modify the matrix elements, // so we flip it over to "General" mode. @@ -947,17 +940,17 @@ Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QMatrix4x4 &m); #endif template -QMatrix4x4 qGenericMatrixToMatrix4x4(const QGenericMatrix& matrix) +QMatrix4x4 qGenericMatrixToMatrix4x4(const QGenericMatrix& matrix) { return QMatrix4x4(matrix.constData(), N, M); } template -QGenericMatrix qGenericMatrixFromMatrix4x4(const QMatrix4x4& matrix) +QGenericMatrix qGenericMatrixFromMatrix4x4(const QMatrix4x4& matrix) { - QGenericMatrix result; - const qrealinner *m = matrix.constData(); - qrealinner *values = result.data(); + QGenericMatrix result; + const float *m = matrix.constData(); + float *values = result.data(); for (int col = 0; col < N; ++col) { for (int row = 0; row < M; ++row) { if (col < 4 && row < 4) diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp index 121ff51..efde362 100644 --- a/src/gui/math3d/qquaternion.cpp +++ b/src/gui/math3d/qquaternion.cpp @@ -40,8 +40,8 @@ ****************************************************************************/ #include "qquaternion.h" -#include "qmath3dutil_p.h" #include +#include QT_BEGIN_NAMESPACE @@ -223,8 +223,7 @@ QT_BEGIN_NAMESPACE */ qreal QQuaternion::length() const { - return qvtsqrt64(qvtmul64(xp, xp) + qvtmul64(yp, yp) + - qvtmul64(zp, zp) + qvtmul64(wp, wp)); + return qSqrt(xp * xp + yp * yp + zp * zp + wp * wp); } /*! @@ -234,8 +233,7 @@ qreal QQuaternion::length() const */ qreal QQuaternion::lengthSquared() const { - return qvtdot64(qvtmul64(xp, xp) + qvtmul64(yp, yp) + - qvtmul64(zp, zp) + qvtmul64(wp, wp)); + return xp * xp + yp * yp + zp * zp + wp * wp; } /*! @@ -342,6 +340,10 @@ QVector3D QQuaternion::rotateVector(const QVector3D& vector) const \sa operator*=() */ +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + #ifndef QT_NO_VECTOR3D /*! @@ -354,9 +356,10 @@ QQuaternion QQuaternion::fromAxisAndAngle(const QVector3D& axis, qreal angle) // http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q56 // We normalize the result just in case the values are close // to zero, as suggested in the above FAQ. - qrealinner s, c; + qreal a = (angle / 2.0f) * M_PI / 180.0f; + qreal s = qSin(a); + qreal c = qCos(a); QVector3D ax = axis.normalized(); - qt_math3d_sincos(angle / 2.0f, &s, &c); return QQuaternion(c, ax.xp * s, ax.yp * s, ax.zp * s, 1).normalized(); } @@ -369,17 +372,18 @@ QQuaternion QQuaternion::fromAxisAndAngle(const QVector3D& axis, qreal angle) QQuaternion QQuaternion::fromAxisAndAngle (qreal x, qreal y, qreal z, qreal angle) { - qrealinner xp = x; - qrealinner yp = y; - qrealinner zp = z; - qrealinner s, c; - qreal length = qvtsqrt(xp * xp + yp * yp + zp * zp); + float xp = x; + float yp = y; + float zp = z; + qreal length = qSqrt(xp * xp + yp * yp + zp * zp); if (!qIsNull(length)) { xp /= length; yp /= length; zp /= length; } - qt_math3d_sincos(angle / 2.0f, &s, &c); + qreal a = (angle / 2.0f) * M_PI / 180.0f; + qreal s = qSin(a); + qreal c = qCos(a); return QQuaternion(c, xp * s, yp * s, zp * s, 1).normalized(); } @@ -500,8 +504,7 @@ QQuaternion QQuaternion::interpolate // Determine the angle between the two quaternions. QQuaternion q2b; qreal dot; - dot = qvtdot64(qvtmul64(q1.xp, q2.xp) + qvtmul64(q1.yp, q2.yp) + - qvtmul64(q1.zp, q2.zp) + qvtmul64(q1.wp, q2.wp)); + dot = q1.xp * q2.xp + q1.yp * q2.yp + q1.zp * q2.zp + q1.wp * q2.wp; if (dot >= 0.0f) { q2b = q2; } else { diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h index 6ba63ec..f0cb308 100644 --- a/src/gui/math3d/qquaternion.h +++ b/src/gui/math3d/qquaternion.h @@ -129,11 +129,11 @@ public: (const QQuaternion& q1, const QQuaternion& q2, qreal t); private: - qrealinner wp, xp, yp, zp; + float wp, xp, yp, zp; friend class QMatrix4x4; - QQuaternion(qrealinner scalar, qrealinner xpos, qrealinner ypos, qrealinner zpos, int dummy); + QQuaternion(float scalar, float xpos, float ypos, float zpos, int dummy); }; inline QQuaternion::QQuaternion() : wp(1.0f), xp(0.0f), yp(0.0f), zp(0.0f) {} @@ -141,7 +141,7 @@ inline QQuaternion::QQuaternion() : wp(1.0f), xp(0.0f), yp(0.0f), zp(0.0f) {} inline QQuaternion::QQuaternion(qreal scalar, qreal xpos, qreal ypos, qreal zpos) : wp(scalar), xp(xpos), yp(ypos), zp(zpos) {} -inline QQuaternion::QQuaternion(qrealinner scalar, qrealinner xpos, qrealinner ypos, qrealinner zpos, int) : wp(scalar), xp(xpos), yp(ypos), zp(zpos) {} +inline QQuaternion::QQuaternion(float scalar, float xpos, float ypos, float zpos, int) : wp(scalar), xp(xpos), yp(ypos), zp(zpos) {} inline QQuaternion::QQuaternion(int scalar, int xpos, int ypos, int zpos) : wp(scalar), xp(xpos), yp(ypos), zp(zpos) {} @@ -155,10 +155,10 @@ inline bool QQuaternion::isIdentity() const return qIsNull(xp) && qIsNull(yp) && qIsNull(zp) && wp == 1.0f; } -inline qreal QQuaternion::x() const { return qt_math3d_convert(xp); } -inline qreal QQuaternion::y() const { return qt_math3d_convert(yp); } -inline qreal QQuaternion::z() const { return qt_math3d_convert(zp); } -inline qreal QQuaternion::scalar() const { return qt_math3d_convert(wp); } +inline qreal QQuaternion::x() const { return qreal(xp); } +inline qreal QQuaternion::y() const { return qreal(yp); } +inline qreal QQuaternion::z() const { return qreal(zp); } +inline qreal QQuaternion::scalar() const { return qreal(wp); } inline void QQuaternion::setX(qreal x) { xp = x; } inline void QQuaternion::setY(qreal y) { yp = y; } @@ -190,11 +190,10 @@ inline QQuaternion &QQuaternion::operator-=(const QQuaternion &quaternion) inline QQuaternion &QQuaternion::operator*=(qreal factor) { - qrealinner f(factor); - xp *= f; - yp *= f; - zp *= f; - wp *= f; + xp *= factor; + yp *= factor; + zp *= factor; + wp *= factor; return *this; } @@ -202,19 +201,19 @@ inline const QQuaternion operator*(const QQuaternion &q1, const QQuaternion& q2) { // Algorithm from: // http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q53 - qrealinner x = q1.wp * q2.xp + + float x = q1.wp * q2.xp + q1.xp * q2.wp + q1.yp * q2.zp - q1.zp * q2.yp; - qrealinner y = q1.wp * q2.yp + + float y = q1.wp * q2.yp + q1.yp * q2.wp + q1.zp * q2.xp - q1.xp * q2.zp; - qrealinner z = q1.wp * q2.zp + + float z = q1.wp * q2.zp + q1.zp * q2.wp + q1.xp * q2.yp - q1.yp * q2.xp; - qrealinner w = q1.wp * q2.wp - + float w = q1.wp * q2.wp - q1.xp * q2.xp - q1.yp * q2.yp - q1.zp * q2.zp; @@ -229,11 +228,10 @@ inline QQuaternion &QQuaternion::operator*=(const QQuaternion &quaternion) inline QQuaternion &QQuaternion::operator/=(qreal divisor) { - qrealinner d(divisor); - xp /= d; - yp /= d; - zp /= d; - wp /= d; + xp /= divisor; + yp /= divisor; + zp /= divisor; + wp /= divisor; return *this; } @@ -259,14 +257,12 @@ inline const QQuaternion operator-(const QQuaternion &q1, const QQuaternion &q2) inline const QQuaternion operator*(qreal factor, const QQuaternion &quaternion) { - qrealinner f(factor); - return QQuaternion(quaternion.wp * f, quaternion.xp * f, quaternion.yp * f, quaternion.zp * f, 1); + return QQuaternion(quaternion.wp * factor, quaternion.xp * factor, quaternion.yp * factor, quaternion.zp * factor, 1); } inline const QQuaternion operator*(const QQuaternion &quaternion, qreal factor) { - qrealinner f(factor); - return QQuaternion(quaternion.wp * f, quaternion.xp * f, quaternion.yp * f, quaternion.zp * f, 1); + return QQuaternion(quaternion.wp * factor, quaternion.xp * factor, quaternion.yp * factor, quaternion.zp * factor, 1); } inline const QQuaternion operator-(const QQuaternion &quaternion) @@ -276,8 +272,7 @@ inline const QQuaternion operator-(const QQuaternion &quaternion) inline const QQuaternion operator/(const QQuaternion &quaternion, qreal divisor) { - qrealinner d(divisor); - return QQuaternion(quaternion.wp / d, quaternion.xp / d, quaternion.yp / d, quaternion.zp / d, 1); + return QQuaternion(quaternion.wp / divisor, quaternion.xp / divisor, quaternion.yp / divisor, quaternion.zp / divisor, 1); } inline bool qFuzzyCompare(const QQuaternion& q1, const QQuaternion& q2) diff --git a/src/gui/math3d/qvector2d.cpp b/src/gui/math3d/qvector2d.cpp index 0426fc5..31e5be6 100644 --- a/src/gui/math3d/qvector2d.cpp +++ b/src/gui/math3d/qvector2d.cpp @@ -42,7 +42,8 @@ #include "qvector2d.h" #include "qvector3d.h" #include "qvector4d.h" -#include "qmath3dutil_p.h" +#include +#include QT_BEGIN_NAMESPACE @@ -169,7 +170,7 @@ QVector2D::QVector2D(const QVector4D& vector) */ qreal QVector2D::length() const { - return qvtsqrt64(qvtmul64(xp, xp) + qvtmul64(yp, yp)); + return qSqrt(xp * xp + yp * yp); } /*! @@ -180,7 +181,7 @@ qreal QVector2D::length() const */ qreal QVector2D::lengthSquared() const { - return qvtdot64(qvtmul64(xp, xp) + qvtmul64(yp, yp)); + return xp * xp + yp * yp; } /*! @@ -263,7 +264,7 @@ void QVector2D::normalize() */ qreal QVector2D::dotProduct(const QVector2D& v1, const QVector2D& v2) { - return qvtdot64(qvtmul64(v1.xp, v2.xp) + qvtmul64(v1.yp, v2.yp)); + return v1.xp * v2.xp + v1.yp * v2.yp; } /*! diff --git a/src/gui/math3d/qvector2d.h b/src/gui/math3d/qvector2d.h index a72ecc5..5e15de6 100644 --- a/src/gui/math3d/qvector2d.h +++ b/src/gui/math3d/qvector2d.h @@ -42,7 +42,6 @@ #ifndef QVECTOR2D_H #define QVECTOR2D_H -#include #include #include @@ -117,18 +116,17 @@ public: QPointF toPointF() const; private: - qrealinner xp, yp; + float xp, yp; - QVector2D(qrealinner xpos, qrealinner ypos, int dummy); + QVector2D(float xpos, float ypos, int dummy); friend class QVector3D; friend class QVector4D; - friend class QVertexArray; }; inline QVector2D::QVector2D() : xp(0.0f), yp(0.0f) {} -inline QVector2D::QVector2D(qrealinner xpos, qrealinner ypos, int) : xp(xpos), yp(ypos) {} +inline QVector2D::QVector2D(float xpos, float ypos, int) : xp(xpos), yp(ypos) {} inline QVector2D::QVector2D(qreal xpos, qreal ypos) : xp(xpos), yp(ypos) {} @@ -143,8 +141,8 @@ inline bool QVector2D::isNull() const return qIsNull(xp) && qIsNull(yp); } -inline qreal QVector2D::x() const { return qt_math3d_convert(xp); } -inline qreal QVector2D::y() const { return qt_math3d_convert(yp); } +inline qreal QVector2D::x() const { return qreal(xp); } +inline qreal QVector2D::y() const { return qreal(yp); } inline void QVector2D::setX(qreal x) { xp = x; } inline void QVector2D::setY(qreal y) { yp = y; } @@ -165,9 +163,8 @@ inline QVector2D &QVector2D::operator-=(const QVector2D &vector) inline QVector2D &QVector2D::operator*=(qreal factor) { - qrealinner f(factor); - xp *= f; - yp *= f; + xp *= factor; + yp *= factor; return *this; } @@ -180,9 +177,8 @@ inline QVector2D &QVector2D::operator*=(const QVector2D &vector) inline QVector2D &QVector2D::operator/=(qreal divisor) { - qrealinner d(divisor); - xp /= d; - yp /= d; + xp /= divisor; + yp /= divisor; return *this; } @@ -208,14 +204,12 @@ inline const QVector2D operator-(const QVector2D &v1, const QVector2D &v2) inline const QVector2D operator*(qreal factor, const QVector2D &vector) { - qrealinner f(factor); - return QVector2D(vector.xp * f, vector.yp * f, 1); + return QVector2D(vector.xp * factor, vector.yp * factor, 1); } inline const QVector2D operator*(const QVector2D &vector, qreal factor) { - qrealinner f(factor); - return QVector2D(vector.xp * f, vector.yp * f, 1); + return QVector2D(vector.xp * factor, vector.yp * factor, 1); } inline const QVector2D operator*(const QVector2D &v1, const QVector2D &v2) @@ -230,8 +224,7 @@ inline const QVector2D operator-(const QVector2D &vector) inline const QVector2D operator/(const QVector2D &vector, qreal divisor) { - qrealinner d(divisor); - return QVector2D(vector.xp / d, vector.yp / d, 1); + return QVector2D(vector.xp / divisor, vector.yp / divisor, 1); } inline bool qFuzzyCompare(const QVector2D& v1, const QVector2D& v2) @@ -246,8 +239,7 @@ inline QPoint QVector2D::toPoint() const inline QPointF QVector2D::toPointF() const { - return QPointF(qt_math3d_convert(xp), - qt_math3d_convert(yp)); + return QPointF(qreal(xp), qreal(yp)); } #ifndef QT_NO_DEBUG_STREAM diff --git a/src/gui/math3d/qvector3d.cpp b/src/gui/math3d/qvector3d.cpp index 32068ee..814753d 100644 --- a/src/gui/math3d/qvector3d.cpp +++ b/src/gui/math3d/qvector3d.cpp @@ -42,8 +42,8 @@ #include "qvector3d.h" #include "qvector2d.h" #include "qvector4d.h" -#include "qmath3dutil_p.h" #include +#include QT_BEGIN_NAMESPACE @@ -287,7 +287,7 @@ void QVector3D::normalize() */ qreal QVector3D::dotProduct(const QVector3D& v1, const QVector3D& v2) { - return qvtdot64(qvtmul64(v1.xp, v2.xp) + qvtmul64(v1.yp, v2.yp) + qvtmul64(v1.zp, v2.zp)); + return v1.xp * v2.xp + v1.yp * v2.yp + v1.zp * v2.zp; } /*! @@ -535,7 +535,7 @@ QVector4D QVector3D::toVector4D() const */ qreal QVector3D::length() const { - return qvtsqrt64(qvtmul64(xp, xp) + qvtmul64(yp, yp) + qvtmul64(zp, zp)); + return qSqrt(xp * xp + yp * yp + zp * zp); } /*! @@ -546,7 +546,7 @@ qreal QVector3D::length() const */ qreal QVector3D::lengthSquared() const { - return qvtdot64(qvtmul64(xp, xp) + qvtmul64(yp, yp) + qvtmul64(zp, zp)); + return xp * xp + yp * yp + zp * zp; } #ifndef QT_NO_DEBUG_STREAM diff --git a/src/gui/math3d/qvector3d.h b/src/gui/math3d/qvector3d.h index 8f8f3b4..4771d5a 100644 --- a/src/gui/math3d/qvector3d.h +++ b/src/gui/math3d/qvector3d.h @@ -42,7 +42,6 @@ #ifndef QVECTOR3D_H #define QVECTOR3D_H -#include #include #include @@ -130,16 +129,14 @@ public: QPointF toPointF() const; private: - qrealinner xp, yp, zp; + float xp, yp, zp; - QVector3D(qrealinner xpos, qrealinner ypos, qrealinner zpos, int dummy); + QVector3D(float xpos, float ypos, float zpos, int dummy); friend class QVector2D; friend class QVector4D; friend class QQuaternion; friend class QMatrix4x4; - friend class QVertexArray; - friend class QGLPainter; #ifndef QT_NO_MATRIX4X4 friend QVector3D operator*(const QVector3D& vector, const QMatrix4x4& matrix); friend QVector3D operator*(const QMatrix4x4& matrix, const QVector3D& vector); @@ -150,7 +147,7 @@ inline QVector3D::QVector3D() : xp(0.0f), yp(0.0f), zp(0.0f) {} inline QVector3D::QVector3D(qreal xpos, qreal ypos, qreal zpos) : xp(xpos), yp(ypos), zp(zpos) {} -inline QVector3D::QVector3D(qrealinner xpos, qrealinner ypos, qrealinner zpos, int) : xp(xpos), yp(ypos), zp(zpos) {} +inline QVector3D::QVector3D(float xpos, float ypos, float zpos, int) : xp(xpos), yp(ypos), zp(zpos) {} inline QVector3D::QVector3D(int xpos, int ypos, int zpos) : xp(xpos), yp(ypos), zp(zpos) {} @@ -163,9 +160,9 @@ inline bool QVector3D::isNull() const return qIsNull(xp) && qIsNull(yp) && qIsNull(zp); } -inline qreal QVector3D::x() const { return qt_math3d_convert(xp); } -inline qreal QVector3D::y() const { return qt_math3d_convert(yp); } -inline qreal QVector3D::z() const { return qt_math3d_convert(zp); } +inline qreal QVector3D::x() const { return qreal(xp); } +inline qreal QVector3D::y() const { return qreal(yp); } +inline qreal QVector3D::z() const { return qreal(zp); } inline void QVector3D::setX(qreal x) { xp = x; } inline void QVector3D::setY(qreal y) { yp = y; } @@ -189,10 +186,9 @@ inline QVector3D &QVector3D::operator-=(const QVector3D &vector) inline QVector3D &QVector3D::operator*=(qreal factor) { - qrealinner f(factor); - xp *= f; - yp *= f; - zp *= f; + xp *= factor; + yp *= factor; + zp *= factor; return *this; } @@ -206,10 +202,9 @@ inline QVector3D &QVector3D::operator*=(const QVector3D& vector) inline QVector3D &QVector3D::operator/=(qreal divisor) { - qrealinner d(divisor); - xp /= d; - yp /= d; - zp /= d; + xp /= divisor; + yp /= divisor; + zp /= divisor; return *this; } @@ -235,14 +230,12 @@ inline const QVector3D operator-(const QVector3D &v1, const QVector3D &v2) inline const QVector3D operator*(qreal factor, const QVector3D &vector) { - qrealinner f(factor); - return QVector3D(vector.xp * f, vector.yp * f, vector.zp * f, 1); + return QVector3D(vector.xp * factor, vector.yp * factor, vector.zp * factor, 1); } inline const QVector3D operator*(const QVector3D &vector, qreal factor) { - qrealinner f(factor); - return QVector3D(vector.xp * f, vector.yp * f, vector.zp * f, 1); + return QVector3D(vector.xp * factor, vector.yp * factor, vector.zp * factor, 1); } inline const QVector3D operator*(const QVector3D &v1, const QVector3D& v2) @@ -257,8 +250,7 @@ inline const QVector3D operator-(const QVector3D &vector) inline const QVector3D operator/(const QVector3D &vector, qreal divisor) { - qrealinner d(divisor); - return QVector3D(vector.xp / d, vector.yp / d, vector.zp / d, 1); + return QVector3D(vector.xp / divisor, vector.yp / divisor, vector.zp / divisor, 1); } inline bool qFuzzyCompare(const QVector3D& v1, const QVector3D& v2) @@ -275,8 +267,7 @@ inline QPoint QVector3D::toPoint() const inline QPointF QVector3D::toPointF() const { - return QPointF(qt_math3d_convert(xp), - qt_math3d_convert(yp)); + return QPointF(qreal(xp), qreal(yp)); } #ifndef QT_NO_DEBUG_STREAM diff --git a/src/gui/math3d/qvector4d.cpp b/src/gui/math3d/qvector4d.cpp index 4287806..d19665a 100644 --- a/src/gui/math3d/qvector4d.cpp +++ b/src/gui/math3d/qvector4d.cpp @@ -42,7 +42,8 @@ #include "qvector4d.h" #include "qvector3d.h" #include "qvector2d.h" -#include "qmath3dutil_p.h" +#include +#include QT_BEGIN_NAMESPACE @@ -237,8 +238,7 @@ QVector4D::QVector4D(const QVector3D& vector, qreal wpos) */ qreal QVector4D::length() const { - return qvtsqrt64(qvtmul64(xp, xp) + qvtmul64(yp, yp) + - qvtmul64(zp, zp) + qvtmul64(wp, wp)); + return qSqrt(xp * xp + yp * yp + zp * zp + wp * wp); } /*! @@ -249,8 +249,7 @@ qreal QVector4D::length() const */ qreal QVector4D::lengthSquared() const { - return qvtdot64(qvtmul64(xp, xp) + qvtmul64(yp, yp) + - qvtmul64(zp, zp) + qvtmul64(wp, wp)); + return xp * xp + yp * yp + zp * zp + wp * wp; } /*! @@ -336,8 +335,7 @@ void QVector4D::normalize() */ qreal QVector4D::dotProduct(const QVector4D& v1, const QVector4D& v2) { - return qvtdot64(qvtmul64(v1.xp, v2.xp) + qvtmul64(v1.yp, v2.yp) + - qvtmul64(v1.zp, v2.zp) + qvtmul64(v1.wp, v2.wp)); + return v1.xp * v2.xp + v1.yp * v2.yp + v1.zp * v2.zp + v1.wp * v2.wp; } /*! diff --git a/src/gui/math3d/qvector4d.h b/src/gui/math3d/qvector4d.h index 4ac6ae8..12efc95 100644 --- a/src/gui/math3d/qvector4d.h +++ b/src/gui/math3d/qvector4d.h @@ -42,7 +42,6 @@ #ifndef QVECTOR4D_H #define QVECTOR4D_H -#include #include #include @@ -127,15 +126,14 @@ public: QPointF toPointF() const; private: - qrealinner xp, yp, zp, wp; + float xp, yp, zp, wp; - QVector4D(qrealinner xpos, qrealinner ypos, qrealinner zpos, qrealinner wpos, int dummy); + QVector4D(float xpos, float ypos, float zpos, float wpos, int dummy); friend class QVector2D; friend class QVector3D; friend class QQuaternion; friend class QMatrix4x4; - friend class QVertexArray; #ifndef QT_NO_MATRIX4X4 friend QVector4D operator*(const QVector4D& vector, const QMatrix4x4& matrix); friend QVector4D operator*(const QMatrix4x4& matrix, const QVector4D& vector); @@ -146,7 +144,7 @@ inline QVector4D::QVector4D() : xp(0.0f), yp(0.0f), zp(0.0f), wp(0.0f) {} inline QVector4D::QVector4D(qreal xpos, qreal ypos, qreal zpos, qreal wpos) : xp(xpos), yp(ypos), zp(zpos), wp(wpos) {} -inline QVector4D::QVector4D(qrealinner xpos, qrealinner ypos, qrealinner zpos, qrealinner wpos, int) : xp(xpos), yp(ypos), zp(zpos), wp(wpos) {} +inline QVector4D::QVector4D(float xpos, float ypos, float zpos, float wpos, int) : xp(xpos), yp(ypos), zp(zpos), wp(wpos) {} inline QVector4D::QVector4D(int xpos, int ypos, int zpos, int wpos) : xp(xpos), yp(ypos), zp(zpos), wp(wpos) {} @@ -159,10 +157,10 @@ inline bool QVector4D::isNull() const return qIsNull(xp) && qIsNull(yp) && qIsNull(zp) && qIsNull(wp); } -inline qreal QVector4D::x() const { return qt_math3d_convert(xp); } -inline qreal QVector4D::y() const { return qt_math3d_convert(yp); } -inline qreal QVector4D::z() const { return qt_math3d_convert(zp); } -inline qreal QVector4D::w() const { return qt_math3d_convert(wp); } +inline qreal QVector4D::x() const { return qreal(xp); } +inline qreal QVector4D::y() const { return qreal(yp); } +inline qreal QVector4D::z() const { return qreal(zp); } +inline qreal QVector4D::w() const { return qreal(wp); } inline void QVector4D::setX(qreal x) { xp = x; } inline void QVector4D::setY(qreal y) { yp = y; } @@ -189,11 +187,10 @@ inline QVector4D &QVector4D::operator-=(const QVector4D &vector) inline QVector4D &QVector4D::operator*=(qreal factor) { - qrealinner f(factor); - xp *= f; - yp *= f; - zp *= f; - wp *= f; + xp *= factor; + yp *= factor; + zp *= factor; + wp *= factor; return *this; } @@ -208,11 +205,10 @@ inline QVector4D &QVector4D::operator*=(const QVector4D &vector) inline QVector4D &QVector4D::operator/=(qreal divisor) { - qrealinner d(divisor); - xp /= d; - yp /= d; - zp /= d; - wp /= d; + xp /= divisor; + yp /= divisor; + zp /= divisor; + wp /= divisor; return *this; } @@ -238,14 +234,12 @@ inline const QVector4D operator-(const QVector4D &v1, const QVector4D &v2) inline const QVector4D operator*(qreal factor, const QVector4D &vector) { - qrealinner f(factor); - return QVector4D(vector.xp * f, vector.yp * f, vector.zp * f, vector.wp * f, 1); + return QVector4D(vector.xp * factor, vector.yp * factor, vector.zp * factor, vector.wp * factor, 1); } inline const QVector4D operator*(const QVector4D &vector, qreal factor) { - qrealinner f(factor); - return QVector4D(vector.xp * f, vector.yp * f, vector.zp * f, vector.wp * f, 1); + return QVector4D(vector.xp * factor, vector.yp * factor, vector.zp * factor, vector.wp * factor, 1); } inline const QVector4D operator*(const QVector4D &v1, const QVector4D& v2) @@ -260,8 +254,7 @@ inline const QVector4D operator-(const QVector4D &vector) inline const QVector4D operator/(const QVector4D &vector, qreal divisor) { - qrealinner d(divisor); - return QVector4D(vector.xp / d, vector.yp / d, vector.zp / d, vector.wp / d, 1); + return QVector4D(vector.xp / divisor, vector.yp / divisor, vector.zp / divisor, vector.wp / divisor, 1); } inline bool qFuzzyCompare(const QVector4D& v1, const QVector4D& v2) @@ -279,8 +272,7 @@ inline QPoint QVector4D::toPoint() const inline QPointF QVector4D::toPointF() const { - return QPointF(qt_math3d_convert(xp), - qt_math3d_convert(yp)); + return QPointF(qreal(xp), qreal(yp)); } #ifndef QT_NO_DEBUG_STREAM diff --git a/tests/auto/math3d/math3d.pro b/tests/auto/math3d/math3d.pro index 3977e92..d6189ef 100644 --- a/tests/auto/math3d/math3d.pro +++ b/tests/auto/math3d/math3d.pro @@ -1,3 +1,2 @@ TEMPLATE = subdirs -SUBDIRS = qfixedpt qmatrixnxn qquaternion qvectornd -SUBDIRS += qmatrixnxn_fixed qquaternion_fixed qvectornd_fixed +SUBDIRS = qmatrixnxn qquaternion qvectornd diff --git a/tests/auto/math3d/qfixedpt/qfixedpt.pro b/tests/auto/math3d/qfixedpt/qfixedpt.pro deleted file mode 100644 index 94598b5..0000000 --- a/tests/auto/math3d/qfixedpt/qfixedpt.pro +++ /dev/null @@ -1,2 +0,0 @@ -load(qttest_p4) -SOURCES += tst_qfixedpt.cpp diff --git a/tests/auto/math3d/qfixedpt/tst_qfixedpt.cpp b/tests/auto/math3d/qfixedpt/tst_qfixedpt.cpp deleted file mode 100644 index ef333a6..0000000 --- a/tests/auto/math3d/qfixedpt/tst_qfixedpt.cpp +++ /dev/null @@ -1,643 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the $MODULE$ of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include - -class tst_QFixedPt : public QObject -{ - Q_OBJECT -public: - tst_QFixedPt() {} - ~tst_QFixedPt() {} - -private slots: - void create_data(); - void create(); - void add_data(); - void add(); - void sub_data(); - void sub(); - void mul_data(); - void mul(); - void div_data(); - void div(); - void neg_data(); - void neg(); - void shift_data(); - void shift(); - void sqrt_data(); - void sqrt(); - void round_data(); - void round(); - void compare_data(); - void compare(); -}; - -// qFuzzyCompare isn't quite "fuzzy" enough to handle conversion -// to fixed-point and back again. So create a "fuzzier" compare. -static bool fuzzyCompare(double x, double y) -{ - double diff = x - y; - if (diff < 0.0f) - diff = -diff; - return (diff < 0.0001); -} - -// Test the creation of QFixedPt values in various ways. -void tst_QFixedPt::create_data() -{ - QTest::addColumn("value"); - QTest::addColumn("intValue"); - QTest::addColumn("realValue"); - - QTest::newRow("zero") << 0x00000000 << 0 << 0.0f; - QTest::newRow("one") << 0x00010000 << 1 << 1.0f; - QTest::newRow("1.5") << 0x00018000 << 2 << 1.5f; // int rounds up - QTest::newRow("-1.5") << (int)0xFFFE8000 << -1 << -1.5f; // int rounds up - QTest::newRow("-7") << (int)0xFFF90000 << -7 << -7.0f; -} -void tst_QFixedPt::create() -{ - QFETCH(int, value); - QFETCH(int, intValue); - QFETCH(float, realValue); - - if (qFloor(realValue) == realValue) { - QFixedPt<16> ivalue(intValue); - QCOMPARE(ivalue.bits(), value); - QCOMPARE(ivalue.toInt(), intValue); - QCOMPARE(ivalue.toReal(), (qreal)realValue); - } - - QFixedPt<16> fvalue(realValue); - QCOMPARE(fvalue.bits(), value); - QCOMPARE(fvalue.toInt(), intValue); - QCOMPARE(fvalue.toReal(), (qreal)realValue); - - QFixedPt<16> fpvalue; - fpvalue.setBits(value); - QCOMPARE(fpvalue.bits(), value); - QCOMPARE(fpvalue.toInt(), intValue); - QCOMPARE(fpvalue.toReal(), (qreal)realValue); - - QFixedPt<16> fpvalue2(fpvalue); - QCOMPARE(fpvalue2.bits(), value); - QCOMPARE(fpvalue2.toInt(), intValue); - QCOMPARE(fpvalue2.toReal(), (qreal)realValue); - - if (qFloor(realValue) == realValue) { - QFixedPt<16> ivalue2(63); // Initialize the something else. - ivalue2 = intValue; // Then change the value. - QCOMPARE(ivalue2.bits(), value); - QCOMPARE(ivalue2.toInt(), intValue); - QCOMPARE(ivalue2.toReal(), (qreal)realValue); - } - - QFixedPt<16> fvalue2(36); - fvalue2 = realValue; - QCOMPARE(fvalue2.bits(), value); - QCOMPARE(fvalue2.toInt(), intValue); - QCOMPARE(fvalue2.toReal(), (qreal)realValue); - - QFixedPt<16> fpvalue3; - fpvalue3 = fpvalue; - QCOMPARE(fpvalue3.bits(), value); - QCOMPARE(fpvalue3.toInt(), intValue); - QCOMPARE(fpvalue3.toReal(), (qreal)realValue); - - // Now do some of the tests again with a different precision value. - - if (qFloor(realValue) == realValue) { - QFixedPt<4> ivalue3(intValue); - QCOMPARE(ivalue3.bits(), value >> 12); - QCOMPARE(ivalue3.toInt(), intValue); - QCOMPARE(ivalue3.toReal(), (qreal)realValue); - } - - QFixedPt<4> fvalue3(realValue); - QCOMPARE(fvalue3.bits(), value >> 12); - QCOMPARE(fvalue3.toInt(), intValue); - QCOMPARE(fvalue3.toReal(), (qreal)realValue); - - QFixedPt<4> fpvalue4; - fpvalue4.setBits(value >> 12); - QCOMPARE(fpvalue4.bits(), value >> 12); - QCOMPARE(fpvalue4.toInt(), intValue); - QCOMPARE(fpvalue4.toReal(), (qreal)realValue); - - // Test conversion between the precision values. - -#if !defined(QT_NO_MEMBER_TEMPLATES) - if (qFloor(realValue) == realValue) { - QFixedPt<16> ivalue(intValue); - QFixedPt<4> ivalue3(intValue); - QVERIFY(ivalue.toPrecision<4>() == ivalue3); - QVERIFY(ivalue3.toPrecision<16>() == ivalue); - } - QVERIFY(fvalue.toPrecision<4>() == fvalue3); - QVERIFY(fvalue3.toPrecision<16>() == fvalue); -#endif - - if (qFloor(realValue) == realValue) { - QFixedPt<16> ivalue(intValue); - QFixedPt<4> ivalue3(intValue); - QVERIFY(qFixedPtToPrecision<4>(ivalue) == ivalue3); - QVERIFY(qFixedPtToPrecision<16>(ivalue3) == ivalue); - } - QVERIFY(qFixedPtToPrecision<4>(fvalue) == fvalue3); - QVERIFY(qFixedPtToPrecision<16>(fvalue3) == fvalue); -} - -// Test fixed point addition. -void tst_QFixedPt::add_data() -{ - QTest::addColumn("a"); - QTest::addColumn("b"); - - QTest::newRow("zero") << 0.0f << 0.0f; - QTest::newRow("test1") << 1.0f << 0.0f; - QTest::newRow("test2") << 0.0f << 1.0f; - QTest::newRow("test3") << 10.0f << -3.0f; - QTest::newRow("test4") << 10.5f << 3.25f; -} -void tst_QFixedPt::add() -{ - QFETCH(float, a); - QFETCH(float, b); - - QFixedPt<16> avalue(a); - QFixedPt<16> bvalue(b); - - QFixedPt<16> cvalue = avalue + bvalue; - QFixedPt<16> dvalue = a + bvalue; - QFixedPt<16> evalue = avalue + b; - - QCOMPARE(cvalue.toReal(), (qreal)(a + b)); - QCOMPARE(dvalue.toReal(), (qreal)(a + b)); - QCOMPARE(evalue.toReal(), (qreal)(a + b)); - - QFixedPt<16> fvalue(avalue); - fvalue += bvalue; - QCOMPARE(fvalue.toReal(), (qreal)(a + b)); - - QFixedPt<16> gvalue(avalue); - gvalue += b; - QCOMPARE(gvalue.toReal(), (qreal)(a + b)); - - if (qFloor(a) == a && qFloor(b) == b) { - QFixedPt<16> hvalue = int(a) + bvalue; - QFixedPt<16> ivalue = avalue + int(b); - - QCOMPARE(hvalue.toInt(), int(a) + int(b)); - QCOMPARE(ivalue.toInt(), int(a) + int(b)); - QCOMPARE(hvalue.toReal(), (qreal)(a + b)); - QCOMPARE(ivalue.toReal(), (qreal)(a + b)); - - QFixedPt<16> jvalue(avalue); - jvalue += int(b); - QCOMPARE(jvalue.toReal(), (qreal)(a + b)); - } -} - -// Test fixed point subtraction. -void tst_QFixedPt::sub_data() -{ - // Use the same test data as the add() test. - add_data(); -} -void tst_QFixedPt::sub() -{ - QFETCH(float, a); - QFETCH(float, b); - - QFixedPt<16> avalue(a); - QFixedPt<16> bvalue(b); - - QFixedPt<16> cvalue = avalue - bvalue; - QFixedPt<16> dvalue = a - bvalue; - QFixedPt<16> evalue = avalue - b; - - QCOMPARE(cvalue.toReal(), (qreal)(a - b)); - QCOMPARE(dvalue.toReal(), (qreal)(a - b)); - QCOMPARE(evalue.toReal(), (qreal)(a - b)); - - QFixedPt<16> fvalue(avalue); - fvalue -= bvalue; - QCOMPARE(fvalue.toReal(), (qreal)(a - b)); - - QFixedPt<16> gvalue(avalue); - gvalue -= b; - QCOMPARE(gvalue.toReal(), (qreal)(a - b)); - - if (qFloor(a) == a && qFloor(b) == b) { - QFixedPt<16> hvalue = int(a) - bvalue; - QFixedPt<16> ivalue = avalue - int(b); - - QCOMPARE(hvalue.toInt(), int(a) - int(b)); - QCOMPARE(ivalue.toInt(), int(a) - int(b)); - QCOMPARE(hvalue.toReal(), (qreal)(a - b)); - QCOMPARE(ivalue.toReal(), (qreal)(a - b)); - - QFixedPt<16> jvalue(avalue); - jvalue -= int(b); - QCOMPARE(jvalue.toReal(), (qreal)(a - b)); - } -} - -// Test fixed point multiplication. -void tst_QFixedPt::mul_data() -{ - // Use the same test data as the add() test. - add_data(); -} -void tst_QFixedPt::mul() -{ - QFETCH(float, a); - QFETCH(float, b); - - QFixedPt<16> avalue(a); - QFixedPt<16> bvalue(b); - - QFixedPt<16> cvalue = avalue * bvalue; - QFixedPt<16> dvalue = a * bvalue; - QFixedPt<16> evalue = avalue * b; - - QCOMPARE(cvalue.toReal(), (qreal)(a * b)); - QCOMPARE(dvalue.toReal(), (qreal)(a * b)); - QCOMPARE(evalue.toReal(), (qreal)(a * b)); - - QFixedPt<16> fvalue(avalue); - fvalue *= bvalue; - QCOMPARE(fvalue.toReal(), (qreal)(a * b)); - - QFixedPt<16> gvalue(avalue); - gvalue *= b; - QCOMPARE(gvalue.toReal(), (qreal)(a * b)); - - if (qFloor(a) == a && qFloor(b) == b) { - QFixedPt<16> hvalue = int(a) * bvalue; - QFixedPt<16> ivalue = avalue * int(b); - - QCOMPARE(hvalue.toInt(), int(a) * int(b)); - QCOMPARE(ivalue.toInt(), int(a) * int(b)); - QCOMPARE(hvalue.toReal(), (qreal)(a * b)); - QCOMPARE(ivalue.toReal(), (qreal)(a * b)); - - QFixedPt<16> jvalue(avalue); - jvalue *= int(b); - QCOMPARE(jvalue.toReal(), (qreal)(a * b)); - } -} - -// Test fixed point division. -void tst_QFixedPt::div_data() -{ - // Use the same test data as the add() test. - add_data(); -} -void tst_QFixedPt::div() -{ - QFETCH(float, a); - QFETCH(float, b); - - QFixedPt<16> avalue(a); - QFixedPt<16> bvalue(b); - - qreal result; - if (b == 0.0f) - result = 0.0f; // Divide by zero results in zero. - else - result = a / b; - - QFixedPt<16> cvalue = avalue / bvalue; - QFixedPt<16> dvalue = a / bvalue; - QFixedPt<16> evalue = avalue / b; - - QVERIFY(fuzzyCompare(cvalue.toReal(), result)); - QVERIFY(fuzzyCompare(dvalue.toReal(), result)); - QVERIFY(fuzzyCompare(evalue.toReal(), result)); - - QFixedPt<16> fvalue(avalue); - fvalue /= bvalue; - QVERIFY(fuzzyCompare(fvalue.toReal(), result)); - - QFixedPt<16> gvalue(avalue); - gvalue /= b; - QVERIFY(fuzzyCompare(gvalue.toReal(), result)); - - if (qFloor(a) == a && qFloor(b) == b) { - QFixedPt<16> hvalue = int(a) / bvalue; - QFixedPt<16> ivalue = avalue / int(b); - - QCOMPARE(hvalue.toInt(), int(result)); - QCOMPARE(ivalue.toInt(), int(result)); - QVERIFY(fuzzyCompare(hvalue.toReal(), result)); - QVERIFY(fuzzyCompare(ivalue.toReal(), result)); - - QFixedPt<16> jvalue(avalue); - jvalue /= int(b); - QVERIFY(fuzzyCompare(jvalue.toReal(), result)); - } -} - -// Test fixed point negation. -void tst_QFixedPt::neg_data() -{ - // Use the same test data as the add() test. - add_data(); -} -void tst_QFixedPt::neg() -{ - QFETCH(float, a); - QFETCH(float, b); - - QFixedPt<16> avalue(a); - QFixedPt<16> bvalue(b); - - QFixedPt<16> cvalue = -avalue; - QCOMPARE(cvalue.bits(), -avalue.bits()); - QCOMPARE(cvalue.toInt(), int(-a)); - QCOMPARE(cvalue.toReal(), (qreal)-a); - - QFixedPt<16> dvalue = -bvalue; - QCOMPARE(dvalue.bits(), -bvalue.bits()); - QCOMPARE(dvalue.toInt(), int(-b)); - QCOMPARE(dvalue.toReal(), (qreal)-b); -} - -// Test left and right shift operators on fixed point values. -void tst_QFixedPt::shift_data() -{ - QTest::addColumn("a"); - QTest::addColumn("amount"); - - QTest::newRow("zero") << 0.0f << 5; - QTest::newRow("one") << 1.0f << 4; - QTest::newRow("-1.75") << -1.75f << 4; -} -void tst_QFixedPt::shift() -{ - QFETCH(float, a); - QFETCH(int, amount); - - int lresult = int((a * 65536.0) * (1 << amount)); - int rresult = int((a * 65536.0) / (1 << amount)); - - QFixedPt<16> avalue(a); - avalue <<= amount; - QCOMPARE(avalue.bits(), lresult); - - QFixedPt<16> bvalue(a); - bvalue >>= amount; - QCOMPARE(bvalue.bits(), rresult); - - QFixedPt<16> cvalue(a); - - QFixedPt<16> dvalue; - dvalue = cvalue << amount; - QCOMPARE(dvalue.bits(), lresult); - - QFixedPt<16> evalue; - evalue = cvalue >> amount; - QCOMPARE(evalue.bits(), rresult); -} - -// Test fixed point square root. -void tst_QFixedPt::sqrt_data() -{ - QTest::addColumn("a"); - - QTest::newRow("zero") << 0.0f; - QTest::newRow("one") << 1.0f; - QTest::newRow("two") << 2.0f; - QTest::newRow("sixteen") << 16.0f; - QTest::newRow("1.5") << 1.5f; -} -void tst_QFixedPt::sqrt() -{ - QFETCH(float, a); - - QFixedPt<16> avalue(a); - QVERIFY(fuzzyCompare(avalue.sqrt().toReal(), qSqrt(a))); - QVERIFY(fuzzyCompare(avalue.sqrtF(), qSqrt(a))); -} - -// Test fixed point rounding. -void tst_QFixedPt::round_data() -{ - QTest::addColumn("a"); - QTest::addColumn("rounded"); - QTest::addColumn("ceiling"); - QTest::addColumn("flooring"); - QTest::addColumn("truncated"); - - QTest::newRow("zero") << 0.0f << 0 << 0 << 0 << 0; - QTest::newRow("test1") << 1.0f << 1 << 1 << 1 << 1; - QTest::newRow("test2") << 2.5f << 3 << 3 << 2 << 2; - QTest::newRow("test3") << 2.3f << 2 << 3 << 2 << 2; - QTest::newRow("test4") << -2.5f << -2 << -2 << -3 << -3; - QTest::newRow("test5") << -2.3f << -2 << -2 << -3 << -3; - QTest::newRow("test6") << -2.7f << -3 << -2 << -3 << -3; -} -void tst_QFixedPt::round() -{ - QFETCH(float, a); - QFETCH(int, rounded); - QFETCH(int, ceiling); - QFETCH(int, flooring); - QFETCH(int, truncated); - - QFixedPt<16> avalue(a); - QVERIFY(avalue.round() == rounded); - QVERIFY(avalue.ceil() == ceiling); - QVERIFY(avalue.floor() == flooring); - QVERIFY(avalue.truncate() == truncated); - - QCOMPARE(qRound(avalue), rounded); - QCOMPARE(qCeil(avalue), ceiling); - QCOMPARE(qFloor(avalue), flooring); -} - -// Test comparison operators. -void tst_QFixedPt::compare_data() -{ - QTest::addColumn("a"); - QTest::addColumn("b"); - - QTest::newRow("test1") << 0.0f << 0.0f; - QTest::newRow("test2") << 1.0f << 0.0f; - QTest::newRow("test3") << 2.5f << 2.5f; - QTest::newRow("test4") << 2.5f << -2.5f; - QTest::newRow("test5") << -2.5f << 2.5f; -} -void tst_QFixedPt::compare() -{ - QFETCH(float, a); - QFETCH(float, b); - - QFixedPt<16> avalue(a); - QFixedPt<16> bvalue(b); - - if (a == b) { - QVERIFY(avalue == bvalue); - QVERIFY(avalue == b); - QVERIFY(a == bvalue); - QVERIFY(!(avalue != bvalue)); - QVERIFY(!(avalue != b)); - QVERIFY(!(a != bvalue)); - QVERIFY(!(avalue < bvalue)); - QVERIFY(!(avalue < b)); - QVERIFY(!(a < bvalue)); - QVERIFY(!(avalue > bvalue)); - QVERIFY(!(avalue > b)); - QVERIFY(!(a > bvalue)); - QVERIFY(avalue <= bvalue); - QVERIFY(avalue <= b); - QVERIFY(a <= bvalue); - QVERIFY(avalue >= bvalue); - QVERIFY(avalue >= b); - QVERIFY(a >= bvalue); - if (qFloor(a) == a) { - QVERIFY(int(a) == bvalue); - QVERIFY(!(int(a) != bvalue)); - QVERIFY(!(int(a) < bvalue)); - QVERIFY(!(int(a) > bvalue)); - QVERIFY(int(a) <= bvalue); - QVERIFY(int(a) >= bvalue); - } - if (qFloor(b) == b) { - QVERIFY(avalue == int(b)); - QVERIFY(!(avalue != int(b))); - QVERIFY(!(avalue < int(b))); - QVERIFY(!(avalue > int(b))); - QVERIFY(avalue <= int(b)); - QVERIFY(avalue >= int(b)); - } - } - - if (a != b) { - QVERIFY(avalue != bvalue); - QVERIFY(avalue != b); - QVERIFY(a != bvalue); - QVERIFY(!(avalue == bvalue)); - QVERIFY(!(avalue == b)); - QVERIFY(!(a == bvalue)); - if (qFloor(a) == a) { - QVERIFY(int(a) != bvalue); - QVERIFY(!(int(a) == bvalue)); - } - if (qFloor(b) == b) { - QVERIFY(avalue != int(b)); - QVERIFY(!(avalue == int(b))); - } - } - - if (a < b) { - QVERIFY(avalue < bvalue); - QVERIFY(avalue < b); - QVERIFY(a < bvalue); - QVERIFY(!(avalue >= bvalue)); - QVERIFY(!(avalue >= b)); - QVERIFY(!(a >= bvalue)); - QVERIFY(!(avalue > bvalue)); - QVERIFY(!(avalue > b)); - QVERIFY(!(a > bvalue)); - QVERIFY(avalue <= bvalue); - QVERIFY(avalue <= b); - QVERIFY(a <= bvalue); - QVERIFY(!(avalue >= bvalue)); - QVERIFY(!(avalue >= b)); - QVERIFY(!(a >= bvalue)); - if (qFloor(a) == a) { - QVERIFY(int(a) < bvalue); - QVERIFY(!(int(a) >= bvalue)); - QVERIFY(!(int(a) > bvalue)); - QVERIFY(int(a) <= bvalue); - } - if (qFloor(b) == b) { - QVERIFY(avalue < int(b)); - QVERIFY(!(avalue >= int(b))); - QVERIFY(!(avalue > int(b))); - QVERIFY(avalue <= int(b)); - } - } - - if (a > b) { - QVERIFY(avalue > bvalue); - QVERIFY(avalue > b); - QVERIFY(a > bvalue); - QVERIFY(!(avalue <= bvalue)); - QVERIFY(!(avalue <= b)); - QVERIFY(!(a <= bvalue)); - QVERIFY(!(avalue < bvalue)); - QVERIFY(!(avalue < b)); - QVERIFY(!(a < bvalue)); - QVERIFY(avalue >= bvalue); - QVERIFY(avalue >= b); - QVERIFY(a >= bvalue); - QVERIFY(!(avalue <= bvalue)); - QVERIFY(!(avalue <= b)); - QVERIFY(!(a <= bvalue)); - if (qFloor(a) == a) { - QVERIFY(int(a) > bvalue); - QVERIFY(!(int(a) <= bvalue)); - QVERIFY(!(int(a) < bvalue)); - QVERIFY(int(a) >= bvalue); - } - if (qFloor(b) == b) { - QVERIFY(avalue > int(b)); - QVERIFY(!(avalue <= int(b))); - QVERIFY(!(avalue < int(b))); - QVERIFY(avalue >= int(b)); - } - } - - if (qFuzzyCompare(a, b)) - QVERIFY(qFuzzyCompare(avalue, bvalue)); - else - QVERIFY(!qFuzzyCompare(avalue, bvalue)); -} - -QTEST_APPLESS_MAIN(tst_QFixedPt) - -#include "tst_qfixedpt.moc" diff --git a/tests/auto/math3d/qmatrixnxn/tst_qmatrixnxn.cpp b/tests/auto/math3d/qmatrixnxn/tst_qmatrixnxn.cpp index 8a7dd49..bb510fc 100644 --- a/tests/auto/math3d/qmatrixnxn/tst_qmatrixnxn.cpp +++ b/tests/auto/math3d/qmatrixnxn/tst_qmatrixnxn.cpp @@ -321,7 +321,7 @@ void tst_QMatrix::setMatrix(QMatrix4x3& m, const qreal *values) // to be in row-major order. This sets the values using fixed-point. void tst_QMatrix::setMatrixFixed(QMatrix2x2& m, const qreal *values) { - qrealinner *data = m.data(); + float *data = m.data(); for (int row = 0; row < 2; ++row) { for (int col = 0; col < 2; ++col) { data[row + col * 2] = values[row * 2 + col]; @@ -330,7 +330,7 @@ void tst_QMatrix::setMatrixFixed(QMatrix2x2& m, const qreal *values) } void tst_QMatrix::setMatrixFixed(QMatrix3x3& m, const qreal *values) { - qrealinner *data = m.data(); + float *data = m.data(); for (int row = 0; row < 3; ++row) { for (int col = 0; col < 3; ++col) { data[row + col * 3] = values[row * 3 + col]; @@ -339,7 +339,7 @@ void tst_QMatrix::setMatrixFixed(QMatrix3x3& m, const qreal *values) } void tst_QMatrix::setMatrixFixed(QMatrix4x4& m, const qreal *values) { - qrealinner *data = m.data(); + float *data = m.data(); for (int row = 0; row < 4; ++row) { for (int col = 0; col < 4; ++col) { data[row + col * 4] = values[row * 4 + col]; @@ -348,7 +348,7 @@ void tst_QMatrix::setMatrixFixed(QMatrix4x4& m, const qreal *values) } void tst_QMatrix::setMatrixFixed(QMatrix4x3& m, const qreal *values) { - qrealinner *data = m.data(); + float *data = m.data(); for (int row = 0; row < 3; ++row) { for (int col = 0; col < 4; ++col) { data[row + col * 3] = values[row * 4 + col]; @@ -365,15 +365,6 @@ static bool fuzzyCompare(float x, float y, qreal epsilon = 0.001) diff = -diff; return (diff < epsilon); } -#ifdef QT_GL_FIXED_PREFERRED -static bool fuzzyCompareFixed(qrealinner x, int y) -{ - int diff = x.bits() - y; - if (diff < 0) - diff = -diff; - return (diff < 50); -} -#endif static bool fuzzyCompare(const QVector3D &v1, const QVector3D &v2, qreal epsilon = 0.001) { @@ -402,7 +393,7 @@ static bool matrixFuzzyCompare(const QMatrix4x4 &m1, const QMatrix4x4 &m2) // The values are assumed to be specified in row-major order. bool tst_QMatrix::isSame(const QMatrix2x2& m, const qreal *values) { - const qrealinner *mv = m.constData(); + const float *mv = m.constData(); for (int row = 0; row < 2; ++row) { for (int col = 0; col < 2; ++col) { // Check the values using the operator() function. @@ -413,24 +404,17 @@ bool tst_QMatrix::isSame(const QMatrix2x2& m, const qreal *values) // Check the values using direct access, which verifies that the values // are stored internally in column-major order. -#ifdef QT_GL_FIXED_PREFERRED - if (!fuzzyCompareFixed(mv[col * 2 + row], (int)(values[row * 2 + col] * 65536.0))) { - qDebug() << "column fixed-point failure at" << row << col << "actual =" << mv[col * 2 + row] << "expected =" << (int)(values[row * 2 + col] * 65536.0); - return false; - } -#else if (!fuzzyCompare((float)(mv[col * 2 + row]), (float)(values[row * 2 + col]))) { qDebug() << "column floating-point failure at" << row << col << "actual =" << mv[col * 2 + row] << "expected =" << values[row * 2 + col]; return false; } -#endif } } return true; } bool tst_QMatrix::isSame(const QMatrix3x3& m, const qreal *values) { - const qrealinner *mv = m.constData(); + const float *mv = m.constData(); for (int row = 0; row < 3; ++row) { for (int col = 0; col < 3; ++col) { // Check the values using the operator() access function. @@ -441,24 +425,17 @@ bool tst_QMatrix::isSame(const QMatrix3x3& m, const qreal *values) // Check the values using direct access, which verifies that the values // are stored internally in column-major order. -#ifdef QT_GL_FIXED_PREFERRED - if (!fuzzyCompareFixed(mv[col * 3 + row], (int)(values[row * 3 + col] * 65536.0))) { - qDebug() << "column fixed-point failure at" << row << col << "actual =" << mv[col * 3 + row] << "expected =" << (int)(values[row * 3 + col] * 65536.0); - return false; - } -#else if (!fuzzyCompare((float)(mv[col * 3 + row]), (float)(values[row * 3 + col]))) { qDebug() << "column floating-point failure at" << row << col << "actual =" << mv[col * 3 + row] << "expected =" << values[row * 3 + col]; return false; } -#endif } } return true; } bool tst_QMatrix::isSame(const QMatrix4x4& m, const qreal *values) { - const qrealinner *mv = m.constData(); + const float *mv = m.constData(); for (int row = 0; row < 4; ++row) { for (int col = 0; col < 4; ++col) { // Check the values using the operator() access function. @@ -469,24 +446,17 @@ bool tst_QMatrix::isSame(const QMatrix4x4& m, const qreal *values) // Check the values using direct access, which verifies that the values // are stored internally in column-major order. -#ifdef QT_GL_FIXED_PREFERRED - if (!fuzzyCompareFixed(mv[col * 4 + row], (int)(values[row * 4 + col] * 65536.0))) { - qDebug() << "column fixed-point failure at" << row << col << "actual =" << mv[col * 4 + row] << "expected =" << (int)(values[row * 4 + col] * 65536.0); - return false; - } -#else if (!fuzzyCompare((float)(mv[col * 4 + row]), (float)(values[row * 4 + col]))) { qDebug() << "column floating-point failure at" << row << col << "actual =" << mv[col * 4 + row] << "expected =" << values[row * 4 + col]; return false; } -#endif } } return true; } bool tst_QMatrix::isSame(const QMatrix4x3& m, const qreal *values) { - const qrealinner *mv = m.constData(); + const float *mv = m.constData(); for (int row = 0; row < 3; ++row) { for (int col = 0; col < 4; ++col) { // Check the values using the operator() access function. @@ -497,17 +467,10 @@ bool tst_QMatrix::isSame(const QMatrix4x3& m, const qreal *values) // Check the values using direct access, which verifies that the values // are stored internally in column-major order. -#ifdef QT_GL_FIXED_PREFERRED - if (!fuzzyCompareFixed(mv[col * 3 + row], (int)(values[row * 4 + col] * 65536.0))) { - qDebug() << "column fixed-point failure at" << row << col << "actual =" << mv[col * 3 + row] << "expected =" << (int)(values[row * 4 + col] * 65536.0); - return false; - } -#else if (!fuzzyCompare((float)(mv[col * 3 + row]), (float)(values[row * 4 + col]))) { qDebug() << "column floating-point failure at" << row << col << "actual =" << mv[col * 3 + row] << "expected =" << values[row * 4 + col]; return false; } -#endif } } return true; @@ -1333,7 +1296,7 @@ void tst_QMatrix::multiply4x3() QMatrix4x3 m1((const qreal *)m1Values); QMatrix3x4 m2((const qreal *)m2Values); - QGenericMatrix<3, 3, qreal, qrealinner> m4; + QGenericMatrix<3, 3, qreal, float> m4; m4 = m1 * m2; qreal values[9]; m4.toValueArray(values); @@ -2901,11 +2864,7 @@ void tst_QMatrix::extractAxisRotation() m.extractAxisRotation(extractedAngle, extractedAxis); -#ifdef QT_GL_FIXED_PREFERRED - qreal epsilon = 0.003; -#else qreal epsilon = 0.001; -#endif if (angle > 180) { QVERIFY(fuzzyCompare(360.0f - angle, extractedAngle, epsilon)); @@ -2953,11 +2912,7 @@ void tst_QMatrix::extractTranslation() QVector3D vec = rotation.extractTranslation(); -#ifdef QT_GL_FIXED_PREFERRED - qreal epsilon = 0.01; -#else qreal epsilon = 0.001; -#endif QVERIFY(fuzzyCompare(vec.x(), x, epsilon)); QVERIFY(fuzzyCompare(vec.y(), y, epsilon)); @@ -2992,7 +2947,7 @@ enum { // Structure that allows direct access to "flagBits" for testing. struct Matrix4x4 { - qrealinner m[4][4]; + float m[4][4]; int flagBits; }; @@ -3225,24 +3180,6 @@ void tst_QMatrix::fill() QVERIFY(isSame(m2, fillValues4x3)); } -// Force the fixed-point version of the test case to put a -// different test name on the front of failure reports. -class tst_QMatrixFixed : public tst_QMatrix -{ - Q_OBJECT -public: - tst_QMatrixFixed() {} - ~tst_QMatrixFixed() {} -}; - -#ifdef QT_GL_FIXED_PREFERRED - -QTEST_APPLESS_MAIN(tst_QMatrixFixed) - -#else - QTEST_APPLESS_MAIN(tst_QMatrix) -#endif - #include "tst_qmatrixnxn.moc" diff --git a/tests/auto/math3d/qmatrixnxn_fixed/qmatrixnxn_fixed.pro b/tests/auto/math3d/qmatrixnxn_fixed/qmatrixnxn_fixed.pro deleted file mode 100644 index cd1c8fa..0000000 --- a/tests/auto/math3d/qmatrixnxn_fixed/qmatrixnxn_fixed.pro +++ /dev/null @@ -1,8 +0,0 @@ -load(qttest_p4) -VPATH += ../shared -VPATH += ../qmatrixnxn -INCLUDEPATH += ../shared -INCLUDEPATH += ../../../../src/gui/math3d -DEFINES += FIXED_POINT_TESTS -HEADERS += math3dincludes.h -SOURCES += tst_qmatrixnxn.cpp math3dincludes.cpp diff --git a/tests/auto/math3d/qquaternion/tst_qquaternion.cpp b/tests/auto/math3d/qquaternion/tst_qquaternion.cpp index 325cb40..fd7c7f8 100644 --- a/tests/auto/math3d/qquaternion/tst_qquaternion.cpp +++ b/tests/auto/math3d/qquaternion/tst_qquaternion.cpp @@ -768,24 +768,6 @@ void tst_QQuaternion::interpolate() QVERIFY(fuzzyCompare(result.scalar(), q3.scalar())); } -// Force the fixed-point version of the test case to put a -// different test name on the front of failure reports. -class tst_QQuaternionFixed : public tst_QQuaternion -{ - Q_OBJECT -public: - tst_QQuaternionFixed() {} - ~tst_QQuaternionFixed() {} -}; - -#ifdef QT_GL_FIXED_PREFERRED - -QTEST_APPLESS_MAIN(tst_QQuaternionFixed) - -#else - QTEST_APPLESS_MAIN(tst_QQuaternion) -#endif - #include "tst_qquaternion.moc" diff --git a/tests/auto/math3d/qquaternion_fixed/qquaternion_fixed.pro b/tests/auto/math3d/qquaternion_fixed/qquaternion_fixed.pro deleted file mode 100644 index a0d5401..0000000 --- a/tests/auto/math3d/qquaternion_fixed/qquaternion_fixed.pro +++ /dev/null @@ -1,8 +0,0 @@ -load(qttest_p4) -VPATH += ../shared -VPATH += ../qquaternion -INCLUDEPATH += ../shared -INCLUDEPATH += ../../../../src/gui/math3d -DEFINES += FIXED_POINT_TESTS -HEADERS += math3dincludes.h -SOURCES += tst_qquaternion.cpp math3dincludes.cpp diff --git a/tests/auto/math3d/qvectornd/tst_qvectornd.cpp b/tests/auto/math3d/qvectornd/tst_qvectornd.cpp index 83bacdf..a092fb0 100644 --- a/tests/auto/math3d/qvectornd/tst_qvectornd.cpp +++ b/tests/auto/math3d/qvectornd/tst_qvectornd.cpp @@ -2040,24 +2040,6 @@ void tst_QVector::dotProduct4() QCOMPARE(QVector4D::dotProduct(v1, v2), d); } -// Force the fixed-point version of the test case to put a -// different test name on the front of failure reports. -class tst_QVectorFixed : public tst_QVector -{ - Q_OBJECT -public: - tst_QVectorFixed() {} - ~tst_QVectorFixed() {} -}; - -#ifdef QT_GL_FIXED_PREFERRED - -QTEST_APPLESS_MAIN(tst_QVectorFixed) - -#else - QTEST_APPLESS_MAIN(tst_QVector) -#endif - #include "tst_qvectornd.moc" diff --git a/tests/auto/math3d/qvectornd_fixed/qvectornd_fixed.pro b/tests/auto/math3d/qvectornd_fixed/qvectornd_fixed.pro deleted file mode 100644 index a667fcc..0000000 --- a/tests/auto/math3d/qvectornd_fixed/qvectornd_fixed.pro +++ /dev/null @@ -1,8 +0,0 @@ -load(qttest_p4) -VPATH += ../shared -VPATH += ../qvectornd -INCLUDEPATH += ../shared -INCLUDEPATH += ../../../../src/gui/math3d -DEFINES += FIXED_POINT_TESTS -HEADERS += math3dincludes.h -SOURCES += tst_qvectornd.cpp math3dincludes.cpp diff --git a/tests/auto/math3d/shared/math3dincludes.cpp b/tests/auto/math3d/shared/math3dincludes.cpp deleted file mode 100644 index 725079d..0000000 --- a/tests/auto/math3d/shared/math3dincludes.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Qt Software Information (qt-info@nokia.com) -** -** This file is part of the $MODULE$ of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this -** package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at qt-sales@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "math3dincludes.h" - -#if defined(FIXED_POINT_TESTS) - -#include "qmatrix4x4.cpp" -#include "qgenericmatrix.cpp" -#include "qvector2d.cpp" -#include "qvector3d.cpp" -#include "qvector4d.cpp" -#include "qquaternion.cpp" -#include "qmath3dutil.cpp" - -#endif diff --git a/tests/auto/math3d/shared/math3dincludes.h b/tests/auto/math3d/shared/math3dincludes.h index 23b0f16..1ac0c08 100644 --- a/tests/auto/math3d/shared/math3dincludes.h +++ b/tests/auto/math3d/shared/math3dincludes.h @@ -42,41 +42,6 @@ #ifndef MATH3DINCLUDES_H #define MATH3DINCLUDES_H -#if defined(FIXED_POINT_TESTS) - -// Rename the classes we want to test in fixed-point mode so that -// they don't conflict with the ones that are built into Qt. -#define QT_NO_GL_FLOAT 1 -#define QVector2D tst_QVector2D -#define QVector3D tst_QVector3D -#define QVector4D tst_QVector4D -#define QQuaternion tst_QQuaternionX -#define QMatrix2x2 tst_QMatrix2x2 -#define QMatrix3x3 tst_QMatrix3x3 -#define QMatrix4x4 tst_QMatrix4x4 -#define QMatrix2x3 tst_QMatrix2x3 -#define QMatrix2x4 tst_QMatrix2x4 -#define QMatrix3x2 tst_QMatrix3x2 -#define QMatrix3x4 tst_QMatrix3x4 -#define QMatrix4x2 tst_QMatrix4x2 -#define QMatrix4x3 tst_QMatrix4x3 -#define QGenericMatrix tst_QGenericMatrix -#define qt_math3d_sincos tst_qt_math3d_sincos -#define qt_math3d_convert tst_qt_math3d_convert -#define qrealinner tst_qrealinner - -// We need to re-include the headers with the changed class names. -#undef QGENERICMATRIX_H -#undef QMATH3DGLOBAL_H -#undef QMATH3DUTIL_P_H -#undef QMATRIX4X4_H -#undef QQUATERNION_H -#undef QVECTOR2D_H -#undef QVECTOR3D_H -#undef QVECTOR4D_H - -#endif - #include #include #include -- cgit v0.12 From 25b8d04ad9f2d5b89e81f56212b4dbfaeff1304d Mon Sep 17 00:00:00 2001 From: Bill King Date: Wed, 8 Apr 2009 14:55:00 +1000 Subject: Missed these changes from the last commit. Last of the changes to include behaviour from QPtrVector --- src/sql/drivers/db2/qsql_db2.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/sql/drivers/db2/qsql_db2.cpp b/src/sql/drivers/db2/qsql_db2.cpp index a6be435..5d221b8 100644 --- a/src/sql/drivers/db2/qsql_db2.cpp +++ b/src/sql/drivers/db2/qsql_db2.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #ifndef UNICODE #define UNICODE @@ -578,7 +579,8 @@ bool QDB2Result::reset (const QString& query) } else { setSelect(false); } - d->valueCache.resize(count, NULL); + d->valueCache.resize(count); + d->valueCache.fill(NULL); setActive(true); return true; } @@ -821,7 +823,8 @@ bool QDB2Result::exec() setSelect(false); } setActive(true); - d->valueCache.resize(count, NULL); + d->valueCache.resize(count); + d->valueCache.fill(NULL); //get out parameters if (!hasOutValues()) @@ -1130,7 +1133,8 @@ bool QDB2Result::nextResult() for (int i = 0; i < fieldCount; ++i) d->recInf.append(qMakeFieldInfo(d, i)); - d->valueCache.resize(fieldCount, NULL); + d->valueCache.resize(fieldCount); + d->valueCache.fill(NULL); setActive(true); return true; -- cgit v0.12 From 9565e3420bdc214c389aa513748da11ff16b1fca Mon Sep 17 00:00:00 2001 From: Bill King Date: Wed, 8 Apr 2009 15:40:24 +1000 Subject: DB2 driver returning double field as empty The high precision code path was getting an empty string on the second call to getstringdata, which was causing it to return empty for the field. Really only needed to call it once anyway, so use the original call. Reviewed-by: Justin McPherson --- src/sql/drivers/db2/qsql_db2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sql/drivers/db2/qsql_db2.cpp b/src/sql/drivers/db2/qsql_db2.cpp index 5d221b8..2786dbb 100644 --- a/src/sql/drivers/db2/qsql_db2.cpp +++ b/src/sql/drivers/db2/qsql_db2.cpp @@ -1058,7 +1058,7 @@ QVariant QDB2Result::data(int field) case QSql::HighPrecision: default: // length + 1 for the comma - v = new QVariant(qGetStringData(d->hStmt, field, info.length() + 1, isNull)); + v = new QVariant(value); ok = true; break; } -- cgit v0.12 From a4252201f631d65553846c6af65df905a0cf4048 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 8 Apr 2009 08:05:44 +0200 Subject: Enable test for WinCE While we integrate into native menubar on Windows Mobile, we can still test WinCE itself. --- tests/auto/qmenubar/tst_qmenubar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qmenubar/tst_qmenubar.cpp b/tests/auto/qmenubar/tst_qmenubar.cpp index e0a9f42..6d069c6 100644 --- a/tests/auto/qmenubar/tst_qmenubar.cpp +++ b/tests/auto/qmenubar/tst_qmenubar.cpp @@ -1429,7 +1429,7 @@ void tst_QMenuBar::check_menuPosition() #ifdef Q_WS_MAC QSKIP("Qt/Mac does not use the native popups/menubar", SkipAll); #endif -#ifdef Q_OS_WINCE +#ifdef Q_OS_WINCE_WM QSKIP("Qt/CE uses native menubar", SkipAll); #endif QMenu menu; -- cgit v0.12 From 64858dcac58621295c419903efe58ce9a8d0e5b7 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 8 Apr 2009 08:06:40 +0200 Subject: add deployment for WinCE --- tests/auto/qtextcodec/test/test.pro | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/qtextcodec/test/test.pro b/tests/auto/qtextcodec/test/test.pro index ed2ade3..e52bb7a 100644 --- a/tests/auto/qtextcodec/test/test.pro +++ b/tests/auto/qtextcodec/test/test.pro @@ -5,6 +5,7 @@ wince*: { addFiles.sources = ../*.txt addFiles.path = . DEPLOYMENT += addFiles + DEPLOYMENT_PLUGIN += qcncodecs qjpcodecs qkrcodecs qtwcodecs } -- cgit v0.12 From 7332065a28577444e7c97617fb03d0f14c706b5b Mon Sep 17 00:00:00 2001 From: Marius Storm-Olsen Date: Wed, 8 Apr 2009 08:18:55 +0200 Subject: Don't check license for internal configurations A Nokia build doesn't require a license. Reviewed-by: mauricek BT: yes --- tools/configure/configureapp.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index df583a6..5e77606 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -3511,7 +3511,8 @@ void Configure::readLicense() } #else } else { - Tools::checkLicense(dictionary, licenseInfo, firstLicensePath()); + if (dictionary[ "BUILDNOKIA" ] != "yes") + Tools::checkLicense(dictionary, licenseInfo, firstLicensePath()); if (dictionary["DONE"] != "error") { // give the user some feedback, and prompt for license acceptance cout << endl << "This is the " << dictionary["PLATFORM NAME"] << " " << dictionary["EDITION"] << " Edition."<< endl << endl; -- cgit v0.12 From f0239a4983dd84b0e23c1e6f796c5c44dfde26b2 Mon Sep 17 00:00:00 2001 From: Marius Storm-Olsen Date: Wed, 8 Apr 2009 08:25:05 +0200 Subject: New binary for Windows configure Reviewed-by: mauricek BT: yes --- configure.exe | Bin 1134592 -> 851968 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/configure.exe b/configure.exe index 13ca0e5..891e928 100644 Binary files a/configure.exe and b/configure.exe differ -- cgit v0.12 From ccaf16278f4fd422458d01b80579952846e6cf38 Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Wed, 8 Apr 2009 08:57:16 +0200 Subject: BT: Revert "Fixes: Remove warnings in the embeddeddialogs demo." This reverts commit 7d24c0af8e52687b4e5735950495bb25947ca9f0. This change removed the accidental recursion leading to console warnings on Mac OS X by changing the way the scene event filter is registered for popups. But it also broke the behavior of the demo with regards to popup handling, in that the custom proxy no longer can detect popups that close, so dialogs stay zoomed in after the cursor has left. So before, the demo worked but printed warnings to the console on Mac OS X, and after, the warnings were gone but the demo behavior broke on all platforms... The change also accidentally removed the cache mode from the popup; I don't think this was intentional. Reviewed-by: Alexis --- demos/embeddeddialogs/main.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/demos/embeddeddialogs/main.cpp b/demos/embeddeddialogs/main.cpp index 4cf7325..cfb31c4 100644 --- a/demos/embeddeddialogs/main.cpp +++ b/demos/embeddeddialogs/main.cpp @@ -68,7 +68,6 @@ int main(int argc, char *argv[]) proxy->setCacheMode(QGraphicsItem::DeviceCoordinateCache); scene.addItem(proxy); - proxy->installSceneEventFilter(proxy); } } scene.setSceneRect(scene.itemsBoundingRect()); -- cgit v0.12 From e2360b31d93e856945f030ea9526c5936ab62a8c Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 8 Apr 2009 09:05:42 +0200 Subject: remove senseless testfunctions Reviewed-by: joerg Some of the testfunctions use key/mouse events, which doesn't work on Windows Mobile due to native menubar integration. Basically the same situation like on Mac. In addition there are still two test functions failing, waiting for input on those. --- tests/auto/qmenubar/tst_qmenubar.cpp | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/auto/qmenubar/tst_qmenubar.cpp b/tests/auto/qmenubar/tst_qmenubar.cpp index 6d069c6..538e443 100644 --- a/tests/auto/qmenubar/tst_qmenubar.cpp +++ b/tests/auto/qmenubar/tst_qmenubar.cpp @@ -457,8 +457,8 @@ void tst_QMenuBar::accel() void tst_QMenuBar::accel_noQt3() { -#ifdef Q_WS_MAC - QSKIP("On Mac, native key events are needed to test menu action activation", SkipAll); +#if defined(Q_WS_MAC) || defined(Q_OS_WINCE_WM) + QSKIP("On Mac/WinCE, native key events are needed to test menu action activation", SkipAll); #endif // create a popup menu with menu items set the accelerators later... initSimpleMenubar_noQt3(); @@ -486,8 +486,8 @@ void tst_QMenuBar::activatedCount() void tst_QMenuBar::activatedCount_noQt3() { -#ifdef Q_WS_MAC - QSKIP("On Mac, native key events are needed to test menu action activation", SkipAll); +#if defined(Q_WS_MAC) || defined(Q_OS_WINCE_WM) + QSKIP("On Mac/WinCE, native key events are needed to test menu action activation", SkipAll); #endif // create a popup menu with menu items set the accelerators later... initSimpleMenubar_noQt3(); @@ -888,8 +888,8 @@ void tst_QMenuBar::insertItem_QString_QObject_noQt3() void tst_QMenuBar::check_accelKeys() { -#ifdef Q_WS_MAC - QSKIP("On Mac, native key events are needed to test menu action activation", SkipAll); +#if defined(Q_WS_MAC) || defined(Q_OS_WINCE_WM) + QSKIP("On Mac/WinCE, native key events are needed to test menu action activation", SkipAll); #endif #ifdef QT3_SUPPORT initComplexMenubar(); @@ -961,8 +961,8 @@ void tst_QMenuBar::check_accelKeys() void tst_QMenuBar::check_cursorKeys1() { -#ifdef Q_WS_MAC - QSKIP("Qt/Mac does not use the native popups/menubar", SkipAll); +#if defined(Q_WS_MAC) || defined(Q_OS_WINCE_WM) + QSKIP("Qt/Mac,WinCE does not use the native popups/menubar", SkipAll); #endif #ifdef QT3_SUPPORT @@ -996,8 +996,8 @@ void tst_QMenuBar::check_cursorKeys1() void tst_QMenuBar::check_cursorKeys2() { -#ifdef Q_WS_MAC - QSKIP("Qt/Mac does not use the native popups/menubar", SkipAll); +#if defined(Q_WS_MAC) || defined(Q_OS_WINCE_WM) + QSKIP("Qt/Mac,WinCE does not use the native popups/menubar", SkipAll); #endif #ifdef QT3_SUPPORT @@ -1030,8 +1030,8 @@ void tst_QMenuBar::check_cursorKeys2() */ void tst_QMenuBar::check_cursorKeys3() { -#ifdef Q_WS_MAC - QSKIP("Qt/Mac does not use the native popups/menubar", SkipAll); +#if defined(Q_WS_MAC) || defined(Q_OS_WINCE_WM) + QSKIP("Qt/Mac,WinCE does not use the native popups/menubar", SkipAll); #endif #ifdef QT3_SUPPORT @@ -1186,8 +1186,8 @@ void tst_QMenuBar::check_escKey() void tst_QMenuBar::check_escKey_noQt3() { -#ifdef Q_WS_MAC - QSKIP("Qt/Mac does not use the native popups/menubar", SkipAll); +#if defined(Q_WS_MAC) || defined(Q_OS_WINCE_WM) + QSKIP("Qt/Mac,WinCE does not use the native popups/menubar", SkipAll); #endif initComplexMenubar_noQt3(); @@ -1329,7 +1329,7 @@ void tst_QMenuBar::check_escKey_noQt3() void tst_QMenuBar::allowActiveAndDisabled() { -#ifndef Q_WS_MAC +#if !defined(Q_WS_MAC) && !defined(Q_OS_WINCE_WM) mb->hide(); mb->clear(); @@ -1393,8 +1393,8 @@ void tst_QMenuBar::check_altPress() void tst_QMenuBar::check_shortcutPress() { -#ifdef Q_WS_MAC - QSKIP("Qt/Mac does not use the native popups/menubar", SkipAll); +#if defined(Q_WS_MAC) || defined(Q_OS_WINCE_WM) + QSKIP("Qt/Mac,WinCE does not use the native popups/menubar", SkipAll); #endif #ifdef QT3_SUPPORT -- cgit v0.12 From f13c24438b5baec0c11220a5d783fc6830d47aa3 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 8 Apr 2009 10:20:14 +0200 Subject: fix assert Reviewed-by: thartman - in case we explicitly use double as testdata, one cannot push float to it. - fuzzyCompare is not fuzzy enough, thus adopt the epsilon check of other testfunctions. --- tests/auto/qline/tst_qline.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/auto/qline/tst_qline.cpp b/tests/auto/qline/tst_qline.cpp index 932ec8e..ab0bd9b 100644 --- a/tests/auto/qline/tst_qline.cpp +++ b/tests/auto/qline/tst_qline.cpp @@ -201,8 +201,8 @@ void tst_QLine::testIntersection_data() b = b.translated(1, 1); QTest::newRow(qPrintable(QString::fromLatin1("rotation-%0").arg(i))) - << a.x1() << a.y1() << a.x2() << a.y2() - << b.x1() << b.y1() << b.x2() << b.y2() + << (double)a.x1() << (double)a.y1() << (double)a.x2() << (double)a.y2() + << (double)b.x1() << (double)b.y1() << (double)b.x2() << (double)b.y2() << int(QLineF::BoundedIntersection) << 1.0 << 1.0; @@ -232,8 +232,8 @@ void tst_QLine::testIntersection() QCOMPARE(int(itype), type); if (type != QLineF::NoIntersection) { - QCOMPARE(ip.x(), qreal(ix)); - QCOMPARE(ip.y(), qreal(iy)); + QVERIFY(qAbs(ip.x() - ix) < epsilon); + QVERIFY(qAbs(ip.y() - iy) < epsilon); } } -- cgit v0.12 From 72f84ad17d0905f91e9d3988bb0f6482df6c6c78 Mon Sep 17 00:00:00 2001 From: Bjoern Erik Nilsen Date: Tue, 7 Apr 2009 16:50:23 +0200 Subject: Use qIsFuzzyNull rather than the more expensive qFuzzyCompare See also fde7f3d03782c801901f511131458d6fcb1021a5 Reviewed-by: Olivier Reviewed-by: Samuel --- src/corelib/tools/qsize.h | 8 +++---- src/gui/graphicsview/qgraphicsitem.cpp | 2 +- src/gui/kernel/qwidget.cpp | 2 +- src/gui/math3d/qmatrix4x4.cpp | 2 +- src/gui/painting/qbezier.cpp | 24 ++++++++++----------- src/gui/painting/qcolor.cpp | 4 ++-- src/gui/painting/qmatrix.h | 2 +- src/gui/painting/qpaintengine_d3d.cpp | 6 +++--- src/gui/painting/qpaintengine_raster.cpp | 24 ++++++++++----------- src/gui/painting/qpainter.cpp | 24 ++++++++++----------- src/gui/painting/qpainterpath.cpp | 8 +++---- src/gui/painting/qpathclipper.cpp | 36 ++++++++++++++++---------------- src/gui/painting/qstroker.cpp | 12 +++++------ src/gui/painting/qtessellator.cpp | 2 +- src/opengl/qpaintengine_opengl.cpp | 9 ++++---- src/svg/qgraphicssvgitem.cpp | 2 +- src/svg/qsvggenerator.cpp | 2 +- src/svg/qsvggraphics.cpp | 16 +++++++------- 18 files changed, 92 insertions(+), 93 deletions(-) diff --git a/src/corelib/tools/qsize.h b/src/corelib/tools/qsize.h index 57c55ca..df2c183 100644 --- a/src/corelib/tools/qsize.h +++ b/src/corelib/tools/qsize.h @@ -171,14 +171,14 @@ inline const QSize operator*(qreal c, const QSize &s) inline QSize &QSize::operator/=(qreal c) { - Q_ASSERT(!qFuzzyCompare(c + 1, 1)); + Q_ASSERT(!qIsFuzzyNull(c)); wd = qRound(wd/c); ht = qRound(ht/c); return *this; } inline const QSize operator/(const QSize &s, qreal c) { - Q_ASSERT(!qFuzzyCompare(c + 1, 1)); + Q_ASSERT(!qIsFuzzyNull(c)); return QSize(qRound(s.wd/c), qRound(s.ht/c)); } @@ -327,14 +327,14 @@ inline const QSizeF operator*(qreal c, const QSizeF &s) inline QSizeF &QSizeF::operator/=(qreal c) { - Q_ASSERT(!qFuzzyCompare(c + 1, 1)); + Q_ASSERT(!qIsFuzzyNull(c)); wd = wd/c; ht = ht/c; return *this; } inline const QSizeF operator/(const QSizeF &s, qreal c) { - Q_ASSERT(!qFuzzyCompare(c + 1, 1)); + Q_ASSERT(!qIsFuzzyNull(c)); return QSizeF(s.wd/c, s.ht/c); } diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index b8ff5b4..0d846d9 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -4091,7 +4091,7 @@ void QGraphicsItem::scroll(qreal dx, qreal dy, const QRectF &rect) return; if (d->cacheMode != NoCache) { QGraphicsItemCache *c; - bool scrollCache = qFuzzyCompare(dx - int(dx), qreal(0.0)) && qFuzzyCompare(dy - int(dy), qreal(0.0)) + bool scrollCache = qIsFuzzyNull(dx - int(dx)) && qIsFuzzyNull(dy - int(dy)) && (c = (QGraphicsItemCache *)qVariantValue(d_ptr->extra(QGraphicsItemPrivate::ExtraCacheData))) && (d->cacheMode == ItemCoordinateCache && !c->fixedSize.isValid()); if (scrollCache) { diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 20b79ce..623ba59 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -4780,7 +4780,7 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset, } const qreal opacity = painter->opacity(); - if (qFuzzyCompare(opacity + 1, qreal(1.0))) + if (qIsFuzzyNull(opacity)) return; // Fully transparent. Q_D(QWidget); diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp index c2873e0..1457400 100644 --- a/src/gui/math3d/qmatrix4x4.cpp +++ b/src/gui/math3d/qmatrix4x4.cpp @@ -1514,7 +1514,7 @@ void QMatrix4x4::extractAxisRotation(qreal &angle, QVector3D &axis) const angle = acos(cosa) * 180.0f / M_PI; // Any axis will work if r is zero (means no rotation) - if (qFuzzyCompare(angle, (qreal)0.0f)) { + if (qIsFuzzyNull(angle)) { axis.setX(1.0f); axis.setY(0.0f); axis.setZ(0.0f); diff --git a/src/gui/painting/qbezier.cpp b/src/gui/painting/qbezier.cpp index 8317dd8..1168b5a 100644 --- a/src/gui/painting/qbezier.cpp +++ b/src/gui/painting/qbezier.cpp @@ -127,13 +127,13 @@ static inline void flattenBezierWithoutInflections(QBezier &bez, qreal dy = bez.y2 - bez.y1; qreal normalized = qSqrt(dx * dx + dy * dy); - if (qFuzzyCompare(normalized + 1, 1)) + if (qIsFuzzyNull(normalized)) break; qreal d = qAbs(dx * (bez.y3 - bez.y2) - dy * (bez.x3 - bez.x2)); qreal t = qSqrt(4. / 3. * normalized * flatness / d); - if (t > 1 || qFuzzyCompare(t, (qreal)1.)) + if (t > 1 || qIsFuzzyNull(t - (qreal)1.)) break; bez.parameterSplitLeft(t, &left); p->append(bez.pt1()); @@ -144,19 +144,19 @@ static inline void flattenBezierWithoutInflections(QBezier &bez, static inline int quadraticRoots(qreal a, qreal b, qreal c, qreal *x1, qreal *x2) { - if (qFuzzyCompare(a + 1, 1)) { - if (qFuzzyCompare(b + 1, 1)) + if (qIsFuzzyNull(a)) { + if (qIsFuzzyNull(b)) return 0; *x1 = *x2 = (-c / b); return 1; } else { const qreal det = b * b - 4 * a * c; - if (qFuzzyCompare(det + 1, 1)) { + if (qIsFuzzyNull(det)) { *x1 = *x2 = -b / (2 * a); return 1; } if (det > 0) { - if (qFuzzyCompare(b + 1, 1)) { + if (qIsFuzzyNull(b)) { *x2 = qSqrt(-c / a); *x1 = -(*x2); return 2; @@ -187,7 +187,7 @@ static inline bool findInflections(qreal a, qreal b, qreal c, *t1 = r2; *t2 = r1; } - if (!qFuzzyCompare(a + 1, 1)) + if (!qIsFuzzyNull(a)) *tCups = 0.5 * (-b / a); else *tCups = 2; @@ -243,7 +243,7 @@ void QBezier::addToPolygonMixed(QPolygonF *polygon) const qreal b = 6 * (ay * cx - ax * cy); qreal c = 2 * (by * cx - bx * cy); - if ((qFuzzyCompare(a + 1, 1) && qFuzzyCompare(b + 1, 1)) || + if ((qIsFuzzyNull(a) && qIsFuzzyNull(b)) || (b * b - 4 * a *c) < 0) { QBezier bez(*this); flattenBezierWithoutInflections(bez, polygon); @@ -447,7 +447,7 @@ static ShiftResult shift(const QBezier *orig, QBezier *shifted, qreal offset, qr qreal r = 1.0 + prev_normal.x() * next_normal.x() + prev_normal.y() * next_normal.y(); - if (qFuzzyCompare(r + 1, 1)) { + if (qIsFuzzyNull(r)) { points_shifted[i] = points[i] + offset * prev_normal; } else { qreal k = offset / r; @@ -477,12 +477,12 @@ static bool addCircle(const QBezier *b, qreal offset, QBezier *o) normals[0] = QPointF(b->y2 - b->y1, b->x1 - b->x2); qreal dist = qSqrt(normals[0].x()*normals[0].x() + normals[0].y()*normals[0].y()); - if (qFuzzyCompare(dist + 1, 1)) + if (qIsFuzzyNull(dist)) return false; normals[0] /= dist; normals[2] = QPointF(b->y4 - b->y3, b->x3 - b->x4); dist = qSqrt(normals[2].x()*normals[2].x() + normals[2].y()*normals[2].y()); - if (qFuzzyCompare(dist + 1, 1)) + if (qIsFuzzyNull(dist)) return false; normals[2] /= dist; @@ -1022,7 +1022,7 @@ int QBezier::stationaryYPoints(qreal &t0, qreal &t1) const QList result; - if (qFuzzyCompare(reciprocal + 1, 1)) { + if (qIsFuzzyNull(reciprocal)) { t0 = -b / (2 * a); return 1; } else if (reciprocal > 0) { diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index 5d7d4ab..6eecea0 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -1387,7 +1387,7 @@ QColor QColor::toHsv() const const qreal min = Q_MIN_3(r, g, b); const qreal delta = max - min; color.ct.ahsv.value = qRound(max * USHRT_MAX); - if (qFuzzyCompare(delta + 1, 1)) { + if (qIsFuzzyNull(delta)) { // achromatic case, hue is undefined color.ct.ahsv.hue = USHRT_MAX; color.ct.ahsv.saturation = 0; @@ -1441,7 +1441,7 @@ QColor QColor::toCmyk() const // cmy -> cmyk const qreal k = qMin(c, qMin(m, y)); - if (!qFuzzyCompare(k,1)) { + if (!qIsFuzzyNull(k - 1)) { c = (c - k) / (1.0 - k); m = (m - k) / (1.0 - k); y = (y - k) / (1.0 - k); diff --git a/src/gui/painting/qmatrix.h b/src/gui/painting/qmatrix.h index 1b6bd6d..71c1e34 100644 --- a/src/gui/painting/qmatrix.h +++ b/src/gui/painting/qmatrix.h @@ -99,7 +99,7 @@ public: QMatrix &shear(qreal sh, qreal sv); QMatrix &rotate(qreal a); - bool isInvertible() const { return !qFuzzyCompare(_m11*_m22 - _m12*_m21 + 1, 1); } + bool isInvertible() const { return !qIsFuzzyNull(_m11*_m22 - _m12*_m21); } qreal det() const { return _m11*_m22 - _m12*_m21; } QMatrix inverted(bool *invertible = 0) const; diff --git a/src/gui/painting/qpaintengine_d3d.cpp b/src/gui/painting/qpaintengine_d3d.cpp index bb81623..4b494d1 100644 --- a/src/gui/painting/qpaintengine_d3d.cpp +++ b/src/gui/painting/qpaintengine_d3d.cpp @@ -2506,8 +2506,8 @@ void QD3DDrawHelper::addTrap(const Trapezoid &trap) qreal _rightA = (qreal)_w/_h; qreal _rightB = topRightX - _rightA * topRightY; - qreal invLeftA = qFuzzyCompare(_leftA + 1, 1) ? 0.0 : 1.0 / _leftA; - qreal invRightA = qFuzzyCompare(_rightA + 1, 1) ? 0.0 : 1.0 / _rightA; + qreal invLeftA = qIsFuzzyNull(_leftA) ? 0.0 : 1.0 / _leftA; + qreal invRightA = qIsFuzzyNull(_rightA) ? 0.0 : 1.0 / _rightA; vertex v1 = { {1.f, top - 1.f, 0.5f}, 0.f, top, bottom, invLeftA, -invRightA, @@ -2970,7 +2970,7 @@ qreal calculateAngle(qreal dx, qreal dy) { qreal angle; - if (qFuzzyCompare(dx + 1, 1)) { + if (qIsFuzzyNull(dx)) { angle = (dy < 0) ? -M_PI/2 : M_PI/2; } else { angle = atanf(dy/dx); diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index addd63d..7aab25c 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -618,22 +618,22 @@ void QRasterPaintEngine::updateMatrix(const QTransform &matrix) d->isPlain45DegreeRotation = false; if (txop >= QTransform::TxRotate) { d->isPlain45DegreeRotation = - (qFuzzyCompare(matrix.m11() + 1, qreal(1)) - && qFuzzyCompare(matrix.m12(), qreal(1)) - && qFuzzyCompare(matrix.m21(), qreal(-1)) - && qFuzzyCompare(matrix.m22() + 1, qreal(1)) + (qIsFuzzyNull(matrix.m11()) + && qIsFuzzyNull(matrix.m12() - qreal(1)) + && qIsFuzzyNull(matrix.m21() + qreal(1)) + && qIsFuzzyNull(matrix.m22()) ) || - (qFuzzyCompare(matrix.m11(), qreal(-1)) - && qFuzzyCompare(matrix.m12() + 1, qreal(1)) - && qFuzzyCompare(matrix.m21() + 1, qreal(1)) - && qFuzzyCompare(matrix.m22(), qreal(-1)) + (qIsFuzzyNull(matrix.m11() + qreal(1)) + && qIsFuzzyNull(matrix.m12()) + && qIsFuzzyNull(matrix.m21()) + && qIsFuzzyNull(matrix.m22() + qreal(1)) ) || - (qFuzzyCompare(matrix.m11() + 1, qreal(1)) - && qFuzzyCompare(matrix.m12(), qreal(-1)) - && qFuzzyCompare(matrix.m21(), qreal(1)) - && qFuzzyCompare(matrix.m22() + 1, qreal(1)) + (qIsFuzzyNull(matrix.m11()) + && qIsFuzzyNull(matrix.m12() + qreal(1)) + && qIsFuzzyNull(matrix.m21() - qreal(1)) + && qIsFuzzyNull(matrix.m22()) ) ; } diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 2beb8c2..d4271ae 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -6055,22 +6055,22 @@ void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti) const QTransform &m = d->state->matrix; if (d->state->matrix.type() < QTransform::TxShear) { bool isPlain90DegreeRotation = - (qFuzzyCompare(m.m11() + 1, qreal(1)) - && qFuzzyCompare(m.m12(), qreal(1)) - && qFuzzyCompare(m.m21(), qreal(-1)) - && qFuzzyCompare(m.m22() + 1, qreal(1)) + (qIsFuzzyNull(m.m11()) + && qIsFuzzyNull(m.m12() - qreal(1)) + && qIsFuzzyNull(m.m21() + qreal(1)) + && qIsFuzzyNull(m.m22()) ) || - (qFuzzyCompare(m.m11(), qreal(-1)) - && qFuzzyCompare(m.m12() + 1, qreal(1)) - && qFuzzyCompare(m.m21() + 1, qreal(1)) - && qFuzzyCompare(m.m22(), qreal(-1)) + (qIsFuzzyNull(m.m11() + qreal(1)) + && qIsFuzzyNull(m.m12()) + && qIsFuzzyNull(m.m21()) + && qIsFuzzyNull(m.m22() + qreal(1)) ) || - (qFuzzyCompare(m.m11() + 1, qreal(1)) - && qFuzzyCompare(m.m12(), qreal(-1)) - && qFuzzyCompare(m.m21(), qreal(1)) - && qFuzzyCompare(m.m22() + 1, qreal(1)) + (qIsFuzzyNull(m.m11()) + && qIsFuzzyNull(m.m12() + qreal(1)) + && qIsFuzzyNull(m.m21() - qreal(1)) + && qIsFuzzyNull(m.m22()) ) ; aa = !isPlain90DegreeRotation; diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp index 6ae908c..de8969c 100644 --- a/src/gui/painting/qpainterpath.cpp +++ b/src/gui/painting/qpainterpath.cpp @@ -1299,10 +1299,10 @@ static QRectF qt_painterpath_bezier_extrema(const QBezier &b) qreal bx = QT_BEZIER_B(b, x); qreal cx = QT_BEZIER_C(b, x); // specialcase quadratic curves to avoid div by zero - if (qFuzzyCompare(ax + 1, 1)) { + if (qIsFuzzyNull(ax)) { // linear curves are covered by initialization. - if (!qFuzzyCompare(bx + 1, 1)) { + if (!qIsFuzzyNull(bx)) { qreal t = -cx / bx; QT_BEZIER_CHECK_T(b, t); } @@ -1329,10 +1329,10 @@ static QRectF qt_painterpath_bezier_extrema(const QBezier &b) qreal cy = QT_BEZIER_C(b, y); // specialcase quadratic curves to avoid div by zero - if (qFuzzyCompare(ay + 1, 1)) { + if (qIsFuzzyNull(ay)) { // linear curves are covered by initialization. - if (!qFuzzyCompare(by + 1, 1)) { + if (!qIsFuzzyNull(by)) { qreal t = -cy / by; QT_BEZIER_CHECK_T(b, t); } diff --git a/src/gui/painting/qpathclipper.cpp b/src/gui/painting/qpathclipper.cpp index 297cdd3..33609ad 100644 --- a/src/gui/painting/qpathclipper.cpp +++ b/src/gui/painting/qpathclipper.cpp @@ -138,11 +138,11 @@ bool QIntersectionFinder::linesIntersect(const QLineF &a, const QLineF &b) const const qreal par = pDelta.x() * qDelta.y() - pDelta.y() * qDelta.x(); - if (qFuzzyCompare(par + 1, 1)) { + if (qIsFuzzyNull(par)) { const QPointF normal(-pDelta.y(), pDelta.x()); // coinciding? - if (qFuzzyCompare(dot(normal, q1 - p1) + 1, 1)) { + if (qIsFuzzyNull(dot(normal, q1 - p1))) { const qreal dp = dot(pDelta, pDelta); const qreal tq1 = dot(pDelta, q1 - p1); @@ -202,13 +202,13 @@ void QIntersectionFinder::intersectBeziers(const QBezier &one, const QBezier &tw qreal alpha_q = t.at(i).second; QPointF pt; - if (qFuzzyCompare(alpha_p + 1, 1)) { + if (qIsFuzzyNull(alpha_p)) { pt = one.pt1(); - } else if (qFuzzyCompare(alpha_p, 1)) { + } else if (qIsFuzzyNull(alpha_p - 1)) { pt = one.pt4(); - } else if (qFuzzyCompare(alpha_q + 1, 1)) { + } else if (qIsFuzzyNull(alpha_q)) { pt = two.pt1(); - } else if (qFuzzyCompare(alpha_q, 1)) { + } else if (qIsFuzzyNull(alpha_q - 1)) { pt = two.pt4(); } else { pt = one.pointAt(alpha_p); @@ -250,11 +250,11 @@ void QIntersectionFinder::intersectLines(const QLineF &a, const QLineF &b, QData const qreal par = pDelta.x() * qDelta.y() - pDelta.y() * qDelta.x(); - if (qFuzzyCompare(par + 1, 1)) { + if (qIsFuzzyNull(par)) { const QPointF normal(-pDelta.y(), pDelta.x()); // coinciding? - if (qFuzzyCompare(dot(normal, q1 - p1) + 1, 1)) { + if (qIsFuzzyNull(dot(normal, q1 - p1))) { const qreal invDp = 1 / dot(pDelta, pDelta); const qreal tq1 = dot(pDelta, q1 - p1) * invDp; @@ -315,11 +315,11 @@ void QIntersectionFinder::intersectLines(const QLineF &a, const QLineF &b, QData if (tp<0 || tp>1 || tq<0 || tq>1) return; - const bool p_zero = qFuzzyCompare(tp + 1, 1); - const bool p_one = qFuzzyCompare(tp, 1); + const bool p_zero = qIsFuzzyNull(tp); + const bool p_one = qIsFuzzyNull(tp - 1); - const bool q_zero = qFuzzyCompare(tq + 1, 1); - const bool q_one = qFuzzyCompare(tq, 1); + const bool q_zero = qIsFuzzyNull(tq); + const bool q_one = qIsFuzzyNull(tq - 1); if ((q_zero || q_one) && (p_zero || p_one)) return; @@ -922,7 +922,7 @@ qreal QWingedEdge::delta(int vertex, int a, int b) const qreal result = b_angle - a_angle; - if (qFuzzyCompare(result + 1, 1) || qFuzzyCompare(result, 128)) + if (qIsFuzzyNull(result) || qFuzzyCompare(result, 128)) return 0; if (result < 0) @@ -951,7 +951,7 @@ static inline QPointF tangentAt(const QWingedEdge &list, int vi, int ei) if (ep->bezier) { normal = ep->bezier->derivedAt(t); - if (qFuzzyCompare(normal.x() + 1, 1) && qFuzzyCompare(normal.y() + 1, 1)) + if (qIsFuzzyNull(normal.x()) && qIsFuzzyNull(normal.y())) normal = ep->bezier->secondDerivedAt(t); } else { const QPointF a = *list.vertex(ep->first); @@ -1080,7 +1080,7 @@ QWingedEdge::TraversalStatus QWingedEdge::findInsertStatus(int vi, int ei) const qDebug() << "Delta to edge" << status.edge << d2 << ", angles: " << op->angle << op->invAngle; #endif - if (!(qFuzzyCompare(d2 + 1, 1) && isLeftOf(*this, vi, status.edge, ei)) + if (!(qIsFuzzyNull(d2) && isLeftOf(*this, vi, status.edge, ei)) && (d2 < d || (qFuzzyCompare(d2, d) && isLeftOf(*this, vi, status.edge, position)))) { position = status.edge; d = d2; @@ -1232,10 +1232,10 @@ int QWingedEdge::addEdge(int fi, int si, const QBezier *bezier, qreal t0, qreal QPointF aTangent = bezier->derivedAt(t0); QPointF bTangent = -bezier->derivedAt(t1); - if (qFuzzyCompare(aTangent.x() + 1, 1) && qFuzzyCompare(aTangent.y() + 1, 1)) + if (qIsFuzzyNull(aTangent.x()) && qIsFuzzyNull(aTangent.y())) aTangent = bezier->secondDerivedAt(t0); - if (qFuzzyCompare(bTangent.x() + 1, 1) && qFuzzyCompare(bTangent.y() + 1, 1)) + if (qIsFuzzyNull(bTangent.x()) && qIsFuzzyNull(bTangent.y())) bTangent = bezier->secondDerivedAt(t1); ep->angle = computeAngle(aTangent); @@ -1400,7 +1400,7 @@ static void addLineTo(QPainterPath &path, const QPointF &point) const QPointF p(-d1.y(), d1.x()); - if (qFuzzyCompare(dot(p, d2) + 1, 1)) { + if (qIsFuzzyNull(dot(p, d2))) { path.setElementPositionAt(elementCount - 1, point.x(), point.y()); return; } diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp index b894c62..3a856d3 100644 --- a/src/gui/painting/qstroker.cpp +++ b/src/gui/painting/qstroker.cpp @@ -763,7 +763,7 @@ template bool qt_stroke_side(Iterator *it, qreal qt_t_for_arc_angle(qreal angle) { - if (qFuzzyCompare(angle + 1, qreal(1))) + if (qIsFuzzyNull(angle)) return 0; if (qFuzzyCompare(angle, qreal(90))) @@ -904,13 +904,13 @@ QPointF qt_curves_for_arc(const QRectF &rect, qreal startAngle, qreal sweepLengt } // avoid empty start segment - if (qFuzzyCompare(startT, qreal(1))) { + if (qIsFuzzyNull(startT - qreal(1))) { startT = 0; startSegment += delta; } // avoid empty end segment - if (qFuzzyCompare(endT + 1, qreal(1))) { + if (qIsFuzzyNull(endT)) { endT = 1; endSegment -= delta; } @@ -918,8 +918,8 @@ QPointF qt_curves_for_arc(const QRectF &rect, qreal startAngle, qreal sweepLengt startT = qt_t_for_arc_angle(startT * 90); endT = qt_t_for_arc_angle(endT * 90); - const bool splitAtStart = !qFuzzyCompare(startT + 1, qreal(1)); - const bool splitAtEnd = !qFuzzyCompare(endT, qreal(1)); + const bool splitAtStart = !qIsFuzzyNull(startT); + const bool splitAtEnd = !qIsFuzzyNull(endT - qreal(1)); const int end = endSegment + delta; @@ -1018,7 +1018,7 @@ void QDashStroker::processCurrentSubpath() sumLength += dashes[i]; } - if (qFuzzyCompare(sumLength + 1, qreal(1))) + if (qIsFuzzyNull(sumLength)) return; Q_ASSERT(dashCount > 0); diff --git a/src/gui/painting/qtessellator.cpp b/src/gui/painting/qtessellator.cpp index e02f02d..ae07565 100644 --- a/src/gui/painting/qtessellator.cpp +++ b/src/gui/painting/qtessellator.cpp @@ -1436,7 +1436,7 @@ void QTessellator::tessellateRect(const QPointF &a_, const QPointF &b_, qreal wi QPointF perp(pb.y() - pa.y(), pa.x() - pb.x()); qreal length = qSqrt(perp.x() * perp.x() + perp.y() * perp.y()); - if (qFuzzyCompare(length + 1, static_cast(1))) + if (qIsFuzzyNull(length)) return; // need the half of the width diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index 88fd379..11df590 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -1924,15 +1924,15 @@ static void drawTrapezoid(const QGLTrapezoid &trap, const qreal offscreenHeight, qreal leftB = trap.bottomLeftX + (trap.topLeftX - trap.bottomLeftX) * reciprocal; qreal rightB = trap.bottomRightX + (trap.topRightX - trap.bottomRightX) * reciprocal; - const bool topZero = qFuzzyCompare(topDist + 1, 1); + const bool topZero = qIsFuzzyNull(topDist); reciprocal = topZero ? 1.0 / bottomDist : 1.0 / topDist; qreal leftA = topZero ? (trap.bottomLeftX - leftB) * reciprocal : (trap.topLeftX - leftB) * reciprocal; qreal rightA = topZero ? (trap.bottomRightX - rightB) * reciprocal : (trap.topRightX - rightB) * reciprocal; - qreal invLeftA = qFuzzyCompare(leftA + 1, 1) ? 0.0 : 1.0 / leftA; - qreal invRightA = qFuzzyCompare(rightA + 1, 1) ? 0.0 : 1.0 / rightA; + qreal invLeftA = qIsFuzzyNull(leftA) ? 0.0 : 1.0 / leftA; + qreal invRightA = qIsFuzzyNull(rightA) ? 0.0 : 1.0 / rightA; // fragment program needs the negative of invRightA as it mirrors the line glTexCoord4f(topDist, bottomDist, invLeftA, -invRightA); @@ -3445,8 +3445,7 @@ QVector QGLRectMaskGenerator::generateTrapezoids() // manhattan distance (no rotation) qreal width = qAbs(delta.x()) + qAbs(delta.y()); - Q_ASSERT(qFuzzyCompare(delta.x() + 1, static_cast(1)) - || qFuzzyCompare(delta.y() + 1, static_cast(1))); + Q_ASSERT(qIsFuzzyNull(delta.x()) || qIsFuzzyNull(delta.y())); tessellator.tessellateRect(first, last, width); } else { diff --git a/src/svg/qgraphicssvgitem.cpp b/src/svg/qgraphicssvgitem.cpp index e17df03..5c8a3c0 100644 --- a/src/svg/qgraphicssvgitem.cpp +++ b/src/svg/qgraphicssvgitem.cpp @@ -186,7 +186,7 @@ static void qt_graphicsItem_highlightSelected( QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option) { const QRectF murect = painter->transform().mapRect(QRectF(0, 0, 1, 1)); - if (qFuzzyCompare(qMax(murect.width(), murect.height()) + 1, 1)) + if (qIsFuzzyNull(qMax(murect.width(), murect.height()))) return; const QRectF mbrect = painter->transform().mapRect(item->boundingRect()); diff --git a/src/svg/qsvggenerator.cpp b/src/svg/qsvggenerator.cpp index e822da5..7c8926d 100644 --- a/src/svg/qsvggenerator.cpp +++ b/src/svg/qsvggenerator.cpp @@ -971,7 +971,7 @@ void QSvgPaintEngine::updateState(const QPaintEngineState &state) } if (flags & QPaintEngine::DirtyOpacity) { - if (!qFuzzyCompare(state.opacity(), 1)) + if (!qIsFuzzyNull(state.opacity() - 1)) stream() << "opacity=\""< Date: Wed, 8 Apr 2009 10:07:10 +0200 Subject: Rename qIsFuzzyNull to qFuzzyIsNull The function was added in fde7f3d03782c801901f511131458d6fcb1021a5 and we believe qFuzzyIsNull is a better naming and more in line with qFuzzyCompare. Reviewed-by: Lars Knoll Reviewed-by: nrc Reviewed-by: Samuel --- src/corelib/global/qglobal.h | 4 ++-- src/corelib/tools/qsize.h | 8 +++---- src/gui/graphicsview/qgraphicsitem.cpp | 10 ++++----- src/gui/graphicsview/qgraphicsitem_p.h | 2 +- src/gui/graphicsview/qgraphicsscene.cpp | 4 ++-- src/gui/kernel/qwidget.cpp | 2 +- src/gui/math3d/qmatrix4x4.cpp | 2 +- src/gui/painting/qbezier.cpp | 24 ++++++++++----------- src/gui/painting/qcolor.cpp | 4 ++-- src/gui/painting/qmatrix.h | 6 +++--- src/gui/painting/qpaintengine_d3d.cpp | 6 +++--- src/gui/painting/qpaintengine_raster.cpp | 24 ++++++++++----------- src/gui/painting/qpainter.cpp | 24 ++++++++++----------- src/gui/painting/qpainterpath.cpp | 8 +++---- src/gui/painting/qpathclipper.cpp | 36 ++++++++++++++++---------------- src/gui/painting/qstroker.cpp | 12 +++++------ src/gui/painting/qtessellator.cpp | 2 +- src/gui/painting/qtransform.cpp | 16 +++++++------- src/gui/painting/qtransform.h | 2 +- src/opengl/qpaintengine_opengl.cpp | 8 +++---- src/svg/qgraphicssvgitem.cpp | 2 +- src/svg/qsvggenerator.cpp | 2 +- src/svg/qsvggraphics.cpp | 16 +++++++------- 23 files changed, 112 insertions(+), 112 deletions(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 28b9d08..5fd05c0 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1709,7 +1709,7 @@ static inline bool qFuzzyCompare(float p1, float p2) /*! \internal */ -static inline bool qIsFuzzyNull(double d) +static inline bool qFuzzyIsNull(double d) { return qAbs(d) <= 0.000000000001; } @@ -1717,7 +1717,7 @@ static inline bool qIsFuzzyNull(double d) /*! \internal */ -static inline bool qIsFuzzyNull(float f) +static inline bool qFuzzyIsNull(float f) { return qAbs(f) <= 0.00001f; } diff --git a/src/corelib/tools/qsize.h b/src/corelib/tools/qsize.h index df2c183..34a6c99 100644 --- a/src/corelib/tools/qsize.h +++ b/src/corelib/tools/qsize.h @@ -171,14 +171,14 @@ inline const QSize operator*(qreal c, const QSize &s) inline QSize &QSize::operator/=(qreal c) { - Q_ASSERT(!qIsFuzzyNull(c)); + Q_ASSERT(!qFuzzyIsNull(c)); wd = qRound(wd/c); ht = qRound(ht/c); return *this; } inline const QSize operator/(const QSize &s, qreal c) { - Q_ASSERT(!qIsFuzzyNull(c)); + Q_ASSERT(!qFuzzyIsNull(c)); return QSize(qRound(s.wd/c), qRound(s.ht/c)); } @@ -327,14 +327,14 @@ inline const QSizeF operator*(qreal c, const QSizeF &s) inline QSizeF &QSizeF::operator/=(qreal c) { - Q_ASSERT(!qIsFuzzyNull(c)); + Q_ASSERT(!qFuzzyIsNull(c)); wd = wd/c; ht = ht/c; return *this; } inline const QSizeF operator/(const QSizeF &s, qreal c) { - Q_ASSERT(!qIsFuzzyNull(c)); + Q_ASSERT(!qFuzzyIsNull(c)); return QSizeF(s.wd/c, s.ht/c); } diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 0d846d9..e7f9bd3 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1906,11 +1906,11 @@ void QGraphicsItem::setOpacity(qreal opacity) newOpacity = qBound(0.0, newOpacity, 1.0); // No change? Done. - if (qIsFuzzyNull(newOpacity - this->opacity())) + if (qFuzzyIsNull(newOpacity - this->opacity())) return; // Assign local opacity. - if (qIsFuzzyNull(newOpacity - 1)) { + if (qFuzzyIsNull(newOpacity - 1)) { // Opaque, unset opacity. d_ptr->hasOpacity = 0; d_ptr->unsetExtra(QGraphicsItemPrivate::ExtraOpacity); @@ -3771,7 +3771,7 @@ void QGraphicsItemPrivate::resolveEffectiveOpacity(qreal parentEffectiveOpacity) } // Set this item's resolved opacity. - if (qIsFuzzyNull(myEffectiveOpacity - 1)) { + if (qFuzzyIsNull(myEffectiveOpacity - 1)) { // Opaque, unset effective opacity. hasEffectiveOpacity = 0; unsetExtra(ExtraEffectiveOpacity); @@ -4091,7 +4091,7 @@ void QGraphicsItem::scroll(qreal dx, qreal dy, const QRectF &rect) return; if (d->cacheMode != NoCache) { QGraphicsItemCache *c; - bool scrollCache = qIsFuzzyNull(dx - int(dx)) && qIsFuzzyNull(dy - int(dy)) + bool scrollCache = qFuzzyIsNull(dx - int(dx)) && qFuzzyIsNull(dy - int(dy)) && (c = (QGraphicsItemCache *)qVariantValue(d_ptr->extra(QGraphicsItemPrivate::ExtraCacheData))) && (d->cacheMode == ItemCoordinateCache && !c->fixedSize.isValid()); if (scrollCache) { @@ -5854,7 +5854,7 @@ static void qt_graphicsItem_highlightSelected( QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option) { const QRectF murect = painter->transform().mapRect(QRectF(0, 0, 1, 1)); - if (qIsFuzzyNull(qMax(murect.width(), murect.height()))) + if (qFuzzyIsNull(qMax(murect.width(), murect.height()))) return; const QRectF mbrect = painter->transform().mapRect(item->boundingRect()); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 77db691..078c543 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -269,7 +269,7 @@ public: void updateCachedClipPathFromSetPosHelper(const QPointF &newPos); inline bool isFullyTransparent() const - { return hasEffectiveOpacity && qIsFuzzyNull(q_func()->effectiveOpacity()); } + { return hasEffectiveOpacity && qFuzzyIsNull(q_func()->effectiveOpacity()); } inline bool childrenCombineOpacity() const { return allChildrenCombineOpacity || children.isEmpty(); } diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index e885238..bd66c3d 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4642,7 +4642,7 @@ static void _q_paintItem(QGraphicsItem *item, QPainter *painter, ? proxy->widget()->windowOpacity() : 1.0; const qreal oldPainterOpacity = painter->opacity(); - if (qIsFuzzyNull(windowOpacity)) + if (qFuzzyIsNull(windowOpacity)) return; // Set new painter opacity. if (windowOpacity < 1.0) @@ -5282,7 +5282,7 @@ void QGraphicsScene::itemUpdated(QGraphicsItem *item, const QRectF &rect) // Deliver the actual update. if (!d->updateAll) { if (d->views.isEmpty() || ((d->connectedSignals & d->changedSignalMask) && !item->d_ptr->itemIsUntransformable() - && qIsFuzzyNull(item->boundingRegionGranularity()))) { + && qFuzzyIsNull(item->boundingRegionGranularity()))) { // This block of code is kept for compatibility. Since 4.5, by default // QGraphicsView does not connect the signal and we use the below // method of delivering updates. diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 623ba59..3e25ffc 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -4780,7 +4780,7 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset, } const qreal opacity = painter->opacity(); - if (qIsFuzzyNull(opacity)) + if (qFuzzyIsNull(opacity)) return; // Fully transparent. Q_D(QWidget); diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp index 1457400..e00d772 100644 --- a/src/gui/math3d/qmatrix4x4.cpp +++ b/src/gui/math3d/qmatrix4x4.cpp @@ -1514,7 +1514,7 @@ void QMatrix4x4::extractAxisRotation(qreal &angle, QVector3D &axis) const angle = acos(cosa) * 180.0f / M_PI; // Any axis will work if r is zero (means no rotation) - if (qIsFuzzyNull(angle)) { + if (qFuzzyIsNull(angle)) { axis.setX(1.0f); axis.setY(0.0f); axis.setZ(0.0f); diff --git a/src/gui/painting/qbezier.cpp b/src/gui/painting/qbezier.cpp index 1168b5a..7ed521e 100644 --- a/src/gui/painting/qbezier.cpp +++ b/src/gui/painting/qbezier.cpp @@ -127,13 +127,13 @@ static inline void flattenBezierWithoutInflections(QBezier &bez, qreal dy = bez.y2 - bez.y1; qreal normalized = qSqrt(dx * dx + dy * dy); - if (qIsFuzzyNull(normalized)) + if (qFuzzyIsNull(normalized)) break; qreal d = qAbs(dx * (bez.y3 - bez.y2) - dy * (bez.x3 - bez.x2)); qreal t = qSqrt(4. / 3. * normalized * flatness / d); - if (t > 1 || qIsFuzzyNull(t - (qreal)1.)) + if (t > 1 || qFuzzyIsNull(t - (qreal)1.)) break; bez.parameterSplitLeft(t, &left); p->append(bez.pt1()); @@ -144,19 +144,19 @@ static inline void flattenBezierWithoutInflections(QBezier &bez, static inline int quadraticRoots(qreal a, qreal b, qreal c, qreal *x1, qreal *x2) { - if (qIsFuzzyNull(a)) { - if (qIsFuzzyNull(b)) + if (qFuzzyIsNull(a)) { + if (qFuzzyIsNull(b)) return 0; *x1 = *x2 = (-c / b); return 1; } else { const qreal det = b * b - 4 * a * c; - if (qIsFuzzyNull(det)) { + if (qFuzzyIsNull(det)) { *x1 = *x2 = -b / (2 * a); return 1; } if (det > 0) { - if (qIsFuzzyNull(b)) { + if (qFuzzyIsNull(b)) { *x2 = qSqrt(-c / a); *x1 = -(*x2); return 2; @@ -187,7 +187,7 @@ static inline bool findInflections(qreal a, qreal b, qreal c, *t1 = r2; *t2 = r1; } - if (!qIsFuzzyNull(a)) + if (!qFuzzyIsNull(a)) *tCups = 0.5 * (-b / a); else *tCups = 2; @@ -243,7 +243,7 @@ void QBezier::addToPolygonMixed(QPolygonF *polygon) const qreal b = 6 * (ay * cx - ax * cy); qreal c = 2 * (by * cx - bx * cy); - if ((qIsFuzzyNull(a) && qIsFuzzyNull(b)) || + if ((qFuzzyIsNull(a) && qFuzzyIsNull(b)) || (b * b - 4 * a *c) < 0) { QBezier bez(*this); flattenBezierWithoutInflections(bez, polygon); @@ -447,7 +447,7 @@ static ShiftResult shift(const QBezier *orig, QBezier *shifted, qreal offset, qr qreal r = 1.0 + prev_normal.x() * next_normal.x() + prev_normal.y() * next_normal.y(); - if (qIsFuzzyNull(r)) { + if (qFuzzyIsNull(r)) { points_shifted[i] = points[i] + offset * prev_normal; } else { qreal k = offset / r; @@ -477,12 +477,12 @@ static bool addCircle(const QBezier *b, qreal offset, QBezier *o) normals[0] = QPointF(b->y2 - b->y1, b->x1 - b->x2); qreal dist = qSqrt(normals[0].x()*normals[0].x() + normals[0].y()*normals[0].y()); - if (qIsFuzzyNull(dist)) + if (qFuzzyIsNull(dist)) return false; normals[0] /= dist; normals[2] = QPointF(b->y4 - b->y3, b->x3 - b->x4); dist = qSqrt(normals[2].x()*normals[2].x() + normals[2].y()*normals[2].y()); - if (qIsFuzzyNull(dist)) + if (qFuzzyIsNull(dist)) return false; normals[2] /= dist; @@ -1022,7 +1022,7 @@ int QBezier::stationaryYPoints(qreal &t0, qreal &t1) const QList result; - if (qIsFuzzyNull(reciprocal)) { + if (qFuzzyIsNull(reciprocal)) { t0 = -b / (2 * a); return 1; } else if (reciprocal > 0) { diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index 6eecea0..24d167e 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -1387,7 +1387,7 @@ QColor QColor::toHsv() const const qreal min = Q_MIN_3(r, g, b); const qreal delta = max - min; color.ct.ahsv.value = qRound(max * USHRT_MAX); - if (qIsFuzzyNull(delta)) { + if (qFuzzyIsNull(delta)) { // achromatic case, hue is undefined color.ct.ahsv.hue = USHRT_MAX; color.ct.ahsv.saturation = 0; @@ -1441,7 +1441,7 @@ QColor QColor::toCmyk() const // cmy -> cmyk const qreal k = qMin(c, qMin(m, y)); - if (!qIsFuzzyNull(k - 1)) { + if (!qFuzzyIsNull(k - 1)) { c = (c - k) / (1.0 - k); m = (m - k) / (1.0 - k); y = (y - k) / (1.0 - k); diff --git a/src/gui/painting/qmatrix.h b/src/gui/painting/qmatrix.h index 71c1e34..1e5fbb4 100644 --- a/src/gui/painting/qmatrix.h +++ b/src/gui/painting/qmatrix.h @@ -99,7 +99,7 @@ public: QMatrix &shear(qreal sh, qreal sv); QMatrix &rotate(qreal a); - bool isInvertible() const { return !qIsFuzzyNull(_m11*_m22 - _m12*_m21); } + bool isInvertible() const { return !qFuzzyIsNull(_m11*_m22 - _m12*_m21); } qreal det() const { return _m11*_m22 - _m12*_m21; } QMatrix inverted(bool *invertible = 0) const; @@ -161,8 +161,8 @@ Q_GUI_EXPORT QPainterPath operator *(const QPainterPath &p, const QMatrix &m); inline bool QMatrix::isIdentity() const { - return qIsFuzzyNull(_m11 - 1) && qIsFuzzyNull(_m22 - 1) && qIsFuzzyNull(_m12) - && qIsFuzzyNull(_m21) && qIsFuzzyNull(_dx) && qIsFuzzyNull(_dy); + return qFuzzyIsNull(_m11 - 1) && qFuzzyIsNull(_m22 - 1) && qFuzzyIsNull(_m12) + && qFuzzyIsNull(_m21) && qFuzzyIsNull(_dx) && qFuzzyIsNull(_dy); } /***************************************************************************** diff --git a/src/gui/painting/qpaintengine_d3d.cpp b/src/gui/painting/qpaintengine_d3d.cpp index 4b494d1..9a7638b 100644 --- a/src/gui/painting/qpaintengine_d3d.cpp +++ b/src/gui/painting/qpaintengine_d3d.cpp @@ -2506,8 +2506,8 @@ void QD3DDrawHelper::addTrap(const Trapezoid &trap) qreal _rightA = (qreal)_w/_h; qreal _rightB = topRightX - _rightA * topRightY; - qreal invLeftA = qIsFuzzyNull(_leftA) ? 0.0 : 1.0 / _leftA; - qreal invRightA = qIsFuzzyNull(_rightA) ? 0.0 : 1.0 / _rightA; + qreal invLeftA = qFuzzyIsNull(_leftA) ? 0.0 : 1.0 / _leftA; + qreal invRightA = qFuzzyIsNull(_rightA) ? 0.0 : 1.0 / _rightA; vertex v1 = { {1.f, top - 1.f, 0.5f}, 0.f, top, bottom, invLeftA, -invRightA, @@ -2970,7 +2970,7 @@ qreal calculateAngle(qreal dx, qreal dy) { qreal angle; - if (qIsFuzzyNull(dx)) { + if (qFuzzyIsNull(dx)) { angle = (dy < 0) ? -M_PI/2 : M_PI/2; } else { angle = atanf(dy/dx); diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 7aab25c..92160f9 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -618,22 +618,22 @@ void QRasterPaintEngine::updateMatrix(const QTransform &matrix) d->isPlain45DegreeRotation = false; if (txop >= QTransform::TxRotate) { d->isPlain45DegreeRotation = - (qIsFuzzyNull(matrix.m11()) - && qIsFuzzyNull(matrix.m12() - qreal(1)) - && qIsFuzzyNull(matrix.m21() + qreal(1)) - && qIsFuzzyNull(matrix.m22()) + (qFuzzyIsNull(matrix.m11()) + && qFuzzyIsNull(matrix.m12() - qreal(1)) + && qFuzzyIsNull(matrix.m21() + qreal(1)) + && qFuzzyIsNull(matrix.m22()) ) || - (qIsFuzzyNull(matrix.m11() + qreal(1)) - && qIsFuzzyNull(matrix.m12()) - && qIsFuzzyNull(matrix.m21()) - && qIsFuzzyNull(matrix.m22() + qreal(1)) + (qFuzzyIsNull(matrix.m11() + qreal(1)) + && qFuzzyIsNull(matrix.m12()) + && qFuzzyIsNull(matrix.m21()) + && qFuzzyIsNull(matrix.m22() + qreal(1)) ) || - (qIsFuzzyNull(matrix.m11()) - && qIsFuzzyNull(matrix.m12() + qreal(1)) - && qIsFuzzyNull(matrix.m21() - qreal(1)) - && qIsFuzzyNull(matrix.m22()) + (qFuzzyIsNull(matrix.m11()) + && qFuzzyIsNull(matrix.m12() + qreal(1)) + && qFuzzyIsNull(matrix.m21() - qreal(1)) + && qFuzzyIsNull(matrix.m22()) ) ; } diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index d4271ae..133520e 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -6055,22 +6055,22 @@ void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti) const QTransform &m = d->state->matrix; if (d->state->matrix.type() < QTransform::TxShear) { bool isPlain90DegreeRotation = - (qIsFuzzyNull(m.m11()) - && qIsFuzzyNull(m.m12() - qreal(1)) - && qIsFuzzyNull(m.m21() + qreal(1)) - && qIsFuzzyNull(m.m22()) + (qFuzzyIsNull(m.m11()) + && qFuzzyIsNull(m.m12() - qreal(1)) + && qFuzzyIsNull(m.m21() + qreal(1)) + && qFuzzyIsNull(m.m22()) ) || - (qIsFuzzyNull(m.m11() + qreal(1)) - && qIsFuzzyNull(m.m12()) - && qIsFuzzyNull(m.m21()) - && qIsFuzzyNull(m.m22() + qreal(1)) + (qFuzzyIsNull(m.m11() + qreal(1)) + && qFuzzyIsNull(m.m12()) + && qFuzzyIsNull(m.m21()) + && qFuzzyIsNull(m.m22() + qreal(1)) ) || - (qIsFuzzyNull(m.m11()) - && qIsFuzzyNull(m.m12() + qreal(1)) - && qIsFuzzyNull(m.m21() - qreal(1)) - && qIsFuzzyNull(m.m22()) + (qFuzzyIsNull(m.m11()) + && qFuzzyIsNull(m.m12() + qreal(1)) + && qFuzzyIsNull(m.m21() - qreal(1)) + && qFuzzyIsNull(m.m22()) ) ; aa = !isPlain90DegreeRotation; diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp index de8969c..d471aaa 100644 --- a/src/gui/painting/qpainterpath.cpp +++ b/src/gui/painting/qpainterpath.cpp @@ -1299,10 +1299,10 @@ static QRectF qt_painterpath_bezier_extrema(const QBezier &b) qreal bx = QT_BEZIER_B(b, x); qreal cx = QT_BEZIER_C(b, x); // specialcase quadratic curves to avoid div by zero - if (qIsFuzzyNull(ax)) { + if (qFuzzyIsNull(ax)) { // linear curves are covered by initialization. - if (!qIsFuzzyNull(bx)) { + if (!qFuzzyIsNull(bx)) { qreal t = -cx / bx; QT_BEZIER_CHECK_T(b, t); } @@ -1329,10 +1329,10 @@ static QRectF qt_painterpath_bezier_extrema(const QBezier &b) qreal cy = QT_BEZIER_C(b, y); // specialcase quadratic curves to avoid div by zero - if (qIsFuzzyNull(ay)) { + if (qFuzzyIsNull(ay)) { // linear curves are covered by initialization. - if (!qIsFuzzyNull(by)) { + if (!qFuzzyIsNull(by)) { qreal t = -cy / by; QT_BEZIER_CHECK_T(b, t); } diff --git a/src/gui/painting/qpathclipper.cpp b/src/gui/painting/qpathclipper.cpp index 33609ad..9ef3eb7 100644 --- a/src/gui/painting/qpathclipper.cpp +++ b/src/gui/painting/qpathclipper.cpp @@ -138,11 +138,11 @@ bool QIntersectionFinder::linesIntersect(const QLineF &a, const QLineF &b) const const qreal par = pDelta.x() * qDelta.y() - pDelta.y() * qDelta.x(); - if (qIsFuzzyNull(par)) { + if (qFuzzyIsNull(par)) { const QPointF normal(-pDelta.y(), pDelta.x()); // coinciding? - if (qIsFuzzyNull(dot(normal, q1 - p1))) { + if (qFuzzyIsNull(dot(normal, q1 - p1))) { const qreal dp = dot(pDelta, pDelta); const qreal tq1 = dot(pDelta, q1 - p1); @@ -202,13 +202,13 @@ void QIntersectionFinder::intersectBeziers(const QBezier &one, const QBezier &tw qreal alpha_q = t.at(i).second; QPointF pt; - if (qIsFuzzyNull(alpha_p)) { + if (qFuzzyIsNull(alpha_p)) { pt = one.pt1(); - } else if (qIsFuzzyNull(alpha_p - 1)) { + } else if (qFuzzyIsNull(alpha_p - 1)) { pt = one.pt4(); - } else if (qIsFuzzyNull(alpha_q)) { + } else if (qFuzzyIsNull(alpha_q)) { pt = two.pt1(); - } else if (qIsFuzzyNull(alpha_q - 1)) { + } else if (qFuzzyIsNull(alpha_q - 1)) { pt = two.pt4(); } else { pt = one.pointAt(alpha_p); @@ -250,11 +250,11 @@ void QIntersectionFinder::intersectLines(const QLineF &a, const QLineF &b, QData const qreal par = pDelta.x() * qDelta.y() - pDelta.y() * qDelta.x(); - if (qIsFuzzyNull(par)) { + if (qFuzzyIsNull(par)) { const QPointF normal(-pDelta.y(), pDelta.x()); // coinciding? - if (qIsFuzzyNull(dot(normal, q1 - p1))) { + if (qFuzzyIsNull(dot(normal, q1 - p1))) { const qreal invDp = 1 / dot(pDelta, pDelta); const qreal tq1 = dot(pDelta, q1 - p1) * invDp; @@ -315,11 +315,11 @@ void QIntersectionFinder::intersectLines(const QLineF &a, const QLineF &b, QData if (tp<0 || tp>1 || tq<0 || tq>1) return; - const bool p_zero = qIsFuzzyNull(tp); - const bool p_one = qIsFuzzyNull(tp - 1); + const bool p_zero = qFuzzyIsNull(tp); + const bool p_one = qFuzzyIsNull(tp - 1); - const bool q_zero = qIsFuzzyNull(tq); - const bool q_one = qIsFuzzyNull(tq - 1); + const bool q_zero = qFuzzyIsNull(tq); + const bool q_one = qFuzzyIsNull(tq - 1); if ((q_zero || q_one) && (p_zero || p_one)) return; @@ -922,7 +922,7 @@ qreal QWingedEdge::delta(int vertex, int a, int b) const qreal result = b_angle - a_angle; - if (qIsFuzzyNull(result) || qFuzzyCompare(result, 128)) + if (qFuzzyIsNull(result) || qFuzzyCompare(result, 128)) return 0; if (result < 0) @@ -951,7 +951,7 @@ static inline QPointF tangentAt(const QWingedEdge &list, int vi, int ei) if (ep->bezier) { normal = ep->bezier->derivedAt(t); - if (qIsFuzzyNull(normal.x()) && qIsFuzzyNull(normal.y())) + if (qFuzzyIsNull(normal.x()) && qFuzzyIsNull(normal.y())) normal = ep->bezier->secondDerivedAt(t); } else { const QPointF a = *list.vertex(ep->first); @@ -1080,7 +1080,7 @@ QWingedEdge::TraversalStatus QWingedEdge::findInsertStatus(int vi, int ei) const qDebug() << "Delta to edge" << status.edge << d2 << ", angles: " << op->angle << op->invAngle; #endif - if (!(qIsFuzzyNull(d2) && isLeftOf(*this, vi, status.edge, ei)) + if (!(qFuzzyIsNull(d2) && isLeftOf(*this, vi, status.edge, ei)) && (d2 < d || (qFuzzyCompare(d2, d) && isLeftOf(*this, vi, status.edge, position)))) { position = status.edge; d = d2; @@ -1232,10 +1232,10 @@ int QWingedEdge::addEdge(int fi, int si, const QBezier *bezier, qreal t0, qreal QPointF aTangent = bezier->derivedAt(t0); QPointF bTangent = -bezier->derivedAt(t1); - if (qIsFuzzyNull(aTangent.x()) && qIsFuzzyNull(aTangent.y())) + if (qFuzzyIsNull(aTangent.x()) && qFuzzyIsNull(aTangent.y())) aTangent = bezier->secondDerivedAt(t0); - if (qIsFuzzyNull(bTangent.x()) && qIsFuzzyNull(bTangent.y())) + if (qFuzzyIsNull(bTangent.x()) && qFuzzyIsNull(bTangent.y())) bTangent = bezier->secondDerivedAt(t1); ep->angle = computeAngle(aTangent); @@ -1400,7 +1400,7 @@ static void addLineTo(QPainterPath &path, const QPointF &point) const QPointF p(-d1.y(), d1.x()); - if (qIsFuzzyNull(dot(p, d2))) { + if (qFuzzyIsNull(dot(p, d2))) { path.setElementPositionAt(elementCount - 1, point.x(), point.y()); return; } diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp index 3a856d3..5fffc72 100644 --- a/src/gui/painting/qstroker.cpp +++ b/src/gui/painting/qstroker.cpp @@ -763,7 +763,7 @@ template bool qt_stroke_side(Iterator *it, qreal qt_t_for_arc_angle(qreal angle) { - if (qIsFuzzyNull(angle)) + if (qFuzzyIsNull(angle)) return 0; if (qFuzzyCompare(angle, qreal(90))) @@ -904,13 +904,13 @@ QPointF qt_curves_for_arc(const QRectF &rect, qreal startAngle, qreal sweepLengt } // avoid empty start segment - if (qIsFuzzyNull(startT - qreal(1))) { + if (qFuzzyIsNull(startT - qreal(1))) { startT = 0; startSegment += delta; } // avoid empty end segment - if (qIsFuzzyNull(endT)) { + if (qFuzzyIsNull(endT)) { endT = 1; endSegment -= delta; } @@ -918,8 +918,8 @@ QPointF qt_curves_for_arc(const QRectF &rect, qreal startAngle, qreal sweepLengt startT = qt_t_for_arc_angle(startT * 90); endT = qt_t_for_arc_angle(endT * 90); - const bool splitAtStart = !qIsFuzzyNull(startT); - const bool splitAtEnd = !qIsFuzzyNull(endT - qreal(1)); + const bool splitAtStart = !qFuzzyIsNull(startT); + const bool splitAtEnd = !qFuzzyIsNull(endT - qreal(1)); const int end = endSegment + delta; @@ -1018,7 +1018,7 @@ void QDashStroker::processCurrentSubpath() sumLength += dashes[i]; } - if (qIsFuzzyNull(sumLength)) + if (qFuzzyIsNull(sumLength)) return; Q_ASSERT(dashCount > 0); diff --git a/src/gui/painting/qtessellator.cpp b/src/gui/painting/qtessellator.cpp index ae07565..ce5ab74 100644 --- a/src/gui/painting/qtessellator.cpp +++ b/src/gui/painting/qtessellator.cpp @@ -1436,7 +1436,7 @@ void QTessellator::tessellateRect(const QPointF &a_, const QPointF &b_, qreal wi QPointF perp(pb.y() - pa.y(), pa.x() - pb.x()); qreal length = qSqrt(perp.x() * perp.x() + perp.y() * perp.y()); - if (qIsFuzzyNull(length)) + if (qFuzzyIsNull(length)) return; // need the half of the width diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp index 6c37ab6..dfcca63 100644 --- a/src/gui/painting/qtransform.cpp +++ b/src/gui/painting/qtransform.cpp @@ -353,8 +353,8 @@ QTransform QTransform::inverted(bool *invertible) const invert.affine._dy = -affine._dy; break; case TxScale: - inv = !qIsFuzzyNull(affine._m11); - inv &= !qIsFuzzyNull(affine._m22); + inv = !qFuzzyIsNull(affine._m11); + inv &= !qFuzzyIsNull(affine._m22); if (inv) { invert.affine._m11 = 1. / affine._m11; invert.affine._m22 = 1. / affine._m22; @@ -369,7 +369,7 @@ QTransform QTransform::inverted(bool *invertible) const default: // general case qreal det = determinant(); - inv = !qIsFuzzyNull(det); + inv = !qFuzzyIsNull(det); if (inv) invert = adjoint() / det; break; @@ -1958,27 +1958,27 @@ QTransform::TransformationType QTransform::type() const switch (static_cast(m_dirty)) { case TxProject: - if (!qIsFuzzyNull(m_13) || !qIsFuzzyNull(m_23) || !qIsFuzzyNull(m_33 - 1)) { + if (!qFuzzyIsNull(m_13) || !qFuzzyIsNull(m_23) || !qFuzzyIsNull(m_33 - 1)) { m_type = TxProject; break; } case TxShear: case TxRotate: - if (!qIsFuzzyNull(affine._m12) || !qIsFuzzyNull(affine._m21)) { + if (!qFuzzyIsNull(affine._m12) || !qFuzzyIsNull(affine._m21)) { const qreal dot = affine._m11 * affine._m12 + affine._m21 * affine._m22; - if (qIsFuzzyNull(dot)) + if (qFuzzyIsNull(dot)) m_type = TxRotate; else m_type = TxShear; break; } case TxScale: - if (!qIsFuzzyNull(affine._m11 - 1) || !qIsFuzzyNull(affine._m22 - 1)) { + if (!qFuzzyIsNull(affine._m11 - 1) || !qFuzzyIsNull(affine._m22 - 1)) { m_type = TxScale; break; } case TxTranslate: - if (!qIsFuzzyNull(affine._dx) || !qIsFuzzyNull(affine._dy)) { + if (!qFuzzyIsNull(affine._dx) || !qFuzzyIsNull(affine._dy)) { m_type = TxTranslate; break; } diff --git a/src/gui/painting/qtransform.h b/src/gui/painting/qtransform.h index 2d6c889..aac7c31 100644 --- a/src/gui/painting/qtransform.h +++ b/src/gui/painting/qtransform.h @@ -204,7 +204,7 @@ inline bool QTransform::isIdentity() const inline bool QTransform::isInvertible() const { - return !qIsFuzzyNull(determinant()); + return !qFuzzyIsNull(determinant()); } inline bool QTransform::isScaling() const diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index 11df590..4afc621 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -1924,15 +1924,15 @@ static void drawTrapezoid(const QGLTrapezoid &trap, const qreal offscreenHeight, qreal leftB = trap.bottomLeftX + (trap.topLeftX - trap.bottomLeftX) * reciprocal; qreal rightB = trap.bottomRightX + (trap.topRightX - trap.bottomRightX) * reciprocal; - const bool topZero = qIsFuzzyNull(topDist); + const bool topZero = qFuzzyIsNull(topDist); reciprocal = topZero ? 1.0 / bottomDist : 1.0 / topDist; qreal leftA = topZero ? (trap.bottomLeftX - leftB) * reciprocal : (trap.topLeftX - leftB) * reciprocal; qreal rightA = topZero ? (trap.bottomRightX - rightB) * reciprocal : (trap.topRightX - rightB) * reciprocal; - qreal invLeftA = qIsFuzzyNull(leftA) ? 0.0 : 1.0 / leftA; - qreal invRightA = qIsFuzzyNull(rightA) ? 0.0 : 1.0 / rightA; + qreal invLeftA = qFuzzyIsNull(leftA) ? 0.0 : 1.0 / leftA; + qreal invRightA = qFuzzyIsNull(rightA) ? 0.0 : 1.0 / rightA; // fragment program needs the negative of invRightA as it mirrors the line glTexCoord4f(topDist, bottomDist, invLeftA, -invRightA); @@ -3445,7 +3445,7 @@ QVector QGLRectMaskGenerator::generateTrapezoids() // manhattan distance (no rotation) qreal width = qAbs(delta.x()) + qAbs(delta.y()); - Q_ASSERT(qIsFuzzyNull(delta.x()) || qIsFuzzyNull(delta.y())); + Q_ASSERT(qFuzzyIsNull(delta.x()) || qFuzzyIsNull(delta.y())); tessellator.tessellateRect(first, last, width); } else { diff --git a/src/svg/qgraphicssvgitem.cpp b/src/svg/qgraphicssvgitem.cpp index 5c8a3c0..a14636e 100644 --- a/src/svg/qgraphicssvgitem.cpp +++ b/src/svg/qgraphicssvgitem.cpp @@ -186,7 +186,7 @@ static void qt_graphicsItem_highlightSelected( QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option) { const QRectF murect = painter->transform().mapRect(QRectF(0, 0, 1, 1)); - if (qIsFuzzyNull(qMax(murect.width(), murect.height()))) + if (qFuzzyIsNull(qMax(murect.width(), murect.height()))) return; const QRectF mbrect = painter->transform().mapRect(item->boundingRect()); diff --git a/src/svg/qsvggenerator.cpp b/src/svg/qsvggenerator.cpp index 7c8926d..2b5fbd5 100644 --- a/src/svg/qsvggenerator.cpp +++ b/src/svg/qsvggenerator.cpp @@ -971,7 +971,7 @@ void QSvgPaintEngine::updateState(const QPaintEngineState &state) } if (flags & QPaintEngine::DirtyOpacity) { - if (!qIsFuzzyNull(state.opacity() - 1)) + if (!qFuzzyIsNull(state.opacity() - 1)) stream() << "opacity=\""< Date: Wed, 8 Apr 2009 10:30:50 +0200 Subject: Autotest: Cisco changed their DNS setup; update our test. Reviewed-by: TrustMe --- tests/auto/qhostinfo/tst_qhostinfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qhostinfo/tst_qhostinfo.cpp b/tests/auto/qhostinfo/tst_qhostinfo.cpp index 3a7698b..0c5bc59 100644 --- a/tests/auto/qhostinfo/tst_qhostinfo.cpp +++ b/tests/auto/qhostinfo/tst_qhostinfo.cpp @@ -305,7 +305,7 @@ void tst_QHostInfo::reverseLookup_data() // ### Use internal DNS instead. Discussed with Andreas. //QTest::newRow("classical.hexago.com") << QString("2001:5c0:0:2::24") << QStringList(QString("classical.hexago.com")) << 0; - QTest::newRow("www.cisco.com") << QString("198.133.219.25") << QStringList(QString("www.cisco.com")) << 0; + QTest::newRow("www.cisco.com") << QString("198.133.219.25") << QStringList(QString("origin-www.cisco.com")) << 0; QTest::newRow("bogusexample.doenstexist.org") << QString("1::2::3::4") << QStringList() << 1; } -- cgit v0.12 From 3f3d09cf1511dde99797671a7bc848cdabc8d7fa Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Wed, 8 Apr 2009 10:25:06 +0200 Subject: Revert "Bt: Fix regression in the Embedded dialogs example" This reverts commit 35c26d696cbff269d551c012a212c09692dd6f6b. The change to QComboBox introduces a behavior change; whereas before the view container would always get its palette set as a response to QEvent::PaletteChange, it would now miss this event and rely on regular palette propagation to get the right contens. The difference in behavior is that QWidget::setPalette() also resolves the palette mask, and after 35c26d69 this would no longer happen. The bug in the embedded dialogs demo is caused by the embedded dialogs demo. See upcoming commit. Reviewed-by: Alexis Reviewed-by: Jens Bache-Wiig --- demos/embeddeddialogs/customproxy.cpp | 11 ++--------- src/gui/widgets/qcombobox.cpp | 24 +++++++++++------------- 2 files changed, 13 insertions(+), 22 deletions(-) diff --git a/demos/embeddeddialogs/customproxy.cpp b/demos/embeddeddialogs/customproxy.cpp index ed2fc76..56a0548 100644 --- a/demos/embeddeddialogs/customproxy.cpp +++ b/demos/embeddeddialogs/customproxy.cpp @@ -111,15 +111,8 @@ bool CustomProxy::sceneEventFilter(QGraphicsItem *watched, QEvent *event) QVariant CustomProxy::itemChange(GraphicsItemChange change, const QVariant &value) { - if (change == ItemChildAddedChange || change == ItemChildRemovedChange) { - QGraphicsItem *item = qVariantValue(value); - if (change == ItemChildAddedChange) { - item->setCacheMode(ItemCoordinateCache); - item->installSceneEventFilter(this); - } else { - item->removeSceneEventFilter(this); - } - } + if (change == ItemChildRemovedChange) + removeSceneEventFilter(this); return QGraphicsProxyWidget::itemChange(change, value); } diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp index b9dbc62..09a51fe 100644 --- a/src/gui/widgets/qcombobox.cpp +++ b/src/gui/widgets/qcombobox.cpp @@ -2572,21 +2572,19 @@ void QComboBox::changeEvent(QEvent *e) hidePopup(); break; case QEvent::PaletteChange: { - if (d->container) { - QStyleOptionComboBox opt; - initStyleOption(&opt); + QStyleOptionComboBox opt; + initStyleOption(&opt); #ifndef QT_NO_MENU - if (style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, this)) { - QMenu menu; - menu.ensurePolished(); - d->viewContainer()->setPalette(menu.palette()); - d->viewContainer()->setWindowOpacity(menu.windowOpacity()); - } else + if (style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, this)) { + QMenu menu; + menu.ensurePolished(); + d->viewContainer()->setPalette(menu.palette()); + d->viewContainer()->setWindowOpacity(menu.windowOpacity()); + } else #endif - { - d->viewContainer()->setPalette(palette()); - d->viewContainer()->setWindowOpacity(1.0); - } + { + d->viewContainer()->setPalette(palette()); + d->viewContainer()->setWindowOpacity(1.0); } break; } -- cgit v0.12 From 510ce6fa8a3a30063744eaaf004850679610060e Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Wed, 8 Apr 2009 10:27:28 +0200 Subject: BT: Fix the embedded dialogs demo on Mac OS X and Motif style The CustomProxy class installs an event filter on its child to detect whether it is shadowed by a popup or not. The problem is it does this regardless of whether it currently has a scene assigned or not. Styles that assign palettes, or otherwise cause side effects when assigned to a QGraphicsProxyWidget, will cause the demo to print warnings to the console and fail to install the event filter. The reason for the failure to install the filter is that QGraphicsItem only allows scene event filters to be installed between items that are in the same scene. So, depending on the style, you either get an ItemSceneHasChanged or an ItemChildAddedChange first. The demo must account for this, and install its filter only when the items are guaranteed to be in the scene already. Reviewed-by: Alexis --- demos/embeddeddialogs/customproxy.cpp | 17 ++++++++++++++--- demos/embeddeddialogs/customproxy.h | 1 + 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/demos/embeddeddialogs/customproxy.cpp b/demos/embeddeddialogs/customproxy.cpp index 56a0548..dd8766f 100644 --- a/demos/embeddeddialogs/customproxy.cpp +++ b/demos/embeddeddialogs/customproxy.cpp @@ -44,7 +44,7 @@ #include CustomProxy::CustomProxy(QGraphicsItem *parent, Qt::WindowFlags wFlags) - : QGraphicsProxyWidget(parent, wFlags), popupShown(false) + : QGraphicsProxyWidget(parent, wFlags), popupShown(false), currentPopup(0) { timeLine = new QTimeLine(250, this); connect(timeLine, SIGNAL(valueChanged(qreal)), @@ -111,8 +111,19 @@ bool CustomProxy::sceneEventFilter(QGraphicsItem *watched, QEvent *event) QVariant CustomProxy::itemChange(GraphicsItemChange change, const QVariant &value) { - if (change == ItemChildRemovedChange) - removeSceneEventFilter(this); + if (change == ItemChildAddedChange || change == ItemChildRemovedChange) { + if (change == ItemChildAddedChange) { + currentPopup = qVariantValue(value); + currentPopup->setCacheMode(ItemCoordinateCache); + if (scene()) + currentPopup->installSceneEventFilter(this); + } else if (scene()) { + currentPopup->removeSceneEventFilter(this); + currentPopup = 0; + } + } else if (currentPopup && change == ItemSceneHasChanged) { + currentPopup->installSceneEventFilter(this); + } return QGraphicsProxyWidget::itemChange(change, value); } diff --git a/demos/embeddeddialogs/customproxy.h b/demos/embeddeddialogs/customproxy.h index 0a5fbaf..d324426 100644 --- a/demos/embeddeddialogs/customproxy.h +++ b/demos/embeddeddialogs/customproxy.h @@ -70,6 +70,7 @@ private slots: private: QTimeLine *timeLine; bool popupShown; + QGraphicsItem *currentPopup; }; #endif -- cgit v0.12 From c131208e59f5b2dd517b00c4539458760b8fd8aa Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Wed, 8 Apr 2009 10:45:41 +0200 Subject: BT: Fix infinite recursion potential from change acff913a6287ad50b0ac782 It seems there is a potential for recursion because calling keyDown: can bubble up to the window which will start the process all over again. keyDown: will actually call qt_dispatchKeyEvent(), we may as well short it out here. All the previous cases I tried continue to work and we don't crash Creator if you are really impatient hitting keys. --- src/gui/widgets/qcocoamenu_mac.mm | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/gui/widgets/qcocoamenu_mac.mm b/src/gui/widgets/qcocoamenu_mac.mm index bae270a..bd62a00 100644 --- a/src/gui/widgets/qcocoamenu_mac.mm +++ b/src/gui/widgets/qcocoamenu_mac.mm @@ -159,10 +159,11 @@ QT_END_NAMESPACE accel_ev.ignore(); qt_sendSpontaneousEvent(widget, &accel_ev); if (accel_ev.isAccepted()) { - *target = nil; - *action = nil; - [qt_mac_nativeview_for(widget) keyDown:event]; - return YES; + if (qt_dispatchKeyEvent(event, widget)) { + *target = nil; + *action = nil; + return YES; + } } } } -- cgit v0.12 From 74f092408d1a870e2c1e2a49182c8e09f952055d Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Wed, 8 Apr 2009 11:07:33 +0200 Subject: Javascript: When there is javascript running then it will spin the CPU at 100% Zero timers on Windows would continue to fire even after being stopped as long as a new timer was started that reused the pointer address of the zero timer. Fix this by only re-firing zero timers if the zero timer hadn't been stopped (we can check this by looking at the inTimerEvent flag, which is set to false by registerTimer()). Task-number: 247401 Reviewed-by: Denis Dzyubenko Reviewed-by: Prasanth Ullattil --- dist/changes-4.5.1 | 4 ++ src/corelib/kernel/qeventdispatcher_win.cpp | 15 +++++-- tests/auto/qtimer/tst_qtimer.cpp | 65 +++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 3 deletions(-) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index de4eef7..eb8ec5f 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -68,6 +68,10 @@ Qt for Linux/X11 Qt for Windows -------------- +- QCoreApplication + * [247401] Fixed a bug that would cause a restarted timer to fire + too early, causing Javascript in QtWebKit to consume 100% CPU on + Windows. Qt for Mac OS X --------------- diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 880e95c..c4061f4 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -1059,11 +1059,20 @@ bool QEventDispatcherWin32::event(QEvent *e) QZeroTimerEvent *zte = static_cast(e); WinTimerInfo *t = d->timerDict.value(zte->timerId()); if (t) { + t->inTimerEvent = true; + QTimerEvent te(zte->timerId()); QCoreApplication::sendEvent(t->obj, &te); - WinTimerInfo *tn = d->timerDict.value(zte->timerId()); - if (tn && t == tn) - QCoreApplication::postEvent(this, new QZeroTimerEvent(zte->timerId())); + + t = d->timerDict.value(zte->timerId()); + if (t) { + if (t->interval == 0 && t->inTimerEvent) { + // post the next zero timer event as long as the timer was not restarted + QCoreApplication::postEvent(this, new QZeroTimerEvent(zte->timerId())); + } + + t->inTimerEvent = false; + } } return true; } else if (e->type() == QEvent::Timer) { diff --git a/tests/auto/qtimer/tst_qtimer.cpp b/tests/auto/qtimer/tst_qtimer.cpp index 527628c..bffb4f2 100644 --- a/tests/auto/qtimer/tst_qtimer.cpp +++ b/tests/auto/qtimer/tst_qtimer.cpp @@ -83,6 +83,7 @@ private slots: void recurringTimer(); void deleteLaterOnQTimer(); // long name, don't want to shadow QObject::deleteLater() void moveToThread(); + void restartedTimerFiresTooSoon(); }; class TimerHelper : public QObject @@ -416,5 +417,69 @@ void tst_QTimer::moveToThread() QVERIFY((ti3.timerId() & 0xffffff) != (ti1.timerId() & 0xffffff)); } +class RestartedTimerFiresTooSoonObject : public QObject +{ + Q_OBJECT + +public: + QBasicTimer m_timer; + + int m_interval; + QTime m_startedTime; + QEventLoop eventLoop; + + inline RestartedTimerFiresTooSoonObject() + : QObject(), m_interval(0) + { } + + void timerFired() + { + static int interval = 1000; + + m_interval = interval; + m_startedTime.start(); + m_timer.start(interval, this); + + // alternate between single-shot and 1 sec + interval = interval ? 0 : 1000; + } + + void timerEvent(QTimerEvent* ev) + { + if (ev->timerId() != m_timer.timerId()) + return; + + m_timer.stop(); + + QTime now = QTime::currentTime(); + int elapsed = m_startedTime.elapsed(); + + if (elapsed < m_interval / 2) { + // severely too early! + m_timer.stop(); + eventLoop.exit(-1); + return; + } + + timerFired(); + + // don't do this forever + static int count = 0; + if (count++ > 20) { + m_timer.stop(); + eventLoop.quit(); + return; + } + } +}; + +void tst_QTimer::restartedTimerFiresTooSoon() +{ + RestartedTimerFiresTooSoonObject object; + object.timerFired(); + QVERIFY(object.eventLoop.exec() == 0); +} + QTEST_MAIN(tst_QTimer) #include "tst_qtimer.moc" +\ -- cgit v0.12 From be3b8acbd311b9cbeaa7c87b4f34b2e33b4a7fa3 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Wed, 8 Apr 2009 11:45:50 +0200 Subject: BT: Fix up comments in new Cocoa files. It seems that Vim or Xcode or whatever I was using to paste these in messed up and added an extra space. Now we should be consistent with the .cpp files and I found a file that we missed too. --- src/gui/kernel/qcocoaapplication_mac.mm | 22 +++---- src/gui/kernel/qcocoaapplicationdelegate_mac.mm | 22 +++---- src/gui/kernel/qcocoamenuloader_mac.mm | 22 +++---- src/gui/kernel/qcocoawindow_mac.mm | 22 +++---- src/gui/kernel/qcocoawindowdelegate_mac.mm | 22 +++---- src/gui/widgets/qcocoamenu_mac.mm | 84 ++++++++++++------------- src/gui/widgets/qmaccocoaviewcontainer_mac.mm | 22 +++---- src/gui/widgets/qmacnativewidget_mac.mm | 22 +++---- src/gui/widgets/qmainwindowlayout_mac.mm | 44 +++++++++++++ 9 files changed, 163 insertions(+), 119 deletions(-) diff --git a/src/gui/kernel/qcocoaapplication_mac.mm b/src/gui/kernel/qcocoaapplication_mac.mm index f95f004f..a3cc2c1 100644 --- a/src/gui/kernel/qcocoaapplication_mac.mm +++ b/src/gui/kernel/qcocoaapplication_mac.mm @@ -1,11 +1,11 @@ /**************************************************************************** - ** - ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) - ** - ** This file is part of the QtGui module of the Qt Toolkit. - ** - ** $QT_BEGIN_LICENSE:LGPL$ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions @@ -36,11 +36,11 @@ ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ - ** - ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - ** - ****************************************************************************/ +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ /**************************************************************************** ** diff --git a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm index e6bd511..6571068 100644 --- a/src/gui/kernel/qcocoaapplicationdelegate_mac.mm +++ b/src/gui/kernel/qcocoaapplicationdelegate_mac.mm @@ -1,11 +1,11 @@ /**************************************************************************** - ** - ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) - ** - ** This file is part of the QtGui module of the Qt Toolkit. - ** - ** $QT_BEGIN_LICENSE:LGPL$ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions @@ -36,11 +36,11 @@ ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ - ** - ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - ** - ****************************************************************************/ +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ /**************************************************************************** ** diff --git a/src/gui/kernel/qcocoamenuloader_mac.mm b/src/gui/kernel/qcocoamenuloader_mac.mm index 7ecb765..e836286 100644 --- a/src/gui/kernel/qcocoamenuloader_mac.mm +++ b/src/gui/kernel/qcocoamenuloader_mac.mm @@ -1,11 +1,11 @@ /**************************************************************************** - ** - ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) - ** - ** This file is part of the QtGui module of the Qt Toolkit. - ** - ** $QT_BEGIN_LICENSE:LGPL$ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions @@ -36,11 +36,11 @@ ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ - ** - ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - ** - ****************************************************************************/ +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ #include "qmacdefines_mac.h" #ifdef QT_MAC_USE_COCOA diff --git a/src/gui/kernel/qcocoawindow_mac.mm b/src/gui/kernel/qcocoawindow_mac.mm index e7b76a7..972e477 100644 --- a/src/gui/kernel/qcocoawindow_mac.mm +++ b/src/gui/kernel/qcocoawindow_mac.mm @@ -1,11 +1,11 @@ /**************************************************************************** - ** - ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) - ** - ** This file is part of the QtGui module of the Qt Toolkit. - ** - ** $QT_BEGIN_LICENSE:LGPL$ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions @@ -36,11 +36,11 @@ ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ - ** - ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - ** - ****************************************************************************/ +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ #include "qmacdefines_mac.h" #ifdef QT_MAC_USE_COCOA diff --git a/src/gui/kernel/qcocoawindowdelegate_mac.mm b/src/gui/kernel/qcocoawindowdelegate_mac.mm index 8480179..03b2fce 100644 --- a/src/gui/kernel/qcocoawindowdelegate_mac.mm +++ b/src/gui/kernel/qcocoawindowdelegate_mac.mm @@ -1,11 +1,11 @@ /**************************************************************************** - ** - ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) - ** - ** This file is part of the QtGui module of the Qt Toolkit. - ** - ** $QT_BEGIN_LICENSE:LGPL$ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions @@ -36,11 +36,11 @@ ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ - ** - ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - ** - ****************************************************************************/ +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ #import "private/qcocoawindowdelegate_mac_p.h" #ifdef QT_MAC_USE_COCOA diff --git a/src/gui/widgets/qcocoamenu_mac.mm b/src/gui/widgets/qcocoamenu_mac.mm index bd62a00..c5fee66 100644 --- a/src/gui/widgets/qcocoamenu_mac.mm +++ b/src/gui/widgets/qcocoamenu_mac.mm @@ -1,46 +1,46 @@ /**************************************************************************** - ** - ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). - ** Contact: Qt Software Information (qt-info@nokia.com) - ** - ** This file is part of the QtGui module of the Qt Toolkit. - ** - ** $QT_BEGIN_LICENSE:LGPL$ - ** No Commercial Usage - ** This file contains pre-release code and may not be distributed. - ** You may use this file in accordance with the terms and conditions - ** contained in the either Technology Preview License Agreement or the - ** Beta Release License Agreement. - ** - ** GNU Lesser General Public License Usage - ** Alternatively, this file may be used under the terms of the GNU Lesser - ** General Public License version 2.1 as published by the Free Software - ** Foundation and appearing in the file LICENSE.LGPL included in the - ** packaging of this file. Please review the following information to - ** ensure the GNU Lesser General Public License version 2.1 requirements - ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. - ** - ** In addition, as a special exception, Nokia gives you certain - ** additional rights. These rights are described in the Nokia Qt LGPL - ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this - ** package. - ** - ** GNU General Public License Usage - ** Alternatively, this file may be used under the terms of the GNU - ** General Public License version 3.0 as published by the Free Software - ** Foundation and appearing in the file LICENSE.GPL included in the - ** packaging of this file. Please review the following information to - ** ensure the GNU General Public License version 3.0 requirements will be - ** met: http://www.gnu.org/copyleft/gpl.html. - ** - ** If you are unsure which license is appropriate for your use, please - ** contact the sales department at qt-sales@nokia.com. - ** $QT_END_LICENSE$ - ** - ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - ** - ****************************************************************************/ +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ #include "qmacdefines_mac.h" #include "qapplication.h" diff --git a/src/gui/widgets/qmaccocoaviewcontainer_mac.mm b/src/gui/widgets/qmaccocoaviewcontainer_mac.mm index 710af6a..380e983 100644 --- a/src/gui/widgets/qmaccocoaviewcontainer_mac.mm +++ b/src/gui/widgets/qmaccocoaviewcontainer_mac.mm @@ -1,11 +1,11 @@ /**************************************************************************** - ** - ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) - ** - ** This file is part of the QtGui module of the Qt Toolkit. - ** - ** $QT_BEGIN_LICENSE:LGPL$ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions @@ -36,11 +36,11 @@ ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ - ** - ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - ** - ****************************************************************************/ +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ #import #include diff --git a/src/gui/widgets/qmacnativewidget_mac.mm b/src/gui/widgets/qmacnativewidget_mac.mm index 1bc0430..0f4edf9 100644 --- a/src/gui/widgets/qmacnativewidget_mac.mm +++ b/src/gui/widgets/qmacnativewidget_mac.mm @@ -1,11 +1,11 @@ /**************************************************************************** - ** - ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) - ** - ** This file is part of the QtGui module of the Qt Toolkit. - ** - ** $QT_BEGIN_LICENSE:LGPL$ +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions @@ -36,11 +36,11 @@ ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ - ** - ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - ** - ****************************************************************************/ +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ #import #import diff --git a/src/gui/widgets/qmainwindowlayout_mac.mm b/src/gui/widgets/qmainwindowlayout_mac.mm index 950f758..c807afb 100644 --- a/src/gui/widgets/qmainwindowlayout_mac.mm +++ b/src/gui/widgets/qmainwindowlayout_mac.mm @@ -1,3 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + #include #include #include -- cgit v0.12 From 3b5f04843c9ab5e0ccce7f4aa8a73d45c9021c35 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 8 Apr 2009 12:47:47 +0200 Subject: update/fix configure Reviewed-by: Thiago - display the nokia internal usage text like on configure - instead of skipping the license check we need to actually call it to set QT_EDITION and friends properly. Otherwise the build gets broken. --- tools/configure/configureapp.cpp | 8 +++++--- tools/configure/tools.cpp | 7 +++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 5e77606..bcbf557 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -474,6 +474,9 @@ void Configure::parseCmdLine() else if( configCmdLine.at(i) == "-developer-build" ) dictionary[ "BUILDDEV" ] = "yes"; else if( configCmdLine.at(i) == "-nokia-developer" ) { + cout << "Detected -nokia-developer option" << endl; + cout << "Nokia employees and agents are allowed to use this software under" << endl; + cout << "the authority of Nokia Corporation and/or its subsidiary(-ies)" << endl; dictionary[ "BUILDNOKIA" ] = "yes"; dictionary[ "BUILDDEV" ] = "yes"; dictionary["LICENSE_CONFIRMED"] = "yes"; @@ -3511,9 +3514,8 @@ void Configure::readLicense() } #else } else { - if (dictionary[ "BUILDNOKIA" ] != "yes") - Tools::checkLicense(dictionary, licenseInfo, firstLicensePath()); - if (dictionary["DONE"] != "error") { + Tools::checkLicense(dictionary, licenseInfo, firstLicensePath()); + if (dictionary["DONE"] != "error" && dictionary["BUILDNOKIA"] != "yes") { // give the user some feedback, and prompt for license acceptance cout << endl << "This is the " << dictionary["PLATFORM NAME"] << " " << dictionary["EDITION"] << " Edition."<< endl << endl; if (!showLicense(dictionary["LICENSE FILE"])) { diff --git a/tools/configure/tools.cpp b/tools/configure/tools.cpp index 760c101..2649d44 100644 --- a/tools/configure/tools.cpp +++ b/tools/configure/tools.cpp @@ -58,6 +58,13 @@ using namespace std; void Tools::checkLicense(QMap &dictionary, QMap &licenseInfo, const QString &path) { + if (dictionary[ "BUILDNOKIA" ] == "yes") { + dictionary["EDITION"] = "NokiaInternalBuild"; + dictionary["LICENSE_FILE"] = ""; // No License for nokia developers + dictionary["QT_EDITION"] = "QT_EDITION_OPENSOURCE"; + return; // No license key checking in internal builds + } + QString tpLicense = dictionary["QT_SOURCE_TREE"] + "/LICENSE.PREVIEW.OPENSOURCE"; if (QFile::exists(tpLicense)) { dictionary["EDITION"] = "Preview"; -- cgit v0.12 From a08d7a675a4e7f61b80a8a92114cda6f8dbacd96 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Wed, 8 Apr 2009 12:56:08 +0200 Subject: Added some changes for 4.5.1 --- dist/changes-4.5.1 | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index eb8ec5f..17e32d4 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -52,6 +52,10 @@ Third party components * [245668] set also protocol, verifyMode and verifyDepth in setSslConfiguration() +- QStyleSheetStyle + * Improved support for setting background and foreground roles in styles + such as the text color in a combo box popup on Mac and Cleanlooks. + **************************************************************************** * Database Drivers * **************************************************************************** @@ -64,6 +68,27 @@ Third party components Qt for Linux/X11 ---------------- +- Phonon/GStreamer + * [244259] Fixed a problem where the backend would fail to indicate an + error when streaming fails. + * [233188] Fixed a problem where the seek slider would reset to 0 while + being dragged. + * [246189] Fixed a problem where the backend would fail to correctly + escape certain file names so that playback would not start + * [246097] Added support for the MediaController interface to allow audio + CD playback. + +- QGtkStyle + * The system palette is no longer strictly forced. Also behavior related + to system theme changes have been improved. + * [249363] QFrame is now styled as a GtkScrolledWindow. + * [247653] Fixed a compilation issue on solaris. + * Fixed palette and styling issues with the background color of + combo box popups. + * [239829] Disabled alt-key navigation for QGtkStyle to follow + GTK+ behavior. + * [238196] Allow middle click to set scrollbar position to follow + GTK+ behavior. Qt for Windows -------------- @@ -72,6 +97,9 @@ Qt for Windows * [247401] Fixed a bug that would cause a restarted timer to fire too early, causing Javascript in QtWebKit to consume 100% CPU on Windows. +- QWindowsXPStyle + * [248036] Fixed an issue where tool buttons would incorrectly + hover when disabled. Qt for Mac OS X --------------- @@ -122,7 +150,6 @@ Qt for Windows CE - moc - - uic * [244998] Fixed include file generation for phonon widgets. * [248070] Fixed code generation for QStringList-type properties to use -- cgit v0.12 From 7edc2b05cfdf143c7f8ac444f93db918a5fd5344 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Wed, 8 Apr 2009 13:02:19 +0200 Subject: Refactor the palette and opacity change into a separate function. We can save on some creation and only show the container when we really need to. It does mean that we need to ensure that everything is correct on construction as well. It's now factored into another file. Reviewed-by: Jens Bache-Wiig --- src/gui/widgets/qcombobox.cpp | 37 +++++++++++++++++++++++-------------- src/gui/widgets/qcombobox_p.h | 1 + 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp index 09a51fe..f30ece4 100644 --- a/src/gui/widgets/qcombobox.cpp +++ b/src/gui/widgets/qcombobox.cpp @@ -949,6 +949,7 @@ QComboBoxPrivateContainer* QComboBoxPrivate::viewContainer() container->itemView()->setTextElideMode(Qt::ElideMiddle); updateDelegate(); updateLayoutDirection(); + updateViewContainerPaletteAndOpacity(); QObject::connect(container, SIGNAL(itemSelected(QModelIndex)), q, SLOT(_q_itemSelected(QModelIndex))); QObject::connect(container->itemView()->selectionModel(), @@ -1051,6 +1052,27 @@ void QComboBoxPrivate::_q_rowsRemoved(const QModelIndex &parent, int /*start*/, } +void QComboBoxPrivate::updateViewContainerPaletteAndOpacity() +{ + if (!container) + return; + Q_Q(QComboBox); + QStyleOptionComboBox opt; + q->initStyleOption(&opt); +#ifndef QT_NO_MENU + if (q->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, q)) { + QMenu menu; + menu.ensurePolished(); + container->setPalette(menu.palette()); + container->setWindowOpacity(menu.windowOpacity()); + } else +#endif + { + container->setPalette(q->palette()); + container->setWindowOpacity(1.0); + } +} + /*! Initialize \a option with the values from this QComboBox. This method is useful for subclasses when they need a QStyleOptionComboBox, but don't want @@ -2572,20 +2594,7 @@ void QComboBox::changeEvent(QEvent *e) hidePopup(); break; case QEvent::PaletteChange: { - QStyleOptionComboBox opt; - initStyleOption(&opt); -#ifndef QT_NO_MENU - if (style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, this)) { - QMenu menu; - menu.ensurePolished(); - d->viewContainer()->setPalette(menu.palette()); - d->viewContainer()->setWindowOpacity(menu.windowOpacity()); - } else -#endif - { - d->viewContainer()->setPalette(palette()); - d->viewContainer()->setWindowOpacity(1.0); - } + d->updateViewContainerPaletteAndOpacity(); break; } case QEvent::FontChange: diff --git a/src/gui/widgets/qcombobox_p.h b/src/gui/widgets/qcombobox_p.h index c39a231..a0b76cf 100644 --- a/src/gui/widgets/qcombobox_p.h +++ b/src/gui/widgets/qcombobox_p.h @@ -370,6 +370,7 @@ public: void updateDelegate(); void keyboardSearchString(const QString &text); void modelChanged(); + void updateViewContainerPaletteAndOpacity(); QAbstractItemModel *model; QLineEdit *lineEdit; -- cgit v0.12 From 8da880e77db04cc4509e0f48e0b5b1d6265da223 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Wed, 8 Apr 2009 13:43:39 +0200 Subject: =?UTF-8?q?QTextEdit=20character=20are=20lost=20after=20special=20?= =?UTF-8?q?characters=20like=20^=20=C2=B4=20`=20This=20happens=20only=20on?= =?UTF-8?q?=20keyboard=20layouts=20like=20French.=20The=20is=20mainly=20du?= =?UTF-8?q?e=20to=20the=20key=20event=20processing=20done=20by=20the=20Inp?= =?UTF-8?q?ut=20manager.=20In=20carbon,=20the=20key=20down=20event=20has?= =?UTF-8?q?=20to=20be=20replayed=20after=20the=20input=20manager=20finishe?= =?UTF-8?q?s=20his=20processing.=20In=20Cocoa,=20while=20unmarking=20we=20?= =?UTF-8?q?have=20to=20accept=20the=20current=20text.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: 123740 Reviewed-by: nrc --- src/gui/inputmethod/qmacinputcontext_mac.cpp | 20 +++++++++++++++++++- src/gui/inputmethod/qmacinputcontext_p.h | 5 +++++ src/gui/kernel/qcocoaview_mac.mm | 14 +++++++++++++- src/gui/kernel/qcocoaview_mac_p.h | 1 + src/gui/kernel/qkeymapper_mac.cpp | 15 ++++++++++++--- 5 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/gui/inputmethod/qmacinputcontext_mac.cpp b/src/gui/inputmethod/qmacinputcontext_mac.cpp index f0e7ea9..86385fa 100644 --- a/src/gui/inputmethod/qmacinputcontext_mac.cpp +++ b/src/gui/inputmethod/qmacinputcontext_mac.cpp @@ -45,6 +45,7 @@ #include "qtextformat.h" #include #include +#include QT_BEGIN_NAMESPACE @@ -63,7 +64,8 @@ static QTextFormat qt_mac_compose_format() } QMacInputContext::QMacInputContext(QObject *parent) - : QInputContext(parent), composing(false), recursionGuard(false), textDocument(0) + : QInputContext(parent), composing(false), recursionGuard(false), textDocument(0), + keydownEvent(0) { // createTextDocument(); } @@ -183,6 +185,16 @@ QMacInputContext::cleanup() #endif } +void QMacInputContext::setLastKeydownEvent(EventRef event) +{ + EventRef tmpEvent = keydownEvent; + keydownEvent = event; + if (keydownEvent) + RetainEvent(keydownEvent); + if (tmpEvent) + ReleaseEvent(tmpEvent); +} + OSStatus QMacInputContext::globalEventProcessor(EventHandlerCallRef, EventRef event, void *) { @@ -335,6 +347,12 @@ QMacInputContext::globalEventProcessor(EventHandlerCallRef, EventRef event, void GetEventParameter(key_ev, kEventParamKeyMacCharCodes, typeChar, 0, sizeof(chr), 0, &chr); if(!chr || chr >= 128 || (text.length() > 0 && (text.length() > 1 || text.at(0) != QLatin1Char(chr)))) handled_event = !widget->testAttribute(Qt::WA_InputMethodEnabled); + QMacInputContext *context = qobject_cast(qApp->inputContext()); + if (context && context->lastKeydownEvent()) { + qt_keymapper_private()->translateKeyEvent(widget, 0, context->lastKeydownEvent(), + 0, false); + context->setLastKeydownEvent(0); + } } break; } default: diff --git a/src/gui/inputmethod/qmacinputcontext_p.h b/src/gui/inputmethod/qmacinputcontext_p.h index f708040..c3f245a 100644 --- a/src/gui/inputmethod/qmacinputcontext_p.h +++ b/src/gui/inputmethod/qmacinputcontext_p.h @@ -78,6 +78,10 @@ public: static OSStatus globalEventProcessor(EventHandlerCallRef, EventRef, void *); static void initialize(); static void cleanup(); + + EventRef lastKeydownEvent() { return keydownEvent; } + void setLastKeydownEvent(EventRef); + protected: void mouseHandler(int pos, QMouseEvent *); private: @@ -85,6 +89,7 @@ private: bool recursionGuard; TSMDocumentID textDocument; QString currentText; + EventRef keydownEvent; }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 19367d1..2d6f5ad 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -195,6 +195,7 @@ extern "C" { if (self) { [self finishInitWithQWidget:widget widgetPrivate:widgetprivate]; } + composingText = new QString(); composing = false; sendKeyEvents = true; [self setHidden:YES]; @@ -364,6 +365,7 @@ extern "C" { - (void)dealloc { + delete composingText; [[NSNotificationCenter defaultCenter] removeObserver:self]; [super dealloc]; } @@ -917,7 +919,7 @@ extern "C" { - (void) insertText:(id)aString { - if (composing) { + if ([aString length]) { // Send the commit string to the widget. QString commitText; if ([aString isKindOfClass:[NSAttributedString class]]) { @@ -931,6 +933,7 @@ extern "C" { e.setCommitString(commitText); qt_sendSpontaneousEvent(qwidget, &e); } + composingText->clear(); } - (void) setMarkedText:(id)aString selectedRange:(NSRange)selRange @@ -984,12 +987,21 @@ extern "C" { attrs<clear(); composing = false; } diff --git a/src/gui/kernel/qcocoaview_mac_p.h b/src/gui/kernel/qcocoaview_mac_p.h index 9de94d5..ec1281e 100644 --- a/src/gui/kernel/qcocoaview_mac_p.h +++ b/src/gui/kernel/qcocoaview_mac_p.h @@ -83,6 +83,7 @@ Q_GUI_EXPORT bool composing; int composingLength; bool sendKeyEvents; + QString *composingText; } - (id)initWithQWidget:(QWidget *)widget widgetPrivate:(QWidgetPrivate *)widgetprivate; - (void) finishInitWithQWidget:(QWidget *)widget widgetPrivate:(QWidgetPrivate *)widgetprivate; diff --git a/src/gui/kernel/qkeymapper_mac.cpp b/src/gui/kernel/qkeymapper_mac.cpp index 1a0fb08..39abc5e 100644 --- a/src/gui/kernel/qkeymapper_mac.cpp +++ b/src/gui/kernel/qkeymapper_mac.cpp @@ -48,6 +48,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -480,7 +481,8 @@ static bool translateKeyEventInternal(EventHandlerCallRef er, EventRef keyEvent, #ifdef QT_MAC_USE_COCOA if (outHandled) { qt_mac_eat_unicode_key = false; - CallNextEventHandler(er, keyEvent); + if (er) + CallNextEventHandler(er, keyEvent); *outHandled = qt_mac_eat_unicode_key; } #endif @@ -692,8 +694,14 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, EventHandlerCallRef e return true; } - if (qApp->inputContext() && qApp->inputContext()->isComposing()) + if (qApp->inputContext() && qApp->inputContext()->isComposing()) { + if (ekind == kEventRawKeyDown) { + QMacInputContext *context = qobject_cast(qApp->inputContext()); + if (context) + context->setLastKeydownEvent(event); + } return false; + } //get modifiers Qt::KeyboardModifiers modifiers; int qtKey; @@ -721,7 +729,8 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, EventHandlerCallRef e //is it of use to text services? If so we won't bother //with a QKeyEvent. qt_mac_eat_unicode_key = false; - CallNextEventHandler(er, event); + if (er) + CallNextEventHandler(er, event); extern bool qt_mac_menubar_is_open(); if (qt_mac_eat_unicode_key || qt_mac_menubar_is_open()) { return true; -- cgit v0.12 From f034683be4d84bacd874b24a846d1833f4d4f4df Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 8 Apr 2009 14:00:23 +0200 Subject: Fixes: No navigation with alt for the native menubar (Windows CE) RevBy: Mauricek AutoTest: tst_QMenuBar::check_altPress() Details: We do not allow alt navigation with the windows mobile style --- src/gui/styles/qwindowsmobilestyle.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/styles/qwindowsmobilestyle.cpp b/src/gui/styles/qwindowsmobilestyle.cpp index c52c700..1c03b9e 100644 --- a/src/gui/styles/qwindowsmobilestyle.cpp +++ b/src/gui/styles/qwindowsmobilestyle.cpp @@ -3401,6 +3401,9 @@ int QWindowsMobileStyle::styleHint(StyleHint hint, const QStyleOption *opt, cons case SH_ScrollBar_ContextMenu: ret = false; break; + case SH_MenuBar_AltKeyNavigation: + ret = false; + break; default: ret = QWindowsStyle::styleHint(hint, opt, widget, returnData); break; -- cgit v0.12 From 27c1edac6769f863549f0940d35cf3f82e778a46 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Wed, 8 Apr 2009 14:04:26 +0200 Subject: My changes. --- dist/changes-4.5.1 | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index 17e32d4..5584c11 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -45,6 +45,13 @@ Third party components - QHttp * [208445] cancel request upon receiving unknown authentication method +- QMacStyle + * [248769] Fix regression where QMacStyle would only draw tabs when passed a QStyleOptionTabV3. + * Adjust the opacity value for popups. + +- QMainWindow + * [248048] Fix a regression that would cause tooltips to disappear when using the unified toolbar. + - QSharedPointer * [246843] Fixed a crash caused by using QSharedPointer in global statics @@ -104,6 +111,35 @@ Qt for Windows Qt for Mac OS X --------------- +- Cocoa port + * Fixed a bug where actions in the native menubar weren't properly disabled. + * Make shortcuts work properly when using the Dvorak-QWERTY+CMD keyboard layout. + * Fixed a bug where dialogs would be positioned in the wrong place on the screen. + * [244369] Window flags on Cocoa windows should match have a similar look as the Carbon ones. + * The build-key for Cocoa was changed in the unlikely case that a plugin may make + assumptions on how Qt was built. All Cocoa plugins built against 4.5.0 WILL NOT WORK + with 4.5.1, we don't foresee changing this again. + * Fixed a bug where some windows would not get activation when they normally should. + * Key events sent to popups do not get propagated onwards. + * [249296] Fix a bug where lineedits on a second page of a stack widget wourd not get key events + * QFileOpenEvents are no longer sent for items passed on the command line. + * Various fixes for determining metrics of text and the ability to disable kerning. + * [248918] Fixed color matching for themed text items. + * Modify the colliding mice example to work better with coalesced updates. + +- Fix a crash when showing a widget that is window modal but has no parent. +- [248803] Showing two dialogs at the same time don't get shared activation. +- Added QSysInfo::MV_10_6 as an enum to test against. +- Various compile fixes for Snow Leopard (preliminary support). + + +- The uninstall-qt.py script included in the binary package no longer complains about removing itself multiple times. + +- Document a bit clearer how qt_mac_set_dock_menu() works. + +- QTestLib + * Activate the test application when launched from the command line. + Qt for Embedded Linux --------------------- @@ -161,6 +197,7 @@ Qt for Windows CE - qmake + * [248806] Ensure that the Xcode generator includes the right path to frameworks. - configure -- cgit v0.12 From f2edb497ac2c3ff6f8c004046e216b8bdf7c4347 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Wed, 8 Apr 2009 14:34:18 +0200 Subject: BT: Fix a painting glitch in gtk combo box This improves the look of combo box with gtk style which is somewhat a regression from 4.5.0 since we did not style this part before. Reviewed-by: nrc --- src/gui/styles/qgtkstyle.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index b569b5c..519fed7 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -2507,6 +2507,10 @@ void QGtkStyle::drawControl(ControlElement element, if (selected) { QRect rect = option->rect.adjusted(0, 0, -1, -1); +#ifndef QT_NO_COMBOBOX + if (qobject_cast(widget)) + rect = option->rect; +#endif gtkPainter.paintBox( gtkMenuItem, "menuitem", rect, GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, style); } -- cgit v0.12 From b273cd322345c54d5cbd6f178791d1ccfcc08e05 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 8 Apr 2009 15:47:42 +0200 Subject: BT: Compilefix for Windows CE and namespaces RevBy: Mauricek Details: functions needs to be declared outside of the namespace --- src/gui/inputmethod/qwininputcontext_win.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/gui/inputmethod/qwininputcontext_win.cpp b/src/gui/inputmethod/qwininputcontext_win.cpp index 720f0b8..e3e8aa4 100644 --- a/src/gui/inputmethod/qwininputcontext_win.cpp +++ b/src/gui/inputmethod/qwininputcontext_win.cpp @@ -57,15 +57,17 @@ #ifdef Q_IME_DEBUG #include "qdebug.h" -#endif - -QT_BEGIN_NAMESPACE +#endif -extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); #if defined(Q_OS_WINCE) extern void qt_wince_show_SIP(bool show); // defined in qguifunctions_wince.cpp #endif +QT_BEGIN_NAMESPACE + +extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); + + DEFINE_GUID(IID_IActiveIMMApp, 0x08c0e040, 0x62d1, 0x11d1, 0x93, 0x26, 0x0, 0x60, 0xb0, 0x67, 0xb8, 0x6e); -- cgit v0.12 From 91081c68b7899c95a998b03ee581927d62bd6880 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Wed, 8 Apr 2009 12:24:58 -0700 Subject: Don't convert unsupported images for dfb Fall back to raster engine for formats not supported by dfb rather than converting the image to a supported format. Reviewed-by: Donald --- src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index a93bbf7..452ee48 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -694,16 +694,10 @@ void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, } void QDirectFBPaintEnginePrivate::drawImage(const QRectF &dest, - const QImage &srcImage, + const QImage &image, const QRectF &src) { - QImage image = srcImage; - if (QDirectFBScreen::getSurfacePixelFormat(image.format()) == DSPF_UNKNOWN) { - image = image.convertToFormat(image.hasAlphaChannel() - ? QDirectFBScreen::instance()->alphaPixmapFormat() - : QDirectFBScreen::instance()->pixelFormat()); - } - + Q_ASSERT(QDirectFBScreen::getSurfacePixelFormat(image.format()) != DSPF_UNKNOWN); CachedImage *img = imageCache[image.cacheKey()]; IDirectFBSurface *imgSurface = 0; bool doRelease = false; @@ -1017,7 +1011,8 @@ void QDirectFBPaintEngine::drawImage(const QRectF &r, const QImage &image, #ifndef QT_NO_DIRECTFB_PREALLOCATED d->updateClip(); - if (!d->dfbCanHandleClip(r) || d->matrixRotShear) + if (!d->dfbCanHandleClip(r) || d->matrixRotShear + || QDirectFBScreen::getSurfacePixelFormat(image.format()) == DSPF_UNKNOWN) #endif { d->lock(); -- cgit v0.12 From d554a4b6218885e683c98b7c538fb5feee618067 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Wed, 8 Apr 2009 13:59:51 -0700 Subject: Fix up drawing/blitting/porterduff situation This was rather broken previously. For example, porterduff mode does not play well with alpha values and blends. Also, setting the flags to the existing value is a noop in DirectFB (checked the code) so bool dirty approach buys us nothing. Reviewed-by: Donald --- .../gfxdrivers/directfb/qdirectfbpaintengine.cpp | 212 ++++++++------------- 1 file changed, 77 insertions(+), 135 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 452ee48..f72b0da 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -196,10 +196,10 @@ public: void setPen(const QPen &pen); void setBrush(const QBrush &brush); void setCompositionMode(QPainter::CompositionMode mode); - void setOpacity(const qreal value); + void setOpacity(quint8 value); void setRenderHints(QPainter::RenderHints hints); - inline void setDFBColor(const QColor &color) const; + inline void setDFBColor(const QColor &color); inline void lock(); inline void unlock(); @@ -222,14 +222,14 @@ public: void drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap); void drawImage(const QRectF &dest, const QImage &image, const QRectF &src); - void updateClip(); - void updateFlags(); + inline void updateClip(); inline void setClipDirty(); void systemStateChanged(); //Needed to be notified when system clip changes void begin(QPaintDevice *device); void end(); + void prepareForBlit(bool alpha); SurfaceCache *surfaceCache; QTransform transform; int lastLockedHeight; @@ -244,10 +244,9 @@ private: quint8 opacity; - quint32 drawFlags; - quint32 blitFlags; - quint32 duffFlags; - bool dirtyFlags; + quint32 drawFlagsFromCompositionMode, blitFlagsFromCompositionMode; + DFBSurfacePorterDuffRule porterDuffRule; + bool dirtyClip; bool dfbHandledClip; QDirectFBPaintDevice *dfbDevice; @@ -258,8 +257,9 @@ private: QDirectFBPaintEnginePrivate::QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p) : surface(0), antialiased(false), forceRasterPrimitives(false), simplePen(false), simpleBrush(false), matrixRotShear(false), matrixScale(false), lastLockedHeight(-1), - fbWidth(-1), fbHeight(-1), opacity(255), drawFlags(0), blitFlags(0), duffFlags(0), - dirtyFlags(false), dirtyClip(true), dfbHandledClip(false), dfbDevice(0), q(p) + fbWidth(-1), fbHeight(-1), opacity(255), drawFlagsFromCompositionMode(0), + blitFlagsFromCompositionMode(0), porterDuffRule(DSPD_SRC_OVER), dirtyClip(true), + dfbHandledClip(false), dfbDevice(0), q(p) { fb = QDirectFBScreen::instance()->dfb(); surfaceCache = new SurfaceCache; @@ -295,7 +295,6 @@ void QDirectFBPaintEnginePrivate::setClipDirty() dirtyClip = true; } - void QDirectFBPaintEnginePrivate::lock() { // We will potentially get a new pointer to the buffer after a @@ -345,11 +344,8 @@ void QDirectFBPaintEnginePrivate::begin(QPaintDevice *device) setTransform(QTransform()); antialiased = false; - drawFlags = DSDRAW_BLEND; - blitFlags = DSBLIT_BLEND_ALPHACHANNEL; - duffFlags = DSPD_SRC_OVER; opacity = 255; - dirtyFlags = true; + setCompositionMode(q->state()->compositionMode()); dirtyClip = true; setPen(q->state()->pen); setDFBColor(pen.color()); @@ -382,91 +378,72 @@ void QDirectFBPaintEnginePrivate::setBrush(const QBrush &b) void QDirectFBPaintEnginePrivate::setCompositionMode(QPainter::CompositionMode mode) { - drawFlags &= ~(DSDRAW_XOR); - blitFlags &= ~(DSBLIT_XOR); - - // TODO: check these mappings!!!! - quint32 duff = DSPD_NONE; - quint32 blit = blitFlags; + blitFlagsFromCompositionMode = DSBLIT_NOFX; + drawFlagsFromCompositionMode = DSDRAW_NOFX; + bool blend = true; switch (mode) { case QPainter::CompositionMode_SourceOver: - duff = DSPD_SRC_OVER; - blit |= DSBLIT_BLEND_ALPHACHANNEL; + porterDuffRule = DSPD_SRC_OVER; break; case QPainter::CompositionMode_DestinationOver: - duff = DSPD_DST_OVER; - blit |= DSBLIT_BLEND_ALPHACHANNEL; + porterDuffRule = DSPD_DST_OVER; break; case QPainter::CompositionMode_Clear: - duff = DSPD_CLEAR; - blit &= ~DSBLIT_BLEND_ALPHACHANNEL; + porterDuffRule = DSPD_CLEAR; + blend = false; break; case QPainter::CompositionMode_Source: - duff = DSPD_SRC; - blit &= ~DSBLIT_BLEND_ALPHACHANNEL; + porterDuffRule = DSPD_SRC; + blend = false; break; case QPainter::CompositionMode_Destination: - blit &= ~DSBLIT_BLEND_ALPHACHANNEL; + porterDuffRule = DSPD_NONE; // ### need to double check this + blend = false; return; case QPainter::CompositionMode_SourceIn: - duff = DSPD_SRC_IN; - blit |= DSBLIT_BLEND_ALPHACHANNEL; + porterDuffRule = DSPD_SRC_IN; break; case QPainter::CompositionMode_DestinationIn: - duff = DSPD_DST_IN; - blit |= DSBLIT_BLEND_ALPHACHANNEL; + porterDuffRule = DSPD_DST_IN; break; case QPainter::CompositionMode_SourceOut: - duff = DSPD_SRC_OUT; - blit |= DSBLIT_BLEND_ALPHACHANNEL; + porterDuffRule = DSPD_SRC_OUT; break; case QPainter::CompositionMode_DestinationOut: - duff = DSPD_DST_OUT; - blit |= DSBLIT_BLEND_ALPHACHANNEL; - break; - case QPainter::CompositionMode_SourceAtop: - duff = DSPD_SRC_OVER; - blit |= DSBLIT_BLEND_ALPHACHANNEL; - break; - case QPainter::CompositionMode_DestinationAtop: - duff = DSPD_DST_OVER; + porterDuffRule = DSPD_DST_OUT; break; case QPainter::CompositionMode_Xor: - duff = DSPD_NONE; - blit |= DSBLIT_BLEND_ALPHACHANNEL; - drawFlags |= DSDRAW_XOR; - blit |= DSBLIT_XOR; - dirtyFlags = true; + porterDuffRule = DSPD_XOR; + blitFlagsFromCompositionMode |= DSBLIT_XOR; + drawFlagsFromCompositionMode |= DSDRAW_XOR; break; +// case QPainter::CompositionMode_Plus: // ??? +// porterDuffRule = DSPD_ADD; +// break; default: qWarning("QDirectFBPaintEnginePrivate::setCompositionMode(): " "mode %d not implemented", mode); - break; + return; } - - if (duff != duffFlags || blit != blitFlags) { - duffFlags = duff; - blitFlags = blit; - dirtyFlags = true; + // intentially not comparing with current porterDuffRule. surface might have changed. + if (blend) { + blitFlagsFromCompositionMode |= DSBLIT_BLEND_ALPHACHANNEL; + drawFlagsFromCompositionMode |= DSDRAW_BLEND; + } + if (opacity != 255) { + setOpacity(opacity); } } -void QDirectFBPaintEnginePrivate::setOpacity(const qreal value) +void QDirectFBPaintEnginePrivate::setOpacity(quint8 opacity) { - const bool wasOpaque = (opacity == 255); - opacity = quint8(value * 255); - const bool opaque = (opacity == 255); - - if (opaque == wasOpaque) - return; - - if (opaque) - blitFlags &= ~(DSBLIT_BLEND_COLORALPHA | DSBLIT_SRC_PREMULTCOLOR); - else - blitFlags |= (DSBLIT_BLEND_COLORALPHA | DSBLIT_SRC_PREMULTCOLOR); - - dirtyFlags = true; + if (opacity == 255) { + // ### need to check this stuff + blitFlagsFromCompositionMode &= ~(DSBLIT_BLEND_COLORALPHA | DSBLIT_SRC_PREMULTCOLOR); + } else { + blitFlagsFromCompositionMode |= (DSBLIT_BLEND_COLORALPHA | DSBLIT_SRC_PREMULTCOLOR); + } } void QDirectFBPaintEnginePrivate::setRenderHints(QPainter::RenderHints hints) @@ -478,22 +455,33 @@ void QDirectFBPaintEnginePrivate::setRenderHints(QPainter::RenderHints hints) } } -void QDirectFBPaintEnginePrivate::updateFlags() +void QDirectFBPaintEnginePrivate::prepareForBlit(bool alpha) { - if (!dirtyFlags) - return; - surface->SetDrawingFlags(surface, DFBSurfaceDrawingFlags(drawFlags)); - surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blitFlags)); - surface->SetPorterDuff(surface, DFBSurfacePorterDuffRule(duffFlags)); - dirtyFlags = false; + quint32 blittingFlags = blitFlagsFromCompositionMode; + if (!alpha) { + blittingFlags &= ~DSBLIT_BLEND_ALPHACHANNEL; + surface->SetPorterDuff(surface, DSPD_NONE); + } else { + surface->SetPorterDuff(surface, porterDuffRule); + } + surface->SetColor(surface, 0xff, 0xff, 0xff, opacity); + surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blittingFlags)); } -void QDirectFBPaintEnginePrivate::setDFBColor(const QColor &color) const +void QDirectFBPaintEnginePrivate::setDFBColor(const QColor &color) { + Q_ASSERT(surface); const quint8 alpha = (opacity == 255 ? color.alpha() : ALPHA_MUL(color.alpha(), opacity)); surface->SetColor(surface, color.red(), color.green(), color.blue(), alpha); + quint32 drawingFlags = drawFlagsFromCompositionMode; + if (alpha == 255) { + drawingFlags &= ~DSDRAW_BLEND; + } + surface->SetPorterDuff(surface, DSPD_NONE); + // PorterDuff messes up alpha values for primitives + surface->SetDrawingFlags(surface, DFBSurfaceDrawingFlags(drawingFlags)); } void QDirectFBPaintEnginePrivate::drawLines(const QLine *lines, int n) const @@ -601,15 +589,7 @@ void QDirectFBPaintEnginePrivate::drawPixmap(const QRectF &dest, const QPixmap &pixmap, const QRectF &src) { - surface->SetColor(surface, 0xff, 0xff, 0xff, opacity); - - const bool changeFlags = !pixmap.hasAlphaChannel() - && (blitFlags & DSBLIT_BLEND_ALPHACHANNEL); - if (changeFlags) { - quint32 flags = blitFlags & ~DSBLIT_BLEND_ALPHACHANNEL; - surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(flags)); - } - + prepareForBlit(pixmap.hasAlphaChannel()); QPixmapData *data = pixmap.pixmapData(); Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); QDirectFBPixmapData *dfbData = static_cast(data); @@ -627,22 +607,12 @@ void QDirectFBPaintEnginePrivate::drawPixmap(const QRectF &dest, } if (result != DFB_OK) DirectFBError("QDirectFBPaintEngine::drawPixmap()", result); - if (changeFlags) - surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blitFlags)); } void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap) { - surface->SetColor(surface, 0xff, 0xff, 0xff, opacity); - - const bool changeFlags = !pixmap.hasAlphaChannel() - && (blitFlags & DSBLIT_BLEND_ALPHACHANNEL); - if (changeFlags) { - quint32 flags = blitFlags & ~DSBLIT_BLEND_ALPHACHANNEL; - surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(flags)); - } - + prepareForBlit(pixmap.hasAlphaChannel()); QPixmapData *data = pixmap.pixmapData(); Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); QDirectFBPixmapData *dfbData = static_cast(data); @@ -688,9 +658,6 @@ void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, if (result != DFB_OK) DirectFBError("QDirectFBPaintEngine::drawTiledPixmap()", result); - - if (changeFlags) - surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blitFlags)); } void QDirectFBPaintEnginePrivate::drawImage(const QRectF &dest, @@ -739,14 +706,7 @@ void QDirectFBPaintEnginePrivate::drawImage(const QRectF &dest, const QRect dr = transform.mapRect(dest).toRect(); const DFBRectangle sRect = { sr.x(), sr.y(), sr.width(), sr.height() }; - surface->SetColor(surface, 0xff, 0xff, 0xff, opacity); - - const bool changeFlags = !image.hasAlphaChannel() - && (blitFlags & DSBLIT_BLEND_ALPHACHANNEL); - if (changeFlags) { - quint32 flags = blitFlags & ~DSBLIT_BLEND_ALPHACHANNEL; - surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(flags)); - } + prepareForBlit(image.hasAlphaChannel()); if (dr.size() == sr.size()) { surface->Blit(surface, imgSurface, &sRect, dr.x(), dr.y()); } else { @@ -754,8 +714,6 @@ void QDirectFBPaintEnginePrivate::drawImage(const QRectF &dest, dr.width(), dr.height() }; surface->StretchBlit(surface, imgSurface, &sRect, &dRect); } - if (changeFlags) - surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blitFlags)); if (doRelease) { surface->ReleaseSource(surface); imgSurface->Release(imgSurface); @@ -850,8 +808,7 @@ void QDirectFBPaintEngine::brushChanged() void QDirectFBPaintEngine::opacityChanged() { Q_D(QDirectFBPaintEngine); - d->setOpacity(state()->opacity); - + d->setOpacity(quint8(state()->opacity * 255)); QRasterPaintEngine::opacityChanged(); } @@ -859,7 +816,6 @@ void QDirectFBPaintEngine::compositionModeChanged() { Q_D(QDirectFBPaintEngine); d->setCompositionMode(state()->compositionMode()); - QRasterPaintEngine::compositionModeChanged(); } @@ -888,7 +844,7 @@ void QDirectFBPaintEngine::setState(QPainterState *s) d->setClipDirty(); d->setPen(state()->pen); d->setBrush(state()->brush); - d->setOpacity(state()->opacity); + d->setOpacity(quint8(state()->opacity * 255)); d->setCompositionMode(state()->compositionMode()); d->setTransform(state()->transform()); } @@ -930,12 +886,10 @@ void QDirectFBPaintEngine::drawRects(const QRect *rects, int rectCount) d->unlock(); if (d->brush != Qt::NoBrush) { - d->updateFlags(); d->setDFBColor(d->brush.color()); d->fillRects(rects, rectCount); } if (d->pen != Qt::NoPen) { - d->updateFlags(); d->setDFBColor(d->pen.color()); d->drawRects(rects, rectCount); } @@ -955,12 +909,10 @@ void QDirectFBPaintEngine::drawRects(const QRectF *rects, int rectCount) d->unlock(); if (d->brush != Qt::NoBrush) { - d->updateFlags(); d->setDFBColor(d->brush.color()); d->fillRects(rects, rectCount); } if (d->pen != Qt::NoPen) { - d->updateFlags(); d->setDFBColor(d->pen.color()); d->drawRects(rects, rectCount); } @@ -978,7 +930,6 @@ void QDirectFBPaintEngine::drawLines(const QLine *lines, int lineCount) if (d->pen != Qt::NoPen) { d->unlock(); - d->updateFlags(); d->setDFBColor(d->pen.color()); d->drawLines(lines, lineCount); } @@ -996,7 +947,6 @@ void QDirectFBPaintEngine::drawLines(const QLineF *lines, int lineCount) if (d->pen != Qt::NoPen) { d->unlock(); - d->updateFlags(); d->setDFBColor(d->pen.color()); d->drawLines(lines, lineCount); } @@ -1022,7 +972,6 @@ void QDirectFBPaintEngine::drawImage(const QRectF &r, const QImage &image, #ifndef QT_NO_DIRECTFB_PREALLOCATED d->unlock(); - d->updateFlags(); d->drawImage(r, image, sr); #endif } @@ -1041,15 +990,12 @@ void QDirectFBPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pixmap, if (pixmap.pixmapData()->classId() != QPixmapData::DirectFBClass) { d->lock(); QRasterPaintEngine::drawPixmap(r, pixmap, sr); - } - else if (!d->dfbCanHandleClip(r) || d->matrixRotShear) { + } else if (!d->dfbCanHandleClip(r) || d->matrixRotShear) { const QImage *img = static_cast(pixmap.pixmapData())->buffer(); d->lock(); QRasterPaintEngine::drawImage(r, *img, sr); - } - else { + } else { d->unlock(); - d->updateFlags(); d->drawPixmap(r, pixmap, sr); } } @@ -1068,18 +1014,15 @@ void QDirectFBPaintEngine::drawTiledPixmap(const QRectF &r, if (pixmap.pixmapData()->classId() != QPixmapData::DirectFBClass) { d->lock(); QRasterPaintEngine::drawTiledPixmap(r, pixmap, sp); - } - else if (!d->dfbCanHandleClip(r) || d->matrixRotShear || !sp.isNull()) { + } else if (!d->dfbCanHandleClip(r) || d->matrixRotShear || !sp.isNull()) { const QImage *img = static_cast(pixmap.pixmapData())->buffer(); d->lock(); QRasterPixmapData *data = new QRasterPixmapData(QPixmapData::PixmapType); data->fromImage(*img, Qt::AutoColor); const QPixmap pix(data); QRasterPaintEngine::drawTiledPixmap(r, pix, sp); - } - else { + } else { d->unlock(); - d->updateFlags(); d->drawTiledPixmap(r, pixmap); } } @@ -1162,7 +1105,6 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) if (d->forceRasterPrimitives) break; d->unlock(); - d->updateFlags(); d->setDFBColor(brush.color()); const QRect r = d->transform.mapRect(rect).toRect(); d->surface->FillRectangle(d->surface, r.x(), r.y(), @@ -1172,7 +1114,6 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) if (state()->brushOrigin == QPointF() && brush.transform().isIdentity()) { //could handle certain types of brush.transform() E.g. scale d->unlock(); - d->updateFlags(); d->drawTiledPixmap(rect, brush.texture()); return; } @@ -1194,7 +1135,6 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QColor &color) QRasterPaintEngine::fillRect(rect, color); } else { d->unlock(); - d->updateFlags(); d->setDFBColor(color); const QRect r = d->transform.mapRect(rect).toRect(); d->surface->FillRectangle(d->surface, r.x(), r.y(), @@ -1224,6 +1164,7 @@ void QDirectFBPaintEngine::drawColorSpans(const QSpan *spans, int count, } else { DFBSpan span = { spans[i].x, spans[i].len }; uint c = BYTE_MUL(color, spans[i].coverage); + // ### how does this play with setDFBColor d->surface->SetColor(d->surface, qRed(c), qGreen(c), qBlue(c), qAlpha(c)); d->surface->FillSpans(d->surface, spans[i].y, &span, 1); @@ -1244,6 +1185,7 @@ void QDirectFBPaintEngine::drawBufferSpan(const uint *buffer, int bufsize, { Q_D(QDirectFBPaintEngine); IDirectFBSurface *src = d->surfaceCache->getSurface(buffer, bufsize); + // ### how does this play with setDFBColor src->SetColor(src, 0, 0, 0, const_alpha); const DFBRectangle rect = { 0, 0, length, 1 }; d->surface->Blit(d->surface, src, &rect, x, y); -- cgit v0.12 From 2cf88ffef18622b5c08cd48d4cb0b5624c59a713 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Wed, 8 Apr 2009 16:07:04 -0700 Subject: Diagnostic info when failing to create surface Only enabled in debug builds since it could something that should be ignored. Reviewed-by: Donald --- src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index bf9864a..04d2f57 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -233,6 +233,16 @@ IDirectFBSurface* QDirectFBScreen::createDFBSurface(const DFBSurfaceDescription voDesc.caps = DFBSurfaceCapabilities(voDesc.caps | DSCAPS_VIDEOONLY); } result = d_ptr->dfb->CreateSurface(d_ptr->dfb, &voDesc, &newSurface); +#ifndef QT_NO_DEBUG + if (result != DFB_OK) { + qWarning("QDirectFBScreen::createDFBSurface() Failed to create surface in video memory!\n" + " Flags %0x Caps %0x width %d height %d pixelformat %0x %d preallocated %p %d\n%s", + desc->flags, desc->caps, desc->width, desc->height, + desc->pixelformat, DFB_PIXELFORMAT_INDEX(desc->pixelformat), + desc->preallocated[0].data, desc->preallocated[0].pitch, + DirectFBErrorString(result)); + } +#endif } if (!newSurface) -- cgit v0.12 From d8dda2706408e0c9558966e74376834d290dc6e3 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Wed, 8 Apr 2009 15:08:24 -0700 Subject: Make flipping and paintOnScreen work better Make the paintOnScreen case paint directly on the primary surface if the size of the window surface == size of primary surface. Reviewed-by: Donald --- .../gfxdrivers/directfb/qdirectfbsurface.cpp | 26 ++++++++++++---------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp index f5626c8..8ed308c 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp @@ -139,28 +139,32 @@ void QDirectFBSurface::setGeometry(const QRect &rect, const QRegion &mask) dfbWindow = 0; } #endif - if (dfbSurface) { + if (dfbSurface && dfbSurface != screen->dfbSurface()) { dfbSurface->Release(dfbSurface); dfbSurface = 0; } } else if (rect != geometry()) { - const bool isResize = rect.size() != geometry().size(); DFBResult result = DFB_OK; // If we're in a resize, the surface shouldn't be locked - Q_ASSERT( (lockedImage == 0) || (isResize == false)); + Q_ASSERT((lockedImage == 0) || (rect.size() == geometry().size())); if (onscreen) { - if (dfbSurface) - dfbSurface->Release(dfbSurface); - - DFBRectangle r = { rect.x(), rect.y(), - rect.width(), rect.height() }; IDirectFBSurface *primarySurface = screen->dfbSurface(); Q_ASSERT(primarySurface); - result = primarySurface->GetSubSurface(primarySurface, &r, &dfbSurface); + if (dfbSurface && dfbSurface != primarySurface) + dfbSurface->Release(dfbSurface); + + if (rect == screen->region().boundingRect()) { + dfbSurface = primarySurface; + } else { + const DFBRectangle r = { rect.x(), rect.y(), + rect.width(), rect.height() }; + result = primarySurface->GetSubSurface(primarySurface, &r, &dfbSurface); + } forceRaster = (dfbSurface && QDirectFBScreen::getImageFormat(dfbSurface) == QImage::Format_RGB32); } else { + const bool isResize = rect.size() != geometry().size(); #ifdef QT_NO_DIRECTFB_WM if (isResize) { if (dfbSurface) @@ -362,10 +366,8 @@ void QDirectFBSurface::flush(QWidget *widget, const QRegion ®ion, if (winOpacity != opacity) dfbWindow->SetOpacity(dfbWindow, winOpacity); } -#endif -#ifndef QT_NO_DIRECTFB_WM if (!(flipFlags & DSFLIP_BLIT)) { - dfbSurface->Flip(dfbSurface, 0, DFBSurfaceFlipFlags(flipFlags)); + dfbSurface->Flip(dfbSurface, 0, flipFlags); } else { if (region.numRects() > 1) { const QVector rects = region.rects(); -- cgit v0.12 From 6b494c48efa21f4ed3e2367f8bed8e138fd58190 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Wed, 8 Apr 2009 16:49:08 -0700 Subject: Be smarter about alpha formats Try harder to prevent blends by explicitly checking for alpha pixels in the source image (unless asked not to). Can be defined out by #defining QT_NO_DIRECTFB_OPAQUE_DETECTION Reviewed-by: Donald --- src/plugins/gfxdrivers/directfb/directfb.pro | 1 + .../gfxdrivers/directfb/qdirectfbpixmap.cpp | 161 +++++++++++++++++---- src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h | 3 + 3 files changed, 133 insertions(+), 32 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/directfb.pro b/src/plugins/gfxdrivers/directfb/directfb.pro index 399044e..89a289c 100644 --- a/src/plugins/gfxdrivers/directfb/directfb.pro +++ b/src/plugins/gfxdrivers/directfb/directfb.pro @@ -13,6 +13,7 @@ QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/gfxdrivers #DEFINES += QT_NO_DIRECTFB_MOUSE #DEFINES += QT_NO_DIRECTFB_KEYBOARD #DEFINES += QT_DIRECTFB_TIMING +#DEFINES += QT_NO_DIRECTFB_OPAQUE_DETECTION target.path = $$[QT_INSTALL_PLUGINS]/gfxdrivers INSTALLS += target diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index a20b66a..a4e235b 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -51,7 +51,7 @@ static int global_ser_no = 0; QDirectFBPixmapData::QDirectFBPixmapData(PixelType pixelType) : QPixmapData(pixelType, DirectFBClass), - engine(0) + engine(0), format(QImage::Format_Invalid), alpha(false) { setSerialNumber(0); } @@ -67,16 +67,18 @@ QDirectFBPixmapData::~QDirectFBPixmapData() void QDirectFBPixmapData::resize(int width, int height) { if (width <= 0 || height <= 0) { - setSerialNumber(0); + invalidate(); return; } - dfbSurface = screen->createDFBSurface(QSize(width, height), - screen->pixelFormat(), - QDirectFBScreen::TrackSurface); - forceRaster = (screen->pixelFormat() == QImage::Format_RGB32); + format = screen->pixelFormat(); + dfbSurface = QDirectFBScreen::instance()->createDFBSurface(QSize(width, height), + format, + QDirectFBScreen::TrackSurface); + alpha = false; + forceRaster = (format == QImage::Format_RGB32); if (!dfbSurface) { - setSerialNumber(0); + invalidate(); qWarning("QDirectFBPixmapData::resize(): Unable to allocate surface"); return; } @@ -84,18 +86,98 @@ void QDirectFBPixmapData::resize(int width, int height) setSerialNumber(++global_ser_no); } + +// mostly duplicated from qimage.cpp (QImageData::checkForAlphaPixels) +static bool checkForAlphaPixels(const QImage &img) +{ + const uchar *bits = img.bits(); + const int bytes_per_line = img.bytesPerLine(); + const uchar *end_bits = bits + bytes_per_line; + const int width = img.width(); + const int height = img.height(); + switch (img.format()) { + case QImage::Format_Indexed8: + return img.hasAlphaChannel(); + case QImage::Format_ARGB32: + case QImage::Format_ARGB32_Premultiplied: + for (int y=0; yalphaPixmapFormat() - : screen->pixelFormat(); + Q_ASSERT(img.depth() != 1); // these should be handled by QRasterPixmapData + if (img.hasAlphaChannel() +#ifndef QT_NO_DIRECTFB_OPAQUE_DETECTION + && (flags & Qt::NoOpaqueDetection || ::checkForAlphaPixels(img)) +#endif + ) { + alpha = true; + format = screen->alphaPixmapFormat(); + } else { + alpha = false; + format = screen->pixelFormat(); + } dfbSurface = screen->copyToDFBSurface(img, format, QDirectFBScreen::TrackSurface); forceRaster = (format == QImage::Format_RGB32); if (!dfbSurface) { qWarning("QDirectFBPixmapData::fromImage()"); - setSerialNumber(0); + invalidate(); return; } setSerialNumber(++global_ser_no); @@ -110,15 +192,15 @@ void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect) IDirectFBSurface *src = static_cast(data)->directFBSurface(); const bool hasAlpha = data->hasAlphaChannel(); - const QImage::Format format = (hasAlpha - ? screen->alphaPixmapFormat() - : screen->pixelFormat()); + format = (hasAlpha + ? QDirectFBScreen::instance()->alphaPixmapFormat() + : QDirectFBScreen::instance()->pixelFormat()); dfbSurface = screen->createDFBSurface(rect.size(), format, QDirectFBScreen::TrackSurface); if (!dfbSurface) { qWarning("QDirectFBPixmapData::copy()"); - setSerialNumber(0); + invalidate(); return; } forceRaster = (format == QImage::Format_RGB32); @@ -135,13 +217,28 @@ void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect) dfbSurface->ReleaseSource(dfbSurface); if (result != DFB_OK) { DirectFBError("QDirectFBPixmapData::copy()", result); - setSerialNumber(0); + invalidate(); return; } setSerialNumber(++global_ser_no); } +static inline bool isOpaqueFormat(QImage::Format format) +{ + switch (format) { + case QImage::Format_RGB32: + case QImage::Format_RGB16: + case QImage::Format_RGB666: + case QImage::Format_RGB555: + case QImage::Format_RGB888: + case QImage::Format_RGB444: + return true; + default: + break; + } + return false; +} void QDirectFBPixmapData::fill(const QColor &color) { @@ -150,17 +247,19 @@ void QDirectFBPixmapData::fill(const QColor &color) Q_ASSERT(dfbSurface); - if (color.alpha() < 255 && !hasAlphaChannel()) { + alpha = (color.alpha() < 255); + if (alpha && ::isOpaqueFormat(format)) { QSize size; dfbSurface->GetSize(dfbSurface, &size.rwidth(), &size.rheight()); screen->releaseDFBSurface(dfbSurface); + format = screen->alphaPixmapFormat(); dfbSurface = screen->createDFBSurface(size, screen->alphaPixmapFormat(), QDirectFBScreen::TrackSurface); forceRaster = false; setSerialNumber(++global_ser_no); if (!dfbSurface) { - qWarning("QDirectFBPixmapData::fill()"); - setSerialNumber(0); + qWarning("QDirecttFBPixmapData::fill()"); + invalidate(); return; } } @@ -186,15 +285,7 @@ void QDirectFBPixmapData::fill(const QColor &color) bool QDirectFBPixmapData::hasAlphaChannel() const { - if (!serialNumber()) - return false; - DFBSurfacePixelFormat format; - dfbSurface->GetPixelFormat(dfbSurface, &format); - return QDirectFBScreen::hasAlpha(format); - - // We don't need to ask DFB for this really. Can just keep track - // of what image format this has. It should always have either - // QDirectFBScreen::alphaPixmapFormat() or QScreen::pixelFormat() + return alpha; } QPixmap QDirectFBPixmapData::transformed(const QTransform &transform, @@ -221,11 +312,10 @@ QPixmap QDirectFBPixmapData::transformed(const QTransform &transform, return QPixmap(); QDirectFBPixmapData *data = new QDirectFBPixmapData(QPixmapData::PixmapType); - QImage::Format format = screen->pixelFormat(); DFBSurfaceBlittingFlags flags = DSBLIT_NOFX; - if (hasAlphaChannel()) { + data->alpha = alpha; + if (alpha) { flags = DSBLIT_BLEND_ALPHACHANNEL; - format = screen->alphaPixmapFormat(); } data->dfbSurface = screen->createDFBSurface(size, format, @@ -285,3 +375,10 @@ QImage* QDirectFBPixmapData::buffer() lockDirectFB(); return lockedImage; } + +void QDirectFBPixmapData::invalidate() +{ + setSerialNumber(0); + alpha = false; + format = QImage::Format_Invalid; +} diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h index 32676f8..7aa6df8 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h @@ -75,7 +75,10 @@ public: int metric(QPaintDevice::PaintDeviceMetric m) const {return QDirectFBPaintDevice::metric(m);} private: + void invalidate(); QDirectFBPaintEngine *engine; + QImage::Format format; + bool alpha; }; QT_END_HEADER -- cgit v0.12 From 743fc72ff7fd64ad5a0857f9103b68074a8c8103 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Thu, 9 Apr 2009 07:41:07 +0200 Subject: Revert "New binary for Windows configure" This reverts commit f0239a4983dd84b0e23c1e6f796c5c44dfde26b2. The old change did not write out QT_EDITION etc. to qconfig.h causing the build to break. --- configure.exe | Bin 851968 -> 1134592 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/configure.exe b/configure.exe index 891e928..13ca0e5 100644 Binary files a/configure.exe and b/configure.exe differ -- cgit v0.12 From f1152c539845b4a52f22c8f2c978c684b442f4be Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Thu, 9 Apr 2009 01:30:24 -0700 Subject: Make sure to update the member opacity variable Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index f72b0da..24d77bf 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -436,8 +436,9 @@ void QDirectFBPaintEnginePrivate::setCompositionMode(QPainter::CompositionMode m } } -void QDirectFBPaintEnginePrivate::setOpacity(quint8 opacity) +void QDirectFBPaintEnginePrivate::setOpacity(quint8 op) { + opacity = op; if (opacity == 255) { // ### need to check this stuff blitFlagsFromCompositionMode &= ~(DSBLIT_BLEND_COLORALPHA | DSBLIT_SRC_PREMULTCOLOR); -- cgit v0.12 From f3ee66750d279fb3d44cd13307312b703c77172f Mon Sep 17 00:00:00 2001 From: mae Date: Thu, 9 Apr 2009 12:20:35 +0200 Subject: Default text width before QPlainTextEdit was shown for the first time QTextEdit fakes an infinite width, while QPlainTextEdit defaulted to 0. This was discovered in creator's auto tests. --- src/gui/widgets/qplaintextedit.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index 2e9201d..a51ed2d 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -370,11 +370,16 @@ void QPlainTextDocumentLayout::layoutBlock(const QTextBlock &block) extraMargin += fm.width(QChar(0x21B5)); } tl->beginLayout(); + qreal availableWidth = d->width; + if (availableWidth <= 0) { + availableWidth = INT_MAX; // similar to text edit with pageSize.width == 0 + } + availableWidth -= 2*margin + extraMargin; while (1) { QTextLine line = tl->createLine(); if (!line.isValid()) break; - line.setLineWidth(d->width - 2*margin - extraMargin); + line.setLineWidth(availableWidth); height += leading; line.setPosition(QPointF(margin, height)); -- cgit v0.12 From 405f78f8e1ef68ebce2abd790820438c9e420755 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Thu, 9 Apr 2009 09:32:57 -0700 Subject: Inline hasAlphaChannel and add pixelFormat getter Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp | 5 ----- src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h | 4 ++-- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index a4e235b..0a1696a 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -283,11 +283,6 @@ void QDirectFBPixmapData::fill(const QColor &color) } } -bool QDirectFBPixmapData::hasAlphaChannel() const -{ - return alpha; -} - QPixmap QDirectFBPixmapData::transformed(const QTransform &transform, Qt::TransformationMode mode) const { diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h index 7aa6df8..6cfafcd 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h @@ -64,7 +64,7 @@ public: void fromImage(const QImage &image, Qt::ImageConversionFlags flags); void copy(const QPixmapData *data, const QRect &rect); void fill(const QColor &color); - bool hasAlphaChannel() const; + inline bool hasAlphaChannel() const { return alpha; } QPixmap transformed(const QTransform &matrix, Qt::TransformationMode mode) const; QImage toImage() const; @@ -73,7 +73,7 @@ public: // Pure virtual in QPixmapData, so re-implement here and delegate to QDirectFBPaintDevice int metric(QPaintDevice::PaintDeviceMetric m) const {return QDirectFBPaintDevice::metric(m);} - + inline QImage::Format pixelFormat() const { return format; } private: void invalidate(); QDirectFBPaintEngine *engine; -- cgit v0.12 From b106ddb649ec0260486755ff7a87bbdc719785d1 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Thu, 9 Apr 2009 09:34:14 -0700 Subject: Fix setOpacity Opacity doesn't play well with PorterDuff so we need to disable the porter duff when opacity is set. Also the DSBLIT_SRC_PREMULTCOLOR flag is not the right thing for us. Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 24d77bf..a8fdff8 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -440,10 +440,9 @@ void QDirectFBPaintEnginePrivate::setOpacity(quint8 op) { opacity = op; if (opacity == 255) { - // ### need to check this stuff - blitFlagsFromCompositionMode &= ~(DSBLIT_BLEND_COLORALPHA | DSBLIT_SRC_PREMULTCOLOR); + blitFlagsFromCompositionMode &= ~DSBLIT_BLEND_COLORALPHA; } else { - blitFlagsFromCompositionMode |= (DSBLIT_BLEND_COLORALPHA | DSBLIT_SRC_PREMULTCOLOR); + blitFlagsFromCompositionMode |= DSBLIT_BLEND_COLORALPHA; } } @@ -459,11 +458,14 @@ void QDirectFBPaintEnginePrivate::setRenderHints(QPainter::RenderHints hints) void QDirectFBPaintEnginePrivate::prepareForBlit(bool alpha) { quint32 blittingFlags = blitFlagsFromCompositionMode; - if (!alpha) { + if (alpha) { + surface->SetPorterDuff(surface, + (blittingFlags & DSBLIT_BLEND_COLORALPHA) + ? DSPD_NONE + : porterDuffRule); + } else { blittingFlags &= ~DSBLIT_BLEND_ALPHACHANNEL; surface->SetPorterDuff(surface, DSPD_NONE); - } else { - surface->SetPorterDuff(surface, porterDuffRule); } surface->SetColor(surface, 0xff, 0xff, 0xff, opacity); surface->SetBlittingFlags(surface, DFBSurfaceBlittingFlags(blittingFlags)); -- cgit v0.12 From cde39f381afe9cb255076a49b7859af54ae391d2 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Thu, 9 Apr 2009 09:53:10 -0700 Subject: Clean up code a little and get rid extra memcpys The QVarLengthArray approach makes no sense with DirectFB. Draw.*s is a regular function call and the receiving function even memcpy's the data on arrival anyway. Just call the Draw.* functions one by one Reviewed-by: TrustMe --- .../gfxdrivers/directfb/qdirectfbpaintengine.cpp | 51 ++-------------------- 1 file changed, 3 insertions(+), 48 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index a8fdff8..d9346fd 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -224,7 +224,7 @@ public: inline void updateClip(); inline void setClipDirty(); - void systemStateChanged(); //Needed to be notified when system clip changes + void systemStateChanged(); void begin(QPaintDevice *device); void end(); @@ -234,9 +234,6 @@ public: QTransform transform; int lastLockedHeight; private: -// QRegion rectsToClippedRegion(const QRect *rects, int n) const; -// QRegion rectsToClippedRegion(const QRectF *rects, int n) const; - IDirectFB *fb; DFBSurfaceDescription fbDescription; int fbWidth; @@ -489,61 +486,19 @@ void QDirectFBPaintEnginePrivate::setDFBColor(const QColor &color) void QDirectFBPaintEnginePrivate::drawLines(const QLine *lines, int n) const { - QVarLengthArray regions(n); - for (int i = 0; i < n; ++i) { const QLine l = transform.map(lines[i]); - - regions[i].x1 = l.x1(); - regions[i].y1 = l.y1(); - regions[i].x2 = l.x2(); - regions[i].y2 = l.y2(); + surface->DrawLine(surface, l.x1(), l.y1(), l.x2(), l.y2()); } - surface->DrawLines(surface, regions.data(), n); } void QDirectFBPaintEnginePrivate::drawLines(const QLineF *lines, int n) const { - QVarLengthArray regions(n); - for (int i = 0; i < n; ++i) { const QLine l = transform.map(lines[i]).toLine(); - - regions[i].x1 = l.x1(); - regions[i].y1 = l.y1(); - regions[i].x2 = l.x2(); - regions[i].y2 = l.y2(); + surface->DrawLine(surface, l.x1(), l.y1(), l.x2(), l.y2()); } - surface->DrawLines(surface, regions.data(), n); -} - -/* ### Commented out until it can be implemented properly using raster's QClipData -QRegion QDirectFBPaintEnginePrivate::rectsToClippedRegion(const QRect *rects, - int n) const -{ - QRegion region; - - for (int i = 0; i < n; ++i) { - const QRect r = transform.mapRect(rects[i]); - region += clip & r; - } - - return region; -} - -QRegion QDirectFBPaintEnginePrivate::rectsToClippedRegion(const QRectF *rects, - int n) const -{ - QRegion region; - - for (int i = 0; i < n; ++i) { - const QRect r = transform.mapRect(rects[i]).toRect(); - region += clip & r; - } - - return region; } -*/ void QDirectFBPaintEnginePrivate::fillRegion(const QRegion ®ion) const { -- cgit v0.12 From d4f23b414c337654d65ba54937e40d46b8510c0a Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Thu, 9 Apr 2009 13:37:59 -0700 Subject: Add a change description about DirectFB Reviewed-by: TrustMe --- dist/changes-4.5.1 | 1 + 1 file changed, 1 insertion(+) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index 5584c11..87f808d 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -144,6 +144,7 @@ Qt for Mac OS X Qt for Embedded Linux --------------------- +- Various improvements to the Qt DirectFB plugin. Qt for Windows CE ----------------- -- cgit v0.12 From b52e3da01bd43da12587654f6d4e3f3ececed0cf Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Thu, 9 Apr 2009 15:50:05 -0700 Subject: Better warnings when primary is not in videomem If connect options are set to include videoonly and creating the primary surface in video memory fails warn even in release mode. Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 04d2f57..8e57bb2 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -233,8 +233,11 @@ IDirectFBSurface* QDirectFBScreen::createDFBSurface(const DFBSurfaceDescription voDesc.caps = DFBSurfaceCapabilities(voDesc.caps | DSCAPS_VIDEOONLY); } result = d_ptr->dfb->CreateSurface(d_ptr->dfb, &voDesc, &newSurface); -#ifndef QT_NO_DEBUG - if (result != DFB_OK) { + if (result != DFB_OK +#ifdef QT_NO_DEBUG + && (desc->flags & DSDESC_CAPS) && (desc->caps & DSCAPS_PRIMARY) +#endif + ) { qWarning("QDirectFBScreen::createDFBSurface() Failed to create surface in video memory!\n" " Flags %0x Caps %0x width %d height %d pixelformat %0x %d preallocated %p %d\n%s", desc->flags, desc->caps, desc->width, desc->height, @@ -242,7 +245,6 @@ IDirectFBSurface* QDirectFBScreen::createDFBSurface(const DFBSurfaceDescription desc->preallocated[0].data, desc->preallocated[0].pitch, DirectFBErrorString(result)); } -#endif } if (!newSurface) -- cgit v0.12 From 0634fb1f6d8a4bef7ed82784b5b6deb117765df2 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Thu, 9 Apr 2009 15:56:24 -0700 Subject: Take out the DSCAPS_TRIPLE when not blitting When this code was written there was never a case when we would not blit our flips and hence the entire if (!(flipFlags & DSFLIP_BLIT)) business seems not to have been tested anyway. Since I don't see the point of this I am taking it out. Might enable us to actually create the primary surface in video memory more often. Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 8e57bb2..a230bf9 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -826,13 +826,6 @@ bool QDirectFBScreen::connect(const QString &displaySpec) | DSCAPS_PREMULTIPLIED); } - if (!(d_ptr->flipFlags & DSFLIP_BLIT)) { - description.caps = DFBSurfaceCapabilities(description.caps - | DSCAPS_DOUBLE - | DSCAPS_TRIPLE); - } - - // We don't track the primary surface as it's released in disconnect d_ptr->dfbSurface = createDFBSurface(&description, DontTrackSurface); if (!d_ptr->dfbSurface) { -- cgit v0.12 From 5c36257e21d00106e36f5b68eea78507efc3f39c Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Thu, 9 Apr 2009 16:55:48 -0700 Subject: Beautify displayArgs parsing Also add support for setting the width and height of the primary surface using display arguments (which can be good when debugging performace issues). Reviewed-by: Donald --- .../gfxdrivers/directfb/qdirectfbscreen.cpp | 30 +++++++++++++--------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index a230bf9..041d522 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -772,6 +772,18 @@ static void printDirectFBInfo(IDirectFB *fb) dev.blitting_flags, dev.drawing_flags, dev.video_memory); } +static inline bool setIntOption(const QStringList &arguments, const QString &variable, int *value) +{ + Q_ASSERT(value); + QRegExp rx(QString("%1=?(\\d+)").arg(variable)); + rx.setCaseSensitivity(Qt::CaseInsensitive); + if (arguments.indexOf(rx) != -1) { + *value = rx.cap(1).toInt(); + return true; + } + return false; +} + bool QDirectFBScreen::connect(const QString &displaySpec) { DFBResult result = DFB_OK; @@ -817,6 +829,10 @@ bool QDirectFBScreen::connect(const QString &displaySpec) DFBSurfaceDescription description; description.flags = DFBSurfaceDescriptionFlags(DSDESC_CAPS); + if (::setIntOption(displayArgs, QLatin1String("width"), &description.width)) + description.flags = DFBSurfaceDescriptionFlags(description.flags | DSDESC_WIDTH); + if (::setIntOption(displayArgs, QLatin1String("height"), &description.height)) + description.flags = DFBSurfaceDescriptionFlags(description.flags | DSDESC_HEIGHT); description.caps = DFBSurfaceCapabilities(DSCAPS_PRIMARY | DSCAPS_DOUBLE | DSCAPS_STATIC_ALLOC); @@ -882,18 +898,8 @@ bool QDirectFBScreen::connect(const QString &displaySpec) setPixelFormat(getImageFormat(d_ptr->dfbSurface)); physWidth = physHeight = -1; - QRegExp mmWidthRx(QLatin1String("mmWidth=?(\\d+)")); - int dimIdxW = displayArgs.indexOf(mmWidthRx); - if (dimIdxW >= 0) { - mmWidthRx.exactMatch(displayArgs.at(dimIdxW)); - physWidth = mmWidthRx.cap(1).toInt(); - } - QRegExp mmHeightRx(QLatin1String("mmHeight=?(\\d+)")); - int dimIdxH = displayArgs.indexOf(mmHeightRx); - if (dimIdxH >= 0) { - mmHeightRx.exactMatch(displayArgs.at(dimIdxH)); - physHeight = mmHeightRx.cap(1).toInt(); - } + ::setIntOption(displayArgs, QLatin1String("mmWidth"), &physWidth); + ::setIntOption(displayArgs, QLatin1String("mmHeight"), &physHeight); const int dpi = 72; if (physWidth < 0) physWidth = qRound(dw * 25.4 / dpi); -- cgit v0.12 From 6e5774d84e7e3b68736f95fae09a084bd5b9ac7a Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Thu, 9 Apr 2009 13:50:38 +1000 Subject: Fixes compile of WebKit with MinGW when using any `-j' option to build in parallel. On Windows, when a project has a lot of INCLUDEPATHs, some extra logic takes place to work around an issue of large command lines. Instead of passing all the paths directly to moc.exe, the paths are written to mocinclude.tmp which is then read from by moc.exe. Prior to this change, every moc rule tries to write to mocinclude.tmp. When running make with -j, this will happen in parallel, causing this error message: "The process cannot access the file because it is being used by another process" Change the logic so mocinclude.tmp is generated by its own rule. Reviewed-by: Lincoln Ramsay --- mkspecs/features/moc.prf | 62 ++++++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/mkspecs/features/moc.prf b/mkspecs/features/moc.prf index f18d462..975867e 100644 --- a/mkspecs/features/moc.prf +++ b/mkspecs/features/moc.prf @@ -8,31 +8,45 @@ isEmpty(MOC_DIR):MOC_DIR = . isEmpty(QMAKE_H_MOD_MOC):QMAKE_H_MOD_MOC = moc_ isEmpty(QMAKE_EXT_CPP_MOC):QMAKE_EXT_CPP_MOC = .moc -# This function on Windows puts the includes into a .inc file which moc will read, if the project -# has more than 30 includes. We do this to overcome a command-line limit on Win < XP -# Otherwise the function simply returns the normal command-line for moc -defineReplace(mocCmd) { - win32:count($$list($$INCPATH), 40, >) { - EOC = $$escape_expand(\n\t) +# On Windows, put the includes into a .inc file which moc will read, if the project +# has too many includes. We do this to overcome a command-line limit on Win < XP +INCLUDETEMP= +win32:count($$list($$INCPATH), 40, >) { + INCLUDETEMP = mocinclude.tmp + + # Remove any existing mocinclude.tmp when qmake runs + WIN_OUT_PWD=$$OUT_PWD + WIN_OUT_PWD~=s,/,\,g + system($$QMAKE_DEL_FILE $$WIN_OUT_PWD\\$$INCLUDETEMP > NUL 2>&1) + + EOC = $$escape_expand(\n\t) + + if(contains(TEMPLATE, "vc.*")|contains(TEMPLATE_PREFIX, "vc")) { + # the VCPROJ generator will replace the \r\h with the coded \r\n: + # No other generator understands the \h + if(win32-msvc.net|win32-msvc2*|wince*msvc*): EOC = $$escape_expand(\r\h) + else: EOC = $$escape_expand(\\)$$escape_expand(\n\t) + } - if(contains(TEMPLATE, "vc.*")|contains(TEMPLATE_PREFIX, "vc")) { - # the VCPROJ generator will replace the \r\h with the coded \r\n: - # No other generator understands the \h - if(win32-msvc.net|win32-msvc2*|wince*msvc*): EOC = $$escape_expand(\r\h) - else: EOC = $$escape_expand(\\)$$escape_expand(\n\t) - } + unset(INCFILELIST) + RET = + for(incfile, $$list($$INCPATH)) { + INCFILELIST = -I$$incfile + isEmpty(RET): RET += @echo $$INCFILELIST> $$INCLUDETEMP $$EOC + else: RET += @echo $$INCFILELIST>> $$INCLUDETEMP $$EOC + } + !isEmpty(INCFILELIST):RET += @echo $$INCFILELIST>> $$INCLUDETEMP $$EOC - INCLUDETEMP = mocinclude.tmp - unset(INCFILELIST) - RET = - for(incfile, $$list($$INCPATH)) { - INCFILELIST = -I$$incfile - isEmpty(RET): RET += @echo $$INCFILELIST> $$INCLUDETEMP $$EOC - else: RET += @echo $$INCFILELIST>> $$INCLUDETEMP $$EOC - } - !isEmpty(INCFILELIST):RET += @echo $$INCFILELIST>> $$INCLUDETEMP $$EOC - RET += $$QMAKE_MOC $(DEFINES) @$$INCLUDETEMP $$join(QMAKE_COMPILER_DEFINES, " -D", -D) $$1 -o $$2 - return($$RET) + build_pass|isEmpty(BUILDS) { + mocinclude.target = $$INCLUDETEMP + mocinclude.commands = $$RET + QMAKE_EXTRA_TARGETS += mocinclude + } +} + +defineReplace(mocCmd) { + !isEmpty(INCLUDETEMP) { + return($$QMAKE_MOC $(DEFINES) @$$INCLUDETEMP $$join(QMAKE_COMPILER_DEFINES, " -D", -D) $$1 -o $$2) } return($$QMAKE_MOC $(DEFINES) $(INCPATH) $$join(QMAKE_COMPILER_DEFINES, " -D", -D) $$1 -o $$2) } @@ -45,6 +59,7 @@ moc_header.output = $$MOC_DIR/$${QMAKE_H_MOD_MOC}${QMAKE_FILE_BASE}$${first(QMAK moc_header.input = HEADERS moc_header.variable_out = SOURCES moc_header.name = MOC ${QMAKE_FILE_IN} +!isEmpty(INCLUDETEMP):moc_header.depends += $$INCLUDETEMP silent:moc_header.commands = @echo moc ${QMAKE_FILE_IN} && $$moc_header.commands QMAKE_EXTRA_COMPILERS += moc_header INCREDIBUILD_XGE += moc_header @@ -56,6 +71,7 @@ moc_source.commands = ${QMAKE_FUNC_mocCmd} moc_source.output = $$MOC_DIR/$${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}$${QMAKE_EXT_CPP_MOC} moc_source.input = SOURCES OBJECTIVE_SOURCES moc_source.name = MOC ${QMAKE_FILE_IN} +!isEmpty(INCLUDETEMP):moc_source.depends += $$INCLUDETEMP silent:moc_source.commands = @echo moc ${QMAKE_FILE_IN} && $$moc_source.commands QMAKE_EXTRA_COMPILERS += moc_source INCREDIBUILD_XGE += moc_source -- cgit v0.12 From 02f4f244f585868dc1cca208f0caa6f02d734d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20S=C3=B8rvig?= Date: Tue, 14 Apr 2009 09:16:55 +0200 Subject: Fix spelling error Reviewed-by: TrustMe --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 7e66a98..6d67dee 100755 --- a/configure +++ b/configure @@ -2698,7 +2698,7 @@ if [ "$PLATFORM_MAC" = "yes" ]; then for i in $CFG_MAC_ARCHS do if echo "$ALLOWED" | grep -w -v "$i" > /dev/null 2>&1; then - echo "Unknown architecture: \"$i\". Supported architechtures: x86 ppc x86_64 ppc64"; + echo "Unknown architecture: \"$i\". Supported architectures: x86 ppc x86_64 ppc64"; exit 2; fi done -- cgit v0.12 From 1c4f8069dea405cc80e87548e1e3609611a7bab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20S=C3=B8rvig?= Date: Tue, 14 Apr 2009 09:30:15 +0200 Subject: Allow "i386" as an alias for x86 for Mac universal builds GCC uses i386, but configure has always used x86, which can lead to confusion. Reviewed-by: nrc --- configure | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 6d67dee..adb08a8 100755 --- a/configure +++ b/configure @@ -2694,14 +2694,17 @@ fi # check -arch arguments for validity. if [ "$PLATFORM_MAC" = "yes" ]; then - ALLOWED="x86 ppc x86_64 ppc64" + ALLOWED="x86 ppc x86_64 ppc64 i386" for i in $CFG_MAC_ARCHS do if echo "$ALLOWED" | grep -w -v "$i" > /dev/null 2>&1; then - echo "Unknown architecture: \"$i\". Supported architectures: x86 ppc x86_64 ppc64"; + echo "Unknown architecture: \"$i\". Supported architectures: x86[i386] ppc x86_64 ppc64"; exit 2; fi done + +# replace "i386" with "x86" to support configuring with -arch i386 as an alias for x86. + CFG_MAC_ARCHS="${CFG_MAC_ARCHS/i386/x86}" fi # find the default framework value -- cgit v0.12 From 91e4f13001a2969ea6311171fb5e7ec0164a3165 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20S=C3=B8rvig?= Date: Tue, 14 Apr 2009 09:40:47 +0200 Subject: Fix typo. Reviewed-by: nrc --- tools/macdeployqt/macdeployqt/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/macdeployqt/macdeployqt/main.cpp b/tools/macdeployqt/macdeployqt/main.cpp index d6f7e5f..0026c40 100644 --- a/tools/macdeployqt/macdeployqt/main.cpp +++ b/tools/macdeployqt/macdeployqt/main.cpp @@ -63,7 +63,7 @@ int main(int argc, char **argv) qDebug() << "framework. The accessibilty, image formats, and text codec"; qDebug() << "plugins are always copied, unless \"-no-plugins\" is specified."; qDebug() << ""; - qDebug() << "See the \"Deploying an Application on Qt/Mac\" typic in the"; + qDebug() << "See the \"Deploying an Application on Qt/Mac\" topic in the"; qDebug() << "documentation for more information about deployment on Mac OS X."; return 0; -- cgit v0.12 From 69414e5afeb87df2f7a371962f092c2d277aaf6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20S=C3=B8rvig?= Date: Tue, 14 Apr 2009 09:44:23 +0200 Subject: Remove duplicate defines in the mac accessibility module. This was causing compile warnings. Reviewed-by: nrc --- src/gui/accessible/qaccessible_mac.mm | 122 ---------------------------------- 1 file changed, 122 deletions(-) diff --git a/src/gui/accessible/qaccessible_mac.mm b/src/gui/accessible/qaccessible_mac.mm index b6412c2..68efb8f 100644 --- a/src/gui/accessible/qaccessible_mac.mm +++ b/src/gui/accessible/qaccessible_mac.mm @@ -72,55 +72,36 @@ typedef NSString * const QAXRoleType; #define QAXApplicationRole NSAccessibilityApplicationRole #define QAXButtonRole NSAccessibilityButtonRole #define QAXCancelAction NSAccessibilityCancelAction -#define QAXCancelAction NSAccessibilityCancelAction #define QAXCheckBoxRole NSAccessibilityCheckBoxRole #define QAXChildrenAttribute NSAccessibilityChildrenAttribute -#define QAXChildrenAttribute NSAccessibilityChildrenAttribute -#define QAXChildrenAttribute NSAccessibilityChildrenAttribute #define QAXCloseButtonAttribute NSAccessibilityCloseButtonAttribute #define QAXCloseButtonAttribute NSAccessibilityCloseButtonAttribute #define QAXColumnRole NSAccessibilityColumnRole #define QAXConfirmAction NSAccessibilityConfirmAction -#define QAXConfirmAction NSAccessibilityConfirmAction #define QAXContentsAttribute NSAccessibilityContentsAttribute -#define QAXContentsAttribute NSAccessibilityContentsAttribute -#define QAXDecrementAction NSAccessibilityDecrementAction #define QAXDecrementAction NSAccessibilityDecrementAction #define QAXDecrementArrowSubrole NSAccessibilityDecrementArrowSubrole #define QAXDecrementPageSubrole NSAccessibilityDecrementPageSubrole #define QAXDescriptionAttribute NSAccessibilityDescriptionAttribute -#define QAXDescriptionAttribute NSAccessibilityDescriptionAttribute -#define QAXDescriptionAttribute NSAccessibilityDescriptionAttribute -#define QAXDescriptionAttribute NSAccessibilityDescriptionAttribute -#define QAXEnabledAttribute NSAccessibilityEnabledAttribute #define QAXEnabledAttribute NSAccessibilityEnabledAttribute #define QAXExpandedAttribute NSAccessibilityExpandedAttribute #define QAXFocusedAttribute NSAccessibilityFocusedAttribute -#define QAXFocusedAttribute NSAccessibilityFocusedAttribute -#define QAXFocusedAttribute NSAccessibilityFocusedAttribute #define QAXFocusedUIElementChangedNotification NSAccessibilityFocusedUIElementChangedNotification #define QAXFocusedWindowChangedNotification NSAccessibilityFocusedWindowChangedNotification #define QAXGroupRole NSAccessibilityGroupRole #define QAXGrowAreaAttribute NSAccessibilityGrowAreaAttribute -#define QAXGrowAreaAttribute NSAccessibilityGrowAreaAttribute #define QAXGrowAreaRole NSAccessibilityGrowAreaRole #define QAXHelpAttribute NSAccessibilityHelpAttribute -#define QAXHelpAttribute NSAccessibilityHelpAttribute -#define QAXHelpAttribute NSAccessibilityHelpAttribute #define QAXHorizontalOrientationValue NSAccessibilityHorizontalOrientationValue #define QAXHorizontalScrollBarAttribute NSAccessibilityHorizontalScrollBarAttribute -#define QAXHorizontalScrollBarAttribute NSAccessibilityHorizontalScrollBarAttribute -#define QAXIncrementAction NSAccessibilityIncrementAction #define QAXIncrementAction NSAccessibilityIncrementAction #define QAXIncrementArrowSubrole NSAccessibilityIncrementArrowSubrole #define QAXIncrementPageSubrole NSAccessibilityIncrementPageSubrole #define QAXIncrementorRole NSAccessibilityIncrementorRole #define QAXLinkedUIElementsAttribute NSAccessibilityLinkedUIElementsAttribute -#define QAXLinkedUIElementsAttribute NSAccessibilityLinkedUIElementsAttribute #define QAXListRole NSAccessibilityListRole #define QAXMainAttribute NSAccessibilityMainAttribute #define QAXMaxValueAttribute NSAccessibilityMaxValueAttribute -#define QAXMaxValueAttribute NSAccessibilityMaxValueAttribute #define QAXMenuBarRole NSAccessibilityMenuBarRole #define QAXMenuButtonRole NSAccessibilityMenuButtonRole #define QAXMenuClosedNotification NSAccessibilityMenuClosedNotification @@ -128,151 +109,90 @@ typedef NSString * const QAXRoleType; #define QAXMenuOpenedNotification NSAccessibilityMenuOpenedNotification #define QAXMenuRole NSAccessibilityMenuRole #define QAXMinValueAttribute NSAccessibilityMinValueAttribute -#define QAXMinValueAttribute NSAccessibilityMinValueAttribute #define QAXMinimizeButtonAttribute NSAccessibilityMinimizeButtonAttribute -#define QAXMinimizeButtonAttribute NSAccessibilityMinimizeButtonAttribute -#define QAXMinimizedAttribute NSAccessibilityMinimizedAttribute #define QAXMinimizedAttribute NSAccessibilityMinimizedAttribute #define QAXNextContentsAttribute NSAccessibilityNextContentsAttribute -#define QAXNextContentsAttribute NSAccessibilityNextContentsAttribute -#define QAXOrientationAttribute NSAccessibilityOrientationAttribute -#define QAXOrientationAttribute NSAccessibilityOrientationAttribute #define QAXOrientationAttribute NSAccessibilityOrientationAttribute #define QAXParentAttribute NSAccessibilityParentAttribute #define QAXPickAction NSAccessibilityPickAction -#define QAXPickAction NSAccessibilityPickAction #define QAXPopUpButtonRole NSAccessibilityPopUpButtonRole #define QAXPositionAttribute NSAccessibilityPositionAttribute -#define QAXPositionAttribute NSAccessibilityPositionAttribute -#define QAXPressAction NSAccessibilityPressAction #define QAXPressAction NSAccessibilityPressAction #define QAXPreviousContentsAttribute NSAccessibilityPreviousContentsAttribute -#define QAXPreviousContentsAttribute NSAccessibilityPreviousContentsAttribute -#define QAXPreviousContentsAttribute NSAccessibilityPreviousContentsAttribute #define QAXProgressIndicatorRole NSAccessibilityProgressIndicatorRole #define QAXRadioButtonRole NSAccessibilityRadioButtonRole #define QAXRoleAttribute NSAccessibilityRoleAttribute -#define QAXRoleAttribute NSAccessibilityRoleAttribute #define QAXRoleDescriptionAttribute NSAccessibilityRoleDescriptionAttribute #define QAXRowRole NSAccessibilityRowRole #define QAXRowsAttribute NSAccessibilityRowsAttribute -#define QAXRowsAttribute NSAccessibilityRowsAttribute -#define QAXScrollAreaRole NSAccessibilityScrollAreaRole -#define QAXScrollAreaRole NSAccessibilityScrollAreaRole #define QAXScrollAreaRole NSAccessibilityScrollAreaRole #define QAXScrollBarRole NSAccessibilityScrollBarRole #define QAXSelectedAttribute NSAccessibilitySelectedAttribute #define QAXSelectedChildrenAttribute NSAccessibilitySelectedChildrenAttribute #define QAXSelectedRowsAttribute NSAccessibilitySelectedRowsAttribute -#define QAXSelectedRowsAttribute NSAccessibilitySelectedRowsAttribute -#define QAXSizeAttribute NSAccessibilitySizeAttribute #define QAXSizeAttribute NSAccessibilitySizeAttribute #define QAXSliderRole NSAccessibilitySliderRole #define QAXSplitGroupRole NSAccessibilitySplitGroupRole #define QAXSplitterRole NSAccessibilitySplitterRole -#define QAXSplitterRole NSAccessibilitySplitterRole -#define QAXSplitterRole NSAccessibilitySplitterRole -#define QAXSplittersAttribute NSAccessibilitySplittersAttribute #define QAXSplittersAttribute NSAccessibilitySplittersAttribute #define QAXStaticTextRole NSAccessibilityStaticTextRole -#define QAXStaticTextRole NSAccessibilityStaticTextRole -#define QAXSubroleAttribute NSAccessibilitySubroleAttribute #define QAXSubroleAttribute NSAccessibilitySubroleAttribute #define QAXSubroleAttribute NSAccessibilitySubroleAttribute #define QAXTabGroupRole NSAccessibilityTabGroupRole -#define QAXTabGroupRole NSAccessibilityTabGroupRole #define QAXTableRole NSAccessibilityTableRole #define QAXTabsAttribute NSAccessibilityTabsAttribute -#define QAXTabsAttribute NSAccessibilityTabsAttribute #define QAXTextFieldRole NSAccessibilityTextFieldRole -#define QAXTextFieldRole NSAccessibilityTextFieldRole -#define QAXTitleAttribute NSAccessibilityTitleAttribute -#define QAXTitleAttribute NSAccessibilityTitleAttribute #define QAXTitleAttribute NSAccessibilityTitleAttribute -#define QAXTitleAttribute NSAccessibilityTitleAttribute -#define QAXTitleUIElementAttribute NSAccessibilityTitleUIElementAttribute #define QAXTitleUIElementAttribute NSAccessibilityTitleUIElementAttribute #define QAXToolbarButtonAttribute NSAccessibilityToolbarButtonAttribute -#define QAXToolbarButtonAttribute NSAccessibilityToolbarButtonAttribute #define QAXToolbarRole NSAccessibilityToolbarRole #define QAXTopLevelUIElementAttribute NSAccessibilityTopLevelUIElementAttribute -#define QAXTopLevelUIElementAttribute NSAccessibilityTopLevelUIElementAttribute -#define QAXTopLevelUIElementAttribute NSAccessibilityTopLevelUIElementAttribute -#define QAXUnknownRole NSAccessibilityUnknownRole #define QAXUnknownRole NSAccessibilityUnknownRole #define QAXValueAttribute NSAccessibilityValueAttribute -#define QAXValueAttribute NSAccessibilityValueAttribute -#define QAXValueAttribute NSAccessibilityValueAttribute -#define QAXValueAttribute NSAccessibilityValueAttribute #define QAXValueChangedNotification NSAccessibilityValueChangedNotification #define QAXValueIndicatorRole NSAccessibilityValueIndicatorRole #define QAXVerticalOrientationValue NSAccessibilityVerticalOrientationValue #define QAXVerticalScrollBarAttribute NSAccessibilityVerticalScrollBarAttribute -#define QAXVerticalScrollBarAttribute NSAccessibilityVerticalScrollBarAttribute #define QAXVisibleRowsAttribute NSAccessibilityVisibleRowsAttribute -#define QAXVisibleRowsAttribute NSAccessibilityVisibleRowsAttribute -#define QAXWindowAttribute NSAccessibilityWindowAttribute -#define QAXWindowAttribute NSAccessibilityWindowAttribute #define QAXWindowAttribute NSAccessibilityWindowAttribute #define QAXWindowCreatedNotification NSAccessibilityWindowCreatedNotification #define QAXWindowMovedNotification NSAccessibilityWindowMovedNotification #define QAXWindowRole NSAccessibilityWindowRole #define QAXZoomButtonAttribute NSAccessibilityZoomButtonAttribute -#define QAXZoomButtonAttribute NSAccessibilityZoomButtonAttribute #else typedef CFStringRef const QAXRoleType; #define QAXApplicationRole kAXApplicationRole #define QAXButtonRole kAXButtonRole #define QAXCancelAction kAXCancelAction -#define QAXCancelAction kAXCancelAction #define QAXCheckBoxRole kAXCheckBoxRole #define QAXChildrenAttribute kAXChildrenAttribute -#define QAXChildrenAttribute kAXChildrenAttribute -#define QAXChildrenAttribute kAXChildrenAttribute -#define QAXCloseButtonAttribute kAXCloseButtonAttribute #define QAXCloseButtonAttribute kAXCloseButtonAttribute #define QAXColumnRole kAXColumnRole #define QAXConfirmAction kAXConfirmAction -#define QAXConfirmAction kAXConfirmAction #define QAXContentsAttribute kAXContentsAttribute -#define QAXContentsAttribute kAXContentsAttribute -#define QAXDecrementAction kAXDecrementAction #define QAXDecrementAction kAXDecrementAction #define QAXDecrementArrowSubrole kAXDecrementArrowSubrole #define QAXDecrementPageSubrole kAXDecrementPageSubrole #define QAXDescriptionAttribute kAXDescriptionAttribute -#define QAXDescriptionAttribute kAXDescriptionAttribute -#define QAXDescriptionAttribute kAXDescriptionAttribute -#define QAXDescriptionAttribute kAXDescriptionAttribute -#define QAXEnabledAttribute kAXEnabledAttribute #define QAXEnabledAttribute kAXEnabledAttribute #define QAXExpandedAttribute kAXExpandedAttribute #define QAXFocusedAttribute kAXFocusedAttribute -#define QAXFocusedAttribute kAXFocusedAttribute -#define QAXFocusedAttribute kAXFocusedAttribute #define QAXFocusedUIElementChangedNotification kAXFocusedUIElementChangedNotification #define QAXFocusedWindowChangedNotification kAXFocusedWindowChangedNotification #define QAXGroupRole kAXGroupRole #define QAXGrowAreaAttribute kAXGrowAreaAttribute -#define QAXGrowAreaAttribute kAXGrowAreaAttribute #define QAXGrowAreaRole kAXGrowAreaRole #define QAXHelpAttribute kAXHelpAttribute -#define QAXHelpAttribute kAXHelpAttribute -#define QAXHelpAttribute kAXHelpAttribute #define QAXHorizontalOrientationValue kAXHorizontalOrientationValue #define QAXHorizontalScrollBarAttribute kAXHorizontalScrollBarAttribute -#define QAXHorizontalScrollBarAttribute kAXHorizontalScrollBarAttribute -#define QAXIncrementAction kAXIncrementAction #define QAXIncrementAction kAXIncrementAction #define QAXIncrementArrowSubrole kAXIncrementArrowSubrole #define QAXIncrementPageSubrole kAXIncrementPageSubrole #define QAXIncrementorRole kAXIncrementorRole #define QAXLinkedUIElementsAttribute kAXLinkedUIElementsAttribute -#define QAXLinkedUIElementsAttribute kAXLinkedUIElementsAttribute #define QAXListRole kAXListRole #define QAXMainAttribute kAXMainAttribute #define QAXMaxValueAttribute kAXMaxValueAttribute -#define QAXMaxValueAttribute kAXMaxValueAttribute #define QAXMenuBarRole kAXMenuBarRole #define QAXMenuButtonRole kAXMenuButtonRole #define QAXMenuClosedNotification kAXMenuClosedNotification @@ -280,97 +200,55 @@ typedef CFStringRef const QAXRoleType; #define QAXMenuOpenedNotification kAXMenuOpenedNotification #define QAXMenuRole kAXMenuRole #define QAXMinValueAttribute kAXMinValueAttribute -#define QAXMinValueAttribute kAXMinValueAttribute #define QAXMinimizeButtonAttribute kAXMinimizeButtonAttribute -#define QAXMinimizeButtonAttribute kAXMinimizeButtonAttribute -#define QAXMinimizedAttribute kAXMinimizedAttribute #define QAXMinimizedAttribute kAXMinimizedAttribute #define QAXNextContentsAttribute kAXNextContentsAttribute -#define QAXNextContentsAttribute kAXNextContentsAttribute -#define QAXOrientationAttribute kAXOrientationAttribute -#define QAXOrientationAttribute kAXOrientationAttribute #define QAXOrientationAttribute kAXOrientationAttribute #define QAXParentAttribute kAXParentAttribute #define QAXPickAction kAXPickAction -#define QAXPickAction kAXPickAction #define QAXPopUpButtonRole kAXPopUpButtonRole #define QAXPositionAttribute kAXPositionAttribute -#define QAXPositionAttribute kAXPositionAttribute -#define QAXPressAction kAXPressAction #define QAXPressAction kAXPressAction #define QAXPreviousContentsAttribute kAXPreviousContentsAttribute -#define QAXPreviousContentsAttribute kAXPreviousContentsAttribute -#define QAXPreviousContentsAttribute kAXPreviousContentsAttribute #define QAXProgressIndicatorRole kAXProgressIndicatorRole #define QAXRadioButtonRole kAXRadioButtonRole #define QAXRoleAttribute kAXRoleAttribute -#define QAXRoleAttribute kAXRoleAttribute #define QAXRoleDescriptionAttribute kAXRoleDescriptionAttribute #define QAXRowRole kAXRowRole #define QAXRowsAttribute kAXRowsAttribute -#define QAXRowsAttribute kAXRowsAttribute -#define QAXScrollAreaRole kAXScrollAreaRole -#define QAXScrollAreaRole kAXScrollAreaRole #define QAXScrollAreaRole kAXScrollAreaRole #define QAXScrollBarRole kAXScrollBarRole #define QAXSelectedAttribute kAXSelectedAttribute #define QAXSelectedChildrenAttribute kAXSelectedChildrenAttribute #define QAXSelectedRowsAttribute kAXSelectedRowsAttribute -#define QAXSelectedRowsAttribute kAXSelectedRowsAttribute -#define QAXSizeAttribute kAXSizeAttribute #define QAXSizeAttribute kAXSizeAttribute #define QAXSliderRole kAXSliderRole #define QAXSplitGroupRole kAXSplitGroupRole #define QAXSplitterRole kAXSplitterRole -#define QAXSplitterRole kAXSplitterRole -#define QAXSplitterRole kAXSplitterRole -#define QAXSplittersAttribute kAXSplittersAttribute #define QAXSplittersAttribute kAXSplittersAttribute #define QAXStaticTextRole kAXStaticTextRole -#define QAXStaticTextRole kAXStaticTextRole -#define QAXSubroleAttribute kAXSubroleAttribute #define QAXSubroleAttribute kAXSubroleAttribute -#define QAXSubroleAttribute kAXSubroleAttribute -#define QAXTabGroupRole kAXTabGroupRole #define QAXTabGroupRole kAXTabGroupRole #define QAXTableRole kAXTableRole #define QAXTabsAttribute kAXTabsAttribute -#define QAXTabsAttribute kAXTabsAttribute -#define QAXTextFieldRole kAXTextFieldRole #define QAXTextFieldRole kAXTextFieldRole #define QAXTitleAttribute kAXTitleAttribute -#define QAXTitleAttribute kAXTitleAttribute -#define QAXTitleAttribute kAXTitleAttribute -#define QAXTitleAttribute kAXTitleAttribute #define QAXTitleUIElementAttribute kAXTitleUIElementAttribute -#define QAXTitleUIElementAttribute kAXTitleUIElementAttribute -#define QAXToolbarButtonAttribute kAXToolbarButtonAttribute #define QAXToolbarButtonAttribute kAXToolbarButtonAttribute #define QAXToolbarRole kAXToolbarRole #define QAXTopLevelUIElementAttribute kAXTopLevelUIElementAttribute -#define QAXTopLevelUIElementAttribute kAXTopLevelUIElementAttribute -#define QAXTopLevelUIElementAttribute kAXTopLevelUIElementAttribute #define QAXUnknownRole kAXUnknownRole -#define QAXUnknownRole kAXUnknownRole -#define QAXValueAttribute kAXValueAttribute -#define QAXValueAttribute kAXValueAttribute -#define QAXValueAttribute kAXValueAttribute #define QAXValueAttribute kAXValueAttribute #define QAXValueChangedNotification kAXValueChangedNotification #define QAXValueIndicatorRole kAXValueIndicatorRole #define QAXVerticalOrientationValue kAXVerticalOrientationValue #define QAXVerticalScrollBarAttribute kAXVerticalScrollBarAttribute -#define QAXVerticalScrollBarAttribute kAXVerticalScrollBarAttribute -#define QAXVisibleRowsAttribute kAXVisibleRowsAttribute #define QAXVisibleRowsAttribute kAXVisibleRowsAttribute #define QAXWindowAttribute kAXWindowAttribute -#define QAXWindowAttribute kAXWindowAttribute -#define QAXWindowAttribute kAXWindowAttribute #define QAXWindowCreatedNotification kAXWindowCreatedNotification #define QAXWindowMovedNotification kAXWindowMovedNotification #define QAXWindowRole kAXWindowRole #define QAXZoomButtonAttribute kAXZoomButtonAttribute -#define QAXZoomButtonAttribute kAXZoomButtonAttribute #endif -- cgit v0.12 From d5a99cff5235ff72f68f57ab0772274d332b118b Mon Sep 17 00:00:00 2001 From: jasplin Date: Tue, 14 Apr 2009 10:14:03 +0200 Subject: My changes. --- dist/changes-4.5.1 | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index 87f808d..f0ab546 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -39,6 +39,13 @@ Third party components - QAuthenticator * [237979] fix implemenation of md5-sess +- QColorDialog + * [247349] Fixed bug causing the wrong alpha value to be returned. + +- QCompleter + * [250064] Fixed focus policy propagation regression. + * [246056] Fixed assertion failure in setCompletionPrefix(). + - QFileInfo * [205244] return valid file info also for relative UNC paths @@ -63,6 +70,10 @@ Third party components * Improved support for setting background and foreground roles in styles such as the text color in a combo box popup on Mac and Cleanlooks. +- QWizard + * [248107] Fixed bug on Vista causing Back button to connect twice to the back() signal. + + **************************************************************************** * Database Drivers * **************************************************************************** -- cgit v0.12 From 52f87de53328c661049acf09d5fedc1850aa9bfa Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 8 Apr 2009 10:35:18 +0200 Subject: Fix docs of QPainter::initFrom. --- src/gui/painting/qpainter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 2beb8c2..18993e1 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -1465,8 +1465,8 @@ bool QPainter::isActive() const /*! Initializes the painters pen, background and font to the same as - the given \a widget. Call this function after begin() while the - painter is active. + the given \a widget. This function is automatically when the + painter is opened on a QWidget. \sa begin(), {QPainter#Settings}{Settings} */ -- cgit v0.12 From 4d82197292815c718a569a953de8082e64fc7e46 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Tue, 14 Apr 2009 11:05:51 +0200 Subject: Don't crash in XP style if the painter is inactive. --- src/gui/styles/qwindowsxpstyle.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/styles/qwindowsxpstyle.cpp b/src/gui/styles/qwindowsxpstyle.cpp index 9d735a7..2f4254e 100644 --- a/src/gui/styles/qwindowsxpstyle.cpp +++ b/src/gui/styles/qwindowsxpstyle.cpp @@ -607,7 +607,7 @@ void QWindowsXPStylePrivate::drawBackground(XPThemeData &themeData) QPainter *painter = themeData.painter; Q_ASSERT_X(painter != 0, "QWindowsXPStylePrivate::drawBackground()", "Trying to draw a theme part without a painter"); - if (!painter) + if (!painter || !painter->isActive()) return; painter->save(); @@ -2834,7 +2834,7 @@ void QWindowsXPStyle::drawComplexControl(ComplexControl cc, const QStyleOptionCo bflags |= State_MouseOver; } } - + QStyleOption tool(0); tool.palette = toolbutton->palette; if (toolbutton->subControls & SC_ToolButton) { -- cgit v0.12 From afc51dc4cf5254f6cfb552bc09dd443a8fe0762b Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Tue, 14 Apr 2009 12:59:26 +0200 Subject: Updated changelog for 4.5.1 --- dist/changes-4.5.1 | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index f0ab546..38651a9 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -119,6 +119,11 @@ Qt for Windows * [248036] Fixed an issue where tool buttons would incorrectly hover when disabled. +- [249576] Fixed a crash when using a combobox with Qt::NoFocus. +- [244875] System menu will now be shown for a fullscreen window. +- [240891] Corrected the focus behavior of native file dialogs, when application has multiple toplevels. +- [245330] Fixed a bug which causes mouse inputs to be ignored on modal dialogs, when shown from an ActieQt control. + Qt for Mac OS X --------------- @@ -132,11 +137,13 @@ Qt for Mac OS X with 4.5.1, we don't foresee changing this again. * Fixed a bug where some windows would not get activation when they normally should. * Key events sent to popups do not get propagated onwards. - * [249296] Fix a bug where lineedits on a second page of a stack widget wourd not get key events + * [249296] Fix a bug where lineedits on a second page of a stack widget would not get key events * QFileOpenEvents are no longer sent for items passed on the command line. * Various fixes for determining metrics of text and the ability to disable kerning. * [248918] Fixed color matching for themed text items. * Modify the colliding mice example to work better with coalesced updates. + * Fixed a bug where the drag cursor was not updated when modifier keys are used. + * [247947] Fixed a crash in drag and drop. - Fix a crash when showing a widget that is window modal but has no parent. - [248803] Showing two dialogs at the same time don't get shared activation. -- cgit v0.12 From 67344b0e7617fde78722440346a779aee0bf1286 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 14 Apr 2009 13:38:47 +0200 Subject: Cocoa: dialogs are sometimes not shown if triggered from outside the app NSPanels are set to hide when the application becomes inactive by default. This is not what we wan't for normal dialogs in Qt. This patch makes this setting explicit, in case the window we're about to create is a dialog. Task-number: 250869 Reviewed-by: Trenton Schulz --- src/gui/kernel/qwidget_mac.mm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 5432c55..e7dfde5 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -2172,7 +2172,10 @@ void QWidgetPrivate::finishCreateWindow_sys_Cocoa(void * /*NSWindow * */ voidWin if ((popup || type == Qt::Tool || type == Qt::ToolTip) && !q->isModal()) { [windowRef setHidesOnDeactivate:YES]; [windowRef setHasShadow:YES]; + } else { + [windowRef setHidesOnDeactivate:NO]; } + Q_UNUSED(parentWidget); Q_UNUSED(dialog); -- cgit v0.12 From c28cb85841fb5be154c2460efdc82dde012407b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 14 Apr 2009 13:13:29 +0200 Subject: Remove scale applied to cosmetic pens when antialiasing is enabled (X11). The pen width should not be scaled for cosmetic pens. Task-number: 247083 Reviewed-by: Trond BT: yes --- src/gui/painting/qpaintengine_x11.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp index d931f55..39ce59f 100644 --- a/src/gui/painting/qpaintengine_x11.cpp +++ b/src/gui/painting/qpaintengine_x11.cpp @@ -1760,7 +1760,10 @@ void QX11PaintEngine::drawPath(const QPainterPath &path) QRectF deviceRect(0, 0, d->pdev->width(), d->pdev->height()); // necessary to get aliased alphablended primitives to be drawn correctly if (d->cpen.isCosmetic() || d->has_scaling_xform) { - stroker.setWidth(width == 0 ? 1 : width * d->xform_scale); + if (d->cpen.isCosmetic()) + stroker.setWidth(width == 0 ? 1 : width); + else + stroker.setWidth(width * d->xform_scale); stroker.d_ptr->stroker.setClipRect(deviceRect); stroke = stroker.createStroke(path * d->matrix); if (stroke.isEmpty()) -- cgit v0.12 From 4db6f873386e7b21e23efb4a5ca31eb09f3dd94e Mon Sep 17 00:00:00 2001 From: Morten Engvoldsen Date: Tue, 14 Apr 2009 14:05:23 +0200 Subject: Adding note about setting properties to QPrinter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Setting properties on an invalid printer is not supported. Use isValid() to check if it valid. Rev-by: Trond KjernÃ¥sen Rev-by: Geir Vattekar --- src/gui/painting/qprinter.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/painting/qprinter.cpp b/src/gui/painting/qprinter.cpp index 6c309c7..4f3e71c 100644 --- a/src/gui/painting/qprinter.cpp +++ b/src/gui/painting/qprinter.cpp @@ -284,6 +284,10 @@ void QPrinterPrivate::addToManualSetList(QPrintEngine::PrintEnginePropertyKey ke to send PostScript or PDF output to the printer. As an alternative, the printProgram() function can be used to specify the command or utility to use instead of the system default. + + Note that setting parameters like paper size and resolution on an + invalid printer is undefined. You can use QPrinter::isValid() to + verify this before changing any parameters. QPrinter supports a number of parameters, most of which can be changed by the end user through a \l{QPrintDialog}{print dialog}. In -- cgit v0.12 From eb87a7003153b190d8b635563868717b58ce2faf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Tue, 14 Apr 2009 14:02:36 +0200 Subject: Update docs regarding sibling widgets ontop of QGLWidgets when Qt is built with Cocoa support on Mac. The Cocoa API doesn't have a concept of Z-ordering of widgets, and it's implemented by reordering the widget hierarchy for normal widgets. This does unfortunately not work for GL widgets, and it's not supported by Apple. This apparently work with the Carbon AGL API though. Task-number: 244890 Reviewed-by: Gunnar Sletta BT: yes --- src/opengl/qgl.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 2d90342..6d75d02 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -2615,6 +2615,10 @@ const QGLContext* QGLContext::currentContext() QGLWidget. This will side-step the issue altogether, and is what we recommend for users that need this kind of functionality. + On Mac OS X, when Qt is built with Cocoa support, a QGLWidget + can't have any sibling widgets placed ontop of itself. This is due + to limitations in the Cocoa API and is not supported by Apple. + \section1 Overlays The QGLWidget creates a GL overlay context in addition to the -- cgit v0.12 From e1a9014cc92091e8371f9a888ff94c694f562df0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 14 Apr 2009 14:13:54 +0200 Subject: My updates to 4.5.1 changelog. --- dist/changes-4.5.1 | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index 38651a9..7bd7aa4 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -59,6 +59,22 @@ Third party components - QMainWindow * [248048] Fix a regression that would cause tooltips to disappear when using the unified toolbar. +- QPainter + * [247492] Fix rendering bug in raster paint engine causing one-pixel + offset when drawing premultiplied ARGB32 images on RGB16 images. + * [249490] Fix one-pixel offset between stroke and fills of ellipses in + X11 paint engine. + * [246573] Fix very slow stroking of paths in X11 paint engine. + * [247083] Fix scale applied to antialiased cosmetic pens in X11 paint + engine. + * [247505] Fix missing fills of rectangles with negative width/height in + raster paint engine. + * [249628] Fix crash in OpenGL paint engine when filling using Qt::NoBrush. + +- QPixmap + * [249175] Fix QPixmap::fromImage() of monochrome images to result in + black/white pixels and not transparent/white pixels. + - QSharedPointer * [246843] Fixed a crash caused by using QSharedPointer in global statics @@ -108,6 +124,17 @@ Qt for Linux/X11 * [238196] Allow middle click to set scrollbar position to follow GTK+ behavior. +- Font rendering + * Improve performance of subpixel antialiased text rendering by using a mask + in the calls to XRender's text compositing function. + * [248387] Better respect the font config LCD filter settings for subpixel + antialiased text rendering when Freetype's native subpixel rendering is + disabled. + * [248498] Fix garbled rendering of subpixel antialiased text when using + Freetype's native subpixel rendering for vertical subpixel layouts. + * [248644] Fall back to Qt's subpixel rendering if Freetype's subpixel + rendering is available at compile-time but not at run-time. + Qt for Windows -------------- -- cgit v0.12 From 91aeceb7132f4afae0996443a162a5783d8f17aa Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 14 Apr 2009 10:02:42 +0200 Subject: Fix crash in QTreeView Discovered in Kopete trunk BT: yes Reviewed-by: Thierry --- src/gui/itemviews/qtreeview.cpp | 1 + tests/auto/qtreeview/tst_qtreeview.cpp | 26 +++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index 0117db2..62c1277 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -2019,6 +2019,7 @@ int QTreeView::verticalOffset() const // If we are scrolling per item and have non-uniform row heights, // finding the vertical offset in pixels is going to be relatively slow. // ### find a faster way to do this + d->executePostedLayout(); int offset = 0; for (int i = 0; i < d->viewItems.count(); ++i) { if (i == verticalScrollBar()->value()) diff --git a/tests/auto/qtreeview/tst_qtreeview.cpp b/tests/auto/qtreeview/tst_qtreeview.cpp index e1d405d..dfccd9e 100644 --- a/tests/auto/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/qtreeview/tst_qtreeview.cpp @@ -209,6 +209,8 @@ private slots: void indexRowSizeHint(); void addRowsWhileSectionsAreHidden(); + void filterProxyModelCrash(); + // task-specific tests: void task174627_moveLeftToRoot(); void task171902_expandWith1stColHidden(); @@ -2829,6 +2831,29 @@ void tst_QTreeView::indexRowSizeHint() QCOMPARE(view.indexRowSizeHint(index), w->sizeHint().height()); } +void tst_QTreeView::filterProxyModelCrash() +{ + QStandardItemModel model; + QList items; + for (int i = 0; i < 100; i++) + items << new QStandardItem(QString::fromLatin1("item %1").arg(i)); + model.appendColumn(items); + + QSortFilterProxyModel proxy; + proxy.setSourceModel(&model); + + QTreeView view; + view.setModel(&proxy); + view.show(); + QTest::qWait(30); + proxy.invalidate(); + view.verticalScrollBar()->setValue(15); + QTest::qWait(20); + + proxy.invalidate(); + view.repaint(); //used to crash +} + class task174627_TreeView : public QTreeView { Q_OBJECT @@ -3254,6 +3279,5 @@ void tst_QTreeView::task246536_scrollbarsNotWorking() QVERIFY(o.count > 0); } - QTEST_MAIN(tst_QTreeView) #include "tst_qtreeview.moc" -- cgit v0.12 From b15ec327df81f8b0d4934ee2f52a7ccc6a8281c2 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 14 Apr 2009 11:44:56 +0200 Subject: Fixes: QTreeView font change regression if there is an application stylesheet The way font propagation work has changed since 4.4: When there is a stylesheet enabled, font does not propagate. So when settings a font to the QAbstractItemView, the viewport font will not change, and hence no QEvent::FontChange on it. So catch the QEvent::FontChange in QAbstractItemView::event in addition to QAbstractItemView::viewportEvent. (we seems to use the view's font everywhere anyway) Task-number: 250754 Reviewed-by: Jens Bache-Wiig --- src/gui/itemviews/qabstractitemview.cpp | 3 ++ .../qabstractitemview/tst_qabstractitemview.cpp | 43 +++++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index 7bd6207..55b3a03 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -1400,6 +1400,9 @@ bool QAbstractItemView::event(QEvent *event) case QEvent::FocusOut: d->checkPersistentEditorFocus(); break; + case QEvent::FontChange: + d->doDelayedItemsLayout(); // the size of the items will change + break; default: break; } diff --git a/tests/auto/qabstractitemview/tst_qabstractitemview.cpp b/tests/auto/qabstractitemview/tst_qabstractitemview.cpp index 3337a49..086c551 100644 --- a/tests/auto/qabstractitemview/tst_qabstractitemview.cpp +++ b/tests/auto/qabstractitemview/tst_qabstractitemview.cpp @@ -53,6 +53,8 @@ #include #include #include +#include +#include #include "../../shared/util.h" //TESTED_CLASS= @@ -209,6 +211,7 @@ private slots: void setCurrentIndex(); void task221955_selectedEditor(); + void task250754_fontChange(); }; class MyAbstractItemDelegate : public QAbstractItemDelegate @@ -1179,8 +1182,46 @@ void tst_QAbstractItemView::task221955_selectedEditor() button->setFocus(); QTest::qWait(50); QVERIFY(tree.selectionModel()->selectedIndexes().isEmpty()); +} + +void tst_QAbstractItemView::task250754_fontChange() +{ + QString app_css = qApp->styleSheet(); + qApp->setStyleSheet("/* */"); + + QWidget w; + QTreeView tree(&w); + QVBoxLayout *vLayout = new QVBoxLayout(&w); + vLayout->addWidget(&tree); + + QStandardItemModel *m = new QStandardItemModel(this); + for (int i=0; i<5; ++i) { + QStandardItem *item = new QStandardItem(QString("Item number %1").arg(i)); + for (int j=0; j<5; ++j) { + QStandardItem *child = new QStandardItem(QString("Child Item number %1").arg(j)); + item->setChild(j, 0, child); + } + m->setItem(i, 0, item); + } + tree.setModel(m); + + w.show(); + w.resize(150,150); + QTest::qWait(30); + QFont font = tree.font(); + font.setPointSize(5); + tree.setFont(font); + QTest::qWait(30); + + QVERIFY(!tree.verticalScrollBar()->isVisible()); + + font.setPointSize(45); + tree.setFont(font); + QTest::qWait(30); + //now with the huge items, the scrollbar must be visible + QVERIFY(tree.verticalScrollBar()->isVisible()); - + qApp->setStyleSheet(app_css); } QTEST_MAIN(tst_QAbstractItemView) -- cgit v0.12 From e2fa120510584327b7e46ff2a4413aa659a5bd65 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 14 Apr 2009 14:52:49 +0200 Subject: fix deployment rules add additional file to deployment. --- tests/auto/qtranslator/qtranslator.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qtranslator/qtranslator.pro b/tests/auto/qtranslator/qtranslator.pro index e4ad22a..0d67f70 100644 --- a/tests/auto/qtranslator/qtranslator.pro +++ b/tests/auto/qtranslator/qtranslator.pro @@ -3,7 +3,7 @@ SOURCES += tst_qtranslator.cpp wince*: { - addFiles.sources = hellotr_la.qm + addFiles.sources = hellotr_la.qm msgfmt_from_po.qm addFiles.path = . DEPLOYMENT += addFiles } -- cgit v0.12 From f0ceef57b178d4ed71e61a6ce2681f3d401d69fe Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 14 Apr 2009 14:59:30 +0200 Subject: fix potential crash Reviewed-by: Thomas Hartmann need to check for valid menuBar, otherwise dereferencing will horribly fail. --- src/gui/widgets/qmainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp index 46d6471..2abc9e8 100644 --- a/src/gui/widgets/qmainwindow.cpp +++ b/src/gui/widgets/qmainwindow.cpp @@ -481,7 +481,7 @@ void QMainWindow::setMenuBar(QMenuBar *menuBar) oldMenuBar->deleteLater(); } #ifdef Q_OS_WINCE - if (menuBar->size().height() > 0) + if (menuBar && menuBar->size().height() > 0) #endif d->layout->setMenuBar(menuBar); } -- cgit v0.12 From 9a41b437be6014c7a671591e2741c5ca7d8c8be8 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 14 Apr 2009 15:16:43 +0200 Subject: increase waiting time slower platforms (like WinCE) need some more time to actually update. --- tests/auto/qcolordialog/tst_qcolordialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qcolordialog/tst_qcolordialog.cpp b/tests/auto/qcolordialog/tst_qcolordialog.cpp index e51dfcc..1b5babb 100644 --- a/tests/auto/qcolordialog/tst_qcolordialog.cpp +++ b/tests/auto/qcolordialog/tst_qcolordialog.cpp @@ -108,7 +108,7 @@ void tst_QColorDialog::native_activeModalWidget() // color dialog when it is executing, even when using a native // dialog: TestNativeDialog d; - QTimer::singleShot(100, &d, SLOT(hide())); + QTimer::singleShot(1000, &d, SLOT(hide())); d.exec(); QVERIFY(&d == d.m_activeModalWidget); } -- cgit v0.12 From 56feb92927d48edffcd09491091ec735b86a820d Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Tue, 14 Apr 2009 15:02:34 +0200 Subject: Fix a bug where a widget would not always get the correct Cursor in Cocoa Cocoa has a different way of dealing with cursors than our heavy handed approach that we used in Carbon. We simply need to re-implement the proper function in NSView and set up the rectangles for the cursor correctly. We also need to expose an QCursor2NSCursor type functions since the current QCursor::handle() is useless for doing this and we shouldn't change that. With this change things seem to work much more like the native stuff for both Carbon and Cocoa. --- src/gui/kernel/qcocoaview_mac.mm | 29 +++++++++++++++++++++++++++++ src/gui/kernel/qcursor.h | 2 ++ src/gui/kernel/qcursor_mac.mm | 16 ++++++++++++++++ src/gui/kernel/qwidget_mac.mm | 14 ++++++++++++++ 4 files changed, 61 insertions(+) diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 9b581c5..bcbd1bf 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -181,6 +181,7 @@ QT_FORWARD_DECLARE_CLASS(QAbstractScrollAreaPrivate) QT_FORWARD_DECLARE_CLASS(QPaintEvent) QT_FORWARD_DECLARE_CLASS(QPainter) QT_FORWARD_DECLARE_CLASS(QHoverEvent) +QT_FORWARD_DECLARE_CLASS(QCursor) QT_USE_NAMESPACE extern "C" { extern NSString *NSTextInputReplacementRangeAttributeName; @@ -236,6 +237,34 @@ extern "C" { } } +- (void)resetCursorRects +{ + QWidget *cursorWidget = qwidget; + + if (cursorWidget->testAttribute(Qt::WA_TransparentForMouseEvents)) + cursorWidget = QApplication::widgetAt(qwidget->mapToGlobal(qwidget->rect().center())); + + if (cursorWidget == 0) + return; + + if (!cursorWidget->testAttribute(Qt::WA_SetCursor)) { + [super resetCursorRects]; + return; + } + + QRegion mask = qt_widget_private(cursorWidget)->extra->mask; + NSCursor *nscursor = static_cast(nsCursorForQCursor(cursorWidget->cursor())); + if (mask.isEmpty()) { + [self addCursorRect:[qt_mac_nativeview_for(cursorWidget) visibleRect] cursor:nscursor]; + } else { + const QVector &rects = mask.rects(); + for (int i = 0; i < rects.size(); ++i) { + const QRect &rect = rects.at(i); + [self addCursorRect:NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height()) cursor:nscursor]; + } + } +} + - (void)removeDropData { if (dropData) { diff --git a/src/gui/kernel/qcursor.h b/src/gui/kernel/qcursor.h index 15b4597..ad1860d 100644 --- a/src/gui/kernel/qcursor.h +++ b/src/gui/kernel/qcursor.h @@ -77,6 +77,7 @@ class QBitmap; class QPixmap; #if defined(Q_WS_MAC) +void *nsCursorForQCursor(const QCursor &c); void qt_mac_set_cursor(const QCursor *c, const QPoint &p); #endif @@ -128,6 +129,7 @@ public: private: QCursorData *d; #if defined(Q_WS_MAC) + friend void *nsCursorForQCursor(const QCursor &c); friend void qt_mac_set_cursor(const QCursor *c, const QPoint &p); #endif }; diff --git a/src/gui/kernel/qcursor_mac.mm b/src/gui/kernel/qcursor_mac.mm index d632eb79..ae98f2e 100644 --- a/src/gui/kernel/qcursor_mac.mm +++ b/src/gui/kernel/qcursor_mac.mm @@ -95,9 +95,19 @@ protected: } }; +void *nsCursorForQCursor(const QCursor &c) +{ + c.d->update(); + return [[static_cast(c.d->curs.cp.nscursor) retain] autorelease]; +} + static QCursorData *currentCursor = 0; //current cursor void qt_mac_set_cursor(const QCursor *c, const QPoint &) { +#ifdef QT_MAC_USE_COCOA + Q_UNUSED(c); + return; +#else if (!c) { currentCursor = 0; return; @@ -128,10 +138,15 @@ void qt_mac_set_cursor(const QCursor *c, const QPoint &) } } currentCursor = c->d; +#endif } void qt_mac_update_cursor_at_global_pos(const QPoint &globalPos) { +#ifdef QT_MAC_USE_COCOA + Q_UNUSED(globalPos); + return; +#else QCursor cursor(Qt::ArrowCursor); if (QApplication::overrideCursor()) { cursor = *QApplication::overrideCursor(); @@ -144,6 +159,7 @@ void qt_mac_update_cursor_at_global_pos(const QPoint &globalPos) } } qt_mac_set_cursor(&cursor, globalPos); +#endif } void qt_mac_update_cursor() diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index e7dfde5..827e098 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -2847,12 +2847,26 @@ void QWidgetPrivate::updateSystemBackground() void QWidgetPrivate::setCursor_sys(const QCursor &) { + Q_Q(QWidget); +#ifndef QT_MAC_USE_COCOA qt_mac_update_cursor(); +#else + if (q->testAttribute(Qt::WA_WState_Created)) { + [qt_mac_window_for(q) invalidateCursorRectsForView:qt_mac_nativeview_for(q)]; + } +#endif } void QWidgetPrivate::unsetCursor_sys() { + Q_Q(QWidget); +#ifndef QT_MAC_USE_COCOA qt_mac_update_cursor(); +#else + if (q->testAttribute(Qt::WA_WState_Created)) { + [qt_mac_window_for(q) invalidateCursorRectsForView:qt_mac_nativeview_for(q)]; + } +#endif } void QWidgetPrivate::setWindowTitle_sys(const QString &caption) -- cgit v0.12 From 99ed68cda10355dba5c7a3e2466ee45b59dbb555 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 14 Apr 2009 15:19:41 +0200 Subject: Don't remove the cache file if you have successfully added it. This regression probably happened because of the fix to task 244485 (see 8d500381), which made QFile follow a rename. This means that QTemporaryFile removes its target when it is deleted. This fixes a number of caching autotests that are failing. Reviewed-by: Markus Goetz BT: yes --- src/network/access/qnetworkdiskcache.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/network/access/qnetworkdiskcache.cpp b/src/network/access/qnetworkdiskcache.cpp index fa0fccb..93360c8 100644 --- a/src/network/access/qnetworkdiskcache.cpp +++ b/src/network/access/qnetworkdiskcache.cpp @@ -253,7 +253,8 @@ void QNetworkDiskCachePrivate::storeItem(QCacheItem *cacheItem) // ### use atomic rename rather then remove & rename if (cacheItem->file->rename(fileName)) currentCacheSize += cacheItem->file->size(); - cacheItem->file->setAutoRemove(true); + else + cacheItem->file->setAutoRemove(true); } if (cacheItem->metaData.url() == lastItem.metaData.url()) lastItem.reset(); -- cgit v0.12 From 1657a030b340050f3e813a9a8d34df93e115c7be Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 14 Apr 2009 16:11:55 +0200 Subject: Fix warning: "__LP64__" is not defined" Reviewed-by: Norwegian Rock Cat --- src/gui/kernel/qmacdefines_mac.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qmacdefines_mac.h b/src/gui/kernel/qmacdefines_mac.h index 97ec544..035b8c5 100644 --- a/src/gui/kernel/qmacdefines_mac.h +++ b/src/gui/kernel/qmacdefines_mac.h @@ -105,7 +105,7 @@ Yes, it is an informative comment ;-) # undef qDebug #endif -#if __LP64__ +#ifdef __LP64__ typedef signed int OSStatus; #else typedef signed long OSStatus; -- cgit v0.12 From 36f4460b3d6cc18e737edd7d4b18e4b2636e6ff9 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 14 Apr 2009 16:10:51 +0200 Subject: Changelog: add my changes for 4.5.1 BT: yes --- dist/changes-4.5.1 | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index 7bd7aa4..0d9c2a3 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -33,6 +33,13 @@ Third party components * Library * **************************************************************************** +- QAbstractItemModel + * [243195] Clrarified some warning messages printed if the model is invalid. + +- QAbstractEventDispatcher + * [248805] Duplicates timerid could happen when timer are running while + the QObject is moved to another thread, and would stop timers from working. + - QAbstractSocket * [192037] Emit disconnected only if we were connected before @@ -42,6 +49,9 @@ Third party components - QColorDialog * [247349] Fixed bug causing the wrong alpha value to be returned. +- QCombobox + * [248094] Fixed scrollbar appearing while not required. + - QCompleter * [250064] Fixed focus policy propagation regression. * [246056] Fixed assertion failure in setCompletionPrefix(). @@ -75,20 +85,43 @@ Third party components * [249175] Fix QPixmap::fromImage() of monochrome images to result in black/white pixels and not transparent/white pixels. +- QScrollBar + * [247985] Stylesheet: added ability to style scrollbar menus. + - QSharedPointer * [246843] Fixed a crash caused by using QSharedPointer in global statics +- QSortFilterProxyModel + * [247867] Properly sort when calling appendRows() + * [248868] Resort when the model is reset if dynamicSort is enabled. + * [248868] Fixed QSortFilterProxyModel::sort while dynamicSort was disabled. + - QSSlSocket * [245668] set also protocol, verifyMode and verifyDepth in setSslConfiguration() - QStyleSheetStyle * Improved support for setting background and foreground roles in styles - such as the text color in a combo box popup on Mac and Cleanlooks. + such as the text color in a combo box popup on Mac and Cleanlooks, or + the QScrollBar background. + * [188195] fix background of QAbstractScrollArea loosing its color if styled with pseudo-class. + * Fixed crash while styling the title bar of a QMdiArea. + * [246542] Fixed QToolButton::hover{ color:.... } + +- QTreeView + * Fixed crash that may occurs when event are processed just after QSortFilterProxyModel + has been invalidated + * [246025] Fixed auto-expand that occurs while quicly collapsing an item after clicking on a child + * [248805] Calling programatically QTreeView::sortByColumn was not working if manual + sorting is disabled + * [248163] Fixed possible crash in the paintEvent when spans are used. - QWizard * [248107] Fixed bug on Vista causing Back button to connect twice to the back() signal. +- Q3ListView + * [248689] Q3ListView would not update under certain condition. + **************************************************************************** * Database Drivers * @@ -135,6 +168,11 @@ Qt for Linux/X11 * [248644] Fall back to Qt's subpixel rendering if Freetype's subpixel rendering is available at compile-time but not at run-time. +- QEventDispatcherGlib + * Event posted to a thread before it is started are not processed until + others events are posted. + + Qt for Windows -------------- @@ -185,6 +223,7 @@ Qt for Mac OS X - QTestLib * Activate the test application when launched from the command line. +- Fixed the focus frame transparency that would make widget difficult to use with widget stylesheet. Qt for Embedded Linux --------------------- -- cgit v0.12 From e8877160e332d12958cf700a8a607c36e6c426e1 Mon Sep 17 00:00:00 2001 From: Trond Kjernaasen Date: Tue, 14 Apr 2009 16:16:49 +0200 Subject: Fixes the composition demo for Mac/Cocoa in GL mode. QGLPixelBuffer::generateDynamicTexture() will bind the texture to the pbuffer regardless. Why this works on Carbon is a mystery, but if we're to follow our own docs, we should NOT bind the texture to the pbuffer by default. An explicit call to ::bindToDynamicTexture() is required for that. Task-number: 250664 Reviewed-by: Samuel BT: yes --- src/opengl/qglpixelbuffer_mac.mm | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/opengl/qglpixelbuffer_mac.mm b/src/opengl/qglpixelbuffer_mac.mm index 14941ab..9a679b1 100644 --- a/src/opengl/qglpixelbuffer_mac.mm +++ b/src/opengl/qglpixelbuffer_mac.mm @@ -308,10 +308,6 @@ GLuint QGLPixelBuffer::generateDynamicTexture() const GLuint texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); - [static_cast(d->share_ctx) - setTextureImageToPixelBuffer:static_cast(d->pbuf) - colorBuffer:GL_FRONT]; - glBindTexture(GL_TEXTURE_2D, texture); // updates texture target glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -322,8 +318,6 @@ GLuint QGLPixelBuffer::generateDynamicTexture() const GLuint texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); - aglTexImagePBuffer(d->share_ctx, d->pbuf, GL_FRONT); - glBindTexture(GL_TEXTURE_2D, texture); // updates texture target glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); return texture; -- cgit v0.12 From 5dda84c32b38051ca64c3641ffaaa807e2406285 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Tue, 14 Apr 2009 17:07:05 +0200 Subject: Update changes file with my WebKit changes as well as from external contributors. Reviewed-by: Trust me --- dist/changes-4.5.1 | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index 0d9c2a3..6062093 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -122,6 +122,14 @@ Third party components - Q3ListView * [248689] Q3ListView would not update under certain condition. +- QtWebKit + * Fix bug in cookie handling (WebKit Bugzilla 24062, Benjamin Meyer). + * Fixed support for calling from JavaScript into NPAPI plugins on Windows. + * Fixed updating state of WebActions (Erik Bunce) + * Fixed bug in HTML 5 Canvas clearRect() (Dirk Schulze) + * Fixed text field theming with KDE 4 Oxygen style (Zack Rusin) + * Fixed path fill styles (Zack Rusin) + * Fixed pre-edit text handling with input methods. **************************************************************************** * Database Drivers * -- cgit v0.12 From 28d2b22a940174b4e64f6fa2f5548a7832fc07e8 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Tue, 14 Apr 2009 16:55:24 +0200 Subject: Fix logic for autodetecting the embedded-linux package The previous version would get confused because the embedded package also contains _x11 files. Reviewed-by: Thiago --- configure | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/configure b/configure index adb08a8..730c84a 100755 --- a/configure +++ b/configure @@ -119,7 +119,13 @@ elif [ -f "$relpath"/src/gui/kernel/qapplication_qws.cpp ]; then # ~ src/gui/base/qapplication_qws.cpp is present # ~ this is the free or commercial edition # ~ this is the internal edition and Qt Embedded is explicitly enabled - PLATFORM_QWS=maybe + if [ -f "$relpath"/src/gui/kernel/qapplication_mac.mm ]; then + # This is a depot build, or an all-platforms package + PLATFORM_QWS=maybe + else + # This must be the embedded package, since the Qt/Mac source files are not present + PLATFORM_QWS=yes + fi fi #----------------------------------------------------------------------------- -- cgit v0.12 From 0f6950e11389a3ddf657116a98ee8f4ec0753eb4 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 14 Apr 2009 18:01:26 +0200 Subject: QGraphicsView: Rubber Band drag mode not updated correctly when scrolling [regression] The problem was that we didn't update the new region when we paint the rubber band and we scroll at the same time BT:yes Task-number: 245766 Reviewed-by: bnilsen Reviewed-by: andreas --- src/gui/graphicsview/qgraphicsview.cpp | 40 +++++++++++++++++----------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 418638f..b5a1bdf 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -3621,30 +3621,30 @@ void QGraphicsView::scrollContentsBy(int dx, int dy) if (isRightToLeft()) dx = -dx; - if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate - && d->viewportUpdateMode != QGraphicsView::FullViewportUpdate) { - for (int i = 0; i < d->dirtyRects.size(); ++i) - d->dirtyRects[i].translate(dx, dy); - for (int i = 0; i < d->dirtyRegions.size(); ++i) - d->dirtyRegions[i].translate(dx, dy); - } - + if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate) { + if (d->viewportUpdateMode != QGraphicsView::FullViewportUpdate) { + for (int i = 0; i < d->dirtyRects.size(); ++i) + d->dirtyRects[i].translate(dx, dy); + for (int i = 0; i < d->dirtyRegions.size(); ++i) + d->dirtyRegions[i].translate(dx, dy); + if (d->accelerateScrolling) { #ifndef QT_NO_RUBBERBAND - // Update old rubberband - if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate && !d->rubberBandRect.isEmpty()) { - if (d->viewportUpdateMode != FullViewportUpdate) - viewport()->update(d->rubberBandRegion(viewport(), d->rubberBandRect)); - else - viewport()->update(); - } + // Update new and old rubberband regions + if (!d->rubberBandRect.isEmpty()) { + QRegion rubberBandRegion(d->rubberBandRegion(viewport(), d->rubberBandRect)); + rubberBandRegion += rubberBandRegion.translated(-dx, -dy); + viewport()->update(rubberBandRegion); + } #endif - - if (d->viewportUpdateMode != QGraphicsView::NoViewportUpdate){ - if (d->accelerateScrolling && d->viewportUpdateMode != FullViewportUpdate) - viewport()->scroll(dx, dy); - else + viewport()->scroll(dx, dy); + } else { + viewport()->update(); + } + } else { viewport()->update(); + } } + d->updateLastCenterPoint(); if ((d->cacheMode & CacheBackground) -- cgit v0.12 From 0bb526f8fab33a42df56c8a60c272e2cca4cc792 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 14 Apr 2009 18:05:26 +0200 Subject: QGraphicsItem: When an item is deleted and eventfilters installed The problem here is that we are filling the sceneEventFilters map when we install evenfilter but we never remove the references of an item if it has been removed from the scene or deleted. The deletion can keep stale pointers into the map and a crash can happen. BT:yes Task-number:250272 Reviewed-by: bnilsen Reviewed-by: andreas --- src/gui/graphicsview/qgraphicsscene.cpp | 19 +++++++++++++++++++ tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index a5fec69..9881960 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -746,6 +746,15 @@ void QGraphicsScenePrivate::_q_removeItemLater(QGraphicsItem *item) unpolishedItems.removeAll(item); dirtyItems.removeAll(item); + //We remove all references of item from the sceneEventFilter arrays + QMultiMap::iterator iterator = sceneEventFilters.begin(); + while (iterator != sceneEventFilters.end()) { + if (iterator.value() == item || iterator.key() == item) + iterator = sceneEventFilters.erase(iterator); + else + ++iterator; + } + // Remove from scene transform cache int transformIndex = item->d_func()->sceneTransformIndex; if (transformIndex != -1) { @@ -3293,6 +3302,16 @@ void QGraphicsScene::removeItem(QGraphicsItem *item) d->unpolishedItems.removeAll(item); d->dirtyItems.removeAll(item); + //We remove all references of item from the sceneEventFilter arrays + QMultiMap::iterator iterator = d->sceneEventFilters.begin(); + while (iterator != d->sceneEventFilters.end()) { + if (iterator.value() == item || iterator.key() == item) + iterator = d->sceneEventFilters.erase(iterator); + else + ++iterator; + } + + //Ensure dirty flag have the correct default value so the next time it will be added it will receive updates item->d_func()->dirty = 0; item->d_func()->dirtyChildren = 0; diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index ad0dc97..5dd7e1e 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -4037,6 +4037,25 @@ void tst_QGraphicsItem::sceneEventFilter() QCOMPARE(tester->filteredEventReceivers.at(6), static_cast(text2)); QVERIFY(text2->hasFocus()); + + //Let check if the items are correctly removed from the sceneEventFilters array + //to avoid stale pointers. + QGraphicsView gv; + QGraphicsScene *anotherScene = new QGraphicsScene; + QGraphicsTextItem *ti = anotherScene->addText("This is a test #1"); + ti->moveBy(50, 50); + QGraphicsTextItem *ti2 = anotherScene->addText("This is a test #2"); + QGraphicsTextItem *ti3 = anotherScene->addText("This is a test #3"); + gv.setScene(anotherScene); + gv.show(); + QTest::qWait(250); + ti->installSceneEventFilter(ti2); + ti3->installSceneEventFilter(ti); + delete ti2; + //we souldn't crash + QTest::mouseMove(gv.viewport(), gv.mapFromScene(ti->scenePos())); + QTest::qWait(250); + delete ti; } class GeometryChanger : public QGraphicsItem -- cgit v0.12 From 94a9f77b41c2d924983e92df30e3e4cc7882cb75 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 14 Apr 2009 18:28:19 +0200 Subject: My ChangeLog Reviewed-by: TrustMe --- dist/changes-4.5.1 | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index 6062093..e8595ff 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -56,9 +56,24 @@ Third party components * [250064] Fixed focus policy propagation regression. * [246056] Fixed assertion failure in setCompletionPrefix(). +- QDirIterator + * [247645] Fix a bug that may loose all cached data inside the QFileInfo + - QFileInfo * [205244] return valid file info also for relative UNC paths +- QFileDialog + * [250194] QFileDialog and QSortFilterProxyModel index mapping issue + * [248332] QFileDialog is slow after visiting a large directory + * [221323] QFileDialog programatical file selection bug + +- QGraphicsItem + * [247890] Cached QGraphicsItems are not updated if update() is called when they are hidden + * [250272] When an item is deleted it does not get removed from the sceneeventfilters meaning a crash can occur + +-QGraphicsView + * [245766] Rubber Band drag mode not updated correctly when scrolling + - QHttp * [208445] cancel request upon receiving unknown authentication method -- cgit v0.12 From a94b601866740e483f093233f59f43b022a68735 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 14 Apr 2009 20:56:06 +0200 Subject: Fix auto-test failure since we remove the warning in QColor Reviewed-by: ogoffart --- tests/auto/qcssparser/tst_cssparser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qcssparser/tst_cssparser.cpp b/tests/auto/qcssparser/tst_cssparser.cpp index 6e277d3..9a984c8 100644 --- a/tests/auto/qcssparser/tst_cssparser.cpp +++ b/tests/auto/qcssparser/tst_cssparser.cpp @@ -272,7 +272,7 @@ void tst_CssParser::term_data() val.variant = QVariant(QColor("#ffbb00")); QTest::newRow("hexcolor2") << true << "#fb0" << val; - QTest::ignoreMessage(QtWarningMsg, "QColor::setNamedColor: Could not parse color '#cafebabe'"); + QTest::ignoreMessage(QtWarningMsg, "QCssParser::parseHexColor: Unknown color name '#cafebabe'"); QTest::newRow("hexcolor_failure") << false << "#cafebabe" << val; val.type = QCss::Value::Uri; -- cgit v0.12 From bb7bddc47dd0748b45d22180d9e3c8e5209010b3 Mon Sep 17 00:00:00 2001 From: abcd Date: Wed, 15 Apr 2009 10:16:48 +1000 Subject: Fix the behaviour of sql classes regarding quoted identifiers If no quotes around identifiers are provided by the programmer, identifiers are treated identically to how the underlying engine would behave. i.e. some engines uppercase the identifiers others lowercase them. If the programmer wants case sensitivty and/or use whitespaces they will need to quote their identifiers. The previous (incorrect) behaviour always quoted the identifiers. Reviewed-by: Bill King --- src/sql/drivers/db2/qsql_db2.cpp | 70 +++- src/sql/drivers/ibase/qsql_ibase.cpp | 16 +- src/sql/drivers/mysql/qsql_mysql.cpp | 19 +- src/sql/drivers/mysql/qsql_mysql.h | 3 + src/sql/drivers/oci/qsql_oci.cpp | 58 ++- src/sql/drivers/odbc/qsql_odbc.cpp | 129 ++++++ src/sql/drivers/odbc/qsql_odbc.h | 4 + src/sql/drivers/psql/qsql_psql.cpp | 32 +- src/sql/drivers/sqlite/qsql_sqlite.cpp | 16 +- src/sql/drivers/sqlite2/qsql_sqlite2.cpp | 20 +- src/sql/drivers/tds/qsql_tds.cpp | 21 +- src/sql/kernel/qsqldriver.cpp | 131 +++++- src/sql/kernel/qsqldriver.h | 6 + src/sql/models/qsqlrelationaltablemodel.cpp | 73 +++- src/sql/models/qsqltablemodel.cpp | 20 +- tests/auto/qsqldatabase/tst_databases.h | 37 +- tests/auto/qsqldriver/qsqldriver.pro | 16 + tests/auto/qsqldriver/tst_qsqldriver.cpp | 218 ++++++++++ .../tst_qsqlrelationaltablemodel.cpp | 455 +++++++++++++++++++-- tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp | 15 +- 20 files changed, 1218 insertions(+), 141 deletions(-) create mode 100644 tests/auto/qsqldriver/qsqldriver.pro create mode 100644 tests/auto/qsqldriver/tst_qsqldriver.cpp diff --git a/src/sql/drivers/db2/qsql_db2.cpp b/src/sql/drivers/db2/qsql_db2.cpp index 2786dbb..11d0041 100644 --- a/src/sql/drivers/db2/qsql_db2.cpp +++ b/src/sql/drivers/db2/qsql_db2.cpp @@ -1182,7 +1182,7 @@ QDB2Driver::~QDB2Driver() delete d; } -bool QDB2Driver::open(const QString& db, const QString& user, const QString& password, const QString&, int, +bool QDB2Driver::open(const QString& db, const QString& user, const QString& password, const QString& host, int port, const QString& connOpts) { if (isOpen()) @@ -1205,6 +1205,8 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas setOpenError(true); return false; } + + QString protocol; // Set connection attributes const QStringList opts(connOpts.split(QLatin1Char(';'), QString::SkipEmptyParts)); for (int i = 0; i < opts.count(); ++i) { @@ -1235,7 +1237,10 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas } else if (opt == QLatin1String("SQL_ATTR_LOGIN_TIMEOUT")) { v = val.toUInt(); r = SQLSetConnectAttr(d->hDbc, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER) v, 0); - } else { + } else if (opt.compare(QLatin1String("PROTOCOL"), Qt::CaseInsensitive) == 0) { + protocol = tmp; + } + else { qWarning("QDB2Driver::open: Unknown connection attribute '%s'", tmp.toLocal8Bit().constData()); } @@ -1244,9 +1249,18 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas "Unable to set connection attribute '%1'").arg(opt), d); } + if (protocol.isEmpty()) + protocol = QLatin1String("PROTOCOL=TCPIP"); + + if (port < 0 ) + port = 50000; + QString connQStr; - connQStr = QLatin1String("DSN=") + db + QLatin1String(";UID=") + user + QLatin1String(";PWD=") - + password; + connQStr = protocol + QLatin1String(";DATABASE=") + db + QLatin1String(";HOSTNAME=") + host + + QLatin1String(";PORT=") + QString::number(port) + QLatin1String(";UID=") + user + + QLatin1String(";PWD=") + password; + + SQLTCHAR connOut[SQL_MAX_OPTION_STRING_LENGTH]; SQLSMALLINT cb; @@ -1265,7 +1279,7 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas return false; } - d->user = user.toUpper(); + d->user = user; setOpen(true); setOpenError(false); return true; @@ -1310,10 +1324,25 @@ QSqlRecord QDB2Driver::record(const QString& tableName) const SQLHANDLE hStmt; QString catalog, schema, table; - qSplitTableQualifier(tableName.toUpper(), &catalog, &schema, &table); + qSplitTableQualifier(tableName, &catalog, &schema, &table); if (schema.isEmpty()) schema = d->user; + if (isIdentifierEscaped(catalog, QSqlDriver::TableName)) + catalog = stripDelimiters(catalog, QSqlDriver::TableName); + else + catalog = catalog.toUpper(); + + if (isIdentifierEscaped(schema, QSqlDriver::TableName)) + schema = stripDelimiters(schema, QSqlDriver::TableName); + else + schema = schema.toUpper(); + + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + else + table = table.toUpper(); + SQLRETURN r = SQLAllocHandle(SQL_HANDLE_STMT, d->hDbc, &hStmt); @@ -1327,6 +1356,9 @@ QSqlRecord QDB2Driver::record(const QString& tableName) const (SQLPOINTER) SQL_CURSOR_FORWARD_ONLY, SQL_IS_UINTEGER); + + //Aside: szSchemaName and szTableName parameters of SQLColumns + //are case sensitive search patterns, so no escaping is used. r = SQLColumns(hStmt, NULL, 0, @@ -1407,7 +1439,13 @@ QStringList QDB2Driver::tables(QSql::TableType type) const bool isNull; QString fieldVal = qGetStringData(hStmt, 2, -1, isNull); QString userVal = qGetStringData(hStmt, 1, -1, isNull); - if (userVal != d->user) + QString user = d->user; + if ( isIdentifierEscaped(user, QSqlDriver::TableName)) + user = stripDelimiters(user, QSqlDriver::TableName); + else + user = user.toUpper(); + + if (userVal != user) fieldVal = userVal + QLatin1Char('.') + fieldVal; tl.append(fieldVal); r = SQLFetchScroll(hStmt, @@ -1438,7 +1476,23 @@ QSqlIndex QDB2Driver::primaryIndex(const QString& tablename) const return index; } QString catalog, schema, table; - qSplitTableQualifier(tablename.toUpper(), &catalog, &schema, &table); + qSplitTableQualifier(tablename, &catalog, &schema, &table); + + if (isIdentifierEscaped(catalog, QSqlDriver::TableName)) + catalog = stripDelimiters(catalog, QSqlDriver::TableName); + else + catalog = catalog.toUpper(); + + if (isIdentifierEscaped(schema, QSqlDriver::TableName)) + schema = stripDelimiters(schema, QSqlDriver::TableName); + else + schema = schema.toUpper(); + + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + else + table = table.toUpper(); + r = SQLSetStmtAttr(hStmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER)SQL_CURSOR_FORWARD_ONLY, diff --git a/src/sql/drivers/ibase/qsql_ibase.cpp b/src/sql/drivers/ibase/qsql_ibase.cpp index 64f13b5..0705722 100644 --- a/src/sql/drivers/ibase/qsql_ibase.cpp +++ b/src/sql/drivers/ibase/qsql_ibase.cpp @@ -1552,12 +1552,16 @@ QSqlRecord QIBaseDriver::record(const QString& tablename) const QSqlQuery q(createResult()); q.setForwardOnly(true); - + QString table = tablename; + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + else + table = table.toUpper(); q.exec(QLatin1String("SELECT a.RDB$FIELD_NAME, b.RDB$FIELD_TYPE, b.RDB$FIELD_LENGTH, " "b.RDB$FIELD_SCALE, b.RDB$FIELD_PRECISION, a.RDB$NULL_FLAG " "FROM RDB$RELATION_FIELDS a, RDB$FIELDS b " "WHERE b.RDB$FIELD_NAME = a.RDB$FIELD_SOURCE " - "AND a.RDB$RELATION_NAME = '") + tablename.toUpper() + QLatin1String("' " + "AND a.RDB$RELATION_NAME = '") + table + QLatin1String("' " "ORDER BY a.RDB$FIELD_POSITION")); while (q.next()) { @@ -1585,12 +1589,18 @@ QSqlIndex QIBaseDriver::primaryIndex(const QString &table) const if (!isOpen()) return index; + QString tablename = table; + if (isIdentifierEscaped(tablename, QSqlDriver::TableName)) + tablename = stripDelimiters(tablename, QSqlDriver::TableName); + else + tablename = tablename.toUpper(); + QSqlQuery q(createResult()); q.setForwardOnly(true); q.exec(QLatin1String("SELECT a.RDB$INDEX_NAME, b.RDB$FIELD_NAME, d.RDB$FIELD_TYPE, d.RDB$FIELD_SCALE " "FROM RDB$RELATION_CONSTRAINTS a, RDB$INDEX_SEGMENTS b, RDB$RELATION_FIELDS c, RDB$FIELDS d " "WHERE a.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' " - "AND a.RDB$RELATION_NAME = '") + table.toUpper() + + "AND a.RDB$RELATION_NAME = '") + tablename + QLatin1String(" 'AND a.RDB$INDEX_NAME = b.RDB$INDEX_NAME " "AND c.RDB$RELATION_NAME = a.RDB$RELATION_NAME " "AND c.RDB$FIELD_NAME = b.RDB$FIELD_NAME " diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp index 9b57f3c..a84e840 100644 --- a/src/sql/drivers/mysql/qsql_mysql.cpp +++ b/src/sql/drivers/mysql/qsql_mysql.cpp @@ -1314,7 +1314,7 @@ QSqlIndex QMYSQLDriver::primaryIndex(const QString& tablename) const QSqlQuery i(createResult()); QString stmt(QLatin1String("show index from %1;")); QSqlRecord fil = record(tablename); - i.exec(stmt.arg(escapeIdentifier(tablename, QSqlDriver::TableName))); + i.exec(stmt.arg(tablename)); while (i.isActive() && i.next()) { if (i.value(2).toString() == QLatin1String("PRIMARY")) { idx.append(fil.field(i.value(4).toString())); @@ -1329,10 +1329,14 @@ QSqlIndex QMYSQLDriver::primaryIndex(const QString& tablename) const QSqlRecord QMYSQLDriver::record(const QString& tablename) const { + QString table=tablename; + if(isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + QSqlRecord info; if (!isOpen()) return info; - MYSQL_RES* r = mysql_list_fields(d->mysql, tablename.toLocal8Bit().constData(), 0); + MYSQL_RES* r = mysql_list_fields(d->mysql, table.toLocal8Bit().constData(), 0); if (!r) { return info; } @@ -1443,4 +1447,15 @@ QString QMYSQLDriver::escapeIdentifier(const QString &identifier, IdentifierType return res; } +bool QMYSQLDriver::isIdentifierEscapedImplementation(const QString &identifier, IdentifierType type) const +{ + Q_UNUSED(type); + bool isLeftDelimited = (identifier.left(1) == QString(QLatin1Char('`'))); + bool isRightDelimited = (identifier.right(1) == QString(QLatin1Char('`'))); + if( identifier.size() > 2 && isLeftDelimited && isRightDelimited ) + return true; + else + return false; +} + QT_END_NAMESPACE diff --git a/src/sql/drivers/mysql/qsql_mysql.h b/src/sql/drivers/mysql/qsql_mysql.h index 97aa346..31d9dcf 100644 --- a/src/sql/drivers/mysql/qsql_mysql.h +++ b/src/sql/drivers/mysql/qsql_mysql.h @@ -123,6 +123,9 @@ public: QVariant handle() const; QString escapeIdentifier(const QString &identifier, IdentifierType type) const; +protected Q_SLOTS: + bool isIdentifierEscapedImplementation(const QString &identifier, IdentifierType type) const; + protected: bool beginTransaction(); bool commitTransaction(); diff --git a/src/sql/drivers/oci/qsql_oci.cpp b/src/sql/drivers/oci/qsql_oci.cpp index 7017d6c..fa9b5f0 100644 --- a/src/sql/drivers/oci/qsql_oci.cpp +++ b/src/sql/drivers/oci/qsql_oci.cpp @@ -2098,7 +2098,7 @@ bool QOCIDriver::open(const QString & db, setOpen(true); setOpenError(false); - d->user = user.toUpper(); + d->user = user; return true; } @@ -2200,8 +2200,15 @@ QStringList QOCIDriver::tables(QSql::TableType type) const "and owner != 'WKSYS'" "and owner != 'CTXSYS'" "and owner != 'WMSYS'")); + + QString user = d->user; + if ( isIdentifierEscaped(user, QSqlDriver::TableName)) + user = stripDelimiters(user, QSqlDriver::TableName); + else + user = user.toUpper(); + while (t.next()) { - if (t.value(0).toString() != d->user) + if (t.value(0).toString() != user) tl.append(t.value(0).toString() + QLatin1String(".") + t.value(1).toString()); else tl.append(t.value(1).toString()); @@ -2237,10 +2244,10 @@ void qSplitTableAndOwner(const QString & tname, QString * tbl, { int i = tname.indexOf(QLatin1Char('.')); // prefixed with owner? if (i != -1) { - *tbl = tname.right(tname.length() - i - 1).toUpper(); - *owner = tname.left(i).toUpper(); + *tbl = tname.right(tname.length() - i - 1); + *owner = tname.left(i); } else { - *tbl = tname.toUpper(); + *tbl = tname; } } @@ -2256,7 +2263,7 @@ QSqlRecord QOCIDriver::record(const QString& tablename) const QString stmt(QLatin1String("select column_name, data_type, data_length, " "data_precision, data_scale, nullable, data_default%1" "from all_tab_columns " - "where upper(table_name)=%2")); + "where table_name=%2")); if (d->serverVersion >= 9) stmt = stmt.arg(QLatin1String(", char_length ")); else @@ -2264,11 +2271,23 @@ QSqlRecord QOCIDriver::record(const QString& tablename) const bool buildRecordInfo = false; QString table, owner, tmpStmt; qSplitTableAndOwner(tablename, &table, &owner); + + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + else + table = table.toUpper(); + tmpStmt = stmt.arg(QLatin1Char('\'') + table + QLatin1Char('\'')); if (owner.isEmpty()) { owner = d->user; } - tmpStmt += QLatin1String(" and upper(owner)='") + owner + QLatin1String("'"); + + if (isIdentifierEscaped(owner, QSqlDriver::TableName)) + owner = stripDelimiters(owner, QSqlDriver::TableName); + else + owner = owner.toUpper(); + + tmpStmt += QLatin1String(" and owner='") + owner + QLatin1String("'"); t.setForwardOnly(true); t.exec(tmpStmt); if (!t.next()) { // try and see if the tablename is a synonym @@ -2317,11 +2336,23 @@ QSqlIndex QOCIDriver::primaryIndex(const QString& tablename) const bool buildIndex = false; QString table, owner, tmpStmt; qSplitTableAndOwner(tablename, &table, &owner); - tmpStmt = stmt + QLatin1String(" and upper(a.table_name)='") + table + QLatin1String("'"); + + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + else + table = table.toUpper(); + + tmpStmt = stmt + QLatin1String(" and a.table_name='") + table + QLatin1String("'"); if (owner.isEmpty()) { owner = d->user; } - tmpStmt += QLatin1String(" and upper(a.owner)='") + owner + QLatin1String("'"); + + if (isIdentifierEscaped(owner, QSqlDriver::TableName)) + owner = stripDelimiters(owner, QSqlDriver::TableName); + else + owner = owner.toUpper(); + + tmpStmt += QLatin1String(" and a.owner='") + owner + QLatin1String("'"); t.setForwardOnly(true); t.exec(tmpStmt); @@ -2415,13 +2446,14 @@ QVariant QOCIDriver::handle() const return qVariantFromValue(d->env); } -QString QOCIDriver::escapeIdentifier(const QString &identifier, IdentifierType /* type */) const +QString QOCIDriver::escapeIdentifier(const QString &identifier, IdentifierType type) const { QString res = identifier; - res.replace(QLatin1Char('"'), QLatin1String("\"\"")); - if (identifier.indexOf(QLatin1Char(' ')) != -1) + if(!identifier.isEmpty() && !isIdentifierEscaped(identifier, type)) { + res.replace(QLatin1Char('"'), QLatin1String("\"\"")); res.prepend(QLatin1Char('"')).append(QLatin1Char('"')); -// res.replace(QLatin1Char('.'), QLatin1String("\".\"")); + res.replace(QLatin1Char('.'), QLatin1String("\".\"")); + } return res; } diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp index f6710db..71b1b2a 100644 --- a/src/sql/drivers/odbc/qsql_odbc.cpp +++ b/src/sql/drivers/odbc/qsql_odbc.cpp @@ -88,6 +88,7 @@ static const SQLSMALLINT qParamType[4] = { SQL_PARAM_INPUT, SQL_PARAM_INPUT, SQL class QODBCDriverPrivate { public: + enum DefaultCase{Lower, Mixed, Upper, Sensitive}; QODBCDriverPrivate() : hEnv(0), hDbc(0), useSchema(false), disconnectCount(0), isMySqlServer(false), isMSSqlServer(false), hasSQLFetchScroll(true), hasMultiResultSets(false) @@ -119,6 +120,9 @@ public: bool setConnectionOptions(const QString& connOpts); void splitTableQualifier(const QString &qualifier, QString &catalog, QString &schema, QString &table); + DefaultCase defaultCase() const; + QString adjustCase(const QString&) const; + QChar quoteChar() const; }; class QODBCPrivate @@ -555,6 +559,29 @@ static int qGetODBCVersion(const QString &connOpts) return SQL_OV_ODBC2; } +QChar QODBCDriverPrivate::quoteChar() const +{ + static bool isQuoteInitialized = false; + static QChar quote = QChar::fromLatin1('"'); + if (!isQuoteInitialized) { + char driverResponse[4]; + SQLUSMALLINT casing; + SQLSMALLINT length; + int r = SQLGetInfo(hDbc, + SQL_IDENTIFIER_QUOTE_CHAR, + &driverResponse, + sizeof(driverResponse), + &length); + if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) { + quote = QChar::fromLatin1(driverResponse[0]); + } else { + quote = QChar::fromLatin1('"'); + } + isQuoteInitialized = true; + } + return quote; +} + bool QODBCDriverPrivate::setConnectionOptions(const QString& connOpts) { // Set any connection attributes @@ -705,6 +732,65 @@ void QODBCDriverPrivate::splitTableQualifier(const QString & qualifier, QString } } +QODBCDriverPrivate::DefaultCase QODBCDriverPrivate::defaultCase() const +{ + static bool isInitialized = false; + static DefaultCase ret; + + if (!isInitialized) { + SQLUSMALLINT casing; + int r = SQLGetInfo(hDbc, + SQL_IDENTIFIER_CASE, + &casing, + sizeof(casing), + NULL); + if ( r != SQL_SUCCESS) + ret = Lower;//arbitrary case if driver cannot be queried + else { + switch (casing) { + case (SQL_IC_UPPER): + ret = Upper; + break; + case (SQL_IC_LOWER): + ret = Lower; + break; + case (SQL_IC_SENSITIVE): + ret = Sensitive; + break; + case (SQL_IC_MIXED): + ret = Mixed; + break; + default: + ret = Upper; + } + } + isInitialized = true; + } + return ret; +} + +/* + Adjust the casing of an identifier to match what the + database engine would have done to it. +*/ +QString QODBCDriverPrivate::adjustCase(const QString &identifier) const +{ + QString ret = identifier; + switch(defaultCase()) { + case (Lower): + ret = identifier.toLower(); + break; + case (Upper): + ret = identifier.toUpper(); + break; + case(Mixed): + case(Sensitive): + default: + ret = identifier; + } + return ret; +} + //////////////////////////////////////////////////////////////////////////// QODBCResult::QODBCResult(const QODBCDriver * db, QODBCDriverPrivate* p) @@ -2084,6 +2170,22 @@ QSqlIndex QODBCDriver::primaryIndex(const QString& tablename) const } QString catalog, schema, table; d->splitTableQualifier(tablename, catalog, schema, table); + + if (isIdentifierEscaped(catalog, QSqlDriver::TableName)) + catalog = stripDelimiters(catalog, QSqlDriver::TableName); + else + catalog = d->adjustCase(catalog); + + if (isIdentifierEscaped(schema, QSqlDriver::TableName)) + schema = stripDelimiters(schema, QSqlDriver::TableName); + else + schema = d->adjustCase(schema); + + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + else + table = d->adjustCase(table); + r = SQLSetStmtAttr(hStmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER)SQL_CURSOR_FORWARD_ONLY, @@ -2186,6 +2288,22 @@ QSqlRecord QODBCDriver::record(const QString& tablename) const SQLHANDLE hStmt; QString catalog, schema, table; d->splitTableQualifier(tablename, catalog, schema, table); + + if (isIdentifierEscaped(catalog, QSqlDriver::TableName)) + catalog = stripDelimiters(catalog, QSqlDriver::TableName); + else + catalog = d->adjustCase(catalog); + + if (isIdentifierEscaped(schema, QSqlDriver::TableName)) + schema = stripDelimiters(schema, QSqlDriver::TableName); + else + schema = d->adjustCase(schema); + + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + else + table = d->adjustCase(table); + SQLRETURN r = SQLAllocHandle(SQL_HANDLE_STMT, d->hDbc, &hStmt); @@ -2309,4 +2427,15 @@ QString QODBCDriver::escapeIdentifier(const QString &identifier, IdentifierType) return res; } +bool QODBCDriver::isIdentifierEscapedImplementation(const QString &identifier, IdentifierType) const +{ + QString quote = d->quoteChar(); + bool isLeftDelimited = identifier.left(1) == quote; + bool isRightDelimited = identifier.right(1) == quote; + if( identifier.size() > 2 && isLeftDelimited && isRightDelimited ) + return true; + else + return false; +} + QT_END_NAMESPACE diff --git a/src/sql/drivers/odbc/qsql_odbc.h b/src/sql/drivers/odbc/qsql_odbc.h index 4148007..51f53ea 100644 --- a/src/sql/drivers/odbc/qsql_odbc.h +++ b/src/sql/drivers/odbc/qsql_odbc.h @@ -145,10 +145,14 @@ public: QString escapeIdentifier(const QString &identifier, IdentifierType type) const; +protected Q_SLOTS: + bool isIdentifierEscapedImplementation(const QString &identifier, IdentifierType type) const; + protected: bool beginTransaction(); bool commitTransaction(); bool rollbackTransaction(); + private: void init(); bool endTrans(); diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp index afe45fc..16d19f1 100644 --- a/src/sql/drivers/psql/qsql_psql.cpp +++ b/src/sql/drivers/psql/qsql_psql.cpp @@ -894,6 +894,16 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const QString schema; qSplitTableName(tbl, schema); + if (isIdentifierEscaped(tbl, QSqlDriver::TableName)) + tbl = stripDelimiters(tbl, QSqlDriver::TableName); + else + tbl = tbl.toLower(); + + if (isIdentifierEscaped(schema, QSqlDriver::TableName)) + schema = stripDelimiters(schema, QSqlDriver::TableName); + else + schema = schema.toLower(); + switch(d->pro) { case QPSQLDriver::Version6: stmt = QLatin1String("select pg_att1.attname, int(pg_att1.atttypid), pg_cl.relname " @@ -926,7 +936,7 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const "FROM pg_attribute, pg_class " "WHERE %1 pg_class.oid IN " "(SELECT indexrelid FROM pg_index WHERE indisprimary = true AND indrelid IN " - " (SELECT oid FROM pg_class WHERE lower(relname) = '%2')) " + " (SELECT oid FROM pg_class WHERE relname = '%2')) " "AND pg_attribute.attrelid = pg_class.oid " "AND pg_attribute.attisdropped = false " "ORDER BY pg_attribute.attnum"); @@ -934,11 +944,11 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const stmt = stmt.arg(QLatin1String("pg_table_is_visible(pg_class.oid) AND")); else stmt = stmt.arg(QString::fromLatin1("pg_class.relnamespace = (select oid from " - "pg_namespace where pg_namespace.nspname = '%1') AND ").arg(schema.toLower())); + "pg_namespace where pg_namespace.nspname = '%1') AND ").arg(schema)); break; } - i.exec(stmt.arg(tbl.toLower())); + i.exec(stmt.arg(tbl)); while (i.isActive() && i.next()) { QSqlField f(i.value(0).toString(), qDecodePSQLType(i.value(1).toInt())); idx.append(f); @@ -957,6 +967,16 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const QString schema; qSplitTableName(tbl, schema); + if (isIdentifierEscaped(tbl, QSqlDriver::TableName)) + tbl = stripDelimiters(tbl, QSqlDriver::TableName); + else + tbl = tbl.toLower(); + + if (isIdentifierEscaped(schema, QSqlDriver::TableName)) + schema = stripDelimiters(schema, QSqlDriver::TableName); + else + schema = schema.toLower(); + QString stmt; switch(d->pro) { case QPSQLDriver::Version6: @@ -1001,7 +1021,7 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const "left join pg_attrdef on (pg_attrdef.adrelid = " "pg_attribute.attrelid and pg_attrdef.adnum = pg_attribute.attnum) " "where %1 " - "and lower(pg_class.relname) = '%2' " + "and pg_class.relname = '%2' " "and pg_attribute.attnum > 0 " "and pg_attribute.attrelid = pg_class.oid " "and pg_attribute.attisdropped = false " @@ -1010,12 +1030,12 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const stmt = stmt.arg(QLatin1String("pg_table_is_visible(pg_class.oid)")); else stmt = stmt.arg(QString::fromLatin1("pg_class.relnamespace = (select oid from " - "pg_namespace where pg_namespace.nspname = '%1')").arg(schema.toLower())); + "pg_namespace where pg_namespace.nspname = '%1')").arg(schema)); break; } QSqlQuery query(createResult()); - query.exec(stmt.arg(tbl.toLower())); + query.exec(stmt.arg(tbl)); if (d->pro >= QPSQLDriver::Version71) { while (query.next()) { int len = query.value(3).toInt(); diff --git a/src/sql/drivers/sqlite/qsql_sqlite.cpp b/src/sql/drivers/sqlite/qsql_sqlite.cpp index 605c4e8..f732077 100644 --- a/src/sql/drivers/sqlite/qsql_sqlite.cpp +++ b/src/sql/drivers/sqlite/qsql_sqlite.cpp @@ -661,9 +661,13 @@ QSqlIndex QSQLiteDriver::primaryIndex(const QString &tblname) const if (!isOpen()) return QSqlIndex(); + QString table = tblname; + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + QSqlQuery q(createResult()); q.setForwardOnly(true); - return qGetTableInfo(q, tblname, true); + return qGetTableInfo(q, table, true); } QSqlRecord QSQLiteDriver::record(const QString &tbl) const @@ -671,9 +675,13 @@ QSqlRecord QSQLiteDriver::record(const QString &tbl) const if (!isOpen()) return QSqlRecord(); + QString table = tbl; + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + QSqlQuery q(createResult()); q.setForwardOnly(true); - return qGetTableInfo(q, tbl); + return qGetTableInfo(q, table); } QVariant QSQLiteDriver::handle() const @@ -681,10 +689,10 @@ QVariant QSQLiteDriver::handle() const return qVariantFromValue(d->access); } -QString QSQLiteDriver::escapeIdentifier(const QString &identifier, IdentifierType /*type*/) const +QString QSQLiteDriver::escapeIdentifier(const QString &identifier, IdentifierType type) const { QString res = identifier; - if(!identifier.isEmpty() && identifier.left(1) != QString(QLatin1Char('"')) && identifier.right(1) != QString(QLatin1Char('"')) ) { + if(!identifier.isEmpty() && !isIdentifierEscaped(identifier, type) ) { res.replace(QLatin1Char('"'), QLatin1String("\"\"")); res.prepend(QLatin1Char('"')).append(QLatin1Char('"')); res.replace(QLatin1Char('.'), QLatin1String("\".\"")); diff --git a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp index ff73caa..d0c6e18 100644 --- a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp +++ b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp @@ -167,7 +167,15 @@ void QSQLite2ResultPrivate::init(const char **cnames, int numCols) for (int i = 0; i < numCols; ++i) { const char* lastDot = strrchr(cnames[i], '.'); const char* fieldName = lastDot ? lastDot + 1 : cnames[i]; - rInf.append(QSqlField(QString::fromAscii(fieldName), + + //remove quotations around the field name if any + QString fieldStr = QString::fromAscii(fieldName); + QString quote = QString::fromLatin1("\""); + if ( fieldStr.length() > 2 && fieldStr.left(1) == quote && fieldStr.right(1) == quote) { + fieldStr = fieldStr.mid(1); + fieldStr.chop(1); + } + rInf.append(QSqlField(fieldStr, nameToType(QString::fromAscii(cnames[i+numCols])))); } } @@ -503,8 +511,11 @@ QSqlIndex QSQLite2Driver::primaryIndex(const QString &tblname) const QSqlQuery q(createResult()); q.setForwardOnly(true); + QString table = tblname; + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); // finrst find a UNIQUE INDEX - q.exec(QLatin1String("PRAGMA index_list('") + tblname + QLatin1String("');")); + q.exec(QLatin1String("PRAGMA index_list('") + table + QLatin1String("');")); QString indexname; while(q.next()) { if (q.value(2).toInt()==1) { @@ -517,7 +528,7 @@ QSqlIndex QSQLite2Driver::primaryIndex(const QString &tblname) const q.exec(QLatin1String("PRAGMA index_info('") + indexname + QLatin1String("');")); - QSqlIndex index(tblname, indexname); + QSqlIndex index(table, indexname); while(q.next()) { QString name = q.value(2).toString(); QVariant::Type type = QVariant::Invalid; @@ -532,6 +543,9 @@ QSqlRecord QSQLite2Driver::record(const QString &tbl) const { if (!isOpen()) return QSqlRecord(); + QString table = tbl; + if (isIdentifierEscaped(tbl, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); QSqlQuery q(createResult()); q.setForwardOnly(true); diff --git a/src/sql/drivers/tds/qsql_tds.cpp b/src/sql/drivers/tds/qsql_tds.cpp index 46e4a0b..515f0de 100644 --- a/src/sql/drivers/tds/qsql_tds.cpp +++ b/src/sql/drivers/tds/qsql_tds.cpp @@ -293,6 +293,8 @@ QTDSResult::QTDSResult(const QTDSDriver* db) // insert d in error handler dict errs()->insert(d->dbproc, d); + dbcmd(d->dbproc, "set quoted_identifier on"); + dbsqlexec(d->dbproc); } QTDSResult::~QTDSResult() @@ -367,7 +369,7 @@ bool QTDSResult::gotoNext(QSqlCachedResult::ValueCache &values, int index) if (qIsNull(d->buffer.at(i * 2 + 1))) values[idx] = QVariant(QVariant::String); else - values[idx] = QString::fromLocal8Bit((const char*)d->buffer.at(i * 2)); + values[idx] = QString::fromLocal8Bit((const char*)d->buffer.at(i * 2)).trimmed(); break; case QVariant::ByteArray: { if (qIsNull(d->buffer.at(i * 2 + 1))) @@ -698,9 +700,14 @@ QSqlRecord QTDSDriver::record(const QString& tablename) const return info; QSqlQuery t(createResult()); t.setForwardOnly(true); + + QString table = tablename; + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + QString stmt (QLatin1String("select name, type, length, prec from syscolumns " "where id = (select id from sysobjects where name = '%1')")); - t.exec(stmt.arg(tablename)); + t.exec(stmt.arg(table)); while (t.next()) { QSqlField f(t.value(0).toString().simplified(), qDecodeTDSType(t.value(1).toInt())); f.setLength(t.value(2).toInt()); @@ -770,13 +777,17 @@ QSqlIndex QTDSDriver::primaryIndex(const QString& tablename) const { QSqlRecord rec = record(tablename); - QSqlIndex idx(tablename); - if ((!isOpen()) || (tablename.isEmpty())) + QString table = tablename; + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + + QSqlIndex idx(table); + if ((!isOpen()) || (table.isEmpty())) return QSqlIndex(); QSqlQuery t(createResult()); t.setForwardOnly(true); - t.exec(QString::fromLatin1("sp_helpindex '%1'").arg(tablename)); + t.exec(QString::fromLatin1("sp_helpindex '%1'").arg(table)); if (t.next()) { QStringList fNames = t.value(2).toString().simplified().split(QLatin1Char(',')); QRegExp regx(QLatin1String("\\s*(\\S+)(?:\\s+(DESC|desc))?\\s*")); diff --git a/src/sql/kernel/qsqldriver.cpp b/src/sql/kernel/qsqldriver.cpp index a995005..40bc0df 100644 --- a/src/sql/kernel/qsqldriver.cpp +++ b/src/sql/kernel/qsqldriver.cpp @@ -49,6 +49,17 @@ QT_BEGIN_NAMESPACE +static QString prepareIdentifier(const QString &identifier, + QSqlDriver::IdentifierType type, const QSqlDriver *driver) +{ + Q_ASSERT( driver != NULL ); + QString ret = identifier; + if (!driver->isIdentifierEscaped(identifier, type)) { + ret = driver->escapeIdentifier(identifier, type); + } + return ret; +} + class QSqlDriverPrivate : public QObjectPrivate { public: @@ -372,6 +383,7 @@ QSqlRecord QSqlDriver::record(const QString & /* tableName */) const on \a type. The default implementation does nothing. + \sa isIdentifierEscaped() */ QString QSqlDriver::escapeIdentifier(const QString &identifier, IdentifierType) const { @@ -379,6 +391,55 @@ QString QSqlDriver::escapeIdentifier(const QString &identifier, IdentifierType) } /*! + Returns whether \a identifier is escaped according to the database rules. + \a identifier can either be a table name or field name, dependent + on \a type. + + \warning Because of binary compatability constraints, this function is not virtual. + If you want to provide your own implementation in your QSqlDriver subclass, + reimplement the isIdentifierEscapedImplementation() slot in your subclass instead. + The isIdentifierEscapedFunction() will dynamically detect the slot and call it. + + \sa stripDelimiters(), escapeIdentifier() + */ +bool QSqlDriver::isIdentifierEscaped(const QString &identifier, IdentifierType type) const +{ + bool result; + QMetaObject::invokeMethod(const_cast(this), + "isIdentifierEscapedImplementation", Qt::DirectConnection, + Q_RETURN_ARG(bool, result), + Q_ARG(QString, identifier), + Q_ARG(IdentifierType, type)); + return result; +} + +/*! + Returns the \a identifier with the leading and trailing delimiters removed, + \a identifier can either be a table name or field name, + dependent on \a type. If \a identifier does not have leading + and trailing delimiter characters, \a identifier is returned without + modification. + + \warning Because of binary compatability constraints, this function is not virtual, + If you want to provide your own implementation in your QSqlDriver subclass, + reimplement the stripDelimitersImplementation() slot in your subclass instead. + The stripDelimiters() function will dynamically detect the slot and call it. + + \since 4.5 + \sa isIdentifierEscaped() + */ +QString QSqlDriver::stripDelimiters(const QString &identifier, IdentifierType type) const +{ + QString result; + QMetaObject::invokeMethod(const_cast(this), + "stripDelimitersImplementation", Qt::DirectConnection, + Q_RETURN_ARG(QString, result), + Q_ARG(QString, identifier), + Q_ARG(IdentifierType, type)); + return result; +} + +/*! Returns a SQL statement of type \a type for the table \a tableName with the values from \a rec. If \a preparedStatement is true, the string will contain placeholders instead of values. @@ -397,17 +458,17 @@ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName, case SelectStatement: for (i = 0; i < rec.count(); ++i) { if (rec.isGenerated(i)) - s.append(escapeIdentifier(rec.fieldName(i), FieldName)).append(QLatin1String(", ")); + s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)).append(QLatin1String(", ")); } if (s.isEmpty()) return s; s.chop(2); - s.prepend(QLatin1String("SELECT ")).append(QLatin1String(" FROM ")).append(escapeIdentifier(tableName, TableName)); + s.prepend(QLatin1String("SELECT ")).append(QLatin1String(" FROM ")).append(tableName); break; case WhereStatement: if (preparedStatement) { for (int i = 0; i < rec.count(); ++i) { - s.append(escapeIdentifier(rec.fieldName(i), FieldName)); + s.append(prepareIdentifier(rec.fieldName(i), FieldName,this)); if (rec.isNull(i)) s.append(QLatin1String(" IS NULL")); else @@ -416,7 +477,7 @@ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName, } } else { for (i = 0; i < rec.count(); ++i) { - s.append(escapeIdentifier(rec.fieldName(i), FieldName)); + s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)); QString val = formatValue(rec.field(i)); if (val == QLatin1String("NULL")) s.append(QLatin1String(" IS NULL")); @@ -431,12 +492,12 @@ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName, } break; case UpdateStatement: - s.append(QLatin1String("UPDATE ")).append(escapeIdentifier(tableName, TableName)).append( + s.append(QLatin1String("UPDATE ")).append(tableName).append( QLatin1String(" SET ")); for (i = 0; i < rec.count(); ++i) { if (!rec.isGenerated(i) || !rec.value(i).isValid()) continue; - s.append(escapeIdentifier(rec.fieldName(i), FieldName)).append(QLatin1Char('=')); + s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)).append(QLatin1Char('=')); if (preparedStatement) s.append(QLatin1Char('?')); else @@ -449,15 +510,15 @@ QString QSqlDriver::sqlStatement(StatementType type, const QString &tableName, s.clear(); break; case DeleteStatement: - s.append(QLatin1String("DELETE FROM ")).append(escapeIdentifier(tableName, TableName)); + s.append(QLatin1String("DELETE FROM ")).append(tableName); break; case InsertStatement: { - s.append(QLatin1String("INSERT INTO ")).append(escapeIdentifier(tableName, TableName)).append(QLatin1String(" (")); + s.append(QLatin1String("INSERT INTO ")).append(tableName).append(QLatin1String(" (")); QString vals; for (i = 0; i < rec.count(); ++i) { if (!rec.isGenerated(i) || !rec.value(i).isValid()) continue; - s.append(escapeIdentifier(rec.fieldName(i), FieldName)).append(QLatin1String(", ")); + s.append(prepareIdentifier(rec.fieldName(i), QSqlDriver::FieldName, this)).append(QLatin1String(", ")); if (preparedStatement) vals.append(QLatin1String("?")); else @@ -805,4 +866,56 @@ QStringList QSqlDriver::subscribedToNotificationsImplementation() const return QStringList(); } +/*! + This slot returns whether \a identifier is escaped according to the database rules. + \a identifier can either be a table name or field name, dependent + on \a type. + + Because of binary compatability constraints, isIdentifierEscaped() function + (introduced in Qt 4.5) is not virtual. Instead, isIdentifierEscaped() will + dynamically detect and call \e this slot. The default implementation + assumes the escape/delimiter character is a double quote. Reimplement this + slot in your own QSqlDriver if your database engine uses a different + delimiter character. + + \since 4.5 + \sa isIdentifierEscaped() + */ +bool QSqlDriver::isIdentifierEscapedImplementation(const QString &identifier, IdentifierType type) const +{ + Q_UNUSED(type); + bool isLeftDelimited = identifier.left(1) == QString(QLatin1Char('"')); + bool isRightDelimited = identifier.right(1) == QString(QLatin1Char('"')); + if( identifier.size() > 2 && isLeftDelimited && isRightDelimited ) + return true; + else + return false; +} + +/*! + This slot returns \a identifier with the leading and trailing delimiters removed, + \a identifier can either be a tablename or field name, dependent on \a type. + If \a identifier does not have leading and trailing delimiter characters, \a + identifier is returned without modification. + + Because of binary compatability constraints, the stripDelimiters() function + (introduced in Qt 4.5) is not virtual. Instead, stripDelimiters() will + dynamically detect and call \e this slot. It generally unnecessary + to reimplement this slot. + + \since 4.5 + \sa stripDelimiters() + */ +QString QSqlDriver::stripDelimitersImplementation(const QString &identifier, IdentifierType type) const +{ + QString ret; + if (this->isIdentifierEscaped(identifier, type)) { + ret = identifier.mid(1); + ret.chop(1); + } else { + ret = identifier; + } + return ret; +} + QT_END_NAMESPACE diff --git a/src/sql/kernel/qsqldriver.h b/src/sql/kernel/qsqldriver.h index e763719..8ac1471 100644 --- a/src/sql/kernel/qsqldriver.h +++ b/src/sql/kernel/qsqldriver.h @@ -127,6 +127,9 @@ public: bool unsubscribeFromNotification(const QString &name); // ### Qt 5: make virtual QStringList subscribedToNotifications() const; // ### Qt 5: make virtual + bool isIdentifierEscaped(const QString &identifier, IdentifierType type) const; // ### Qt 5: make virtual + QString stripDelimiters(const QString &identifier, IdentifierType type) const; // ### Qt 5: make virtual + Q_SIGNALS: void notification(const QString &name); @@ -140,6 +143,9 @@ protected Q_SLOTS: bool unsubscribeFromNotificationImplementation(const QString &name); // ### Qt 5: eliminate, see unsubscribeFromNotification() QStringList subscribedToNotificationsImplementation() const; // ### Qt 5: eliminate, see subscribedNotifications() + bool isIdentifierEscapedImplementation(const QString &identifier, IdentifierType type) const; // ### Qt 5: eliminate, see isIdentifierEscaped() + QString stripDelimitersImplementation(const QString &identifier, IdentifierType type) const; // ### Qt 5: eliminate, see stripDelimiters() + private: Q_DISABLE_COPY(QSqlDriver) }; diff --git a/src/sql/models/qsqlrelationaltablemodel.cpp b/src/sql/models/qsqlrelationaltablemodel.cpp index 935466b..12eae84 100644 --- a/src/sql/models/qsqlrelationaltablemodel.cpp +++ b/src/sql/models/qsqlrelationaltablemodel.cpp @@ -182,10 +182,21 @@ void QRelation::populateDictionary() populateModel(); QSqlRecord record; + QString indexColumn; + QString displayColumn; for (int i=0; i < model->rowCount(); ++i) { record = model->record(i); - dictionary[record.field(rel.indexColumn()).value().toString()] = - record.field(rel.displayColumn()).value(); + + indexColumn = rel.indexColumn(); + if (m_parent->database().driver()->isIdentifierEscaped(indexColumn, QSqlDriver::FieldName)) + indexColumn = m_parent->database().driver()->stripDelimiters(indexColumn, QSqlDriver::FieldName); + + displayColumn = rel.displayColumn(); + if (m_parent->database().driver()->isIdentifierEscaped(displayColumn, QSqlDriver::FieldName)) + displayColumn = m_parent->database().driver()->stripDelimiters(displayColumn, QSqlDriver::FieldName); + + dictionary[record.field(indexColumn).value().toString()] = + record.field(displayColumn).value(); } m_dictInitialized = true; } @@ -215,7 +226,7 @@ public: QSqlRelationalTableModelPrivate() : QSqlTableModelPrivate() {} - QString escapedRelationField(const QString &tableName, const QString &fieldName) const; + QString relationField(const QString &tableName, const QString &fieldName) const; int nameToIndex(const QString &name) const; mutable QVector relations; @@ -255,7 +266,10 @@ void QSqlRelationalTableModelPrivate::revertCachedRow(int row) int QSqlRelationalTableModelPrivate::nameToIndex(const QString &name) const { - return baseRec.indexOf(name); + QString fieldname = name; + if (db.driver()->isIdentifierEscaped(fieldname, QSqlDriver::FieldName)) + fieldname = db.driver()->stripDelimiters(fieldname, QSqlDriver::FieldName); + return baseRec.indexOf(fieldname); } void QSqlRelationalTableModelPrivate::clearEditBuffer() @@ -481,14 +495,14 @@ QSqlRelation QSqlRelationalTableModel::relation(int column) const return d->relations.value(column).rel; } -QString QSqlRelationalTableModelPrivate::escapedRelationField(const QString &tableName, +QString QSqlRelationalTableModelPrivate::relationField(const QString &tableName, const QString &fieldName) const { - QString esc; - esc.reserve(tableName.size() + fieldName.size() + 1); - esc.append(tableName).append(QLatin1Char('.')).append(fieldName); + QString ret; + ret.reserve(tableName.size() + fieldName.size() + 1); + ret.append(tableName).append(QLatin1Char('.')).append(fieldName); - return db.driver()->escapeIdentifier(esc, QSqlDriver::FieldName); + return ret; } /*! @@ -514,15 +528,29 @@ QString QSqlRelationalTableModel::selectStatement() const // Count how many times each field name occurs in the record QHash fieldNames; + QStringList fieldList; for (int i = 0; i < rec.count(); ++i) { QSqlRelation relation = d->relations.value(i, nullRelation).rel; QString name; if (relation.isValid()) + { // Count the display column name, not the original foreign key name = relation.displayColumn(); + if (d->db.driver()->isIdentifierEscaped(name, QSqlDriver::FieldName)) + name = d->db.driver()->stripDelimiters(name, QSqlDriver::FieldName); + + QSqlRecord rec = database().record(relation.tableName()); + for (int i = 0; i < rec.count(); ++i) { + if (name.compare(rec.fieldName(i), Qt::CaseInsensitive) == 0) { + name = rec.fieldName(i); + break; + } + } + } else name = rec.fieldName(i); fieldNames.insert(name, fieldNames.value(name, 0) + 1); + fieldList.append(name); } for (int i = 0; i < rec.count(); ++i) { @@ -531,27 +559,30 @@ QString QSqlRelationalTableModel::selectStatement() const QString relTableAlias = QString::fromLatin1("relTblAl_%1").arg(i); if (!fList.isEmpty()) fList.append(QLatin1String(", ")); - fList.append(d->escapedRelationField(relTableAlias, relation.displayColumn())); + fList.append(d->relationField(relTableAlias,relation.displayColumn())); // If there are duplicate field names they must be aliased - if (fieldNames.value(relation.displayColumn()) > 1) { - fList.append(QString::fromLatin1(" AS %1_%2").arg(relation.tableName()).arg(relation.displayColumn())); + if (fieldNames.value(fieldList[i]) > 1) { + QString relTableName = relation.tableName(); + if (d->db.driver()->isIdentifierEscaped(relTableName, QSqlDriver::TableName)) + relTableName = d->db.driver()->stripDelimiters(relTableName, QSqlDriver::TableName); + QString displayColumn = relation.displayColumn(); + if (d->db.driver()->isIdentifierEscaped(displayColumn, QSqlDriver::FieldName)) + displayColumn = d->db.driver()->stripDelimiters(displayColumn, QSqlDriver::FieldName); + fList.append(QString::fromLatin1(" AS %1_%2").arg(relTableName).arg(displayColumn)); } // this needs fixing!! the below if is borken. - if (!tables.contains(relation.tableName())) - tables.append(d->db.driver()->escapeIdentifier(relation.tableName(),QSqlDriver::TableName) - .append(QLatin1String(" ")) - .append(d->db.driver()->escapeIdentifier(relTableAlias, QSqlDriver::TableName))); + tables.append(relation.tableName().append(QLatin1String(" ")).append(relTableAlias)); if(!where.isEmpty()) where.append(QLatin1String(" AND ")); - where.append(d->escapedRelationField(tableName(), rec.fieldName(i))); + where.append(d->relationField(tableName(), d->db.driver()->escapeIdentifier(rec.fieldName(i), QSqlDriver::FieldName))); where.append(QLatin1String(" = ")); - where.append(d->escapedRelationField(relTableAlias, relation.indexColumn())); + where.append(d->relationField(relTableAlias, relation.indexColumn())); } else { if (!fList.isEmpty()) fList.append(QLatin1String(", ")); - fList.append(d->escapedRelationField(tableName(), rec.fieldName(i))); + fList.append(d->relationField(tableName(), d->db.driver()->escapeIdentifier(rec.fieldName(i), QSqlDriver::FieldName))); } } if (!tables.isEmpty()) @@ -560,7 +591,7 @@ QString QSqlRelationalTableModel::selectStatement() const return query; if(!tList.isEmpty()) tList.prepend(QLatin1String(", ")); - tList.prepend(d->db.driver()->escapeIdentifier(tableName(),QSqlDriver::TableName)); + tList.prepend(tableName()); query.append(QLatin1String("SELECT ")); query.append(fList).append(QLatin1String(" FROM ")).append(tList); qAppendWhereClause(query, where, filter()); @@ -690,7 +721,7 @@ QString QSqlRelationalTableModel::orderByClause() const return QSqlTableModel::orderByClause(); QString s = QLatin1String("ORDER BY "); - s.append(d->escapedRelationField(QLatin1String("relTblAl_") + QString::number(d->sortColumn), + s.append(d->relationField(QLatin1String("relTblAl_") + QString::number(d->sortColumn), rel.displayColumn())); s += d->sortOrder == Qt::AscendingOrder ? QLatin1String(" ASC") : QLatin1String(" DESC"); return s; diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp index 2fb9b0f..c2442c5 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -98,7 +98,10 @@ bool QSqlTableModelPrivate::setRecord(int row, const QSqlRecord &record) int QSqlTableModelPrivate::nameToIndex(const QString &name) const { - return rec.indexOf(name); + QString fieldname = name; + if (db.driver()->isIdentifierEscaped(fieldname, QSqlDriver::FieldName)) + fieldname = db.driver()->stripDelimiters(fieldname, QSqlDriver::FieldName); + return rec.indexOf(fieldname); } void QSqlTableModelPrivate::initRecordAndPrimaryIndex() @@ -367,10 +370,7 @@ void QSqlTableModel::setTable(const QString &tableName) { Q_D(QSqlTableModel); clear(); - if(d->db.tables().contains(tableName.toUpper())) - d->tableName = tableName.toUpper(); - else - d->tableName = tableName; + d->tableName = tableName; d->initRecordAndPrimaryIndex(); d->initColOffsets(d->rec.count()); @@ -976,7 +976,9 @@ QString QSqlTableModel::orderByClause() const if (!f.isValid()) return s; - QString table = d->db.driver()->escapeIdentifier(d->tableName, QSqlDriver::TableName); + QString table = d->tableName; + //we can safely escape the field because it would have been obtained from the database + //and have the correct case QString field = d->db.driver()->escapeIdentifier(f.name(), QSqlDriver::FieldName); s.append(QLatin1String("ORDER BY ")).append(table).append(QLatin1Char('.')).append(field); s += d->sortOrder == Qt::AscendingOrder ? QLatin1String(" ASC") : QLatin1String(" DESC"); @@ -1317,8 +1319,12 @@ bool QSqlTableModel::setRecord(int row, const QSqlRecord &record) mrow.rec = d->rec; mrow.primaryValues = d->primaryValues(indexInQuery(createIndex(row, 0)).row()); } + QString fieldName; for (int i = 0; i < record.count(); ++i) { - int idx = mrow.rec.indexOf(record.fieldName(i)); + fieldName = record.fieldName(i); + if (d->db.driver()->isIdentifierEscaped(fieldName, QSqlDriver::FieldName)) + fieldName = d->db.driver()->stripDelimiters(fieldName, QSqlDriver::FieldName); + int idx = mrow.rec.indexOf(fieldName); if (idx == -1) isOk = false; else diff --git a/tests/auto/qsqldatabase/tst_databases.h b/tests/auto/qsqldatabase/tst_databases.h index 9c19048..611077f 100644 --- a/tests/auto/qsqldatabase/tst_databases.h +++ b/tests/auto/qsqldatabase/tst_databases.h @@ -105,11 +105,7 @@ inline static QString qTableName( const QString& prefix, QSqlDriver* driver = 0 inline static bool testWhiteSpaceNames( const QString &name ) { -/* return name.startsWith( "QPSQL" ) - || name.startsWith( "QODBC" ) - || name.startsWith( "QSQLITE" ) - || name.startsWith( "QMYSQL" );*/ - return name != QLatin1String("QSQLITE2"); + return name != QLatin1String("QTDS7"); } inline static QString toHex( const QString& binary ) @@ -211,7 +207,7 @@ public: // This requires a local ODBC data source to be configured( pointing to a MySql database ) // addDb( "QODBC", "mysqlodbc", "troll", "trond" ); // addDb( "QODBC", "SqlServer", "troll", "trond" ); -// addDb( "QTDS7", "testdb", "troll", "trondk", "horsehead.nokia.troll.no" ); +// addDb( "QTDS7", "testdb", "troll", "trondk", "horsehead" ); // addDb( "QODBC", "silencetestdb", "troll", "trond", "silence" ); // addDb( "QODBC", "horseheadtestdb", "troll", "trondk", "horsehead" ); @@ -221,7 +217,7 @@ public: // addDb( "QMYSQL3", "testdb", "troll", "trond", "horsehead.nokia.troll.no", 3309, "CLIENT_COMPRESS=1;CLIENT_SSL=1" ); // MySQL 5.0.18 Linux // addDb( "QMYSQL3", "testdb", "troll", "trond", "iceblink.nokia.troll.no" ); // MySQL 5.0.13 Windows // addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "mysql4-nokia.trolltech.com.au" ); // MySQL 4.1.22-2.el4 linux -// addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "mysql5-nokia.trolltech.com.au" ); // MySQL 5.0.45-7.el5 linux +// addDb( "QMYSQL3", "testdb", "testuser", "Ee4Gabf6_", "mysql5-nokia.trolltech.com.au" ); // MySQL 5.0.45-7.el5 linux // addDb( "QPSQL7", "testdb", "troll", "trond", "horsehead.nokia.troll.no" ); // V7.2 NOT SUPPORTED! // addDb( "QPSQL7", "testdb", "troll", "trond", "horsehead.nokia.troll.no", 5434 ); // V7.2 NOT SUPPORTED! Multi-byte @@ -242,12 +238,15 @@ public: // addDb( "QIBASE", "/opt/firebird/databases/testdb.fdb", "testuser", "Ee4Gabf6_", "firebird2-nokia.trolltech.com.au" ); // Firebird 2.1.1 // use in-memory database to prevent local files -// addDb("QSQLITE", ":memory:"); - addDb( "QSQLITE", QDir::toNativeSeparators(QDir::tempPath()+"/foo.db") ); + addDb("QSQLITE", ":memory:"); +// addDb( "QSQLITE", QDir::toNativeSeparators(QDir::tempPath()+"/foo.db") ); // addDb( "QSQLITE2", QDir::toNativeSeparators(QDir::tempPath()+"/foo2.db") ); // addDb( "QODBC3", "DRIVER={SQL SERVER};SERVER=iceblink.nokia.troll.no\\ICEBLINK", "troll", "trond", "" ); // addDb( "QODBC3", "DRIVER={SQL Native Client};SERVER=silence.nokia.troll.no\\SQLEXPRESS", "troll", "trond", "" ); +// addDb( "QODBC", "DRIVER={MySQL ODBC 3.51 Driver};SERVER=mysql5-nokia.trolltech.com.au;DATABASE=testdb", "testuser", "Ee4Gabf6_", "" ); +// addDb( "QODBC", "DRIVER={FreeTDS};SERVER=horsehead.nokia.troll.no;DATABASE=testdb;PORT=4101;UID=troll;PWD=trondk", "troll", "trondk", "" ); + } void open() @@ -313,16 +312,18 @@ public: QSqlQuery q( db ); QStringList dbtables=db.tables(); - foreach(const QString &tableName, tableNames) { + foreach(QString tableName, tableNames) + { wasDropped = true; - foreach(const QString dbtablesName, dbtables) { - if(dbtablesName.toUpper() == tableName.toUpper()) { - dbtables.removeAll(dbtablesName); - wasDropped = q.exec("drop table " + db.driver()->escapeIdentifier( dbtablesName, QSqlDriver::TableName )); - if(!wasDropped) - wasDropped = q.exec("drop table " + dbtablesName); - } - } + QString table=tableName; + if ( db.driver()->isIdentifierEscaped(table, QSqlDriver::TableName)) + table = db.driver()->stripDelimiters(table, QSqlDriver::TableName); + + if ( dbtables.contains( table, Qt::CaseSensitive ) ) + wasDropped = q.exec( "drop table " + tableName); + else if ( dbtables.contains( table, Qt::CaseInsensitive ) ) + wasDropped = q.exec( "drop table " + tableName); + if ( !wasDropped ) qWarning() << dbToString(db) << "unable to drop table" << tableName << ':' << q.lastError().text() << "tables:" << dbtables; } diff --git a/tests/auto/qsqldriver/qsqldriver.pro b/tests/auto/qsqldriver/qsqldriver.pro new file mode 100644 index 0000000..0024841 --- /dev/null +++ b/tests/auto/qsqldriver/qsqldriver.pro @@ -0,0 +1,16 @@ +load(qttest_p4) +SOURCES += tst_qsqldriver.cpp + +QT += sql + +wince*: { + plugFiles.sources = ../../../plugins/sqldrivers + plugFiles.path = . + DEPLOYMENT += plugFiles +} else { + win32-g++ { + LIBS += -lws2_32 + } else:win32 { + LIBS += ws2_32.lib + } +} diff --git a/tests/auto/qsqldriver/tst_qsqldriver.cpp b/tests/auto/qsqldriver/tst_qsqldriver.cpp new file mode 100644 index 0000000..bbd7483 --- /dev/null +++ b/tests/auto/qsqldriver/tst_qsqldriver.cpp @@ -0,0 +1,218 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include +#include + +#include "../qsqldatabase/tst_databases.h" + + + +//TESTED_CLASS= +//TESTED_FILES= + +class tst_QSqlDriver : public QObject +{ + Q_OBJECT + +public: + void recreateTestTables(QSqlDatabase); + + tst_Databases dbs; + +public slots: + void initTestCase_data(); + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void record(); + void primaryIndex(); +}; + + +void tst_QSqlDriver::initTestCase_data() +{ + dbs.open(); + if (dbs.fillTestTable() == 0) { + qWarning("NO DATABASES"); + QSKIP("No database drivers are available in this Qt configuration", SkipAll); + } +} + +void tst_QSqlDriver::recreateTestTables(QSqlDatabase db) +{ + QSqlQuery q(db); + + QStringList tableNames; + tableNames << qTableName( "relTEST1" ); + tst_Databases::safeDropTables( db, tableNames ); + + QVERIFY_SQL( q, exec("create table " + qTableName("relTEST1") + + " (id int not null primary key, name varchar(20), title_key int, another_title_key int)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("relTEST1") + " values(1, 'harry', 1, 2)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("relTEST1") + " values(2, 'trond', 2, 1)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("relTEST1") + " values(3, 'vohi', 1, 2)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("relTEST1") + " values(4, 'boris', 2, 2)")); +} + +void tst_QSqlDriver::initTestCase() +{ + foreach (const QString &dbname, dbs.dbNames) + recreateTestTables(QSqlDatabase::database(dbname)); +} + +void tst_QSqlDriver::cleanupTestCase() +{ + QStringList tableNames; + tableNames << qTableName( "relTEST1" ); + foreach (const QString &dbName, dbs.dbNames) { + QSqlDatabase db = QSqlDatabase::database(dbName); + tst_Databases::safeDropTables( db, tableNames ); + } + dbs.close(); +} + +void tst_QSqlDriver::init() +{ +} + +void tst_QSqlDriver::cleanup() +{ +} + +void tst_QSqlDriver::record() +{ + QFETCH_GLOBAL(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + QString tablename = qTableName("relTEST1"); + QStringList fields; + fields << "id" << "name" << "title_key" << "another_title_key"; + + //check we can get records using an unquoted mixed case table name + QSqlRecord rec = db.driver()->record(tablename); + QCOMPARE(rec.count(), 4); + + if (db.driverName().startsWith("QIBASE")|| db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + for(int i = 0; i < fields.count(); ++i) + fields[i] = fields[i].toUpper(); + + for (int i = 0; i < fields.count(); ++i) + QCOMPARE(rec.fieldName(i), fields[i]); + + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + tablename = tablename.toUpper(); + else if (db.driverName().startsWith("QPSQL")) + tablename = tablename.toLower(); + + //check we can get records using a properly quoted table name + rec = db.driver()->record(db.driver()->escapeIdentifier(tablename,QSqlDriver::TableName)); + QCOMPARE(rec.count(), 4); + + for (int i = 0; i < fields.count(); ++i) + QCOMPARE(rec.fieldName(i), fields[i]); + + if( db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + tablename = tablename.toLower(); + else if (db.driverName().startsWith("QPSQL")) + tablename = tablename.toUpper(); + + //check that we can't get records using incorrect tablename casing that's been quoted + rec = db.driver()->record(db.driver()->escapeIdentifier(tablename,QSqlDriver::TableName)); + if (db.driverName().startsWith("QMYSQL") || db.driverName().startsWith("QSQLITE") || db.driverName().startsWith("QTDS")) + QCOMPARE(rec.count(), 4); //mysql, sqlite and tds will match + else + QCOMPARE(rec.count(), 0); + +} + +void tst_QSqlDriver::primaryIndex() +{ + QFETCH_GLOBAL(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + QString tablename = qTableName("relTEST1"); + //check that we can get primary index using unquoted mixed case table name + QSqlIndex index = db.driver()->primaryIndex(tablename); + QCOMPARE(index.count(), 1); + + if( db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + QCOMPARE(index.fieldName(0), QString::fromLatin1("ID")); + else + QCOMPARE(index.fieldName(0), QString::fromLatin1("id")); + + + //check that we can get the primary index using a quoted tablename + if( db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + tablename = tablename.toUpper(); + else if (db.driverName().startsWith("QPSQL")) + tablename = tablename.toLower(); + + index = db.driver()->primaryIndex(db.driver()->escapeIdentifier(tablename, QSqlDriver::TableName)); + QCOMPARE(index.count(), 1); + if( db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + QCOMPARE(index.fieldName(0), QString::fromLatin1("ID")); + else + QCOMPARE(index.fieldName(0), QString::fromLatin1("id")); + + + + //check that we can not get the primary index using a quoted but incorrect table name casing + if( db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) + tablename = tablename.toLower(); + else if (db.driverName().startsWith("QPSQL")) + tablename = tablename.toUpper(); + + index = db.driver()->primaryIndex(db.driver()->escapeIdentifier(tablename, QSqlDriver::TableName)); + if (db.driverName().startsWith("QMYSQL") || db.driverName().startsWith("QSQLITE") || db.driverName().startsWith("QTDS")) + QCOMPARE(index.count(), 1); //mysql will always find the table name regardless of casing + else + QCOMPARE(index.count(), 0); +} + +QTEST_MAIN(tst_QSqlDriver) +#include "tst_qsqldriver.moc" diff --git a/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp b/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp index 76785c3..bb2cddd 100644 --- a/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp +++ b/tests/auto/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp @@ -82,6 +82,10 @@ private slots: void insertRecordDuplicateFieldNames(); void invalidData(); void relationModel(); + void casing(); + void escapedRelations(); + void escapedTableName(); + void whiteSpaceInIdentifiers(); }; @@ -103,7 +107,9 @@ void tst_QSqlRelationalTableModel::recreateTestTables(QSqlDatabase db) << qTableName( "reltest2" ) << qTableName( "reltest3" ) << qTableName( "reltest4" ) - << qTableName( "reltest5" ); + << qTableName( "reltest5" ) + << db.driver()->escapeIdentifier(qTableName( "rel test6" ), QSqlDriver::TableName) + << db.driver()->escapeIdentifier(qTableName( "rel test7" ), QSqlDriver::TableName); tst_Databases::safeDropTables( db, tableNames ); QVERIFY_SQL( q, exec("create table " + qTableName("reltest1") + @@ -128,6 +134,19 @@ void tst_QSqlRelationalTableModel::recreateTestTables(QSqlDatabase db) QVERIFY_SQL( q, exec("create table " + qTableName("reltest5") + " (title varchar(20) not null primary key, abbrev varchar(20))")); QVERIFY_SQL( q, exec("insert into " + qTableName("reltest5") + " values('herr', 'Hr')")); QVERIFY_SQL( q, exec("insert into " + qTableName("reltest5") + " values('mister', 'Mr')")); + + if (testWhiteSpaceNames(db.driverName())) { + QString reltest6 = db.driver()->escapeIdentifier(qTableName("rel test6"), QSqlDriver::TableName); + QVERIFY_SQL( q, exec("create table " + reltest6 + " (id int not null primary key, " + db.driver()->escapeIdentifier("city key", QSqlDriver::FieldName) + + " int, " + db.driver()->escapeIdentifier("extra field", QSqlDriver::FieldName) + " int)")); + QVERIFY_SQL( q, exec("insert into " + reltest6 + " values(1, 1,9)")); + QVERIFY_SQL( q, exec("insert into " + reltest6 + " values(2, 2,8)")); + + QString reltest7 = db.driver()->escapeIdentifier(qTableName("rel test7"), QSqlDriver::TableName); + QVERIFY_SQL( q, exec("create table " + reltest7 + " (" + db.driver()->escapeIdentifier("city id", QSqlDriver::TableName) + " int not null primary key, " + db.driver()->escapeIdentifier("city name", QSqlDriver::FieldName) + " varchar(20))")); + QVERIFY_SQL( q, exec("insert into " + reltest7 + " values(1, 'New York')")); + QVERIFY_SQL( q, exec("insert into " + reltest7 + " values(2, 'Washington')")); + } } void tst_QSqlRelationalTableModel::initTestCase() @@ -142,10 +161,14 @@ void tst_QSqlRelationalTableModel::cleanupTestCase() tableNames << qTableName( "reltest1" ) << qTableName( "reltest2" ) << qTableName( "reltest3" ) - << qTableName( "reltest4" ); + << qTableName( "reltest4" ) + << qTableName( "reltest5" ); foreach (const QString &dbName, dbs.dbNames) { QSqlDatabase db = QSqlDatabase::database(dbName); - tst_Databases::safeDropTables( db, tableNames ); + QStringList tables = tableNames; + tables << db.driver()->escapeIdentifier(qTableName( "rel test6" ), QSqlDriver::TableName) + << db.driver()->escapeIdentifier(qTableName( "rel test7" ), QSqlDriver::TableName); + tst_Databases::safeDropTables( db, tables ); } dbs.close(); } @@ -273,7 +296,12 @@ void tst_QSqlRelationalTableModel::setData() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + + //sybase doesn't allow tables with the same alias used twice as col names + //so don't set up an identical relation when using the tds driver + if (!db.driverName().startsWith("QTDS")) + model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + model.setEditStrategy(QSqlTableModel::OnManualSubmit); model.setSort(0, Qt::AscendingOrder); QVERIFY_SQL(model, select()); @@ -284,7 +312,10 @@ void tst_QSqlRelationalTableModel::setData() QCOMPARE(model.data(model.index(2, 1)).toString(), QString("vohi2")); QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); + else + QCOMPARE(model.data(model.index(0, 3)).toInt(), 1); QVERIFY_SQL(model, submitAll()); } @@ -299,10 +330,15 @@ void tst_QSqlRelationalTableModel::setData() QCOMPARE(model.data(model.index(0, 3)).toInt(), 1); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + if (!db.driverName().startsWith("QTDS")) + model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); + + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); + else + QCOMPARE(model.data(model.index(0, 3)).toInt(), 1); } //check setting of data when the relational key is a non-integer type @@ -336,7 +372,8 @@ void tst_QSqlRelationalTableModel::multipleRelation() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + model.setRelation(3, QSqlRelation(qTableName("reltest4"), "id", "name")); + model.setSort(0, Qt::AscendingOrder); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(2, 0)).toInt(), 3); @@ -344,7 +381,7 @@ void tst_QSqlRelationalTableModel::multipleRelation() QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(0, 3)).toString(), QString("mister")); + QCOMPARE(model.data(model.index(0, 3)).toString(), QString("Trondheim")); } void tst_QSqlRelationalTableModel::insertRecord() @@ -357,6 +394,7 @@ void tst_QSqlRelationalTableModel::insertRecord() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); + model.setSort(0, Qt::AscendingOrder); QVERIFY_SQL(model, select()); QSqlRecord rec; @@ -398,6 +436,7 @@ void tst_QSqlRelationalTableModel::setRecord() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); + model.setSort(0, Qt::AscendingOrder); QVERIFY_SQL(model, select()); QSqlRecord rec; @@ -450,13 +489,18 @@ void tst_QSqlRelationalTableModel::insertWithStrategies() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + + if (!db.driverName().startsWith("QTDS")) + model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); QVERIFY_SQL(model, select()); QCOMPARE(model.data(model.index(0,0)).toInt(), 1); QCOMPARE(model.data(model.index(0,1)).toString(), QString("harry")); QCOMPARE(model.data(model.index(0,2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister")); + else + QCOMPARE(model.data(model.index(0,3)).toInt(), 2); model.insertRows(0, 1); model.setData(model.index(0, 0), 1011); @@ -467,12 +511,20 @@ void tst_QSqlRelationalTableModel::insertWithStrategies() QCOMPARE(model.data(model.index(0,0)).toInt(), 1011); QCOMPARE(model.data(model.index(0,1)).toString(), QString("test")); QCOMPARE(model.data(model.index(0,2)).toString(), QString("mister")); - QCOMPARE(model.data(model.index(0,3)).toString(), QString("herr")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(0,3)).toString(), QString("herr")); + else + QCOMPARE(model.data(model.index(0,3)).toInt(), 1); QCOMPARE(model.data(model.index(1,0)).toInt(), 1); QCOMPARE(model.data(model.index(1,1)).toString(), QString("harry")); QCOMPARE(model.data(model.index(1,2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(1,3)).toString(), QString("mister")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(1,3)).toString(), QString("mister")); + else + QCOMPARE(model.data(model.index(1,3)).toInt(), 2); + + QVERIFY_SQL(model, submitAll()); @@ -481,9 +533,16 @@ void tst_QSqlRelationalTableModel::insertWithStrategies() QCOMPARE(model.data(model.index(0,0)).toInt(), 1); QCOMPARE(model.data(model.index(0,1)).toString(), QString("harry")); QCOMPARE(model.data(model.index(0,2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister")); - model.setData(model.index(0,3),1); - QCOMPARE(model.data(model.index(0,3)).toString(), QString("herr")); + + if (!db.driverName().startsWith("QTDS")) { + QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister")); + model.setData(model.index(0,3),1); + QCOMPARE(model.data(model.index(0,3)).toString(), QString("herr")); + } else { + QCOMPARE(model.data(model.index(0,3)).toInt(), 2); + model.setData(model.index(0,3),1); + QCOMPARE(model.data(model.index(0,3)).toInt(), 1); + } model.insertRows(0, 2); model.setData(model.index(0, 0), 1012); @@ -499,17 +558,27 @@ void tst_QSqlRelationalTableModel::insertWithStrategies() QCOMPARE(model.data(model.index(0,0)).toInt(),1012); QCOMPARE(model.data(model.index(0,1)).toString(), QString("george")); QCOMPARE(model.data(model.index(0,2)).toString(), QString("mister")); - QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(0,3)).toString(), QString("mister")); + else + QCOMPARE(model.data(model.index(0,3)).toInt(), 2); + QCOMPARE(model.data(model.index(1,0)).toInt(),1013); QCOMPARE(model.data(model.index(1,1)).toString(), QString("kramer")); QCOMPARE(model.data(model.index(1,2)).toString(), QString("mister")); - QCOMPARE(model.data(model.index(1,3)).toString(), QString("herr")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(1,3)).toString(), QString("herr")); + else + QCOMPARE(model.data(model.index(1,3)).toInt(), 1); QCOMPARE(model.data(model.index(2,0)).toInt(), 1); QCOMPARE(model.data(model.index(2,1)).toString(), QString("harry")); QCOMPARE(model.data(model.index(2,2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(2,3)).toString(), QString("herr")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(2,3)).toString(), QString("herr")); + else + QCOMPARE(model.data(model.index(2,3)).toInt(), 1); QVERIFY_SQL(model, submitAll()); } @@ -574,7 +643,8 @@ void tst_QSqlRelationalTableModel::sort() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + if (!db.driverName().startsWith("QTDS")) + model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); model.setSort(2, Qt::DescendingOrder); QVERIFY_SQL(model, select()); @@ -589,11 +659,19 @@ void tst_QSqlRelationalTableModel::sort() model.setSort(3, Qt::AscendingOrder); QVERIFY_SQL(model, select()); - QCOMPARE(model.rowCount(), 4); - QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(1, 3)).toString(), QString("mister")); - QCOMPARE(model.data(model.index(2, 3)).toString(), QString("mister")); - QCOMPARE(model.data(model.index(3, 3)).toString(), QString("mister")); + if (!db.driverName().startsWith("QTDS")) { + QCOMPARE(model.rowCount(), 4); + QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); + QCOMPARE(model.data(model.index(1, 3)).toString(), QString("mister")); + QCOMPARE(model.data(model.index(2, 3)).toString(), QString("mister")); + QCOMPARE(model.data(model.index(3, 3)).toString(), QString("mister")); + } else { + QCOMPARE(model.data(model.index(0, 3)).toInt(), 1); + QCOMPARE(model.data(model.index(1, 3)).toInt(), 2); + QCOMPARE(model.data(model.index(2, 3)).toInt(), 2); + QCOMPARE(model.data(model.index(3, 3)).toInt(), 2); + } + } static void testRevert(QSqlRelationalTableModel &model) @@ -663,7 +741,7 @@ void tst_QSqlRelationalTableModel::revert() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + model.setRelation(3, QSqlRelation(qTableName("reltest4"), "id", "name")); model.setSort(0, Qt::AscendingOrder); @@ -689,7 +767,9 @@ void tst_QSqlRelationalTableModel::clearDisplayValuesCache() model.setTable(qTableName("reltest1")); model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + + if (!db.driverName().startsWith("QTDS")) + model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); model.setSort(1, Qt::AscendingOrder); model.setEditStrategy(QSqlTableModel::OnManualSubmit); @@ -698,7 +778,10 @@ void tst_QSqlRelationalTableModel::clearDisplayValuesCache() QCOMPARE(model.data(model.index(3, 0)).toInt(), 3); QCOMPARE(model.data(model.index(3, 1)).toString(), QString("vohi")); QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(3, 3)).toString(), QString("mister")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(3, 3)).toString(), QString("mister")); + else + QCOMPARE(model.data(model.index(3, 3)).toInt(), 2 ); model.insertRow(model.rowCount()); QVERIFY(model.setData(model.index(4, 0), 5, Qt::EditRole)); @@ -710,11 +793,18 @@ void tst_QSqlRelationalTableModel::clearDisplayValuesCache() QCOMPARE(model.data(model.index(0, 0)).toInt(), 5); QCOMPARE(model.data(model.index(0, 1)).toString(), QString("anders")); QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(0, 3)).toString(), QString("herr")); + else + QCOMPARE(model.data(model.index(0, 3)).toInt(), 1); + QCOMPARE(model.data(model.index(4, 0)).toInt(), 3); QCOMPARE(model.data(model.index(4, 1)).toString(), QString("vohi")); QCOMPARE(model.data(model.index(4, 2)).toString(), QString("herr")); - QCOMPARE(model.data(model.index(4, 3)).toString(), QString("mister")); + if (!db.driverName().startsWith("QTDS")) + QCOMPARE(model.data(model.index(4, 3)).toString(), QString("mister")); + else + QCOMPARE(model.data(model.index(4, 3)).toInt(), 2); } // For task 140782 and 176374: If the main table and the the related tables uses the same @@ -729,27 +819,38 @@ void tst_QSqlRelationalTableModel::insertRecordDuplicateFieldNames() QSqlRelationalTableModel model(0, db); model.setTable(qTableName("reltest3")); model.setEditStrategy(QSqlTableModel::OnManualSubmit); + model.setSort(0, Qt::AscendingOrder); // Duplication of "name", used in both reltest3 and reltest4. model.setRelation(2, QSqlRelation(qTableName("reltest4"), "id", "name")); QVERIFY_SQL(model, select()); - QCOMPARE(model.record(1).value(qTableName("reltest4").append(QLatin1String("_name"))).toString(), + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + QCOMPARE(model.record(1).value(qTableName("reltest4").append(QLatin1String("_name")).toUpper()).toString(), + QString("Trondheim")); + } else { + QCOMPARE(model.record(1).value(qTableName("reltest4").append(QLatin1String("_name"))).toString(), QString("Trondheim")); + } QSqlRecord rec = model.record(); rec.setValue(0, 3); rec.setValue(1, "Berge"); rec.setValue(2, 1); // Must insert the key value - QCOMPARE(rec.fieldName(0), QLatin1String("id")); - QCOMPARE(rec.fieldName(1), QLatin1String("name")); // This comes from main table + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + QCOMPARE(rec.fieldName(0), QLatin1String("ID")); + QCOMPARE(rec.fieldName(1), QLatin1String("NAME")); // This comes from main table + } else { + QCOMPARE(rec.fieldName(0), QLatin1String("id")); + QCOMPARE(rec.fieldName(1), QLatin1String("name")); + } // The duplicate field names is aliased because it's comes from the relation's display column. - if(!db.driverName().startsWith("QIBASE")) - QCOMPARE(rec.fieldName(2), qTableName("reltest4").append(QLatin1String("_name"))); - else + if(db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) QCOMPARE(rec.fieldName(2), (qTableName("reltest4").append(QLatin1String("_name"))).toUpper()); + else + QCOMPARE(rec.fieldName(2), qTableName("reltest4").append(QLatin1String("_name"))); QVERIFY(model.insertRecord(-1, rec)); QCOMPARE(model.data(model.index(2, 2)).toString(), QString("Oslo")); @@ -793,7 +894,7 @@ void tst_QSqlRelationalTableModel::relationModel() QVERIFY(model.relationModel(3) == NULL); QVERIFY(model.relationModel(4) == NULL); - model.setRelation(3, QSqlRelation(qTableName("reltest2"), "tid", "title")); + model.setRelation(3, QSqlRelation(qTableName("reltest4"), "id", "name")); QVERIFY_SQL(model, select()); QVERIFY(model.relationModel(0) == NULL); @@ -806,5 +907,285 @@ void tst_QSqlRelationalTableModel::relationModel() QCOMPARE(rel_model->data(rel_model->index(0,1)).toString(), QString("herr")); } +void tst_QSqlRelationalTableModel::casing() +{ + QFETCH_GLOBAL(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + if (db.driverName().startsWith("QSQLITE")) + QSKIP("The casing test for SQLITE is irrelevant since SQLITE is case insensitive", SkipAll); + + QStringList tableNames; + tableNames << qTableName("CASETEST1", db.driver()).toUpper(); + tableNames << qTableName("casetest1", db.driver()); + tst_Databases::safeDropTables(db, tableNames); + + QSqlQuery q(db); + QVERIFY_SQL( q, exec("create table " + qTableName("CASETEST1", db.driver()).toUpper() + + " (id int not null primary key, name varchar(20), title_key int, another_title_key int)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db.driver()).toUpper() + " values(1, 'harry', 1, 2)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db.driver()).toUpper() + " values(2, 'trond', 2, 1)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db.driver()).toUpper() + " values(3, 'vohi', 1, 2)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db.driver()).toUpper() + " values(4, 'boris', 2, 2)")); + + QVERIFY_SQL( q, exec("create table " + qTableName("casetest1", db.driver()) + + " (ident int not null primary key, name varchar(20), title_key int)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db.driver()) + " values(1, 'jerry', 1)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db.driver()) + " values(2, 'george', 2)")); + QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db.driver()) + " values(4, 'kramer', 2)")); + + if (db.driverName().startsWith("QOCI")) { + //try an owner that doesn't exist + QSqlRecord rec = db.driver()->record("doug." + qTableName("CASETEST1", db.driver()).toUpper()); + QCOMPARE( rec.count(), 0); + + //try an owner that does exist + rec = db.driver()->record(db.userName() + "." + qTableName("CASETEST1", db.driver()).toUpper()); + QCOMPARE( rec.count(), 4); + } + QSqlRecord rec = db.driver()->record(qTableName("CASETEST1", db.driver()).toUpper()); + QCOMPARE( rec.count(), 4); + + rec = db.driver()->record(qTableName("casetest1", db.driver())); + QCOMPARE( rec.count(), 3); + + QSqlTableModel upperCaseModel(0, db); + upperCaseModel.setTable(qTableName("CASETEST1", db.driver()).toUpper()); + + QCOMPARE(upperCaseModel.tableName(),qTableName("CASETEST1",db.driver()).toUpper()); + + QVERIFY_SQL(upperCaseModel, select()); + + QCOMPARE(upperCaseModel.rowCount(), 4); + + QSqlTableModel lowerCaseModel(0, db); + lowerCaseModel.setTable(qTableName("casetest1", db.driver())); + QCOMPARE(lowerCaseModel.tableName(), qTableName("casetest1",db.driver())); + QVERIFY_SQL(lowerCaseModel, select()); + + QCOMPARE(lowerCaseModel.rowCount(), 3); + + QSqlRelationalTableModel model(0, db); + model.setTable(qTableName("CASETEST1", db.driver()).toUpper()); + model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); + QVERIFY_SQL(model, select()); + + QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); + + tst_Databases::safeDropTables(db, tableNames); +} + +void tst_QSqlRelationalTableModel::escapedRelations() +{ + QFETCH_GLOBAL(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + recreateTestTables(db); + + QSqlRelationalTableModel model(0, db); + model.setTable(qTableName("reltest1")); + + //try with relation table name quoted + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + model.setRelation(2, QSqlRelation(db.driver()->escapeIdentifier(qTableName("reltest2").toUpper(),QSqlDriver::TableName), + "tid", + "title")); + } else { + model.setRelation(2, QSqlRelation(db.driver()->escapeIdentifier(qTableName("reltest2"),QSqlDriver::TableName), + "tid", + "title")); + + } + QVERIFY_SQL(model, select()); + + QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); + + //try with index column quoted + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + model.setRelation(2, QSqlRelation(qTableName("reltest2"), + db.driver()->escapeIdentifier("tid", QSqlDriver::FieldName).toUpper(), + "title")); + } else { + model.setRelation(2, QSqlRelation(qTableName("reltest2"), + db.driver()->escapeIdentifier("tid", QSqlDriver::FieldName), + "title")); + } + QVERIFY_SQL(model, select()); + + QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); + + //try with display column quoted + + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + + model.setRelation(2, QSqlRelation(qTableName("reltest2"), + "tid", + db.driver()->escapeIdentifier("title", QSqlDriver::FieldName).toUpper())); + } else { + model.setRelation(2, QSqlRelation(qTableName("reltest2"), + "tid", + db.driver()->escapeIdentifier("title", QSqlDriver::FieldName))); + } + + QVERIFY_SQL(model, select()); + + QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); + + //try with tablename and index and display columns quoted in the relation + + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + model.setRelation(2, QSqlRelation(qTableName("reltest2"), + "tid", + db.driver()->escapeIdentifier("title", QSqlDriver::FieldName).toUpper())); + } else { + model.setRelation(2, QSqlRelation(qTableName("reltest2"), + "tid", + db.driver()->escapeIdentifier("title", QSqlDriver::FieldName))); + } + QVERIFY_SQL(model, select()); + + QCOMPARE(model.data(model.index(0, 0)).toInt(), 1); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("herr")); +} + +void tst_QSqlRelationalTableModel::escapedTableName() +{ + QFETCH_GLOBAL(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + // set the values using OnRowChange Strategy with an escaped tablename + { + QSqlRelationalTableModel model(0, db); + + if (db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2")) { + model.setTable(db.driver()->escapeIdentifier(qTableName("reltest1").toUpper(), QSqlDriver::TableName)); + } else { + model.setTable(db.driver()->escapeIdentifier(qTableName("reltest1"), QSqlDriver::TableName)); + } + model.setSort(0, Qt::AscendingOrder); + model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); + QVERIFY_SQL(model, select()); + + QVERIFY(model.setData(model.index(0, 1), QString("harry2"))); + QVERIFY(model.setData(model.index(0, 2), 2)); + + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry2")); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("mister")); + + model.submit(); + + QVERIFY(model.setData(model.index(3,1), QString("boris2"))); + QVERIFY(model.setData(model.index(3, 2), 1)); + + QCOMPARE(model.data(model.index(3,1)).toString(), QString("boris2")); + QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr")); + + model.submit(); + } + { //verify values + QSqlRelationalTableModel model(0, db); + model.setTable(qTableName("reltest1")); + model.setSort(0, Qt::AscendingOrder); + QVERIFY_SQL(model, select()); + + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry2")); + QCOMPARE(model.data(model.index(0, 2)).toInt(), 2); + QCOMPARE(model.data(model.index(3, 1)).toString(), QString("boris2")); + QCOMPARE(model.data(model.index(3, 2)).toInt(), 1); + + model.setRelation(2, QSqlRelation(qTableName("reltest2"), "tid", "title")); + QVERIFY_SQL(model, select()); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("mister")); + QCOMPARE(model.data(model.index(3,2)).toString(), QString("herr")); + + } +} + +void tst_QSqlRelationalTableModel::whiteSpaceInIdentifiers() { + + QFETCH_GLOBAL(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + if (!testWhiteSpaceNames(db.driverName())) + QSKIP("White space test irrelevant for driver", SkipAll); + QSqlRelationalTableModel model(0, db); + model.setTable(db.driver()->escapeIdentifier(qTableName("rel test6"), QSqlDriver::TableName)); + model.setSort(0, Qt::DescendingOrder); + model.setRelation(1, QSqlRelation(db.driver()->escapeIdentifier(qTableName("rel test7"), QSqlDriver::TableName), + db.driver()->escapeIdentifier("city id", QSqlDriver::FieldName), + db.driver()->escapeIdentifier("city name", QSqlDriver::FieldName))); + QVERIFY_SQL(model, select()); + + QCOMPARE(model.data(model.index(0,1)).toString(), QString("Washington")); + QCOMPARE(model.data(model.index(1,1)).toString(), QString("New York")); + + QSqlRecord rec; + QSqlField f1("id", QVariant::Int); + QSqlField f2(db.driver()->escapeIdentifier("city key", QSqlDriver::FieldName), QVariant::Int); + QSqlField f3(db.driver()->escapeIdentifier("extra field", QSqlDriver::FieldName), QVariant::Int); + + f1.setValue(3); + f2.setValue(2); + f3.setValue(7); + + f1.setGenerated(true); + f2.setGenerated(true); + f3.setGenerated(true); + + rec.append(f1); + rec.append(f2); + rec.append(f3); + + QVERIFY_SQL(model, insertRecord(-1, rec)); + model.submitAll(); + + QCOMPARE(model.data(model.index(0, 0)).toInt(), 3); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("Washington")); + QCOMPARE(model.data(model.index(0, 2)).toInt(), 7); + + //TODO: For some reson setting a record using manual submit fails + //model.setEditStrategy(QSqlTableModel::OnManualSubmit); + + QSqlRecord recNew; + QSqlField f1New("id", QVariant::Int); + QSqlField f2New(db.driver()->escapeIdentifier("city key", QSqlDriver::FieldName), QVariant::Int); + QSqlField f3New(db.driver()->escapeIdentifier("extra field", QSqlDriver::FieldName), QVariant::Int); + + f1New.setValue(4); + f2New.setValue(1); + f3New.setValue(6); + + f1New.setGenerated(true); + f2New.setGenerated(true); + f3New.setGenerated(true); + + recNew.append(f1New); + recNew.append(f2New); + recNew.append(f3New); + + QVERIFY_SQL(model, setRecord(0, recNew)); + + QCOMPARE(model.data(model.index(0, 0)).toInt(), 4); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("New York")); + QCOMPARE(model.data(model.index(0, 2)).toInt(), 6); + + QVERIFY_SQL(model, submitAll()); + QCOMPARE(model.data(model.index(0, 0)).toInt(), 4); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("New York")); + QCOMPARE(model.data(model.index(0, 2)).toInt(), 6); +} + QTEST_MAIN(tst_QSqlRelationalTableModel) #include "tst_qsqlrelationaltablemodel.moc" diff --git a/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp index d4affe4..0e7355e 100644 --- a/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp +++ b/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp @@ -145,7 +145,7 @@ void tst_QSqlTableModel::dropTestTables() << qTableName("bigtable") << qTableName("foo"); if (testWhiteSpaceNames(db.driverName())) - tableNames << qTableName("qtestw hitespace"); + tableNames << qTableName("qtestw hitespace", db.driver()); tst_Databases::safeDropTables(db, tableNames); @@ -277,6 +277,7 @@ void tst_QSqlTableModel::setRecord() QList policies = QList() << QSqlTableModel::OnFieldChange << QSqlTableModel::OnRowChange << QSqlTableModel::OnManualSubmit; + QString Xsuffix; foreach( QSqlTableModel::EditStrategy submitpolicy, policies) { QSqlTableModel model(0, db); @@ -295,6 +296,8 @@ void tst_QSqlTableModel::setRecord() if ((QSqlTableModel::EditStrategy)submitpolicy == QSqlTableModel::OnManualSubmit) QVERIFY(model.submitAll()); + else if ((QSqlTableModel::EditStrategy)submitpolicy == QSqlTableModel::OnRowChange && i == model.rowCount() -1) + model.submit(); else { // dataChanged() is not emitted when submitAll() is called QCOMPARE(spy.count(), 2); @@ -304,10 +307,12 @@ void tst_QSqlTableModel::setRecord() } } - QCOMPARE(model.data(model.index(0, 1)).toString(), QString("fooX")); - QCOMPARE(model.data(model.index(0, 2)).toString(), QString("barX")); - QCOMPARE(model.data(model.index(1, 1)).toString(), QString("bazX")); - QCOMPARE(model.data(model.index(1, 2)).toString(), QString("joeX")); + Xsuffix.append('X'); + + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("foo").append(Xsuffix)); + QCOMPARE(model.data(model.index(0, 2)).toString(), QString("bar").append(Xsuffix)); + QCOMPARE(model.data(model.index(1, 1)).toString(), QString("baz").append(Xsuffix)); + QCOMPARE(model.data(model.index(1, 2)).toString(), QString("joe").append(Xsuffix)); } } -- cgit v0.12 From 014af3e99616f9ee13ca365566828f7daf77a7f6 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Wed, 15 Apr 2009 10:36:40 +1000 Subject: Fixes WebKit still occasionally failing to compile with MinGW when passing any `-j' to make. Change 6e5774d84e7e3b68736f95fae09a084bd5b9ac7a made the problem much less likely to occur, but in a debug_and_release build, debug and release would share the same mocinclude.tmp. Therefore, if exceptionally unlucky, the bug could still arise. Put mocinclude.tmp under MOC_DIR so each exclusive build has its own. Reviewed-by: Lincoln Ramsay --- mkspecs/features/moc.prf | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/mkspecs/features/moc.prf b/mkspecs/features/moc.prf index 975867e..7c4ff28 100644 --- a/mkspecs/features/moc.prf +++ b/mkspecs/features/moc.prf @@ -11,13 +11,14 @@ isEmpty(QMAKE_EXT_CPP_MOC):QMAKE_EXT_CPP_MOC = .moc # On Windows, put the includes into a .inc file which moc will read, if the project # has too many includes. We do this to overcome a command-line limit on Win < XP INCLUDETEMP= +WIN_INCLUDETEMP= win32:count($$list($$INCPATH), 40, >) { - INCLUDETEMP = mocinclude.tmp + INCLUDETEMP = $$MOC_DIR/mocinclude.tmp # Remove any existing mocinclude.tmp when qmake runs - WIN_OUT_PWD=$$OUT_PWD - WIN_OUT_PWD~=s,/,\,g - system($$QMAKE_DEL_FILE $$WIN_OUT_PWD\\$$INCLUDETEMP > NUL 2>&1) + WIN_INCLUDETEMP=$$INCLUDETEMP + WIN_INCLUDETEMP~=s,/,\,g + system($$QMAKE_DEL_FILE $$WIN_INCLUDETEMP > NUL 2>&1) EOC = $$escape_expand(\n\t) @@ -32,10 +33,10 @@ win32:count($$list($$INCPATH), 40, >) { RET = for(incfile, $$list($$INCPATH)) { INCFILELIST = -I$$incfile - isEmpty(RET): RET += @echo $$INCFILELIST> $$INCLUDETEMP $$EOC - else: RET += @echo $$INCFILELIST>> $$INCLUDETEMP $$EOC + isEmpty(RET): RET += @echo $$INCFILELIST> $$WIN_INCLUDETEMP $$EOC + else: RET += @echo $$INCFILELIST>> $$WIN_INCLUDETEMP $$EOC } - !isEmpty(INCFILELIST):RET += @echo $$INCFILELIST>> $$INCLUDETEMP $$EOC + !isEmpty(INCFILELIST):RET += @echo $$INCFILELIST>> $$WIN_INCLUDETEMP $$EOC build_pass|isEmpty(BUILDS) { mocinclude.target = $$INCLUDETEMP @@ -45,8 +46,8 @@ win32:count($$list($$INCPATH), 40, >) { } defineReplace(mocCmd) { - !isEmpty(INCLUDETEMP) { - return($$QMAKE_MOC $(DEFINES) @$$INCLUDETEMP $$join(QMAKE_COMPILER_DEFINES, " -D", -D) $$1 -o $$2) + !isEmpty(WIN_INCLUDETEMP) { + return($$QMAKE_MOC $(DEFINES) @$$WIN_INCLUDETEMP $$join(QMAKE_COMPILER_DEFINES, " -D", -D) $$1 -o $$2) } return($$QMAKE_MOC $(DEFINES) $(INCPATH) $$join(QMAKE_COMPILER_DEFINES, " -D", -D) $$1 -o $$2) } -- cgit v0.12 From e3462ae7868c679bc88dc01de85ca39454651ff7 Mon Sep 17 00:00:00 2001 From: Jason McDonald Date: Wed, 15 Apr 2009 11:21:13 +1000 Subject: Fix typo in documentation. Error was introduced in change 52f87de53328c661049acf09d5fedc1850aa9bfa. Reviewed-by: Trust Me --- src/gui/painting/qpainter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 18993e1..2fa6a56 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -1465,7 +1465,7 @@ bool QPainter::isActive() const /*! Initializes the painters pen, background and font to the same as - the given \a widget. This function is automatically when the + the given \a widget. This function is called automatically when the painter is opened on a QWidget. \sa begin(), {QPainter#Settings}{Settings} -- cgit v0.12 From c0cba96117acc1d3086ede51f0779a51b7f29fb0 Mon Sep 17 00:00:00 2001 From: Kurt Korbatits Date: Wed, 15 Apr 2009 11:29:19 +1000 Subject: Changed codeeditor include to use double quotes, was failing to compile uncer windows. Reviewed-by: Justin McPherson --- examples/widgets/codeeditor/codeeditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/widgets/codeeditor/codeeditor.cpp b/examples/widgets/codeeditor/codeeditor.cpp index b855c7a..615f39f 100644 --- a/examples/widgets/codeeditor/codeeditor.cpp +++ b/examples/widgets/codeeditor/codeeditor.cpp @@ -41,7 +41,7 @@ #include -#include +#include "codeeditor.h" //![constructor] -- cgit v0.12 From 3eb4aacf07c77876c6ce68e9746906424934433b Mon Sep 17 00:00:00 2001 From: Bill King Date: Wed, 15 Apr 2009 13:22:48 +1000 Subject: Fixes an issue with FreeTDS and quoting. Microsofts SQL Server odbc driver calls SET QUOTED_IDENTIFIER_ON, but freetds doesn't, so any quoting fails. This fixes that issue. Reviewed-by: abcd --- src/sql/drivers/odbc/qsql_odbc.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp index 71b1b2a..d6423ae 100644 --- a/src/sql/drivers/odbc/qsql_odbc.cpp +++ b/src/sql/drivers/odbc/qsql_odbc.cpp @@ -55,6 +55,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -1800,6 +1801,10 @@ bool QODBCDriver::open(const QString & db, d->checkHasMultiResults(); setOpen(true); setOpenError(false); + if(d->isMSSqlServer) { + QSqlQuery i(createResult()); + i.exec(QLatin1String("SET QUOTED_IDENTIFIER ON")); + } return true; } -- cgit v0.12 From 6c4b9cb575292f5f81afc772d993c1a53eb96ea5 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 15 Apr 2009 08:18:30 +0200 Subject: Display QAction keyboard shortcuts in action editor correctly. Use PropertySheetKeySequenceValue instead of plain strings. --- tools/designer/src/lib/shared/actioneditor.cpp | 8 ++++---- tools/designer/src/lib/shared/actionrepository.cpp | 17 +++++++++++------ tools/designer/src/lib/shared/actionrepository_p.h | 7 +++++++ tools/designer/src/lib/shared/newactiondialog.cpp | 4 ++-- tools/designer/src/lib/shared/newactiondialog_p.h | 2 +- 5 files changed, 25 insertions(+), 13 deletions(-) diff --git a/tools/designer/src/lib/shared/actioneditor.cpp b/tools/designer/src/lib/shared/actioneditor.cpp index 6a66442..7f96a15 100644 --- a/tools/designer/src/lib/shared/actioneditor.cpp +++ b/tools/designer/src/lib/shared/actioneditor.cpp @@ -456,7 +456,7 @@ void ActionEditor::slotNewAction() if (actionData.checkable) setInitialProperty(sheet, QLatin1String(checkablePropertyC), QVariant(true)); - if (!actionData.keysequence.isEmpty()) + if (!actionData.keysequence.value().isEmpty()) setInitialProperty(sheet, QLatin1String(shortcutPropertyC), qVariantFromValue(actionData.keysequence)); sheet->setProperty(sheet->indexOf(QLatin1String(iconPropertyC)), qVariantFromValue(actionData.icon)); @@ -491,10 +491,10 @@ static QDesignerFormWindowCommand *setIconPropertyCommand(const PropertySheetIco // return a FormWindow command to apply a QKeySequence or a reset command // in case it is empty. -static QDesignerFormWindowCommand *setKeySequencePropertyCommand(const QKeySequence &ks, QAction *action, QDesignerFormWindowInterface *fw) +static QDesignerFormWindowCommand *setKeySequencePropertyCommand(const PropertySheetKeySequenceValue &ks, QAction *action, QDesignerFormWindowInterface *fw) { const QString shortcutProperty = QLatin1String(shortcutPropertyC); - if (ks.isEmpty()) { + if (ks.value().isEmpty()) { ResetPropertyCommand *cmd = new ResetPropertyCommand(fw); cmd->init(action, shortcutProperty); return cmd; @@ -544,7 +544,7 @@ void ActionEditor::editAction(QAction *action) oldActionData.text = action->text(); oldActionData.toolTip = textPropertyValue(sheet, QLatin1String(toolTipPropertyC)); oldActionData.icon = qVariantValue(sheet->property(sheet->indexOf(QLatin1String(iconPropertyC)))); - oldActionData.keysequence = qVariantValue(sheet->property(sheet->indexOf(QLatin1String(shortcutPropertyC)))); + oldActionData.keysequence = ActionModel::actionShortCut(sheet); oldActionData.checkable = action->isCheckable(); dlg.setActionData(oldActionData); diff --git a/tools/designer/src/lib/shared/actionrepository.cpp b/tools/designer/src/lib/shared/actionrepository.cpp index 941a9ba..1b638c3 100644 --- a/tools/designer/src/lib/shared/actionrepository.cpp +++ b/tools/designer/src/lib/shared/actionrepository.cpp @@ -42,6 +42,7 @@ #include "actionrepository_p.h" #include "qtresourceview_p.h" #include "iconloader_p.h" +#include "qdesigner_utils_p.h" #include #include @@ -168,16 +169,20 @@ QWidgetList ActionModel::associatedWidgets(const QAction *action) } // shortcut is a fake property, need to retrieve it via property sheet. -static QString actionShortCut(QDesignerFormEditorInterface *core, QAction *action) +PropertySheetKeySequenceValue ActionModel::actionShortCut(QDesignerFormEditorInterface *core, QAction *action) { QDesignerPropertySheetExtension *sheet = qt_extension(core->extensionManager(), action); if (!sheet) - return QString(); + return PropertySheetKeySequenceValue(); + return actionShortCut(sheet); +} + +PropertySheetKeySequenceValue ActionModel::actionShortCut(const QDesignerPropertySheetExtension *sheet) +{ const int index = sheet->indexOf(QLatin1String("shortcut")); if (index == -1) - return QString(); - const QKeySequence keysequence = qvariant_cast(sheet->property(index)); - return keysequence.toString(); + return PropertySheetKeySequenceValue(); + return qvariant_cast(sheet->property(index)); } void ActionModel::setItems(QDesignerFormEditorInterface *core, QAction *action, QStandardItemList &sl) @@ -221,7 +226,7 @@ void ActionModel::setItems(QDesignerFormEditorInterface *core, QAction *action, item->setText(action->text()); item->setToolTip(action->text()); // shortcut - const QString shortcut = actionShortCut(core, action); + const QString shortcut = actionShortCut(core, action).value().toString(); item = sl[ShortCutColumn]; item->setText(shortcut); item->setToolTip(shortcut); diff --git a/tools/designer/src/lib/shared/actionrepository_p.h b/tools/designer/src/lib/shared/actionrepository_p.h index 9d1af5a..66d77ce 100644 --- a/tools/designer/src/lib/shared/actionrepository_p.h +++ b/tools/designer/src/lib/shared/actionrepository_p.h @@ -65,9 +65,12 @@ QT_BEGIN_NAMESPACE class QPixmap; class QDesignerFormEditorInterface; +class QDesignerPropertySheetExtension; namespace qdesigner_internal { +class PropertySheetKeySequenceValue; + // Shared model of actions, to be used for several views (detailed/icon view). class QDESIGNER_SHARED_EXPORT ActionModel: public QStandardItemModel { @@ -99,6 +102,10 @@ public: // Find the associated menus and toolbars, ignore toolbuttons static QWidgetList associatedWidgets(const QAction *action); + // Retrieve shortcut via property sheet as it is a fake property + static PropertySheetKeySequenceValue actionShortCut(QDesignerFormEditorInterface *core, QAction *action); + static PropertySheetKeySequenceValue actionShortCut(const QDesignerPropertySheetExtension *ps); + signals: void resourceImageDropped(const QString &path, QAction *action); diff --git a/tools/designer/src/lib/shared/newactiondialog.cpp b/tools/designer/src/lib/shared/newactiondialog.cpp index 53aec4b..bb163d6 100644 --- a/tools/designer/src/lib/shared/newactiondialog.cpp +++ b/tools/designer/src/lib/shared/newactiondialog.cpp @@ -134,7 +134,7 @@ ActionData NewActionDialog::actionData() const rc.toolTip = m_ui->tooltipEditor->text(); rc.icon = m_ui->iconSelector->icon(); rc.checkable = m_ui->checkableCheckBox->checkState() == Qt::Checked; - rc.keysequence = m_ui->keySequenceEdit->keySequence(); + rc.keysequence = PropertySheetKeySequenceValue(m_ui->keySequenceEdit->keySequence()); return rc; } @@ -144,7 +144,7 @@ void NewActionDialog::setActionData(const ActionData &d) m_ui->editObjectName->setText(d.name); m_ui->iconSelector->setIcon(d.icon); m_ui->tooltipEditor->setText(d.toolTip); - m_ui->keySequenceEdit->setKeySequence(d.keysequence); + m_ui->keySequenceEdit->setKeySequence(d.keysequence.value()); m_ui->checkableCheckBox->setCheckState(d.checkable ? Qt::Checked : Qt::Unchecked); m_auto_update_object_name = false; diff --git a/tools/designer/src/lib/shared/newactiondialog_p.h b/tools/designer/src/lib/shared/newactiondialog_p.h index c8bd34c..d4e9b5b 100644 --- a/tools/designer/src/lib/shared/newactiondialog_p.h +++ b/tools/designer/src/lib/shared/newactiondialog_p.h @@ -84,7 +84,7 @@ struct ActionData { QString toolTip; PropertySheetIconValue icon; bool checkable; - QKeySequence keysequence; + PropertySheetKeySequenceValue keysequence; }; inline bool operator==(const ActionData &a1, const ActionData &a2) { return a1.compare(a2) == 0u; } -- cgit v0.12 From f169ca1020886707b04101300e365d79f38a6332 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 15 Apr 2009 08:54:36 +0200 Subject: Make ./configure work better with spaces in path names. Quote a few variables that may contain spaces. Also, quote spaces in qmake's Makefile dependency section. Reviewed-by: Friedemann Kleint --- config.tests/unix/objcopy.test | 2 +- configure | 42 ++++++++++++++++++++++-------------------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/config.tests/unix/objcopy.test b/config.tests/unix/objcopy.test index eb2173d..e2051a7 100755 --- a/config.tests/unix/objcopy.test +++ b/config.tests/unix/objcopy.test @@ -1,6 +1,6 @@ #!/bin/sh -TEST_PATH=`dirname $0` +TEST_PATH=`dirname "$0"` SEP_DEBUG_SUPPORT=no COMPILER=$1 QMAKE_OBJCOPY=$2 diff --git a/configure b/configure index 35fbd2d..e0ea0a1 100755 --- a/configure +++ b/configure @@ -735,7 +735,7 @@ CFG_SQL_AVAILABLE= if [ -d "$relpath/src/plugins/sqldrivers" ]; then for a in "$relpath/src/plugins/sqldrivers/"*; do if [ -d "$a" ]; then - base_a=`basename $a` + base_a=`basename "$a"` CFG_SQL_AVAILABLE="${CFG_SQL_AVAILABLE} ${base_a}" eval "CFG_SQL_${base_a}=auto" fi @@ -746,7 +746,7 @@ CFG_DECORATION_PLUGIN_AVAILABLE= if [ -d "$relpath/src/plugins/decorations" ]; then for a in "$relpath/src/plugins/decorations/"*; do if [ -d "$a" ]; then - base_a=`basename $a` + base_a=`basename "$a"` CFG_DECORATION_PLUGIN_AVAILABLE="${CFG_DECORATION_PLUGIN_AVAILABLE} ${base_a}" fi done @@ -756,7 +756,7 @@ CFG_KBD_PLUGIN_AVAILABLE= if [ -d "$relpath/src/plugins/kbddrivers" ]; then for a in "$relpath/src/plugins/kbddrivers/"*; do if [ -d "$a" ]; then - base_a=`basename $a` + base_a=`basename "$a"` CFG_KBD_PLUGIN_AVAILABLE="${CFG_KBD_PLUGIN_AVAILABLE} ${base_a}" fi done @@ -766,7 +766,7 @@ CFG_MOUSE_PLUGIN_AVAILABLE= if [ -d "$relpath/src/plugins/mousedrivers" ]; then for a in "$relpath/src/plugins/mousedrivers/"*; do if [ -d "$a" ]; then - base_a=`basename $a` + base_a=`basename "$a"` CFG_MOUSE_PLUGIN_AVAILABLE="${CFG_MOUSE_PLUGIN_AVAILABLE} ${base_a}" fi done @@ -776,7 +776,7 @@ CFG_GFX_PLUGIN_AVAILABLE= if [ -d "$relpath/src/plugins/gfxdrivers" ]; then for a in "$relpath/src/plugins/gfxdrivers/"*; do if [ -d "$a" ]; then - base_a=`basename $a` + base_a=`basename "$a"` CFG_GFX_PLUGIN_AVAILABLE="${CFG_GFX_PLUGIN_AVAILABLE} ${base_a}" fi done @@ -2125,7 +2125,7 @@ if [ -z "$MAKE" ]; then MAKE= for mk in gmake make; do if "$WHICH" $mk >/dev/null 2>&1; then - MAKE=`$WHICH $mk` + MAKE=`"$WHICH" $mk` break fi done @@ -2663,7 +2663,7 @@ if [ -z "$PKG_CONFIG" ]; then PKG_CONFIG=`getQMakeConf "$XQMAKESPEC" | sed -n -e 's%PKG_CONFIG[^_].*=%%p' | tr '\n' ' '` fi if [ -z "$PKG_CONFIG" ]; then - PKG_CONFIG=`$WHICH pkg-config 2>/dev/null` + PKG_CONFIG=`"$WHICH" pkg-config 2>/dev/null` fi # Work out if we can use pkg-config @@ -4050,9 +4050,9 @@ if true; then ###[ '!' -f "$outpath/bin/qmake" ]; fi [ -f "$in_mkfile" ] || continue - echo "########################################################################" >$mkfile - echo "## This file was autogenerated by configure, all changes will be lost ##" >>$mkfile - echo "########################################################################" >>$mkfile + echo "########################################################################" > "$mkfile" + echo "## This file was autogenerated by configure, all changes will be lost ##" >> "$mkfile" + echo "########################################################################" >> "$mkfile" EXTRA_OBJS= EXTRA_SRCS= EXTRA_CFLAGS="\$(QMAKE_CFLAGS)" @@ -4063,8 +4063,8 @@ if true; then ###[ '!' -f "$outpath/bin/qmake" ]; EXTRA_LFLAGS="$EXTRA_LFLAGS -lm" fi - [ -n "$CC" ] && echo "CC = $CC" >>$mkfile - [ -n "$CXX" ] && echo "CXX = $CXX" >>$mkfile + [ -n "$CC" ] && echo "CC = $CC" >> "$mkfile" + [ -n "$CXX" ] && echo "CXX = $CXX" >> "$mkfile" if [ "$CFG_SILENT" = "yes" ]; then [ -z "$CC" ] && setBootstrapVariable QMAKE_CC 's,QMAKE_CC.*=,CC=\@,' [ -z "$CXX" ] && setBootstrapVariable QMAKE_CXX 's,QMAKE_CXX.*=,CXX=\@,' @@ -4100,9 +4100,9 @@ if true; then ###[ '!' -f "$outpath/bin/qmake" ]; fi if [ "$PLATFORM_MAC" = "yes" ]; then if [ "$PLATFORM" = "macx-icc" ]; then - echo "export MACOSX_DEPLOYMENT_TARGET = 10.4" >>"$mkfile" + echo "export MACOSX_DEPLOYMENT_TARGET = 10.4" >> "$mkfile" else - echo "export MACOSX_DEPLOYMENT_TARGET = 10.3" >>"$mkfile" + echo "export MACOSX_DEPLOYMENT_TARGET = 10.3" >> "$mkfile" fi echo "CARBON_LFLAGS =-framework ApplicationServices" >>"$mkfile" echo "CARBON_CFLAGS =-fconstant-cfstrings" >>"$mkfile" @@ -4146,18 +4146,20 @@ if true; then ###[ '!' -f "$outpath/bin/qmake" ]; echo >>"$mkfile" adjrelpath=`echo "$relpath" | sed 's/ /\\\\\\\\ /g'` adjoutpath=`echo "$outpath" | sed 's/ /\\\\\\\\ /g'` + adjqmakespec=`echo "$QMAKESPEC" | sed 's/ /\\\\\\\\ /g'` sed -e "s,@SOURCE_PATH@,$adjrelpath,g" -e "s,@BUILD_PATH@,$adjoutpath,g" \ -e "s,@QMAKE_CFLAGS@,$EXTRA_CFLAGS,g" -e "s,@QMAKE_LFLAGS@,$EXTRA_LFLAGS,g" \ -e "s,@QMAKE_CXXFLAGS@,$EXTRA_CXXFLAGS,g" \ -e "s,@QT_INSTALL_BINS@,\$(INSTALL_ROOT)$QMAKE_BIN_DIR,g" \ -e "s,@QT_INSTALL_DATA@,\$(INSTALL_ROOT)$QMAKE_DATA_DIR,g" \ -e "s,@QMAKE_QTOBJS@,$EXTRA_OBJS,g" -e "s,@QMAKE_QTSRCS@,$EXTRA_SRCS,g" \ - -e "s,@QMAKESPEC@,$QMAKESPEC,g" "$in_mkfile" >>"$mkfile" + -e "s,@QMAKESPEC@,$adjqmakespec,g" "$in_mkfile" >>"$mkfile" if "$WHICH" makedepend >/dev/null 2>&1 && grep 'depend:' "$mkfile" >/dev/null 2>&1; then (cd "$outpath/qmake" && "$MAKE" -f "$mkfile" depend) >/dev/null 2>&1 - sed "s,^.*/\([^/]*.o\):,\1:,g" "$mkfile" >"${mkfile}.tmp" - mv "${mkfile}.tmp" "${mkfile}" + sed "s,^.*/\([^/]*.o\):,\1:,g" "$mkfile" >"$mkfile.tmp" + sed "s,$outpath,$adjoutpath,g" "$mkfile.tmp" >"$mkfile" + rm "$mkfile.tmp" fi done @@ -4326,7 +4328,7 @@ for _SQLDR in $CFG_SQL_AVAILABLE; do case $_SQLDR in mysql) if [ "$CFG_SQL_mysql" != "no" ]; then - [ -z "$CFG_MYSQL_CONFIG" ] && CFG_MYSQL_CONFIG=`$WHICH mysql_config` + [ -z "$CFG_MYSQL_CONFIG" ] && CFG_MYSQL_CONFIG=`"$WHICH" mysql_config` if [ -x "$CFG_MYSQL_CONFIG" ]; then QT_CFLAGS_MYSQL=`$CFG_MYSQL_CONFIG --include 2>/dev/null` QT_LFLAGS_MYSQL_R=`$CFG_MYSQL_CONFIG --libs_r 2>/dev/null` @@ -7136,7 +7138,7 @@ for file in .projects .projects.3; do *tools/bootstrap*|*tools/moc*|*tools/rcc*|*tools/uic*) SPEC=$QMAKESPEC ;; *) SPEC=$XQMAKESPEC ;; esac - dir=`dirname $a | sed -e "s;$sepath;.;g"` + dir=`dirname "$a" | sed -e "s;$sepath;.;g"` test -d "$dir" || mkdir -p "$dir" OUTDIR="$outpath/$dir" if [ -f "${OUTDIR}/Makefile" ] && [ "$OPT_FAST" = "yes" ]; then @@ -7279,7 +7281,7 @@ if [ -n "$RPATH_MESSAGE" ]; then echo "$RPATH_MESSAGE" fi -MAKE=`basename $MAKE` +MAKE=`basename "$MAKE"` echo echo Qt is now configured for building. Just run \'$MAKE\'. if [ "$relpath" = "$QT_INSTALL_PREFIX" ]; then -- cgit v0.12 From b33ebce3de3efd98a45c8ca0a349f78aac09c875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Wed, 15 Apr 2009 10:12:34 +0200 Subject: Don't crash or loop infinitely when we retrieving the accessible accel. qt_accHotKey() was pretty buggy; it could both crash or spin forever in some cases. Task-number: 221731 Reviewed-by: alexis --- src/gui/accessible/qaccessiblewidget.cpp | 13 ++++-- tests/auto/qaccessibility/tst_qaccessibility.cpp | 52 +++++++++++++++++++++--- 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/gui/accessible/qaccessiblewidget.cpp b/src/gui/accessible/qaccessiblewidget.cpp index 4b2b2ab..753ac57 100644 --- a/src/gui/accessible/qaccessiblewidget.cpp +++ b/src/gui/accessible/qaccessiblewidget.cpp @@ -131,9 +131,16 @@ QString Q_GUI_EXPORT qt_accHotKey(const QString &text) int fa = 0; QChar ac; while ((fa = text.indexOf(QLatin1Char('&'), fa)) != -1) { - if (fa == text.length() - 1 || text.at(fa+1) != QLatin1Char('&')) { - ac = text.at(fa+1); - break; + ++fa; + if (fa < text.length()) { + // ignore "&&" + if (text.at(fa) == QLatin1Char('&')) { + ++fa; + continue; + } else { + ac = text.at(fa); + break; + } } } if (ac.isNull()) diff --git a/tests/auto/qaccessibility/tst_qaccessibility.cpp b/tests/auto/qaccessibility/tst_qaccessibility.cpp index d023557..1aca624 100644 --- a/tests/auto/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/qaccessibility/tst_qaccessibility.cpp @@ -275,6 +275,7 @@ private slots: void accessibleName(); void treeWidgetTest(); void labelTest(); + void accelerators(); private: QWidget *createGUI(); @@ -2592,8 +2593,8 @@ void tst_QAccessibility::menuTest() QTestAccessibility::clearEvents(); mw.hide(); - - + + // Do not crash if the menu don't have a parent QMenu *menu = new QMenu; menu->addAction(QLatin1String("one")); @@ -2607,7 +2608,7 @@ void tst_QAccessibility::menuTest() delete iface2; delete iface; delete menu; - + } QTestAccessibility::clearEvents(); #else @@ -3988,13 +3989,13 @@ void tst_QAccessibility::treeWidgetTest() QCOMPARE(entry, 0); QCOMPARE(accTreeItem2->text(QAccessible::Name, 0), QLatin1String("row: 1")); - - // test selected/focused state + + // test selected/focused state QItemSelectionModel *selModel = tree->selectionModel(); QVERIFY(selModel); selModel->select(QItemSelection(tree->model()->index(0, 0), tree->model()->index(3, 0)), QItemSelectionModel::Select); selModel->setCurrentIndex(tree->model()->index(1, 0), QItemSelectionModel::Current); - + for (int i = 1; i < 10 ; ++i) { QAccessible::State expected; if (i <= 5 && i >= 2) @@ -4046,6 +4047,45 @@ void tst_QAccessibility::labelTest() #endif } +void tst_QAccessibility::accelerators() +{ +#ifdef QTEST_ACCESSIBILITY + QWidget *window = new QWidget; + QHBoxLayout *lay = new QHBoxLayout(window); + QLabel *label = new QLabel(tr("&Line edit"), window); + QLineEdit *le = new QLineEdit(window); + lay->addWidget(label); + lay->addWidget(le); + label->setBuddy(le); + + window->show(); + + QAccessibleInterface *accLineEdit = QAccessible::queryAccessibleInterface(le); + QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QString(QKeySequence(Qt::ALT) + QLatin1String("L"))); + label->setText(tr("Q &")); + QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QString()); + label->setText(tr("Q &&")); + QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QString()); + label->setText(tr("Q && A")); + QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QString()); + label->setText(tr("Q &&&A")); + QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QString(QKeySequence(Qt::ALT) + QLatin1String("A"))); + label->setText(tr("Q &&A")); + QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QString()); + label->setText(tr("Q &A&B")); + QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QString(QKeySequence(Qt::ALT) + QLatin1String("A"))); + +#if defined(Q_WS_X11) + qt_x11_wait_for_window_manager(window); +#endif + QTest::qWait(100); + delete window; + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); +#endif +} + QTEST_MAIN(tst_QAccessibility) -- cgit v0.12 From 7a0f9ae94ca7a47dc285431d31f6839c07870194 Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Wed, 15 Apr 2009 10:23:08 +0200 Subject: BT: Fix a regression to 4.4 in Graphics View's handling of child clippers Regression caused by optimizations in QGraphicsItem and QGraphicsScene. The changes in QGraphicsItem fix bugs in QGraphicsItem::mapToParent functions, which did the translation before applying the transformation, instead of the other way (transform, then translate). This bug caused almost all mapToParent and mapRectToParent functions to behave wrongly. Unfortunately the new helper functions in QGraphicsScene for discovering items made use of these functions, which introduced a regression. Fixing these functions also fixes item discovery. The other part of this change fixes a regression caused by c1909321, which luckily happened after 4.5.0 and never saw the light of day. The fix is to also invalidate the cached clip path even if there is no scene, which is necessary if you build your scene graph outside the scene, and finish off by adding the root item to the scene. Task-number: 250680 Reviewed-by: Alexis --- src/gui/graphicsview/qgraphicsitem.cpp | 30 +++++---- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 83 ++++++++++++++++++++++++ tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp | 26 ++++++++ 3 files changed, 125 insertions(+), 14 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index b520a3f..e6bcaa6 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -4223,9 +4223,9 @@ QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QRectF &rect */ QPolygonF QGraphicsItem::mapToParent(const QRectF &rect) const { - if (!d_ptr->hasTransform) - return QPolygonF(rect.translated(d_ptr->pos)); - return transform().map(rect.translated(d_ptr->pos)); + QPolygonF p = !d_ptr->hasTransform ? rect : transform().map(rect); + p.translate(d_ptr->pos); + return p; } /*! @@ -4292,8 +4292,8 @@ QRectF QGraphicsItem::mapRectToItem(const QGraphicsItem *item, const QRectF &rec */ QRectF QGraphicsItem::mapRectToParent(const QRectF &rect) const { - QRectF r = rect.translated(d_ptr->pos.x(), d_ptr->pos.y()); - return !d_ptr->hasTransform ? r : transform().mapRect(r); + QRectF r = !d_ptr->hasTransform ? rect : transform().mapRect(rect); + return r.translated(d_ptr->pos); } /*! @@ -4424,9 +4424,9 @@ QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPolygonF &p */ QPolygonF QGraphicsItem::mapToParent(const QPolygonF &polygon) const { - QPolygonF p = polygon; + QPolygonF p = !d_ptr->hasTransform ? polygon : transform().map(polygon); p.translate(d_ptr->pos); - return d_ptr->hasTransform ? transform().map(p) : p; + return p; } /*! @@ -4468,7 +4468,10 @@ QPainterPath QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPainterP */ QPainterPath QGraphicsItem::mapToParent(const QPainterPath &path) const { - return d_ptr->parent ? itemTransform(d_ptr->parent).map(path) : mapToScene(path); + QTransform x = QTransform::fromTranslate(d_ptr->pos.x(), d_ptr->pos.y()); + if (d_ptr->hasTransform) + x = transform() * x; + return x.map(path); } /*! @@ -5697,12 +5700,11 @@ void QGraphicsItem::removeFromIndex() */ void QGraphicsItem::prepareGeometryChange() { - if (!d_ptr->scene) - return; - - d_ptr->updateHelper(QRectF(), false, /*maybeDirtyClipPath=*/!d_ptr->inSetPosHelper); - QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func(); - scenePrivate->removeFromIndex(this); + if (d_ptr->scene) { + d_ptr->updateHelper(QRectF(), false, /*maybeDirtyClipPath=*/!d_ptr->inSetPosHelper); + QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func(); + scenePrivate->removeFromIndex(this); + } if (d_ptr->inSetPosHelper) return; diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 5dd7e1e..2d1be37 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -162,6 +162,8 @@ private slots: void mapFromToParent(); void mapFromToScene(); void mapFromToItem(); + void mapRectFromToParent_data(); + void mapRectFromToParent(); void isAncestorOf(); void commonAncestorItem(); void data(); @@ -2515,6 +2517,87 @@ void tst_QGraphicsItem::mapFromToItem() delete item4; } +void tst_QGraphicsItem::mapRectFromToParent_data() +{ + QTest::addColumn("parent"); + QTest::addColumn("parentPos"); + QTest::addColumn("parentTransform"); + QTest::addColumn("pos"); + QTest::addColumn("transform"); + QTest::addColumn("inputRect"); + QTest::addColumn("outputRect"); + + QTest::newRow("nil") << false << QPointF() << QTransform() << QPointF() << QTransform() << QRectF() << QRectF(); + QTest::newRow("simple") << false << QPointF() << QTransform() << QPointF() << QTransform() + << QRectF(0, 0, 10, 10) << QRectF(0, 0, 10, 10); + QTest::newRow("simple w/parent") << true + << QPointF() << QTransform() + << QPointF() << QTransform() + << QRectF(0, 0, 10, 10) << QRectF(0, 0, 10, 10); + QTest::newRow("simple w/parent parentPos") << true + << QPointF(50, 50) << QTransform() + << QPointF() << QTransform() + << QRectF(0, 0, 10, 10) << QRectF(0, 0, 10, 10); + QTest::newRow("simple w/parent parentPos parentRotation") << true + << QPointF(50, 50) << QTransform().rotate(45) + << QPointF() << QTransform() + << QRectF(0, 0, 10, 10) << QRectF(0, 0, 10, 10); + QTest::newRow("pos w/parent") << true + << QPointF() << QTransform() + << QPointF(50, 50) << QTransform() + << QRectF(0, 0, 10, 10) << QRectF(50, 50, 10, 10); + QTest::newRow("rotation w/parent") << true + << QPointF() << QTransform() + << QPointF() << QTransform().rotate(90) + << QRectF(0, 0, 10, 10) << QRectF(-10, 0, 10, 10); + QTest::newRow("pos rotation w/parent") << true + << QPointF() << QTransform() + << QPointF(50, 50) << QTransform().rotate(90) + << QRectF(0, 0, 10, 10) << QRectF(40, 50, 10, 10); + QTest::newRow("pos rotation w/parent parentPos parentRotation") << true + << QPointF(-170, -190) << QTransform().rotate(90) + << QPointF(50, 50) << QTransform().rotate(90) + << QRectF(0, 0, 10, 10) << QRectF(40, 50, 10, 10); +} + +void tst_QGraphicsItem::mapRectFromToParent() +{ + QFETCH(bool, parent); + QFETCH(QPointF, parentPos); + QFETCH(QTransform, parentTransform); + QFETCH(QPointF, pos); + QFETCH(QTransform, transform); + QFETCH(QRectF, inputRect); + QFETCH(QRectF, outputRect); + + QGraphicsRectItem *rect = new QGraphicsRectItem; + rect->setPos(pos); + rect->setTransform(transform); + + if (parent) { + QGraphicsRectItem *rectParent = new QGraphicsRectItem; + rect->setParentItem(rectParent); + rectParent->setPos(parentPos); + rectParent->setTransform(parentTransform); + } + + // Make sure we use non-destructive transform operations (e.g., 90 degree + // rotations). + QCOMPARE(rect->mapRectToParent(inputRect), outputRect); + QCOMPARE(rect->mapRectFromParent(outputRect), inputRect); + QCOMPARE(rect->itemTransform(rect->parentItem()).mapRect(inputRect), outputRect); + QCOMPARE(rect->mapToParent(inputRect).boundingRect(), outputRect); + QCOMPARE(rect->mapToParent(QPolygonF(inputRect)).boundingRect(), outputRect); + QCOMPARE(rect->mapFromParent(outputRect).boundingRect(), inputRect); + QCOMPARE(rect->mapFromParent(QPolygonF(outputRect)).boundingRect(), inputRect); + QPainterPath inputPath; + inputPath.addRect(inputRect); + QPainterPath outputPath; + outputPath.addRect(outputRect); + QCOMPARE(rect->mapToParent(inputPath).boundingRect(), outputPath.boundingRect()); + QCOMPARE(rect->mapFromParent(outputPath).boundingRect(), inputPath.boundingRect()); +} + void tst_QGraphicsItem::isAncestorOf() { QGraphicsItem *grandPa = new QGraphicsRectItem; diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index 91ed851..354d81a 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -245,6 +245,7 @@ private slots: void task139782_containsItemBoundingRect(); void task176178_itemIndexMethodBreaksSceneRect(); void task160653_selectionChanged(); + void task250680_childClip(); }; void tst_QGraphicsScene::initTestCase() @@ -3384,6 +3385,31 @@ void tst_QGraphicsScene::task160653_selectionChanged() QCOMPARE(spy.count(), 1); } +void tst_QGraphicsScene::task250680_childClip() +{ + QGraphicsRectItem *clipper = new QGraphicsRectItem; + clipper->setFlag(QGraphicsItem::ItemClipsChildrenToShape); + clipper->setPen(QPen(Qt::green)); + clipper->setRect(200, 200, 640, 480); + + QGraphicsRectItem *rect = new QGraphicsRectItem(clipper); + rect->setPen(QPen(Qt::red)); + rect->setBrush(QBrush(QColor(255, 0, 0, 75))); + rect->setPos(320, 240); + rect->setRect(-25, -25, 50, 50); + + QGraphicsScene scene; + scene.addItem(clipper); + + QPainterPath path; + path.addRect(-25, -25, 50, 50); + QCOMPARE(rect->clipPath(), path); + + QCOMPARE(scene.items(QRectF(320, 240, 5, 5)).size(), 2); + rect->rotate(45); + QCOMPARE(scene.items(QRectF(320, 240, 5, 5)).size(), 2); +} + void tst_QGraphicsScene::sorting_data() { QTest::addColumn("cache"); -- cgit v0.12 From a59488d4799f6ac9ea034c0a88a468e73a64d517 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 15 Apr 2009 10:47:29 +0200 Subject: Compile with namespace Reviewed-by: hjk --- src/corelib/tools/qvector.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 6bea03b..3fd52ee 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -98,6 +98,8 @@ struct QVectorTypedData T array[1]; }; +class QRegion; + template class QVector { -- cgit v0.12 From afb3848e0abe0cd2355e7ee7319fd904288e4636 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Wed, 15 Apr 2009 10:30:17 +0200 Subject: Fix regression in QString::replace(int, int, QChar) when string is empty When QString::replace was optimized, this specific overload missed out on sanity checking of the arguments. Task-number: 249517 Reviewed-by: Joao Reviewed-by: hjk BT: yes --- src/corelib/tools/qstring.cpp | 34 ++++++++++++++++------------------ tests/auto/qstring/tst_qstring.cpp | 4 ++++ 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 9c637ac..375d672 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -579,7 +579,7 @@ const QString::Null QString::null = { }; '\\0' character for a null string (\e not a null pointer), and QString() compares equal to QString(""). We recommend that you always use the isEmpty() function and avoid isNull(). - + \section1 Argument Formats In member functions where an argument \e format can be specified @@ -1433,7 +1433,7 @@ QString &QString::append(QChar ch) truncated at the specified \a position. \snippet doc/src/snippets/qstring/main.cpp 37 - + \sa insert(), replace() */ QString &QString::remove(int pos, int len) @@ -1552,7 +1552,7 @@ QString &QString::replace(int pos, int len, const QChar *unicode, int size) return *this; if (pos + len > d->size) len = d->size - pos; - + uint index = pos; replace_helper(&index, 1, len, unicode, size); return *this; @@ -1561,15 +1561,13 @@ QString &QString::replace(int pos, int len, const QChar *unicode, int size) /*! \fn QString &QString::replace(int position, int n, QChar after) \overload replace() - + Replaces \a n characters beginning at index \a position with the character \a after and returns a reference to this string. */ QString &QString::replace(int pos, int len, QChar after) { - uint index = pos; - replace_helper(&index, 1, len, &after, 1); - return *this; + return replace(pos, len, &after, 1); } /*! @@ -1602,7 +1600,7 @@ void QString::replace_helper(uint *indices, int nIndices, int blen, const QChar { if (blen == alen) { detach(); - for (int i = 0; i < nIndices; ++i) + for (int i = 0; i < nIndices; ++i) memcpy(d->data + indices[i], after, alen * sizeof(QChar)); } else if (alen < blen) { detach(); @@ -1633,7 +1631,7 @@ void QString::replace_helper(uint *indices, int nIndices, int blen, const QChar int newLen = d->size + adjust; int moveend = d->size; resize(newLen); - + while (nIndices) { --nIndices; int movestart = indices[nIndices] + blen; @@ -1685,7 +1683,7 @@ QString &QString::replace(const QChar *before, int blen, memcpy(copy, before, blen*sizeof(QChar)); b = copy; } - + QStringMatcher matcher(b, blen, cs); int index = 0; @@ -1712,7 +1710,7 @@ QString &QString::replace(const QChar *before, int blen, // index has to be adjusted in case we get back into the loop above. index += pos*(alen-blen); } - + if (a != after) ::free((QChar *)a); if (b != before) @@ -2250,7 +2248,7 @@ int QString::indexOf(const QLatin1String &str, int from, Qt::CaseSensitivity cs) QVarLengthArray s(len); for (int i = 0; i < len; ++i) s[i] = str.latin1()[i]; - + return qFindString(unicode(), length(), from, (const QChar *)s.data(), len, cs); } @@ -2346,7 +2344,7 @@ static int lastIndexOfHelper(const ushort *haystack, int from, const ushort *nee /* See indexOf() for explanations. */ - + const ushort *end = haystack; haystack += from; const int sl_minus_1 = sl-1; @@ -2408,7 +2406,7 @@ int QString::lastIndexOf(const QString &str, int from, Qt::CaseSensitivity cs) c const int sl = str.d->size; if (sl == 1) return lastIndexOf(QChar(str.d->data[0]), from, cs); - + const int l = d->size; if (from < 0) from += l; @@ -2446,7 +2444,7 @@ int QString::lastIndexOf(const QLatin1String &str, int from, Qt::CaseSensitivity const int sl = qstrlen(str.latin1()); if (sl == 1) return lastIndexOf(QLatin1Char(str.latin1()[0]), from, cs); - + const int l = d->size; if (from < 0) from += l; @@ -5995,7 +5993,7 @@ QString QString::normalized(QString::NormalizationForm mode, QChar::UnicodeVersi } if (simple) return *this; - + QString s = *this; if (version != CURRENT_VERSION) { for (int i = 0; i < NumNormalizationCorrections; ++i) { @@ -6207,7 +6205,7 @@ static QString replaceArgEscapes(const QString &s, const ArgEscapeData &d, int f /*! Returns a copy of this string with the lowest numbered place marker replaced by string \a a, i.e., \c %1, \c %2, ..., \c %99. - + \a fieldWidth specifies the minimum amount of space that argument \a a shall occupy. If \a a requires less space than \a fieldWidth, it is padded to \a fieldWidth with character \a fillChar. A positive @@ -6819,7 +6817,7 @@ void QString::updateProperties() const Appends the given \a ch character onto the end of this string. */ -/*! +/*! \fn std::string QString::toStdString() const Returns a std::string object with the data contained in this diff --git a/tests/auto/qstring/tst_qstring.cpp b/tests/auto/qstring/tst_qstring.cpp index f786965..1263a41 100644 --- a/tests/auto/qstring/tst_qstring.cpp +++ b/tests/auto/qstring/tst_qstring.cpp @@ -432,6 +432,10 @@ void tst_QString::replace_uint_uint_data() QTest::newRow( "rep09" ) << QString("ACABCAB") << 4 << 2 << QString("XX") << QString("ACABXXB"); QTest::newRow( "rep10" ) << QString("ACABCAB") << 5 << 2 << QString("XX") << QString("ACABCXX"); QTest::newRow( "rep10" ) << QString("ACABCAB") << 6 << 2 << QString("XX") << QString("ACABCAXX"); + QTest::newRow( "rep12" ) << QString() << 0 << 10 << QString("X") << QString("X"); + QTest::newRow( "rep13" ) << QString("short") << 0 << 10 << QString("X") << QString("X"); + QTest::newRow( "rep14" ) << QString() << 0 << 10 << QString("XX") << QString("XX"); + QTest::newRow( "rep15" ) << QString("short") << 0 << 10 << QString("XX") << QString("XX"); } void tst_QString::replace_string_data() -- cgit v0.12 From 4626232ff040ce0e66e8cdf5ceb7d725c04a4823 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 14 Apr 2009 18:16:15 +0200 Subject: Fixes warning about potential use of uninitialized value Reviewed-by: bnilsen --- src/gui/painting/qtransform.cpp | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp index fa808d0..39e429d 100644 --- a/src/gui/painting/qtransform.cpp +++ b/src/gui/painting/qtransform.cpp @@ -1715,13 +1715,12 @@ QRect QTransform::mapRect(const QRect &rect) const return QRect(x, y, w, h); } else if (t < TxProject) { // see mapToPolygon for explanations of the algorithm. - qreal x0 = 0, y0 = 0; - qreal x, y; - MAP(rect.left(), rect.top(), x0, y0); - qreal xmin = x0; - qreal ymin = y0; - qreal xmax = x0; - qreal ymax = y0; + qreal x = 0, y = 0; + MAP(rect.left(), rect.top(), x, y); + qreal xmin = x; + qreal ymin = y; + qreal xmax = x; + qreal ymax = y; MAP(rect.right() + 1, rect.top(), x, y); xmin = qMin(xmin, x); ymin = qMin(ymin, y); @@ -1782,13 +1781,12 @@ QRectF QTransform::mapRect(const QRectF &rect) const } return QRectF(x, y, w, h); } else if (t < TxProject) { - qreal x0 = 0, y0 = 0; - qreal x, y; - MAP(rect.x(), rect.y(), x0, y0); - qreal xmin = x0; - qreal ymin = y0; - qreal xmax = x0; - qreal ymax = y0; + qreal x = 0, y = 0; + MAP(rect.x(), rect.y(), x, y); + qreal xmin = x; + qreal ymin = y; + qreal xmax = x; + qreal ymax = y; MAP(rect.x() + rect.width(), rect.y(), x, y); xmin = qMin(xmin, x); ymin = qMin(ymin, y); -- cgit v0.12 From fd5f83e612729cebc5395c992bd98628bb9ea25f Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 14 Apr 2009 18:48:02 +0200 Subject: Fixes QSortFilterProxyModel not reporting child if the model need to fetchMore QSortFilterProxyModel::hasChildren need to construct the mapping. And when it tries to construct the mapping, it needs to fetch the childs, so there is none. Task-number: 250023 Reviewed-by: Marius Bugge Monsen --- src/gui/itemviews/qsortfilterproxymodel.cpp | 3 + .../tst_qsortfilterproxymodel.cpp | 87 ++++++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp index 10bcb9a..b0137d2 100644 --- a/src/gui/itemviews/qsortfilterproxymodel.cpp +++ b/src/gui/itemviews/qsortfilterproxymodel.cpp @@ -274,6 +274,9 @@ IndexMap::const_iterator QSortFilterProxyModelPrivate::create_mapping( Mapping *m = new Mapping; + if (model->canFetchMore(source_parent)) + model->fetchMore(source_parent); + int source_rows = model->rowCount(source_parent); for (int i = 0; i < source_rows; ++i) { if (q->filterAcceptsRow(i, source_parent)) diff --git a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp index 0a48066..ee9daef 100644 --- a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp @@ -131,6 +131,7 @@ private slots: void task247867_insertRowsSort(); void task248868_staticSorting(); void task248868_dynamicSorting(); + void task250023_fetchMore(); protected: void buildHierarchy(const QStringList &data, QAbstractItemModel *model); @@ -2590,6 +2591,92 @@ void tst_QSortFilterProxyModel::task248868_dynamicSorting() } } +class QtTestModel: public QAbstractItemModel +{ + public: + QtTestModel(int _rows, int _cols, QObject *parent = 0): QAbstractItemModel(parent), + rows(_rows), cols(_cols), wrongIndex(false) { } + + bool canFetchMore(const QModelIndex &idx) const { + return !fetched.contains(idx); + } + + void fetchMore(const QModelIndex &idx) { + fetched.insert(idx); + } + + bool hasChildren(const QModelIndex & = QModelIndex()) const { + return true; + } + + int rowCount(const QModelIndex& parent = QModelIndex()) const { + return fetched.contains(parent) ? rows : 0; + } + int columnCount(const QModelIndex& parent = QModelIndex()) const { + return fetched.contains(parent) ? cols : 0; + } + + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const + { + if (row < 0 || column < 0 || column >= cols || row >= rows) { + return QModelIndex(); + } + QModelIndex i = createIndex(row, column, int(parent.internalId() + 1)); + parentHash[i] = parent; + return i; + } + + QModelIndex parent(const QModelIndex &index) const + { + if (!parentHash.contains(index)) + return QModelIndex(); + return parentHash[index]; + } + + QVariant data(const QModelIndex &idx, int role) const + { + if (!idx.isValid()) + return QVariant(); + + if (role == Qt::DisplayRole) { + if (idx.row() < 0 || idx.column() < 0 || idx.column() >= cols || idx.row() >= rows) { + wrongIndex = true; + qWarning("Invalid modelIndex [%d,%d,%p]", idx.row(), idx.column(), + idx.internalPointer()); + } + return QString("[%1,%2]").arg(idx.row()).arg(idx.column()); + } + return QVariant(); + } + + QSet fetched; + int rows, cols; + mutable bool wrongIndex; + mutable QMap parentHash; +}; + +void tst_QSortFilterProxyModel::task250023_fetchMore() +{ + QtTestModel model(10,10); + QSortFilterProxyModel proxy; + proxy.setSourceModel(&model); + QVERIFY(proxy.canFetchMore(QModelIndex())); + QVERIFY(proxy.hasChildren()); + while (proxy.canFetchMore(QModelIndex())) + proxy.fetchMore(QModelIndex()); + QCOMPARE(proxy.rowCount(), 10); + QCOMPARE(proxy.columnCount(), 10); + + QModelIndex idx = proxy.index(1,1); + QVERIFY(idx.isValid()); + QVERIFY(proxy.canFetchMore(idx)); + QVERIFY(proxy.hasChildren(idx)); + while (proxy.canFetchMore(idx)) + proxy.fetchMore(idx); + QCOMPARE(proxy.rowCount(idx), 10); + QCOMPARE(proxy.columnCount(idx), 10); +} + QTEST_MAIN(tst_QSortFilterProxyModel) #include "tst_qsortfilterproxymodel.moc" -- cgit v0.12 From 4e78de5a4281bd1c27a984b13887975798573aae Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 15 Apr 2009 09:39:55 +0200 Subject: Stabilize test for QItemDelegate --- tests/auto/qitemdelegate/tst_qitemdelegate.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/qitemdelegate/tst_qitemdelegate.cpp b/tests/auto/qitemdelegate/tst_qitemdelegate.cpp index befe0eb..27741e0 100644 --- a/tests/auto/qitemdelegate/tst_qitemdelegate.cpp +++ b/tests/auto/qitemdelegate/tst_qitemdelegate.cpp @@ -777,6 +777,7 @@ void tst_QItemDelegate::dateTimeEditor() QCOMPARE(timeEditor->time(), time); widget.clearFocus(); + qApp->setActiveWindow(&widget); widget.setFocus(); widget.editItem(item2); -- cgit v0.12 From 8f223e03effba1aef6be5e50caf7482af1d7dd8a Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 15 Apr 2009 11:51:17 +0200 Subject: The submenu of a multicolumn menu have an incorrect position The submenu would always appear to the side of the menu instead of its right. Task-number: 250673 Reviewed-by: ogoffart --- src/gui/widgets/qmenu.cpp | 4 ++-- tests/auto/qmenu/tst_qmenu.cpp | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index ed3e338..7396a9d 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -2889,8 +2889,8 @@ void QMenu::internalDelayedPopup() int subMenuOffset = style()->pixelMetric(QStyle::PM_SubMenuOverlap, 0, this); const QRect actionRect(d->actionRect(d->currentAction)); const QSize menuSize(d->activeMenu->sizeHint()); - const QPoint rightPos(mapToGlobal(QPoint(rect().right() + subMenuOffset + 1, actionRect.top()))); - const QPoint leftPos(mapToGlobal(QPoint(rect().left() - subMenuOffset - menuSize.width(), actionRect.top()))); + const QPoint rightPos(mapToGlobal(QPoint(actionRect.right() + subMenuOffset + 1, actionRect.top()))); + const QPoint leftPos(mapToGlobal(QPoint(actionRect.left() - subMenuOffset - menuSize.width(), actionRect.top()))); QPoint pos(rightPos); QMenu *caused = qobject_cast(d->activeMenu->d_func()->causedPopup.widget); diff --git a/tests/auto/qmenu/tst_qmenu.cpp b/tests/auto/qmenu/tst_qmenu.cpp index 7607838..a86b754 100644 --- a/tests/auto/qmenu/tst_qmenu.cpp +++ b/tests/auto/qmenu/tst_qmenu.cpp @@ -92,6 +92,7 @@ private slots: void activeSubMenuPosition(); void task242454_sizeHint(); void task176201_clear(); + void task250673_activeMutliColumnSubMenuPosition(); protected slots: void onActivated(QAction*); void onHighlighted(QAction*); @@ -678,6 +679,39 @@ void tst_QMenu::task176201_clear() QTest::mouseClick(&menu, Qt::LeftButton, 0, menu.rect().center()); } +void tst_QMenu::task250673_activeMutliColumnSubMenuPosition() +{ + class MyMenu : public QMenu + { + public: + friend class tst_QMenu; + }; + + QMenu sub; + sub.addAction("Sub-Item1"); + QAction *subAction = sub.addAction("Sub-Item2"); + + MyMenu main; + main.addAction("Item 1"); + QAction *menuAction = main.addMenu(&sub); + main.popup(QPoint(200,200)); + + uint i = 2; + while (main.columnCount() < 2) { + main.addAction(QString("Item %1").arg(i)); + ++i; + Q_ASSERT(i<1000); + } + main.setActiveAction(menuAction); + sub.setActiveAction(subAction); + QVERIFY(main.isVisible()); + QCOMPARE(main.activeAction(), menuAction); + QVERIFY(sub.isVisible()); + QVERIFY(sub.pos().x() > main.pos().x()); + + const int subMenuOffset = main.style()->pixelMetric(QStyle::PM_SubMenuOverlap, 0, &main); + QVERIFY((sub.geometry().left() - subMenuOffset + 5) < main.geometry().right()); +} QTEST_MAIN(tst_QMenu) #include "tst_qmenu.moc" -- cgit v0.12 From 0d7f704856166aea83843697ae98bdcf22dbabb0 Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Wed, 15 Apr 2009 11:58:02 +0200 Subject: Clean up and fix bug in merge conflict for 21099dac. Make use of QPolygonF::translated and QPainterPath::translated to ensure all mapToParent functions follow the exact same pattern. This makes it clear that the functions do the same and do it the same way. Reviewed-by: bnilsen --- src/gui/graphicsview/qgraphicsitem.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 70f5537..7aba576 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -4285,7 +4285,9 @@ QPointF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPointF &point */ QPointF QGraphicsItem::mapToParent(const QPointF &point) const { - return d_ptr->pos + (d_ptr->hasTransform ? transform().map(point) : point); + if (!d_ptr->hasTransform) + return point + d_ptr->pos; + return transform().map(point) + d_ptr->pos; } /*! @@ -4350,9 +4352,9 @@ QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QRectF &rect */ QPolygonF QGraphicsItem::mapToParent(const QRectF &rect) const { - QPolygonF p = !d_ptr->hasTransform ? rect : transform().map(rect); - p.translate(d_ptr->pos); - return p; + if (!d_ptr->hasTransform) + return rect.translated(d_ptr->pos); + return transform().map(rect).translated(d_ptr->pos); } /*! @@ -4551,9 +4553,9 @@ QPolygonF QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPolygonF &p */ QPolygonF QGraphicsItem::mapToParent(const QPolygonF &polygon) const { - QPolygonF p = !d_ptr->hasTransform ? polygon : transform().map(polygon); - p.translate(d_ptr->pos); - return p; + if (!d_ptr->hasTransform) + return polygon.translated(d_ptr->pos); + return transform().map(polygon).translated(d_ptr->pos); } /*! @@ -4595,9 +4597,9 @@ QPainterPath QGraphicsItem::mapToItem(const QGraphicsItem *item, const QPainterP */ QPainterPath QGraphicsItem::mapToParent(const QPainterPath &path) const { - QPainterPath p(path); - p.translate(d_ptr->pos); - return d_ptr->hasTransform ? transform().map(p) : p; + if (!d_ptr->hasTransform) + return path.translated(d_ptr->pos); + return transform().map(path).translated(d_ptr->pos); } /*! -- cgit v0.12 From 85db19b2eef0f7933fa28e8e5e1d365aab72458a Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Wed, 15 Apr 2009 11:58:54 +0200 Subject: BT: QAbstractSocket: fix check for closing state (typo) emit disconnected() if we were in ConnectedState or in ClosingState before Reviewed-by: Thiago Task-number: 250976 --- src/network/socket/qabstractsocket.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 910e30a..f8cf4ca 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -2279,7 +2279,7 @@ void QAbstractSocket::disconnectFromHostImplementation() emit delayedCloseFinished(); // compat signal #endif // only emit disconnected if we were connected before - if (previousState == ConnectedState || ClosingState) + if (previousState == ConnectedState || previousState == ClosingState) emit disconnected(); d->localPort = 0; -- cgit v0.12 From 79891d8284736dc318cff8d9c3f6d7a6e87affd9 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 15 Apr 2009 12:01:36 +0200 Subject: Introduce QPointF::manhattanLength Task-number: 251068 --- src/corelib/tools/qpoint.cpp | 13 +++++++++++++ src/corelib/tools/qpoint.h | 2 ++ tests/auto/qpoint/tst_qpoint.cpp | 20 ++++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/src/corelib/tools/qpoint.cpp b/src/corelib/tools/qpoint.cpp index feea473..5cc71d6 100644 --- a/src/corelib/tools/qpoint.cpp +++ b/src/corelib/tools/qpoint.cpp @@ -442,6 +442,19 @@ QDebug operator<<(QDebug d, const QPointF &p) otherwise returns false. */ + +/*! + Returns the sum of the absolute values of x() and y(), + traditionally known as the "Manhattan length" of the vector from + the origin to the point. + + \sa QPoint::manhattanLength() +*/ +qreal QPointF::manhattanLength() const +{ + return qAbs(x())+qAbs(y()); +} + /*! \fn qreal QPointF::x() const diff --git a/src/corelib/tools/qpoint.h b/src/corelib/tools/qpoint.h index 1dab7e2..e716bf7 100644 --- a/src/corelib/tools/qpoint.h +++ b/src/corelib/tools/qpoint.h @@ -192,6 +192,8 @@ public: QPointF(const QPoint &p); QPointF(qreal xpos, qreal ypos); + qreal manhattanLength() const; + bool isNull() const; qreal x() const; diff --git a/tests/auto/qpoint/tst_qpoint.cpp b/tests/auto/qpoint/tst_qpoint.cpp index 67fefa8..16d55fc 100644 --- a/tests/auto/qpoint/tst_qpoint.cpp +++ b/tests/auto/qpoint/tst_qpoint.cpp @@ -60,6 +60,8 @@ public: private slots: void getSetCheck(); void division(); + + void manhattanLength(); }; tst_QPoint::tst_QPoint() @@ -70,6 +72,24 @@ tst_QPoint::~tst_QPoint() { } + + +void tst_QPoint::manhattanLength() +{ + { + QPoint p(10, 20); + QCOMPARE(p.manhattanLength(), 30); + } + { + QPointF p(10., 20.); + QCOMPARE(p.manhattanLength(), 30.); + } + { + QPointF p(10.1, 20.2); + QCOMPARE(p.manhattanLength(), 30.3); + } +} + // Testing get/set functions void tst_QPoint::getSetCheck() { -- cgit v0.12 From 1ebd0d5e4ad2dd27909b58a57ef15b1cc62d5d02 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 15 Apr 2009 12:03:38 +0200 Subject: Tiny optimization to QImage::setColorTable() Task: 250730 --- src/gui/image/qimage.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index c7a20db..14e8b8f 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -1691,8 +1691,12 @@ void QImage::setColorTable(const QVector colors) d->colortable = colors; d->has_alpha_clut = false; - for (int i = 0; i < d->colortable.size(); ++i) - d->has_alpha_clut |= (qAlpha(d->colortable.at(i)) != 255); + for (int i = 0; i < d->colortable.size(); ++i) { + if (qAlpha(d->colortable.at(i)) != 255) { + d->has_alpha_clut = true; + break; + } + } } /*! -- cgit v0.12 From bf61046989247d495800d7759275a2ef4b0a2150 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 15 Apr 2009 12:05:00 +0200 Subject: Updated WebKit from /home/shausman/src/webkit/trunk to origin/qtwebkit-4.5 ( e446518445c51c56471e41b1697e2a9e9f3adf36 ) Changes in WebKit since the last update: ++ b/WebCore/ChangeLog 2009-02-03 Dirk Schulze Reviewed by Sam Weinig. This is a follow up of r40546. Call toImage() once speeds up ImageBuffer::getImageData() * platform/graphics/qt/ImageBufferQt.cpp: (WebCore::ImageBuffer::getImageData): 2009-02-03 Dirk Schulze Reviewed by Sam Weinig and Oliver Hunt. Added getImageData() support for QtWebKit. [QT] lacks getImageData / putImageData support in Canvas https://bugs.webkit.org/show_bug.cgi?id=22186 * platform/graphics/qt/ImageBufferQt.cpp: (WebCore::ImageBuffer::getImageData): 2009-04-14 Benjamin C Meyer Reviewed by George Staikos. https://bugs.webkit.org/show_bug.cgi?id=25099 When creating a QNetworkRequest make sure to populate the CacheLoadControlAttribute with the value set by the ResourceRequest::cachePolicy() so that the cache will be used as WebKit expects. * WebKit/qt/tests/qwebpage/tst_qwebpage.cpp: (tst_QWebPage::requestCache): * platform/network/qt/ResourceRequestQt.cpp: (WebCore::ResourceRequest::toNetworkRequest): 2009-04-07 Brady Eidson Reviewed by Darin Adler While working on , noticed some glaring problems with LocalStorage. * page/DOMWindow.cpp: (WebCore::DOMWindow::localStorage): Return the cached m_localStorage object if it exists to avoid creating multiple representations for the same underlying StorageArea. * page/DOMWindow.h: (WebCore::DOMWindow::optionalLocalStorage): Return m_localStorage, not m_sessionStorage. ++ b/WebKitTools/ChangeLog 2009-02-25 Adam Treat Reviewed by Alexey Proskuryakov. Do not queue the calls to 'DumpRenderTree::dump()' as this can result in more than one call as a test that calls 'notifyDone()' can then be subsequently fully loaded and initiate a second dump. Also make sure to stop any existing page load that is happening before running the next test. Combined this serves to produce 217 more passing tests for the Qt port or roughly 5% at this point. * DumpRenderTree/qt/DumpRenderTree.cpp: (WebCore::DumpRenderTree::DumpRenderTree): (WebCore::DumpRenderTree::open): --- src/3rdparty/webkit/VERSION | 2 +- src/3rdparty/webkit/WebCore/ChangeLog | 48 + .../webkit/WebCore/generated/CSSPropertyNames.cpp | 5 +- .../webkit/WebCore/generated/CSSValueKeywords.c | 5 +- src/3rdparty/webkit/WebCore/generated/ColorData.c | 5 +- .../webkit/WebCore/generated/DocTypeStrings.cpp | 5 +- .../webkit/WebCore/generated/HTMLEntityNames.c | 5 +- .../webkit/WebCore/generated/tokenizer.cpp | 2315 ++++++++++++++------ src/3rdparty/webkit/WebCore/page/DOMWindow.cpp | 3 + src/3rdparty/webkit/WebCore/page/DOMWindow.h | 2 +- .../WebCore/platform/graphics/qt/ImageBufferQt.cpp | 55 +- .../platform/network/qt/ResourceRequestQt.cpp | 16 + .../WebKit/qt/tests/qwebpage/tst_qwebpage.cpp | 28 + 13 files changed, 1794 insertions(+), 700 deletions(-) diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index 9decb66..1762ecd 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -8,4 +8,4 @@ The commit imported was from the and has the sha1 checksum - f72c14123c593dc9d649d25b7186334bba0026b5 + e446518445c51c56471e41b1697e2a9e9f3adf36 diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index d0382f2..3774ea5 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,51 @@ +2009-02-03 Dirk Schulze + + Reviewed by Sam Weinig. + + This is a follow up of r40546. Call toImage() once speeds up ImageBuffer::getImageData() + + * platform/graphics/qt/ImageBufferQt.cpp: + (WebCore::ImageBuffer::getImageData): + +2009-02-03 Dirk Schulze + + Reviewed by Sam Weinig and Oliver Hunt. + + Added getImageData() support for QtWebKit. + + [QT] lacks getImageData / putImageData support in Canvas + https://bugs.webkit.org/show_bug.cgi?id=22186 + + * platform/graphics/qt/ImageBufferQt.cpp: + (WebCore::ImageBuffer::getImageData): + +2009-04-14 Benjamin C Meyer + + Reviewed by George Staikos. + + https://bugs.webkit.org/show_bug.cgi?id=25099 + + When creating a QNetworkRequest make sure to populate the + CacheLoadControlAttribute with the value set by the ResourceRequest::cachePolicy() so that the cache will be used as WebKit expects. + + * WebKit/qt/tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::requestCache): + + * platform/network/qt/ResourceRequestQt.cpp: + (WebCore::ResourceRequest::toNetworkRequest): + +2009-04-07 Brady Eidson + + Reviewed by Darin Adler + + While working on , noticed some glaring problems with LocalStorage. + + * page/DOMWindow.cpp: + (WebCore::DOMWindow::localStorage): Return the cached m_localStorage object if it exists to + avoid creating multiple representations for the same underlying StorageArea. + * page/DOMWindow.h: + (WebCore::DOMWindow::optionalLocalStorage): Return m_localStorage, not m_sessionStorage. + 2009-04-06 Tor Arne Vestbø Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/WebCore/generated/CSSPropertyNames.cpp b/src/3rdparty/webkit/WebCore/generated/CSSPropertyNames.cpp index ca4ea5a..25313ac 100644 --- a/src/3rdparty/webkit/WebCore/generated/CSSPropertyNames.cpp +++ b/src/3rdparty/webkit/WebCore/generated/CSSPropertyNames.cpp @@ -1,4 +1,4 @@ -/* ANSI-C code produced by gperf version 3.0.2 */ +/* ANSI-C code produced by gperf version 3.0.3 */ /* Command-line: gperf -a -L ANSI-C -E -C -c -o -t --key-positions='*' -NfindProp -Hhash_prop -Wwordlist_prop -D -s 2 CSSPropertyNames.gperf */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ @@ -217,6 +217,9 @@ hash_prop (register const char *str, register unsigned int len) #ifdef __GNUC__ __inline +#ifdef __GNUC_STDC_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif #endif const struct props * findProp (register const char *str, register unsigned int len) diff --git a/src/3rdparty/webkit/WebCore/generated/CSSValueKeywords.c b/src/3rdparty/webkit/WebCore/generated/CSSValueKeywords.c index d0433e0..5ff0858 100644 --- a/src/3rdparty/webkit/WebCore/generated/CSSValueKeywords.c +++ b/src/3rdparty/webkit/WebCore/generated/CSSValueKeywords.c @@ -1,4 +1,4 @@ -/* ANSI-C code produced by gperf version 3.0.2 */ +/* ANSI-C code produced by gperf version 3.0.3 */ /* Command-line: gperf -L ANSI-C -E -C -n -o -t --key-positions='*' -NfindValue -Hhash_val -Wwordlist_value -D CSSValueKeywords.gperf */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ @@ -179,6 +179,9 @@ hash_val (register const char *str, register unsigned int len) #ifdef __GNUC__ __inline +#ifdef __GNUC_STDC_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif #endif const struct css_value * findValue (register const char *str, register unsigned int len) diff --git a/src/3rdparty/webkit/WebCore/generated/ColorData.c b/src/3rdparty/webkit/WebCore/generated/ColorData.c index 18d9926..478566c 100644 --- a/src/3rdparty/webkit/WebCore/generated/ColorData.c +++ b/src/3rdparty/webkit/WebCore/generated/ColorData.c @@ -1,5 +1,5 @@ #include // bogus -/* ANSI-C code produced by gperf version 3.0.2 */ +/* ANSI-C code produced by gperf version 3.0.3 */ /* Command-line: gperf -CDEot -L ANSI-C --key-positions='*' -N findColor -D -s 2 */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ @@ -141,6 +141,9 @@ hash (register const char *str, register unsigned int len) #ifdef __GNUC__ __inline +#ifdef __GNUC_STDC_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif #endif const struct NamedColor * findColor (register const char *str, register unsigned int len) diff --git a/src/3rdparty/webkit/WebCore/generated/DocTypeStrings.cpp b/src/3rdparty/webkit/WebCore/generated/DocTypeStrings.cpp index ad63b9e..686629c 100644 --- a/src/3rdparty/webkit/WebCore/generated/DocTypeStrings.cpp +++ b/src/3rdparty/webkit/WebCore/generated/DocTypeStrings.cpp @@ -1,5 +1,5 @@ #include // bogus -/* ANSI-C code produced by gperf version 3.0.2 */ +/* ANSI-C code produced by gperf version 3.0.3 */ /* Command-line: gperf -CEot -L ANSI-C --key-positions='*' -N findDoctypeEntry -F ,PubIDInfo::eAlmostStandards,PubIDInfo::eAlmostStandards */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ @@ -331,6 +331,9 @@ hash (register const char *str, register unsigned int len) #ifdef __GNUC__ __inline +#ifdef __GNUC_STDC_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif #endif const struct PubIDInfo * findDoctypeEntry (register const char *str, register unsigned int len) diff --git a/src/3rdparty/webkit/WebCore/generated/HTMLEntityNames.c b/src/3rdparty/webkit/WebCore/generated/HTMLEntityNames.c index 470c4cd..993e106 100644 --- a/src/3rdparty/webkit/WebCore/generated/HTMLEntityNames.c +++ b/src/3rdparty/webkit/WebCore/generated/HTMLEntityNames.c @@ -1,4 +1,4 @@ -/* ANSI-C code produced by gperf version 3.0.2 */ +/* ANSI-C code produced by gperf version 3.0.3 */ /* Command-line: gperf -a -L ANSI-C -C -G -c -o -t --key-positions='*' -N findEntity -D -s 2 */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ @@ -520,6 +520,9 @@ static const short lookup[] = #ifdef __GNUC__ __inline +#ifdef __GNUC_STDC_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif #endif const struct Entity * findEntity (register const char *str, register unsigned int len) diff --git a/src/3rdparty/webkit/WebCore/generated/tokenizer.cpp b/src/3rdparty/webkit/WebCore/generated/tokenizer.cpp index 1da1a0b..8462f51 100644 --- a/src/3rdparty/webkit/WebCore/generated/tokenizer.cpp +++ b/src/3rdparty/webkit/WebCore/generated/tokenizer.cpp @@ -78,42 +78,42 @@ static yyconst flex_int16_t yy_accept[479] = { 0, 0, 0, 0, 0, 0, 0, 69, 67, 2, 2, 67, 67, 67, 67, 67, 67, 67, 67, 67, 56, - 67, 67, 67, 67, 15, 15, 15, 67, 67, 66, + 67, 67, 15, 15, 15, 67, 67, 67, 67, 66, 15, 15, 15, 65, 15, 2, 0, 0, 0, 14, - 0, 0, 0, 0, 18, 18, 8, 0, 0, 9, - 0, 0, 0, 15, 15, 15, 57, 0, 55, 0, - 0, 56, 0, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 16, 54, 54, 51, 54, 0, 0, - 0, 35, 35, 35, 35, 35, 35, 35, 15, 15, - 7, 62, 15, 0, 0, 15, 15, 0, 15, 6, + 0, 0, 0, 18, 18, 0, 8, 0, 0, 9, + 0, 0, 15, 15, 15, 0, 57, 0, 55, 0, + 0, 56, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 16, 54, 54, 51, 54, 0, 54, 0, 0, + 35, 35, 35, 35, 35, 35, 35, 0, 62, 15, + 0, 0, 15, 15, 0, 15, 15, 15, 7, 6, 5, 15, 15, 15, 15, 0, 0, 0, 14, 0, - 0, 0, 18, 18, 18, 0, 18, 0, 0, 14, - 0, 0, 4, 16, 15, 0, 0, 54, 54, 54, - 0, 54, 41, 54, 37, 39, 54, 52, 43, 54, - 42, 50, 54, 45, 44, 40, 54, 54, 0, 35, - 35, 35, 35, 0, 35, 35, 35, 35, 35, 35, - 15, 15, 15, 16, 15, 15, 63, 63, 15, 12, - 10, 15, 13, 0, 0, 0, 17, 18, 18, 18, - 17, 0, 0, 15, 0, 1, 54, 54, 54, 54, - 46, 54, 53, 16, 47, 54, 3, 35, 35, 35, - - 35, 35, 35, 35, 35, 35, 35, 15, 15, 58, - 0, 63, 63, 63, 62, 11, 0, 0, 0, 18, - 18, 18, 0, 15, 0, 0, 54, 54, 54, 48, - 49, 35, 35, 35, 35, 35, 35, 35, 35, 20, - 15, 15, 64, 63, 63, 63, 63, 0, 0, 0, - 0, 60, 0, 0, 0, 0, 18, 18, 18, 0, - 15, 54, 54, 38, 35, 35, 35, 35, 35, 35, - 21, 35, 15, 15, 64, 63, 63, 63, 63, 63, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, - 0, 0, 0, 0, 17, 18, 18, 17, 0, 15, - - 54, 54, 35, 35, 35, 35, 35, 19, 35, 15, - 15, 64, 63, 63, 63, 63, 63, 63, 0, 59, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 18, 18, 0, 15, 54, 54, 35, - 35, 35, 23, 35, 35, 15, 64, 63, 63, 63, + 0, 0, 18, 18, 0, 18, 18, 0, 0, 14, + 0, 0, 4, 16, 15, 0, 0, 54, 0, 41, + 54, 37, 39, 54, 52, 43, 54, 42, 50, 54, + 45, 44, 40, 54, 54, 54, 54, 54, 0, 35, + 35, 0, 35, 35, 35, 35, 35, 35, 35, 35, + 15, 15, 16, 15, 15, 63, 63, 15, 15, 12, + 10, 15, 13, 0, 0, 0, 17, 17, 18, 18, + 18, 0, 0, 15, 0, 1, 54, 54, 46, 54, + 53, 16, 47, 54, 54, 54, 3, 35, 35, 35, + + 35, 35, 35, 35, 35, 35, 35, 15, 58, 0, + 63, 63, 63, 62, 15, 11, 0, 0, 0, 18, + 18, 18, 0, 15, 0, 0, 54, 48, 49, 54, + 54, 35, 35, 35, 35, 35, 35, 35, 20, 35, + 15, 64, 63, 63, 63, 63, 0, 0, 0, 0, + 60, 0, 15, 0, 0, 0, 18, 18, 18, 0, + 15, 54, 54, 38, 35, 35, 35, 35, 35, 21, + 35, 35, 15, 64, 63, 63, 63, 63, 63, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, + 0, 15, 0, 0, 17, 17, 18, 18, 0, 15, + + 54, 54, 35, 35, 35, 35, 19, 35, 35, 15, + 64, 63, 63, 63, 63, 63, 63, 0, 59, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 15, 0, 0, 18, 18, 0, 15, 54, 54, 35, + 35, 23, 35, 35, 35, 15, 64, 63, 63, 63, 63, 63, 63, 63, 0, 59, 0, 0, 0, 59, 0, 0, 0, 0, 18, 15, 54, 35, 35, 35, 35, 64, 0, 0, 0, 36, 15, 35, 35, 35, @@ -122,7 +122,7 @@ static yyconst flex_int16_t yy_accept[479] = 35, 35, 35, 35, 35, 35, 35, 35, 0, 0, 0, 0, 0, 0, 35, 35, 35, 35, 25, 35, - 35, 35, 0, 0, 0, 61, 0, 0, 26, 35, + 35, 35, 0, 61, 0, 0, 0, 0, 26, 35, 35, 35, 35, 27, 35, 0, 0, 0, 0, 31, 35, 35, 35, 35, 0, 0, 0, 35, 35, 35, 35, 0, 0, 35, 35, 29, 35, 0, 0, 35, @@ -138,437 +138,909 @@ static yyconst flex_int32_t yy_ec[256] = 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 12, 18, 19, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 12, 22, 23, - 24, 25, 26, 27, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 12, 28, 12, 29, 30, 12, 31, 32, 33, 34, - - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 12, 59, 1, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60 + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 12, 54, 12, 55, 56, 12, 57, 58, 59, 60, + + 61, 62, 63, 64, 65, 37, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 12, 84, 1, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85 } ; -static yyconst flex_int32_t yy_meta[61] = +static yyconst flex_int32_t yy_meta[86] = { 0, - 1, 2, 3, 3, 3, 4, 5, 5, 5, 5, - 5, 5, 5, 6, 7, 5, 5, 8, 5, 5, - 9, 5, 5, 5, 5, 10, 5, 11, 5, 11, - 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 5, 5, 5, 11 + 1, 2, 3, 4, 4, 5, 6, 7, 6, 6, + 6, 6, 7, 8, 9, 6, 6, 10, 6, 6, + 11, 6, 6, 6, 6, 12, 6, 13, 13, 13, + 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 6, 14, 13, 13, 13, 13, + 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 6, 6, 6, 14 } ; -static yyconst flex_int16_t yy_base[517] = +static yyconst flex_int16_t yy_base[550] = { 0, - 0, 0, 39, 41, 1573, 1566, 1594, 2399, 62, 71, - 76, 61, 69, 1560, 78, 1559, 89, 1561, 1565, 132, - 1573, 91, 123, 1555, 80, 104, 97, 1554, 1551, 2399, - 85, 176, 175, 2399, 177, 193, 204, 1531, 84, 2399, - 242, 110, 180, 196, 1545, 205, 2399, 113, 277, 2399, - 1547, 72, 221, 133, 206, 234, 181, 1555, 1548, 1530, - 1528, 0, 268, 118, 1515, 221, 60, 240, 92, 230, - 95, 223, 244, 267, 238, 286, 1512, 268, 1521, 279, - 294, 1510, 278, 190, 290, 232, 292, 293, 308, 335, - 2399, 2399, 317, 326, 1516, 351, 336, 356, 366, 2399, - - 2399, 320, 367, 369, 370, 1478, 393, 327, 345, 420, - 455, 398, 1495, 490, 1481, 446, 481, 372, 365, 386, - 525, 560, 2399, 325, 388, 1491, 387, 1477, 595, 1476, - 516, 399, 1475, 34, 1472, 1461, 378, 1438, 1430, 318, - 1429, 1426, 323, 1424, 1423, 1422, 231, 387, 1430, 377, - 1411, 630, 1396, 551, 382, 108, 415, 408, 419, 412, - 586, 436, 665, 1400, 624, 456, 419, 1382, 457, 490, - 491, 625, 492, 1362, 526, 656, 672, 681, 1378, 716, - 707, 527, 723, 561, 1374, 2399, 732, 1346, 767, 437, - 1322, 410, 1312, 445, 1311, 546, 2399, 469, 758, 1303, - - 802, 576, 482, 580, 470, 440, 472, 793, 809, 2399, - 818, 515, 1288, 1273, 853, 552, 1205, 839, 855, 861, - 877, 883, 899, 645, 1227, 483, 905, 921, 612, 1183, - 1168, 609, 927, 943, 626, 517, 628, 508, 629, 1167, - 949, 965, 971, 550, 1167, 1157, 1123, 1006, 1020, 666, - 682, 2399, 1047, 1091, 1006, 1038, 1055, 1063, 1071, 1079, - 632, 1087, 1095, 1105, 539, 1103, 1111, 542, 543, 681, - 1097, 683, 1119, 1127, 1135, 585, 1091, 1083, 1067, 1039, - 721, 752, 772, 1170, 717, 1205, 1184, 1217, 1244, 1258, - 1285, 1320, 984, 1244, 2399, 1276, 1311, 917, 1328, 767, - - 1336, 1344, 733, 1352, 1360, 734, 578, 899, 582, 1395, - 1381, 1397, 623, 853, 822, 794, 793, 760, 807, 2399, - 875, 788, 1432, 1459, 1494, 818, 769, 1440, 1529, 1564, - 1438, 702, 1485, 919, 1520, 1555, 849, 963, 1572, 587, - 1299, 1580, 706, 441, 614, 1615, 1601, 715, 2399, 2399, - 2399, 2399, 2399, 2399, 1473, 839, 856, 1617, 1652, 804, - 852, 1638, 1654, 633, 1480, 871, 1508, 1650, 1542, 644, - 834, 1673, 1679, 1695, 1701, 2399, 1015, 872, 915, 916, - 877, 959, 704, 616, 586, 2399, 1717, 1723, 1739, 1002, - 1148, 514, 961, 989, 990, 1016, 1745, 1761, 1767, 1802, - - 1137, 1008, 1018, 1017, 985, 1129, 878, 1038, 1790, 1806, - 1829, 1211, 1827, 1849, 944, 1057, 1152, 787, 584, 615, - 1196, 918, 1863, 1890, 1279, 2399, 1869, 1867, 516, 1199, - 1154, 943, 1242, 515, 653, 1904, 1906, 1941, 1968, 480, - 945, 1200, 1149, 1214, 1927, 1949, 1947, 1239, 1301, 1207, - 1302, 1974, 1990, 1392, 1267, 411, 1354, 1996, 2012, 1310, - 376, 1241, 1039, 2018, 2034, 1338, 348, 1377, 2040, 1216, - 1391, 1421, 1394, 324, 1226, 1376, 263, 2399, 2075, 2080, - 2091, 2096, 2101, 2110, 2117, 2128, 2137, 2142, 2153, 2165, - 2167, 2176, 2181, 2190, 2195, 2204, 2213, 2225, 2234, 2243, - - 2248, 2260, 2265, 2276, 2281, 2292, 2303, 2314, 2319, 2330, - 2341, 2346, 2357, 2366, 2377, 2386 + 0, 0, 64, 66, 54, 56, 1407, 6578, 93, 98, + 107, 83, 155, 1376, 77, 1350, 99, 1345, 1328, 207, + 1334, 275, 100, 108, 125, 326, 1315, 1313, 1312, 6578, + 141, 110, 151, 6578, 105, 197, 295, 89, 107, 6578, + 387, 120, 0, 429, 1281, 471, 6578, 117, 532, 6578, + 1283, 269, 137, 176, 281, 574, 283, 1289, 1292, 1246, + 1257, 0, 1221, 249, 135, 282, 276, 153, 91, 169, + 299, 308, 318, 266, 1219, 320, 616, 102, 1246, 348, + 1209, 316, 127, 359, 346, 347, 375, 658, 6578, 208, + 700, 1241, 400, 409, 1220, 397, 327, 761, 6578, 6578, + + 6578, 411, 419, 414, 424, 248, 368, 355, 356, 822, + 883, 0, 1191, 925, 967, 1190, 1028, 381, 421, 464, + 1089, 1150, 6578, 214, 456, 1225, 312, 1151, 1192, 1142, + 442, 1139, 1134, 452, 1131, 1104, 458, 1082, 1060, 358, + 1046, 1028, 1027, 462, 453, 1000, 1253, 469, 1023, 463, + 986, 1295, 492, 486, 500, 484, 502, 513, 969, 1356, + 425, 1417, 1001, 545, 494, 193, 993, 543, 1459, 544, + 554, 558, 555, 508, 398, 1520, 0, 1562, 956, 1623, + 1684, 570, 1745, 563, 993, 6578, 948, 1806, 935, 520, + 921, 498, 914, 546, 1848, 564, 6578, 585, 913, 1909, + + 568, 576, 586, 606, 631, 640, 1951, 2012, 6578, 0, + 203, 924, 907, 694, 2054, 565, 543, 2115, 0, 2157, + 2218, 2279, 2340, 669, 912, 505, 2401, 856, 840, 2443, + 612, 615, 2504, 608, 557, 639, 682, 668, 839, 2546, + 2607, 0, 288, 863, 841, 819, 741, 794, 573, 418, + 6578, 2668, 2710, 620, 2771, 0, 2813, 2874, 2935, 2996, + 3057, 3131, 3173, 3234, 670, 3295, 718, 719, 729, 763, + 684, 3337, 3398, 0, 456, 782, 777, 760, 742, 829, + 649, 834, 3459, 572, 3520, 854, 894, 915, 920, 3581, + 3642, 3684, 593, 3745, 6578, 697, 3806, 3867, 3928, 3989, + + 4050, 4111, 730, 4172, 731, 683, 672, 759, 4214, 4275, + 0, 762, 682, 429, 417, 414, 411, 859, 6578, 650, + 838, 957, 4336, 4397, 607, 926, 988, 4458, 4519, 4580, + 1002, 672, 1010, 4622, 4664, 1042, 752, 4706, 4767, 756, + 4828, 376, 812, 847, 1069, 1033, 0, 387, 6578, 6578, + 6578, 6578, 6578, 6578, 1122, 924, 963, 4870, 1162, 1049, + 1050, 4912, 4973, 678, 1063, 850, 1074, 5005, 1103, 841, + 989, 0, 5062, 5104, 5146, 6578, 1066, 1080, 1081, 1084, + 1108, 1137, 877, 328, 273, 6578, 5188, 5230, 5272, 641, + 1140, 884, 916, 836, 1105, 1161, 5314, 5356, 1233, 1286, + + 1147, 1138, 919, 1206, 1165, 1186, 1141, 1207, 1291, 1263, + 1316, 1345, 1327, 5398, 1086, 1029, 1225, 1133, 258, 1247, + 1248, 1310, 1388, 6578, 1427, 5440, 1449, 5501, 242, 1311, + 1341, 1324, 1326, 173, 1317, 1454, 5562, 1480, 5604, 170, + 1061, 1328, 1355, 1372, 1552, 5646, 5688, 1351, 1374, 1389, + 1409, 5730, 5772, 1419, 1456, 154, 1453, 5814, 5856, 1457, + 112, 897, 793, 5898, 1557, 1418, 109, 1348, 1582, 1550, + 1477, 1481, 1485, 90, 1564, 1458, 39, 6578, 5959, 5964, + 5977, 5982, 5987, 5994, 6004, 6017, 296, 6022, 6032, 6045, + 6059, 651, 6064, 6074, 6079, 6089, 6099, 6103, 571, 6112, + + 6125, 6138, 6152, 6166, 6176, 6186, 6191, 6203, 657, 6217, + 758, 6222, 6234, 6247, 801, 6261, 859, 6266, 6278, 6291, + 6304, 6317, 6330, 1086, 6335, 6348, 1120, 6353, 6365, 6378, + 6391, 6404, 6417, 6430, 6435, 6448, 1216, 6453, 6465, 6478, + 6491, 6504, 6517, 1219, 1220, 6530, 6543, 6553, 6563 } ; -static yyconst flex_int16_t yy_def[517] = +static yyconst flex_int16_t yy_def[550] = { 0, 478, 1, 1, 1, 1, 1, 478, 478, 478, 478, 478, 479, 480, 478, 481, 478, 482, 478, 478, 478, - 478, 483, 484, 478, 485, 485, 485, 478, 478, 478, - 485, 485, 485, 478, 485, 478, 478, 478, 479, 478, - 486, 480, 478, 487, 488, 488, 478, 481, 489, 478, - 478, 478, 484, 485, 485, 485, 20, 490, 478, 491, - 478, 20, 492, 493, 493, 493, 493, 493, 493, 493, - 493, 493, 493, 493, 493, 493, 493, 493, 478, 483, - 494, 495, 495, 495, 495, 495, 495, 495, 485, 485, - 478, 478, 485, 496, 478, 485, 485, 478, 485, 478, - - 478, 485, 485, 485, 485, 478, 479, 479, 479, 479, - 486, 478, 488, 46, 488, 497, 46, 481, 481, 481, - 481, 489, 478, 478, 485, 490, 498, 493, 493, 493, - 499, 493, 493, 493, 493, 493, 493, 493, 493, 493, + 478, 483, 484, 484, 484, 485, 478, 478, 478, 478, + 484, 484, 484, 478, 484, 478, 478, 478, 479, 478, + 486, 480, 487, 488, 488, 489, 478, 481, 490, 478, + 478, 478, 484, 484, 484, 485, 20, 491, 478, 492, + 478, 20, 493, 493, 493, 493, 493, 493, 493, 493, + 493, 493, 493, 493, 493, 493, 494, 493, 478, 483, + 495, 495, 495, 495, 495, 495, 495, 496, 478, 484, + 497, 478, 484, 484, 498, 484, 484, 484, 478, 478, + + 478, 484, 484, 484, 484, 478, 479, 479, 479, 479, + 486, 499, 488, 488, 500, 488, 114, 501, 501, 501, + 501, 502, 478, 478, 484, 503, 504, 493, 505, 493, + 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 478, 495, - 495, 495, 495, 500, 495, 495, 495, 495, 495, 495, - 90, 485, 90, 478, 485, 485, 501, 478, 485, 485, - 485, 485, 485, 478, 479, 110, 478, 114, 488, 114, - 46, 481, 121, 485, 502, 478, 129, 493, 129, 493, - 493, 493, 493, 493, 493, 493, 478, 495, 152, 495, - - 152, 495, 495, 495, 495, 495, 495, 90, 163, 478, - 478, 503, 478, 478, 504, 485, 478, 110, 478, 114, - 180, 46, 121, 485, 502, 498, 129, 189, 493, 493, - 493, 495, 152, 201, 495, 495, 495, 495, 495, 495, - 90, 163, 478, 505, 478, 478, 478, 504, 504, 506, - 507, 478, 508, 478, 110, 478, 114, 180, 46, 121, - 485, 129, 189, 493, 495, 152, 201, 495, 495, 495, - 495, 495, 90, 163, 478, 509, 478, 478, 478, 478, - 478, 506, 478, 510, 507, 511, 504, 504, 504, 504, - 504, 508, 478, 110, 478, 114, 180, 488, 121, 485, - - 129, 189, 495, 152, 201, 495, 495, 495, 495, 485, - 163, 478, 512, 478, 478, 478, 478, 478, 478, 478, - 506, 506, 506, 506, 510, 507, 507, 507, 507, 511, - 291, 478, 110, 488, 180, 121, 485, 493, 189, 495, - 495, 201, 495, 495, 495, 485, 478, 478, 478, 478, - 478, 478, 478, 478, 506, 506, 506, 324, 507, 507, - 507, 329, 291, 478, 488, 485, 493, 495, 495, 495, - 495, 478, 324, 329, 291, 478, 485, 495, 495, 495, - 495, 495, 495, 495, 495, 478, 324, 329, 291, 485, - 495, 495, 495, 495, 495, 495, 324, 329, 291, 513, - - 495, 495, 495, 495, 495, 495, 495, 495, 324, 329, - 513, 411, 514, 515, 495, 495, 495, 495, 495, 495, - 495, 495, 515, 515, 478, 478, 515, 516, 495, 495, - 495, 495, 495, 495, 495, 515, 424, 515, 424, 495, - 495, 495, 495, 495, 424, 515, 439, 495, 495, 495, - 495, 424, 439, 495, 495, 495, 495, 424, 439, 495, - 495, 495, 495, 424, 439, 495, 495, 495, 439, 495, + 495, 506, 495, 495, 495, 495, 495, 495, 495, 495, + 484, 98, 478, 484, 484, 507, 478, 484, 98, 484, + 484, 484, 484, 478, 508, 508, 509, 114, 488, 114, + 114, 501, 501, 484, 510, 478, 493, 147, 493, 493, + 493, 493, 493, 493, 147, 493, 478, 495, 495, 160, + + 495, 495, 495, 495, 495, 495, 160, 98, 478, 511, + 512, 478, 478, 513, 98, 484, 478, 514, 515, 114, + 114, 114, 501, 484, 510, 516, 147, 493, 493, 147, + 493, 495, 160, 495, 495, 495, 495, 495, 495, 160, + 98, 517, 518, 478, 478, 478, 519, 519, 520, 521, + 478, 522, 98, 478, 523, 524, 525, 525, 258, 526, + 98, 147, 147, 147, 495, 160, 495, 495, 495, 495, + 495, 160, 98, 527, 528, 478, 478, 478, 478, 478, + 520, 478, 529, 530, 531, 532, 532, 532, 532, 532, + 533, 98, 478, 534, 478, 535, 535, 297, 536, 98, + + 147, 301, 495, 160, 495, 495, 495, 495, 160, 98, + 537, 538, 478, 478, 478, 478, 478, 478, 478, 539, + 539, 539, 539, 540, 541, 541, 541, 541, 542, 543, + 300, 478, 534, 297, 298, 536, 300, 301, 301, 495, + 160, 495, 495, 495, 495, 300, 544, 478, 478, 478, + 478, 478, 478, 478, 539, 539, 539, 323, 541, 541, + 541, 328, 543, 478, 335, 300, 339, 495, 495, 495, + 495, 545, 323, 328, 363, 478, 300, 495, 495, 495, + 495, 495, 495, 495, 495, 478, 323, 328, 363, 300, + 495, 495, 495, 495, 495, 495, 323, 328, 543, 546, + + 495, 495, 495, 495, 495, 495, 495, 495, 539, 541, + 546, 546, 547, 548, 495, 495, 495, 495, 495, 495, + 495, 495, 478, 478, 547, 549, 547, 547, 495, 495, + 495, 495, 495, 495, 495, 547, 428, 547, 428, 495, + 495, 495, 495, 495, 547, 437, 428, 495, 495, 495, + 495, 437, 428, 495, 495, 495, 495, 437, 428, 495, + 495, 495, 495, 437, 547, 495, 495, 495, 547, 495, 495, 495, 495, 495, 495, 495, 495, 0, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478 + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478 } ; -static yyconst flex_int16_t yy_nxt[2460] = +static yyconst flex_int16_t yy_nxt[6664] = { 0, 8, 9, 10, 9, 9, 9, 11, 12, 13, 14, 8, 8, 15, 8, 8, 16, 8, 17, 18, 19, - 20, 8, 21, 8, 8, 8, 22, 23, 24, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 26, 25, 25, 25, 25, 25, 25, - 27, 25, 25, 25, 25, 25, 8, 28, 29, 25, - 30, 131, 30, 36, 36, 36, 36, 36, 40, 31, - 191, 31, 36, 36, 36, 36, 36, 37, 37, 37, - 37, 37, 32, 33, 32, 33, 42, 131, 41, 43, - 40, 40, 52, 92, 134, 34, 44, 34, 92, 46, - - 46, 46, 46, 46, 46, 49, 51, 94, 80, 52, - 92, 41, 94, 98, 38, 124, 53, 92, 81, 131, - 95, 96, 131, 83, 94, 40, 84, 478, 102, 85, - 478, 94, 55, 86, 87, 154, 88, 44, 139, 137, - 49, 56, 59, 90, 99, 131, 92, 132, 97, 60, - 61, 203, 62, 90, 90, 90, 90, 90, 90, 63, - 94, 64, 65, 65, 66, 67, 68, 65, 69, 70, - 71, 65, 72, 65, 73, 74, 65, 75, 65, 76, - 77, 78, 65, 65, 65, 65, 65, 65, 92, 92, - 92, 65, 95, 96, 36, 36, 36, 36, 36, 478, - - 112, 57, 94, 94, 94, 37, 37, 37, 37, 37, - 112, 112, 112, 112, 112, 112, 114, 154, 104, 92, - 103, 105, 95, 96, 65, 117, 114, 114, 114, 114, - 114, 114, 116, 94, 156, 117, 117, 117, 117, 117, - 117, 90, 38, 39, 39, 39, 107, 92, 131, 109, - 131, 90, 90, 90, 90, 90, 90, 131, 131, 154, - 140, 94, 110, 133, 195, 131, 158, 131, 125, 111, - 144, 131, 110, 110, 110, 110, 110, 110, 48, 48, - 48, 118, 135, 95, 143, 138, 141, 145, 129, 120, - 154, 146, 142, 136, 131, 131, 478, 121, 129, 129, - - 129, 129, 129, 129, 122, 154, 81, 121, 121, 121, - 121, 121, 121, 131, 152, 155, 147, 154, 148, 154, - 154, 92, 159, 160, 152, 152, 152, 152, 152, 152, - 92, 150, 157, 92, 40, 94, 89, 89, 89, 89, - 89, 95, 95, 194, 94, 131, 163, 94, 92, 92, - 131, 154, 40, 170, 41, 161, 163, 163, 163, 163, - 163, 163, 94, 94, 92, 161, 161, 161, 161, 161, - 161, 165, 41, 193, 48, 154, 167, 40, 94, 92, - 92, 168, 92, 92, 40, 166, 167, 167, 167, 167, - 167, 167, 49, 94, 94, 39, 94, 94, 40, 49, - - 40, 92, 127, 154, 154, 131, 186, 169, 192, 154, - 172, 198, 202, 49, 131, 94, 171, 173, 177, 184, - 41, 108, 175, 175, 175, 108, 131, 40, 177, 177, - 177, 177, 177, 177, 196, 154, 211, 131, 154, 154, - 176, 205, 154, 230, 213, 190, 154, 41, 207, 92, - 176, 176, 176, 176, 176, 176, 39, 39, 39, 107, - 204, 206, 109, 94, 131, 194, 180, 154, 154, 210, - 215, 229, 131, 370, 239, 110, 180, 180, 180, 180, - 180, 180, 111, 94, 94, 110, 110, 110, 110, 110, - 110, 113, 113, 113, 113, 113, 154, 154, 226, 154, - - 232, 181, 186, 92, 210, 92, 240, 154, 238, 154, - 178, 181, 181, 181, 181, 181, 181, 94, 94, 94, - 178, 178, 178, 178, 178, 178, 119, 182, 182, 182, - 119, 236, 211, 40, 269, 154, 189, 40, 271, 40, - 245, 154, 154, 154, 154, 183, 189, 189, 189, 189, - 189, 189, 49, 41, 49, 183, 183, 183, 183, 183, - 183, 48, 48, 48, 118, 92, 154, 211, 403, 154, - 154, 201, 120, 131, 92, 277, 306, 303, 307, 94, - 121, 201, 201, 201, 201, 201, 201, 122, 94, 231, - 121, 121, 121, 121, 121, 121, 128, 128, 128, 128, - - 128, 224, 211, 154, 368, 154, 208, 154, 344, 154, - 314, 154, 345, 154, 154, 187, 208, 208, 208, 208, - 208, 208, 131, 235, 237, 187, 187, 187, 187, 187, - 187, 151, 151, 151, 151, 151, 154, 92, 92, 131, - 211, 154, 154, 154, 165, 92, 371, 433, 349, 265, - 199, 94, 94, 154, 264, 154, 154, 154, 92, 94, - 199, 199, 199, 199, 199, 199, 162, 162, 162, 162, - 162, 154, 94, 283, 268, 270, 218, 272, 384, 216, - 154, 300, 376, 261, 444, 209, 218, 218, 218, 218, - 218, 218, 219, 284, 283, 209, 209, 209, 209, 209, - - 209, 220, 219, 219, 219, 219, 219, 219, 154, 286, - 154, 220, 220, 220, 220, 220, 220, 179, 179, 179, - 179, 179, 281, 281, 281, 281, 281, 222, 309, 283, - 308, 154, 211, 154, 396, 252, 221, 222, 222, 222, - 222, 222, 222, 223, 286, 364, 221, 221, 221, 221, - 221, 221, 227, 223, 223, 223, 223, 223, 223, 283, - 154, 154, 227, 227, 227, 227, 227, 227, 188, 188, - 188, 188, 188, 319, 319, 319, 319, 319, 233, 284, - 92, 283, 340, 343, 337, 354, 320, 228, 233, 233, - 233, 233, 233, 233, 94, 283, 286, 228, 228, 228, - - 228, 228, 228, 200, 200, 200, 200, 200, 319, 319, - 319, 319, 319, 241, 154, 284, 283, 432, 353, 352, - 285, 320, 234, 241, 241, 241, 241, 241, 241, 242, - 283, 286, 234, 234, 234, 234, 234, 234, 243, 242, - 242, 242, 242, 242, 242, 286, 283, 351, 243, 243, - 243, 243, 243, 243, 248, 248, 248, 248, 248, 255, - 250, 154, 92, 283, 283, 251, 284, 252, 385, 255, - 255, 255, 255, 255, 255, 256, 94, 282, 350, 286, - 253, 257, 283, 284, 92, 256, 256, 256, 256, 256, - 256, 257, 257, 257, 257, 257, 257, 258, 94, 154, - - 366, 377, 284, 259, 154, 154, 391, 258, 258, 258, - 258, 258, 258, 259, 259, 259, 259, 259, 259, 260, - 113, 113, 113, 113, 113, 262, 154, 394, 421, 260, - 260, 260, 260, 260, 260, 262, 262, 262, 262, 262, - 262, 263, 154, 154, 116, 154, 116, 266, 435, 392, - 393, 263, 263, 263, 263, 263, 263, 266, 266, 266, - 266, 266, 266, 267, 128, 128, 128, 128, 128, 273, - 154, 154, 154, 267, 267, 267, 267, 267, 267, 273, - 273, 273, 273, 273, 273, 274, 154, 448, 154, 442, - 131, 275, 429, 395, 404, 274, 274, 274, 274, 274, - - 274, 275, 275, 275, 275, 275, 275, 248, 248, 248, - 248, 248, 154, 250, 332, 400, 154, 154, 251, 419, - 252, 281, 281, 281, 281, 281, 294, 478, 92, 94, - 405, 406, 478, 253, 252, 154, 294, 294, 294, 294, - 294, 294, 94, 154, 154, 154, 416, 253, 281, 281, - 281, 281, 287, 417, 289, 418, 468, 407, 295, 289, - 289, 290, 390, 408, 318, 154, 154, 291, 295, 295, - 295, 295, 295, 295, 292, 296, 422, 291, 291, 291, - 291, 291, 291, 297, 154, 296, 296, 296, 296, 296, - 296, 298, 317, 297, 297, 297, 297, 297, 297, 299, - - 430, 298, 298, 298, 298, 298, 298, 301, 316, 299, - 299, 299, 299, 299, 299, 302, 315, 301, 301, 301, - 301, 301, 301, 304, 154, 302, 302, 302, 302, 302, - 302, 305, 131, 304, 304, 304, 304, 304, 304, 310, - 293, 305, 305, 305, 305, 305, 305, 311, 280, 310, - 310, 310, 310, 310, 310, 312, 154, 311, 311, 311, - 311, 311, 311, 420, 154, 312, 312, 312, 312, 312, - 312, 282, 282, 282, 321, 154, 154, 323, 415, 154, - 401, 154, 279, 402, 441, 281, 281, 281, 281, 281, - 324, 478, 278, 450, 154, 131, 478, 325, 252, 431, - - 324, 324, 324, 324, 324, 324, 285, 285, 285, 326, - 131, 253, 478, 478, 478, 478, 478, 328, 281, 281, - 281, 281, 281, 154, 478, 329, 154, 154, 478, 478, - 434, 252, 330, 440, 154, 329, 329, 329, 329, 329, - 329, 154, 226, 154, 253, 281, 281, 281, 281, 281, - 449, 478, 254, 154, 456, 451, 478, 472, 252, 281, - 281, 281, 281, 281, 333, 478, 154, 476, 154, 154, - 478, 253, 252, 454, 333, 333, 333, 333, 333, 333, - 425, 425, 425, 425, 425, 253, 287, 287, 287, 287, - 287, 443, 478, 426, 154, 467, 334, 478, 247, 252, - - 151, 151, 151, 151, 151, 331, 334, 334, 334, 334, - 334, 334, 253, 246, 462, 331, 331, 331, 331, 331, - 331, 281, 281, 281, 281, 287, 154, 289, 154, 154, - 154, 335, 289, 289, 290, 455, 457, 154, 131, 131, - 291, 335, 335, 335, 335, 335, 335, 292, 336, 131, - 291, 291, 291, 291, 291, 291, 338, 466, 336, 336, - 336, 336, 336, 336, 339, 154, 338, 338, 338, 338, - 338, 338, 341, 131, 339, 339, 339, 339, 339, 339, - 342, 154, 341, 341, 341, 341, 341, 341, 470, 226, - 342, 342, 342, 342, 342, 342, 89, 89, 89, 89, - - 89, 346, 463, 154, 154, 116, 217, 214, 92, 460, - 471, 346, 346, 346, 346, 346, 346, 347, 154, 154, - 164, 154, 94, 154, 477, 473, 475, 347, 347, 347, - 347, 347, 347, 355, 319, 319, 319, 355, 154, 283, - 461, 359, 319, 319, 319, 359, 356, 197, 154, 131, - 131, 131, 283, 131, 360, 474, 131, 131, 363, 284, - 322, 357, 357, 357, 322, 131, 283, 286, 363, 363, - 363, 363, 363, 363, 355, 319, 319, 319, 355, 358, - 283, 179, 179, 179, 179, 179, 284, 356, 131, 358, - 358, 358, 358, 358, 358, 282, 282, 282, 321, 131, - - 284, 323, 131, 131, 131, 39, 127, 116, 116, 188, - 188, 188, 188, 188, 324, 39, 39, 39, 39, 39, - 39, 325, 116, 174, 324, 324, 324, 324, 324, 324, - 327, 361, 361, 361, 327, 131, 164, 154, 149, 131, - 365, 283, 131, 200, 200, 200, 200, 200, 57, 362, - 365, 365, 365, 365, 365, 365, 286, 63, 59, 362, - 362, 362, 362, 362, 362, 285, 285, 285, 326, 154, - 127, 123, 116, 106, 101, 48, 328, 100, 91, 79, - 58, 57, 50, 47, 329, 48, 48, 48, 48, 48, - 48, 330, 367, 478, 329, 329, 329, 329, 329, 329, - - 369, 35, 367, 367, 367, 367, 367, 367, 35, 478, - 369, 369, 369, 369, 369, 369, 162, 162, 162, 162, - 162, 372, 478, 478, 478, 478, 478, 478, 92, 478, - 478, 372, 372, 372, 372, 372, 372, 373, 478, 478, - 478, 478, 94, 478, 478, 478, 478, 373, 373, 373, - 373, 373, 373, 359, 319, 319, 319, 359, 374, 478, - 478, 478, 478, 478, 283, 478, 360, 478, 374, 374, - 374, 374, 374, 374, 375, 478, 478, 154, 478, 286, - 478, 478, 478, 378, 375, 375, 375, 375, 375, 375, - 379, 478, 380, 386, 478, 478, 478, 381, 382, 387, - - 478, 383, 478, 386, 386, 386, 386, 386, 386, 387, - 387, 387, 387, 387, 387, 388, 478, 478, 478, 478, - 478, 389, 478, 478, 478, 388, 388, 388, 388, 388, - 388, 389, 389, 389, 389, 389, 389, 397, 478, 478, - 478, 478, 478, 398, 478, 478, 478, 397, 397, 397, - 397, 397, 397, 398, 398, 398, 398, 398, 398, 399, - 478, 478, 478, 478, 478, 409, 478, 478, 478, 399, - 399, 399, 399, 399, 399, 409, 409, 409, 409, 409, - 409, 410, 478, 478, 478, 478, 478, 249, 478, 478, - 478, 410, 410, 410, 410, 410, 410, 249, 249, 249, - - 249, 249, 249, 411, 411, 411, 411, 411, 478, 478, - 282, 478, 478, 478, 478, 478, 478, 478, 478, 412, - 282, 282, 282, 282, 282, 282, 285, 478, 478, 413, - 411, 411, 411, 411, 411, 478, 285, 285, 285, 285, - 285, 285, 478, 478, 478, 478, 412, 424, 478, 478, - 425, 425, 425, 425, 425, 478, 413, 424, 424, 424, - 424, 424, 424, 426, 425, 425, 425, 425, 425, 478, - 425, 425, 425, 425, 425, 478, 428, 426, 478, 478, - 478, 478, 478, 426, 478, 478, 478, 439, 478, 478, - 428, 436, 436, 436, 436, 436, 428, 439, 439, 439, - - 439, 439, 439, 478, 426, 425, 425, 425, 425, 425, - 437, 478, 478, 478, 478, 478, 478, 428, 426, 478, - 437, 437, 437, 437, 437, 437, 445, 478, 478, 478, - 478, 428, 478, 478, 478, 478, 445, 445, 445, 445, - 445, 445, 425, 425, 425, 425, 425, 452, 478, 478, - 425, 425, 425, 425, 425, 426, 478, 452, 452, 452, - 452, 452, 452, 426, 478, 478, 478, 453, 428, 446, - 446, 446, 446, 446, 478, 478, 428, 453, 453, 453, - 453, 453, 453, 478, 478, 478, 478, 478, 447, 478, - 478, 478, 478, 478, 458, 478, 478, 478, 447, 447, - - 447, 447, 447, 447, 458, 458, 458, 458, 458, 458, - 459, 478, 478, 478, 478, 478, 464, 478, 478, 478, - 459, 459, 459, 459, 459, 459, 464, 464, 464, 464, - 464, 464, 465, 478, 478, 478, 478, 478, 427, 478, - 478, 478, 465, 465, 465, 465, 465, 465, 427, 427, - 427, 427, 427, 427, 469, 478, 478, 478, 478, 478, - 427, 478, 478, 478, 469, 469, 469, 469, 469, 469, - 427, 427, 427, 427, 427, 427, 39, 478, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 45, 45, 478, - 45, 45, 48, 478, 48, 48, 48, 48, 48, 48, - - 48, 48, 48, 54, 54, 478, 54, 54, 82, 478, - 478, 82, 82, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 93, 478, 93, 93, 478, 93, 93, 108, + 20, 8, 21, 8, 8, 8, 22, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 24, 23, 23, 23, 23, 23, 23, 25, 23, 23, + 23, 23, 23, 26, 27, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 24, 23, + 23, 23, 23, 23, 23, 25, 23, 23, 23, 23, + 23, 8, 28, 29, 23, 30, 35, 30, 35, 40, + 40, 31, 152, 31, 36, 36, 36, 36, 36, 36, + + 36, 36, 36, 36, 32, 33, 32, 33, 37, 37, + 37, 37, 37, 89, 40, 35, 51, 35, 89, 52, + 31, 89, 31, 89, 92, 93, 92, 93, 106, 40, + 49, 136, 32, 33, 32, 33, 41, 478, 89, 54, + 478, 95, 38, 152, 129, 34, 105, 34, 55, 94, + 89, 103, 56, 91, 89, 129, 106, 148, 91, 136, + 41, 91, 152, 91, 89, 152, 131, 54, 154, 96, + 49, 38, 42, 46, 105, 43, 55, 94, 91, 103, + 152, 102, 44, 44, 44, 44, 44, 44, 129, 89, + 91, 104, 92, 93, 91, 131, 154, 96, 36, 36, + + 36, 36, 36, 137, 91, 135, 129, 152, 46, 102, + 210, 44, 44, 44, 44, 44, 44, 59, 212, 104, + 210, 89, 129, 152, 60, 61, 152, 62, 244, 91, + 92, 92, 137, 135, 63, 63, 64, 65, 66, 63, + 67, 68, 69, 63, 70, 63, 71, 72, 63, 73, + 63, 74, 75, 76, 63, 63, 63, 63, 63, 63, + 77, 91, 78, 63, 63, 64, 65, 66, 63, 67, + 68, 69, 70, 63, 71, 72, 63, 73, 63, 74, + 75, 76, 63, 63, 63, 63, 63, 63, 130, 52, + 174, 63, 80, 144, 89, 152, 37, 37, 37, 37, + + 37, 478, 129, 57, 82, 210, 112, 83, 112, 124, + 84, 152, 125, 276, 85, 86, 130, 87, 174, 129, + 134, 132, 144, 63, 92, 140, 152, 127, 88, 129, + 38, 186, 133, 82, 91, 129, 83, 124, 138, 84, + 89, 125, 85, 86, 139, 87, 98, 141, 134, 132, + 153, 63, 129, 98, 98, 98, 98, 98, 98, 38, + 133, 129, 40, 40, 142, 478, 138, 145, 143, 152, + 39, 129, 139, 129, 157, 40, 141, 156, 192, 153, + 91, 152, 98, 98, 98, 98, 98, 98, 39, 39, + 39, 107, 142, 40, 109, 145, 143, 150, 155, 152, + + 152, 88, 158, 157, 210, 40, 156, 110, 41, 41, + 89, 129, 152, 89, 110, 110, 110, 110, 110, 110, + 164, 41, 89, 478, 89, 150, 155, 89, 152, 152, + 282, 158, 89, 40, 49, 168, 354, 89, 89, 353, + 111, 170, 352, 110, 110, 110, 110, 110, 110, 114, + 91, 41, 172, 91, 351, 165, 114, 114, 114, 114, + 114, 114, 91, 168, 91, 171, 478, 91, 173, 89, + 170, 285, 91, 210, 49, 189, 40, 91, 91, 190, + 172, 313, 115, 165, 184, 114, 114, 114, 114, 114, + 114, 117, 193, 171, 198, 129, 173, 194, 117, 117, + + 117, 117, 117, 117, 189, 129, 129, 209, 190, 91, + 191, 129, 196, 184, 204, 129, 152, 49, 192, 201, + 226, 193, 129, 198, 186, 194, 202, 117, 117, 117, + 117, 117, 117, 48, 48, 48, 118, 152, 191, 152, + 196, 205, 203, 204, 120, 152, 206, 91, 201, 217, + 228, 129, 121, 152, 202, 152, 214, 89, 89, 121, + 121, 121, 121, 121, 121, 164, 152, 209, 89, 205, + 203, 89, 478, 129, 268, 206, 89, 217, 89, 228, + 282, 177, 40, 177, 282, 122, 229, 254, 121, 121, + 121, 121, 121, 121, 98, 231, 91, 91, 91, 129, + + 224, 98, 98, 98, 98, 98, 98, 91, 91, 216, + 152, 91, 234, 232, 229, 254, 91, 129, 91, 282, + 332, 152, 235, 49, 231, 285, 283, 236, 224, 152, + 98, 98, 98, 98, 98, 98, 147, 216, 152, 152, + 234, 237, 232, 147, 147, 147, 147, 147, 147, 332, + 235, 264, 265, 267, 400, 236, 282, 282, 90, 152, + 285, 152, 238, 63, 63, 129, 293, 219, 152, 219, + 237, 239, 147, 147, 147, 147, 147, 147, 160, 264, + 265, 267, 89, 269, 152, 160, 160, 160, 160, 160, + 160, 238, 152, 152, 293, 247, 247, 247, 247, 247, + + 239, 249, 283, 283, 261, 303, 250, 350, 251, 270, + 343, 269, 364, 271, 160, 160, 160, 160, 160, 160, + 162, 152, 91, 152, 376, 152, 308, 162, 162, 162, + 162, 162, 162, 261, 303, 152, 152, 152, 270, 343, + 364, 271, 247, 247, 247, 247, 247, 252, 249, 305, + 115, 306, 376, 250, 308, 251, 162, 162, 162, 162, + 162, 162, 97, 97, 97, 97, 97, 317, 242, 90, + 242, 152, 152, 368, 89, 307, 340, 342, 305, 210, + 306, 169, 152, 152, 152, 316, 344, 349, 169, 169, + 169, 169, 169, 169, 252, 280, 280, 280, 280, 280, + + 366, 478, 315, 307, 340, 342, 478, 314, 251, 152, + 468, 256, 152, 256, 91, 344, 152, 169, 169, 169, + 169, 169, 169, 108, 175, 175, 175, 108, 366, 40, + 280, 280, 280, 280, 280, 318, 318, 318, 318, 318, + 478, 370, 176, 251, 279, 282, 152, 252, 319, 176, + 176, 176, 176, 176, 176, 280, 280, 280, 280, 280, + 318, 318, 318, 318, 318, 152, 278, 90, 251, 274, + 370, 274, 384, 319, 405, 41, 371, 377, 176, 176, + 176, 176, 176, 176, 39, 39, 39, 107, 277, 152, + 109, 283, 152, 129, 152, 280, 280, 280, 280, 280, + + 152, 384, 405, 110, 396, 371, 377, 252, 251, 129, + 110, 110, 110, 110, 110, 110, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 478, 226, 478, 251, + 152, 282, 246, 396, 251, 403, 111, 152, 282, 110, + 110, 110, 110, 110, 110, 178, 404, 252, 467, 245, + 152, 417, 178, 178, 178, 178, 178, 178, 355, 318, + 318, 318, 355, 403, 282, 478, 152, 129, 252, 152, + 282, 356, 152, 252, 129, 404, 467, 283, 115, 285, + 417, 178, 178, 178, 178, 178, 178, 180, 129, 359, + 318, 318, 318, 359, 180, 180, 180, 180, 180, 180, + + 282, 129, 360, 97, 97, 97, 97, 97, 226, 115, + 283, 108, 175, 175, 175, 108, 283, 40, 213, 90, + 385, 163, 152, 180, 180, 180, 180, 180, 180, 116, + 116, 116, 116, 116, 161, 161, 161, 161, 161, 152, + 197, 285, 152, 119, 182, 182, 182, 119, 181, 385, + 90, 478, 478, 129, 40, 181, 181, 181, 181, 181, + 181, 282, 282, 41, 179, 179, 179, 179, 179, 430, + 159, 159, 159, 159, 159, 187, 187, 187, 187, 187, + 129, 129, 152, 90, 181, 181, 181, 181, 181, 181, + 119, 182, 182, 182, 119, 49, 295, 430, 295, 129, + + 448, 40, 285, 285, 199, 199, 199, 199, 199, 183, + 390, 391, 392, 129, 152, 393, 183, 183, 183, 183, + 183, 183, 152, 355, 318, 318, 318, 355, 448, 282, + 311, 429, 311, 152, 152, 129, 356, 152, 390, 152, + 391, 392, 49, 406, 393, 183, 183, 183, 183, 183, + 183, 48, 48, 48, 118, 394, 152, 129, 152, 429, + 432, 152, 120, 359, 318, 318, 318, 359, 395, 401, + 121, 406, 402, 416, 282, 283, 360, 121, 121, 121, + 121, 121, 121, 394, 129, 415, 152, 129, 421, 432, + 152, 152, 129, 152, 152, 129, 419, 395, 401, 407, + + 152, 402, 416, 122, 129, 408, 121, 121, 121, 121, + 121, 121, 188, 415, 152, 285, 421, 420, 152, 188, + 188, 188, 188, 188, 188, 419, 347, 407, 347, 372, + 386, 372, 386, 408, 286, 286, 286, 286, 286, 152, + 127, 418, 422, 115, 115, 167, 420, 251, 188, 188, + 188, 188, 188, 188, 146, 146, 146, 146, 146, 152, + 152, 163, 152, 149, 326, 361, 361, 361, 326, 431, + 418, 422, 129, 195, 129, 282, 433, 57, 152, 434, + 195, 195, 195, 195, 195, 195, 252, 411, 411, 411, + 411, 411, 321, 357, 357, 357, 321, 431, 282, 77, + + 152, 152, 59, 412, 127, 433, 129, 123, 434, 195, + 195, 195, 195, 195, 195, 200, 285, 411, 411, 411, + 411, 411, 200, 200, 200, 200, 200, 200, 423, 423, + 423, 423, 423, 412, 115, 101, 100, 435, 99, 414, + 79, 424, 440, 58, 283, 444, 478, 478, 478, 478, + 478, 200, 200, 200, 200, 200, 200, 159, 159, 159, + 159, 159, 478, 152, 152, 57, 435, 442, 441, 414, + 152, 440, 443, 50, 444, 449, 207, 152, 471, 152, + 426, 152, 454, 207, 207, 207, 207, 207, 207, 423, + 423, 423, 423, 423, 152, 442, 450, 441, 414, 47, + + 443, 152, 424, 449, 152, 455, 478, 471, 152, 152, + 451, 454, 207, 207, 207, 207, 207, 207, 161, 161, + 161, 161, 161, 478, 450, 152, 478, 152, 423, 423, + 423, 423, 423, 456, 455, 478, 460, 208, 451, 478, + 457, 424, 152, 478, 208, 208, 208, 208, 208, 208, + 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, + 478, 456, 152, 424, 461, 470, 478, 478, 424, 457, + 478, 152, 152, 208, 208, 208, 208, 208, 208, 215, + 426, 423, 423, 423, 423, 423, 215, 215, 215, 215, + 215, 215, 461, 470, 424, 478, 478, 478, 463, 478, + + 462, 466, 426, 477, 478, 478, 152, 426, 473, 152, + 152, 152, 474, 478, 475, 215, 215, 215, 215, 215, + 215, 108, 175, 175, 175, 108, 463, 40, 462, 466, + 152, 477, 478, 426, 152, 478, 478, 473, 152, 478, + 218, 474, 478, 475, 478, 478, 478, 218, 218, 218, + 218, 218, 218, 423, 423, 423, 423, 423, 438, 438, + 438, 438, 438, 478, 478, 478, 424, 478, 478, 478, + 478, 424, 478, 41, 478, 478, 218, 218, 218, 218, + 218, 218, 220, 445, 445, 445, 445, 445, 472, 220, + 220, 220, 220, 220, 220, 478, 424, 478, 478, 478, + + 478, 478, 476, 152, 478, 426, 478, 478, 478, 478, + 426, 478, 478, 478, 478, 478, 472, 152, 220, 220, + 220, 220, 220, 220, 179, 179, 179, 179, 179, 478, + 476, 478, 478, 478, 478, 426, 478, 478, 478, 478, + 478, 478, 478, 221, 478, 478, 478, 478, 478, 478, + 221, 221, 221, 221, 221, 221, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 221, + 221, 221, 221, 221, 221, 116, 116, 116, 116, 116, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 478, 478, 222, 478, 478, 478, 478, 478, + 478, 222, 222, 222, 222, 222, 222, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 222, 222, 222, 222, 222, 222, 119, 182, 182, 182, + 119, 478, 478, 478, 478, 478, 478, 40, 478, 478, + 478, 478, 478, 478, 478, 223, 478, 478, 478, 478, + 478, 478, 223, 223, 223, 223, 223, 223, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 49, 478, + + 478, 223, 223, 223, 223, 223, 223, 187, 187, 187, + 187, 187, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 227, 478, 478, 478, + 478, 478, 478, 227, 227, 227, 227, 227, 227, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 227, 227, 227, 227, 227, 227, 230, 478, + 478, 478, 478, 478, 478, 230, 230, 230, 230, 230, + 230, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 478, 478, 230, 230, 230, 230, 230, 230, + 199, 199, 199, 199, 199, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 233, + 478, 478, 478, 478, 478, 478, 233, 233, 233, 233, + 233, 233, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 233, 233, 233, 233, 233, + 233, 240, 478, 478, 478, 478, 478, 478, 240, 240, + 240, 240, 240, 240, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 478, 478, 478, 478, 478, 240, 240, 240, + 240, 240, 240, 161, 161, 161, 161, 161, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 241, 478, 478, 478, 478, 478, 478, 241, + 241, 241, 241, 241, 241, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 241, 241, + 241, 241, 241, 241, 253, 478, 478, 478, 478, 478, + 478, 253, 253, 253, 253, 253, 253, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 253, 253, 253, 253, 253, 253, 108, 175, 175, 175, + 108, 478, 40, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 255, 478, 478, 478, 478, + 478, 478, 255, 255, 255, 255, 255, 255, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 41, 478, + 478, 255, 255, 255, 255, 255, 255, 257, 478, 478, + 478, 478, 478, 478, 257, 257, 257, 257, 257, 257, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 257, 257, 257, 257, 257, 257, 179, + 179, 179, 179, 179, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 258, 478, + 478, 478, 478, 478, 478, 258, 258, 258, 258, 258, + 258, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 258, 258, 258, 258, 258, 258, + 116, 116, 116, 116, 116, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 259, + + 478, 478, 478, 478, 478, 478, 259, 259, 259, 259, + 259, 259, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 259, 259, 259, 259, 259, + 259, 119, 182, 182, 182, 119, 478, 478, 478, 478, + 478, 478, 40, 478, 478, 478, 478, 478, 478, 478, + 260, 478, 478, 478, 478, 478, 478, 260, 260, 260, + 260, 260, 260, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 49, 478, 478, 260, 260, 260, 260, + + 260, 260, 187, 187, 187, 187, 187, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 262, 478, 478, 478, 478, 478, 478, 262, 262, + 262, 262, 262, 262, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 262, 262, 262, + 262, 262, 262, 263, 478, 478, 478, 478, 478, 478, + 263, 263, 263, 263, 263, 263, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 263, + + 263, 263, 263, 263, 263, 199, 199, 199, 199, 199, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 266, 478, 478, 478, 478, 478, + 478, 266, 266, 266, 266, 266, 266, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 266, 266, 266, 266, 266, 266, 272, 478, 478, 478, + 478, 478, 478, 272, 272, 272, 272, 272, 272, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 272, 272, 272, 272, 272, 272, 161, 161, + 161, 161, 161, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 273, 478, 478, + 478, 478, 478, 478, 273, 273, 273, 273, 273, 273, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 273, 273, 273, 273, 273, 273, 280, + 280, 280, 280, 286, 478, 288, 478, 478, 478, 478, + 288, 288, 289, 478, 478, 478, 478, 478, 290, 478, + 478, 478, 478, 478, 478, 290, 290, 290, 290, 290, + + 290, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 291, 478, 478, 290, 290, 290, 290, 290, 290, + 292, 478, 478, 478, 478, 478, 478, 292, 292, 292, + 292, 292, 292, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 292, 292, 292, 292, + 292, 292, 108, 175, 175, 175, 108, 478, 40, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 294, 478, 478, 478, 478, 478, 478, 294, 294, + + 294, 294, 294, 294, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 41, 478, 478, 294, 294, 294, + 294, 294, 294, 296, 478, 478, 478, 478, 478, 478, + 296, 296, 296, 296, 296, 296, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 115, 478, 478, 296, + 296, 296, 296, 296, 296, 179, 179, 179, 179, 179, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 297, 478, 478, 478, 478, 478, + + 478, 297, 297, 297, 297, 297, 297, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 115, 478, 478, + 297, 297, 297, 297, 297, 297, 116, 116, 116, 116, + 116, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 298, 478, 478, 478, 478, + 478, 478, 298, 298, 298, 298, 298, 298, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 298, 298, 298, 298, 298, 298, 119, 182, 182, + + 182, 119, 478, 478, 478, 478, 478, 478, 40, 478, + 478, 478, 478, 478, 478, 478, 299, 478, 478, 478, + 478, 478, 478, 299, 299, 299, 299, 299, 299, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 49, + 478, 478, 299, 299, 299, 299, 299, 299, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 90, 478, 478, + 478, 478, 478, 478, 90, 90, 90, 90, 90, 90, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 478, 300, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 90, 90, 90, 90, 90, 90, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 300, 187, 187, 187, 187, 187, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 301, 478, 478, 478, 478, 478, 478, 301, 301, + 301, 301, 301, 301, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 301, 301, 301, + 301, 301, 301, 302, 478, 478, 478, 478, 478, 478, + + 302, 302, 302, 302, 302, 302, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 302, + 302, 302, 302, 302, 302, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 128, 478, 478, 478, 478, 478, + 478, 128, 128, 128, 128, 128, 128, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 128, 128, 128, 128, 128, 128, 199, 199, 199, 199, + + 199, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 304, 478, 478, 478, 478, + 478, 478, 304, 304, 304, 304, 304, 304, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 304, 304, 304, 304, 304, 304, 309, 478, 478, + 478, 478, 478, 478, 309, 309, 309, 309, 309, 309, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 309, 309, 309, 309, 309, 309, 161, + + 161, 161, 161, 161, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 310, 478, + 478, 478, 478, 478, 478, 310, 310, 310, 310, 310, + 310, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 310, 310, 310, 310, 310, 310, + 281, 281, 281, 320, 478, 478, 322, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 323, + 478, 478, 478, 478, 478, 478, 323, 323, 323, 323, + 323, 323, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 324, 478, 478, 323, 323, 323, 323, 323, + 323, 284, 284, 284, 325, 478, 478, 478, 478, 478, + 478, 478, 327, 478, 478, 478, 478, 478, 478, 478, + 328, 478, 478, 478, 478, 478, 478, 328, 328, 328, + 328, 328, 328, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 329, 478, 478, 328, 328, 328, 328, + 328, 328, 286, 286, 286, 286, 286, 478, 478, 478, + 478, 478, 478, 478, 478, 251, 478, 478, 478, 478, + + 478, 330, 478, 478, 478, 478, 478, 478, 330, 330, + 330, 330, 330, 330, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 252, 478, 478, 330, 330, 330, + 330, 330, 330, 280, 280, 280, 280, 286, 478, 288, + 478, 478, 478, 478, 288, 288, 289, 478, 478, 478, + 478, 478, 290, 478, 478, 478, 478, 478, 478, 290, + 290, 290, 290, 290, 290, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 291, 478, 478, 290, 290, + + 290, 290, 290, 290, 331, 478, 478, 478, 478, 478, + 478, 331, 331, 331, 331, 331, 331, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 331, 331, 331, 331, 331, 331, 108, 175, 175, 175, + 108, 478, 40, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 333, 478, 478, 478, 478, + 478, 478, 333, 333, 333, 333, 333, 333, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 41, 478, + + 478, 333, 333, 333, 333, 333, 333, 179, 179, 179, + 179, 179, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 334, 478, 478, 478, + 478, 478, 478, 334, 334, 334, 334, 334, 334, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 115, + 478, 478, 334, 334, 334, 334, 334, 334, 116, 116, + 116, 116, 116, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 335, 478, 478, + 478, 478, 478, 478, 335, 335, 335, 335, 335, 335, + + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 335, 335, 335, 335, 335, 335, 119, + 182, 182, 182, 119, 478, 478, 478, 478, 478, 478, + 40, 478, 478, 478, 478, 478, 478, 478, 336, 478, + 478, 478, 478, 478, 478, 336, 336, 336, 336, 336, + 336, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 49, 478, 478, 336, 336, 336, 336, 336, 336, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 478, 478, 478, 478, 337, 478, 478, 90, + 478, 478, 478, 478, 478, 478, 90, 90, 90, 90, + 90, 90, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 90, 90, 90, 90, 90, + 90, 187, 187, 187, 187, 187, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 338, 478, 478, 478, 478, 478, 478, 338, 338, 338, + 338, 338, 338, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 478, 478, 478, 478, 338, 338, 338, 338, + 338, 338, 146, 146, 146, 146, 146, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 339, 478, 478, 478, 478, 478, 478, 339, 339, + 339, 339, 339, 339, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 339, 339, 339, + 339, 339, 339, 199, 199, 199, 199, 199, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 341, 478, 478, 478, 478, 478, 478, 341, + + 341, 341, 341, 341, 341, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 341, 341, + 341, 341, 341, 341, 345, 478, 478, 478, 478, 478, + 478, 345, 345, 345, 345, 345, 345, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 345, 345, 345, 345, 345, 345, 161, 161, 161, 161, + 161, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 346, 478, 478, 478, 478, + + 478, 478, 346, 346, 346, 346, 346, 346, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 346, 346, 346, 346, 346, 346, 321, 357, 357, + 357, 321, 478, 282, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 358, 478, 478, 478, + 478, 478, 478, 358, 358, 358, 358, 358, 358, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 283, + 478, 478, 358, 358, 358, 358, 358, 358, 281, 281, + + 281, 320, 478, 478, 322, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 323, 478, 478, + 478, 478, 478, 478, 323, 323, 323, 323, 323, 323, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 324, 478, 478, 323, 323, 323, 323, 323, 323, 326, + 361, 361, 361, 326, 478, 478, 478, 478, 478, 478, + 282, 478, 478, 478, 478, 478, 478, 478, 362, 478, + 478, 478, 478, 478, 478, 362, 362, 362, 362, 362, + 362, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 285, 478, 478, 362, 362, 362, 362, 362, 362, + 284, 284, 284, 325, 478, 478, 478, 478, 478, 478, + 478, 327, 478, 478, 478, 478, 478, 478, 478, 328, + 478, 478, 478, 478, 478, 478, 328, 328, 328, 328, + 328, 328, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 329, 478, 478, 328, 328, 328, 328, 328, + 328, 286, 286, 286, 286, 286, 478, 478, 478, 478, + 478, 478, 478, 478, 251, 478, 478, 478, 478, 478, + + 363, 478, 478, 478, 478, 478, 478, 363, 363, 363, + 363, 363, 363, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 252, 478, 478, 363, 363, 363, 363, + 363, 363, 365, 478, 478, 478, 478, 478, 478, 365, + 365, 365, 365, 365, 365, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 365, 365, + 365, 365, 365, 365, 113, 478, 478, 478, 478, 478, + 478, 113, 113, 113, 113, 113, 113, 478, 478, 478, + + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 113, 113, 113, 113, 113, 113, 367, 478, 478, 478, + 478, 478, 478, 367, 367, 367, 367, 367, 367, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 367, 367, 367, 367, 367, 367, 146, 146, + 146, 146, 146, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 128, 478, 478, + 478, 478, 478, 478, 128, 128, 128, 128, 128, 128, + + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 128, 128, 128, 128, 128, 128, 199, + 199, 199, 199, 199, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 369, 478, + 478, 478, 478, 478, 478, 369, 369, 369, 369, 369, + 369, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 369, 369, 369, 369, 369, 369, + 373, 478, 478, 478, 478, 478, 478, 373, 373, 373, + + 373, 373, 373, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 373, 373, 373, 373, + 373, 373, 374, 478, 478, 478, 478, 478, 478, 374, + 374, 374, 374, 374, 374, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 374, 374, + 374, 374, 374, 374, 286, 286, 286, 286, 286, 478, + 478, 478, 478, 478, 478, 478, 478, 251, 478, 478, + 478, 478, 478, 375, 478, 478, 478, 478, 478, 478, + + 375, 375, 375, 375, 375, 375, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 252, 478, 478, 375, + 375, 375, 375, 375, 375, 378, 478, 478, 478, 478, + 478, 478, 379, 478, 380, 478, 478, 478, 478, 381, + 382, 478, 478, 383, 478, 478, 478, 478, 152, 478, + 478, 478, 478, 478, 378, 478, 478, 478, 478, 478, + 379, 478, 380, 478, 478, 478, 478, 381, 382, 478, + 478, 383, 387, 478, 478, 478, 478, 478, 478, 387, + 387, 387, 387, 387, 387, 478, 478, 478, 478, 478, + + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 387, 387, + 387, 387, 387, 387, 388, 478, 478, 478, 478, 478, + 478, 388, 388, 388, 388, 388, 388, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 388, 388, 388, 388, 388, 388, 389, 478, 478, 478, + 478, 478, 478, 389, 389, 389, 389, 389, 389, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 389, 389, 389, 389, 389, 389, 397, 478, + 478, 478, 478, 478, 478, 397, 397, 397, 397, 397, + 397, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 397, 397, 397, 397, 397, 397, + 398, 478, 478, 478, 478, 478, 478, 398, 398, 398, + 398, 398, 398, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 398, 398, 398, 398, + 398, 398, 399, 478, 478, 478, 478, 478, 478, 399, + + 399, 399, 399, 399, 399, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 399, 399, + 399, 399, 399, 399, 409, 478, 478, 478, 478, 478, + 478, 409, 409, 409, 409, 409, 409, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 409, 409, 409, 409, 409, 409, 410, 478, 478, 478, + 478, 478, 478, 410, 410, 410, 410, 410, 410, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 410, 410, 410, 410, 410, 410, 428, 478, + 478, 478, 478, 478, 478, 428, 428, 428, 428, 428, + 428, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 428, 428, 428, 428, 428, 428, + 437, 478, 478, 478, 478, 478, 478, 437, 437, 437, + 437, 437, 437, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 437, 437, 437, 437, + + 437, 437, 438, 438, 438, 438, 438, 478, 478, 478, + 478, 478, 478, 478, 478, 424, 478, 478, 478, 478, + 478, 439, 478, 478, 478, 478, 478, 478, 439, 439, + 439, 439, 439, 439, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 426, 478, 478, 439, 439, 439, + 439, 439, 439, 445, 445, 445, 445, 445, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 446, 478, 478, 478, 478, 478, 478, 446, + 446, 446, 446, 446, 446, 478, 478, 478, 478, 478, + + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 446, 446, + 446, 446, 446, 446, 447, 478, 478, 478, 478, 478, + 478, 447, 447, 447, 447, 447, 447, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 447, 447, 447, 447, 447, 447, 452, 478, 478, 478, + 478, 478, 478, 452, 452, 452, 452, 452, 452, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 452, 452, 452, 452, 452, 452, 453, 478, + 478, 478, 478, 478, 478, 453, 453, 453, 453, 453, + 453, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 453, 453, 453, 453, 453, 453, + 458, 478, 478, 478, 478, 478, 478, 458, 458, 458, + 458, 458, 458, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 458, 458, 458, 458, + 458, 458, 459, 478, 478, 478, 478, 478, 478, 459, + + 459, 459, 459, 459, 459, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 459, 459, + 459, 459, 459, 459, 464, 478, 478, 478, 478, 478, + 478, 464, 464, 464, 464, 464, 464, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 464, 464, 464, 464, 464, 464, 465, 478, 478, 478, + 478, 478, 478, 465, 465, 465, 465, 465, 465, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 465, 465, 465, 465, 465, 465, 469, 478, + 478, 478, 478, 478, 478, 469, 469, 469, 469, 469, + 469, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 469, 469, 469, 469, 469, 469, + 39, 478, 478, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 45, 45, 478, 45, 45, 48, 478, + 478, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 53, 53, 478, 53, 53, 81, 478, 478, 81, + + 81, 90, 478, 90, 90, 478, 90, 90, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 115, - 115, 478, 115, 115, 119, 119, 119, 119, 119, 119, - 119, 119, 119, 119, 119, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 65, 65, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 130, 130, - 478, 130, 130, 151, 151, 151, 151, 151, 151, 151, - - 151, 151, 153, 153, 478, 153, 153, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 200, 200, 200, 200, - 200, 200, 200, 200, 200, 212, 212, 212, 478, 212, + 108, 113, 113, 478, 113, 113, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 128, 128, 478, 128, 128, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, 151, 151, + 478, 151, 151, 159, 159, 159, 159, 159, 159, 159, + + 159, 159, 159, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 166, 166, 166, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 48, 48, 478, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, + 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + + 211, 211, 211, 211, 39, 478, 478, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, - 225, 225, 244, 244, 244, 478, 244, 249, 249, 249, - 249, 478, 249, 249, 249, 249, 249, 249, 276, 276, - 276, 478, 276, 282, 478, 282, 282, 282, 282, 282, - - 282, 282, 282, 282, 285, 478, 285, 285, 285, 285, - 285, 285, 285, 285, 285, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 313, 313, 313, 478, - 313, 322, 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 327, 327, 327, 327, 327, 327, 327, 327, - 327, 327, 327, 348, 348, 348, 478, 348, 414, 414, - 414, 478, 478, 478, 414, 478, 478, 414, 414, 423, - 423, 423, 423, 423, 423, 423, 423, 423, 427, 427, - 427, 478, 478, 427, 427, 427, 478, 427, 427, 438, - 438, 438, 438, 438, 438, 438, 438, 438, 7, 478, + 225, 243, 243, 243, 243, 248, 248, 248, 248, 248, + 248, 478, 248, 248, 248, 248, 248, 248, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 185, 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 275, 275, 275, 275, 248, + 248, 248, 248, 248, 248, 478, 248, 248, 248, 248, + 248, 248, 281, 478, 478, 281, 281, 281, 281, 281, + + 281, 281, 281, 281, 281, 284, 478, 478, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, + 287, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 113, 113, 478, 113, 113, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 312, 312, 312, 312, 321, 321, 321, 321, + 321, 321, 321, 321, 321, 321, 321, 321, 321, 284, + 478, 478, 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 326, 326, 326, 326, 326, 326, 326, 326, + + 326, 326, 326, 326, 326, 248, 248, 248, 248, 248, + 478, 478, 248, 248, 248, 248, 248, 248, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, + 287, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 113, 113, 478, 113, 113, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 348, 348, 348, 348, 281, 281, 478, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 321, + 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, + 321, 321, 284, 284, 478, 284, 284, 284, 284, 284, + + 284, 284, 284, 284, 284, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, 248, 248, + 248, 248, 248, 478, 478, 248, 248, 248, 248, 248, + 248, 413, 413, 413, 413, 478, 478, 478, 478, 413, + 478, 478, 413, 413, 425, 425, 425, 425, 478, 478, + 478, 425, 425, 425, 478, 425, 425, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 7, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478 + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478 } ; -static yyconst flex_int16_t yy_chk[2460] = +static yyconst flex_int16_t yy_chk[6664] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -576,270 +1048,733 @@ static yyconst flex_int16_t yy_chk[2460] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 3, 134, 4, 9, 9, 9, 9, 9, 12, 3, - 134, 4, 10, 10, 10, 10, 10, 11, 11, 11, - 11, 11, 3, 3, 4, 4, 13, 67, 12, 13, - 15, 39, 52, 25, 67, 3, 13, 4, 31, 13, - - 13, 13, 13, 13, 13, 15, 17, 25, 22, 17, - 27, 39, 31, 27, 11, 52, 17, 26, 22, 69, - 26, 26, 71, 22, 27, 48, 22, 42, 31, 22, - 42, 26, 17, 22, 22, 156, 22, 42, 71, 69, - 48, 17, 20, 23, 27, 64, 54, 64, 26, 20, - 20, 156, 20, 23, 23, 23, 23, 23, 23, 20, - 54, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 3, 5, 4, 6, 15, + 12, 3, 477, 4, 9, 9, 9, 9, 9, 10, + + 10, 10, 10, 10, 3, 3, 4, 4, 11, 11, + 11, 11, 11, 23, 39, 5, 17, 6, 35, 17, + 3, 24, 4, 32, 24, 24, 32, 32, 38, 48, + 15, 69, 3, 3, 4, 4, 12, 42, 25, 17, + 42, 25, 11, 474, 69, 3, 35, 4, 17, 24, + 53, 32, 17, 23, 31, 78, 38, 78, 35, 69, + 39, 24, 467, 32, 33, 461, 65, 17, 83, 25, + 48, 11, 13, 42, 35, 13, 17, 24, 25, 32, + 83, 31, 13, 13, 13, 13, 13, 13, 65, 54, + 53, 33, 54, 54, 31, 65, 83, 25, 36, 36, + + 36, 36, 36, 70, 33, 68, 68, 456, 13, 31, + 166, 13, 13, 13, 13, 13, 13, 20, 166, 33, + 211, 90, 70, 440, 20, 20, 434, 20, 211, 54, + 124, 124, 70, 68, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 33, 32, - 35, 20, 32, 32, 36, 36, 36, 36, 36, 57, - - 43, 57, 33, 32, 35, 37, 37, 37, 37, 37, - 43, 43, 43, 43, 43, 43, 44, 84, 33, 55, - 32, 35, 55, 55, 57, 46, 44, 44, 44, 44, - 44, 44, 46, 55, 84, 46, 46, 46, 46, 46, - 46, 53, 37, 41, 41, 41, 41, 56, 66, 41, - 72, 53, 53, 53, 53, 53, 53, 70, 147, 86, - 72, 56, 41, 66, 147, 75, 86, 68, 56, 41, - 75, 73, 41, 41, 41, 41, 41, 41, 49, 49, - 49, 49, 68, 74, 74, 70, 73, 75, 63, 49, - 477, 75, 73, 68, 74, 78, 80, 49, 63, 63, - - 63, 63, 63, 63, 49, 83, 80, 49, 49, 49, - 49, 49, 49, 76, 81, 83, 76, 85, 78, 87, - 88, 89, 87, 88, 81, 81, 81, 81, 81, 81, - 93, 80, 85, 102, 108, 89, 90, 90, 90, 90, - 90, 124, 124, 143, 93, 140, 94, 102, 90, 97, - 143, 474, 109, 102, 108, 90, 94, 94, 94, 94, - 94, 94, 90, 97, 96, 90, 90, 90, 90, 90, - 90, 96, 109, 140, 118, 467, 98, 119, 96, 99, - 103, 98, 104, 105, 118, 97, 98, 98, 98, 98, - 98, 98, 119, 99, 103, 107, 104, 105, 120, 118, - - 107, 125, 127, 461, 150, 137, 127, 99, 137, 155, - 104, 150, 155, 120, 148, 125, 103, 105, 112, 125, - 107, 110, 110, 110, 110, 110, 132, 110, 112, 112, - 112, 112, 112, 112, 148, 158, 167, 192, 456, 160, - 110, 158, 157, 192, 167, 132, 159, 110, 160, 162, - 110, 110, 110, 110, 110, 110, 111, 111, 111, 111, - 157, 159, 111, 162, 190, 194, 116, 206, 344, 166, - 169, 190, 194, 344, 206, 111, 116, 116, 116, 116, - 116, 116, 111, 166, 169, 111, 111, 111, 111, 111, - 111, 114, 114, 114, 114, 114, 198, 205, 226, 207, - - 198, 117, 226, 170, 171, 173, 207, 440, 205, 203, - 114, 117, 117, 117, 117, 117, 117, 170, 171, 173, - 114, 114, 114, 114, 114, 114, 121, 121, 121, 121, - 121, 203, 212, 175, 236, 238, 131, 121, 238, 182, - 212, 392, 434, 429, 236, 121, 131, 131, 131, 131, - 131, 131, 121, 175, 182, 121, 121, 121, 121, 121, - 121, 122, 122, 122, 122, 216, 265, 244, 392, 268, - 269, 154, 122, 196, 184, 244, 268, 265, 269, 216, - 122, 154, 154, 154, 154, 154, 154, 122, 184, 196, - 122, 122, 122, 122, 122, 122, 129, 129, 129, 129, - - 129, 184, 276, 202, 340, 307, 161, 204, 307, 309, - 276, 419, 309, 385, 340, 129, 161, 161, 161, 161, - 161, 161, 129, 202, 204, 129, 129, 129, 129, 129, - 129, 152, 152, 152, 152, 152, 232, 165, 172, 229, - 313, 345, 420, 384, 165, 261, 345, 420, 313, 232, - 152, 165, 172, 235, 229, 237, 239, 152, 224, 261, - 152, 152, 152, 152, 152, 152, 163, 163, 163, 163, - 163, 370, 224, 250, 235, 237, 176, 239, 370, 172, - 435, 261, 364, 224, 435, 163, 176, 176, 176, 176, - 176, 176, 177, 250, 251, 163, 163, 163, 163, 163, - - 163, 178, 177, 177, 177, 177, 177, 177, 270, 251, - 272, 178, 178, 178, 178, 178, 178, 180, 180, 180, - 180, 180, 281, 281, 281, 281, 281, 181, 272, 285, - 270, 383, 348, 343, 383, 281, 180, 181, 181, 181, - 181, 181, 181, 183, 285, 332, 180, 180, 180, 180, - 180, 180, 187, 183, 183, 183, 183, 183, 183, 282, - 303, 306, 187, 187, 187, 187, 187, 187, 189, 189, - 189, 189, 189, 283, 283, 283, 283, 283, 199, 282, - 300, 327, 303, 306, 300, 318, 283, 189, 199, 199, - 199, 199, 199, 199, 300, 322, 327, 189, 189, 189, - - 189, 189, 189, 201, 201, 201, 201, 201, 319, 319, - 319, 319, 319, 208, 418, 322, 360, 418, 317, 316, - 326, 319, 201, 208, 208, 208, 208, 208, 208, 209, - 326, 360, 201, 201, 201, 201, 201, 201, 211, 209, - 209, 209, 209, 209, 209, 326, 356, 315, 211, 211, - 211, 211, 211, 211, 215, 215, 215, 215, 215, 218, - 215, 371, 337, 357, 361, 215, 356, 215, 371, 218, - 218, 218, 218, 218, 218, 219, 337, 321, 314, 361, - 215, 220, 321, 357, 366, 219, 219, 219, 219, 219, - 219, 220, 220, 220, 220, 220, 220, 221, 366, 378, - - 337, 366, 321, 222, 381, 407, 378, 221, 221, 221, - 221, 221, 221, 222, 222, 222, 222, 222, 222, 223, - 334, 334, 334, 334, 334, 227, 308, 381, 407, 223, - 223, 223, 223, 223, 223, 227, 227, 227, 227, 227, - 227, 228, 379, 380, 298, 422, 334, 233, 422, 379, - 380, 228, 228, 228, 228, 228, 228, 233, 233, 233, - 233, 233, 233, 234, 338, 338, 338, 338, 338, 241, - 432, 415, 441, 234, 234, 234, 234, 234, 234, 241, - 241, 241, 241, 241, 241, 242, 382, 441, 393, 432, - 338, 243, 415, 382, 393, 242, 242, 242, 242, 242, - - 242, 243, 243, 243, 243, 243, 243, 248, 248, 248, - 248, 248, 405, 248, 293, 390, 394, 395, 248, 405, - 248, 249, 249, 249, 249, 249, 255, 249, 377, 390, - 394, 395, 249, 248, 249, 402, 255, 255, 255, 255, - 255, 255, 377, 396, 404, 403, 402, 249, 253, 253, - 253, 253, 253, 403, 253, 404, 463, 396, 256, 253, - 253, 253, 377, 396, 280, 408, 463, 253, 256, 256, - 256, 256, 256, 256, 253, 257, 408, 253, 253, 253, - 253, 253, 253, 258, 416, 257, 257, 257, 257, 257, - 257, 259, 279, 258, 258, 258, 258, 258, 258, 260, - - 416, 259, 259, 259, 259, 259, 259, 262, 278, 260, - 260, 260, 260, 260, 260, 263, 277, 262, 262, 262, - 262, 262, 262, 266, 271, 263, 263, 263, 263, 263, - 263, 267, 264, 266, 266, 266, 266, 266, 266, 273, - 254, 267, 267, 267, 267, 267, 267, 274, 247, 273, - 273, 273, 273, 273, 273, 275, 406, 274, 274, 274, - 274, 274, 274, 406, 401, 275, 275, 275, 275, 275, - 275, 284, 284, 284, 284, 391, 443, 284, 401, 417, - 391, 431, 246, 391, 431, 287, 287, 287, 287, 287, - 284, 287, 245, 443, 240, 231, 287, 284, 287, 417, - - 284, 284, 284, 284, 284, 284, 286, 286, 286, 286, - 230, 287, 412, 412, 412, 412, 412, 286, 288, 288, - 288, 288, 288, 421, 288, 286, 430, 442, 412, 288, - 421, 288, 286, 430, 450, 286, 286, 286, 286, 286, - 286, 444, 225, 470, 288, 289, 289, 289, 289, 289, - 442, 289, 217, 475, 450, 444, 289, 470, 289, 290, - 290, 290, 290, 290, 294, 290, 448, 475, 462, 433, - 290, 289, 290, 448, 294, 294, 294, 294, 294, 294, - 425, 425, 425, 425, 425, 290, 291, 291, 291, 291, - 291, 433, 291, 425, 455, 462, 296, 291, 214, 291, - - 341, 341, 341, 341, 341, 291, 296, 296, 296, 296, - 296, 296, 291, 213, 455, 291, 291, 291, 291, 291, - 291, 292, 292, 292, 292, 292, 341, 292, 449, 451, - 200, 297, 292, 292, 292, 449, 451, 460, 195, 193, - 292, 297, 297, 297, 297, 297, 297, 292, 299, 191, - 292, 292, 292, 292, 292, 292, 301, 460, 299, 299, - 299, 299, 299, 299, 302, 466, 301, 301, 301, 301, - 301, 301, 304, 188, 302, 302, 302, 302, 302, 302, - 305, 457, 304, 304, 304, 304, 304, 304, 466, 185, - 305, 305, 305, 305, 305, 305, 310, 310, 310, 310, - - 310, 311, 457, 476, 468, 179, 174, 168, 310, 454, - 468, 311, 311, 311, 311, 311, 311, 312, 471, 454, - 164, 473, 310, 153, 476, 471, 473, 312, 312, 312, - 312, 312, 312, 323, 323, 323, 323, 323, 151, 323, - 454, 328, 328, 328, 328, 328, 323, 149, 472, 146, - 145, 144, 328, 142, 328, 472, 141, 139, 331, 323, - 324, 324, 324, 324, 324, 138, 324, 328, 331, 331, - 331, 331, 331, 331, 355, 355, 355, 355, 355, 324, - 355, 365, 365, 365, 365, 365, 324, 355, 136, 324, - 324, 324, 324, 324, 324, 325, 325, 325, 325, 135, - - 355, 325, 133, 130, 128, 333, 126, 365, 115, 367, - 367, 367, 367, 367, 325, 333, 333, 333, 333, 333, - 333, 325, 113, 106, 325, 325, 325, 325, 325, 325, - 329, 329, 329, 329, 329, 367, 95, 82, 79, 77, - 335, 329, 65, 369, 369, 369, 369, 369, 61, 329, - 335, 335, 335, 335, 335, 335, 329, 60, 59, 329, - 329, 329, 329, 329, 329, 330, 330, 330, 330, 369, - 58, 51, 45, 38, 29, 336, 330, 28, 24, 21, - 19, 18, 16, 14, 330, 336, 336, 336, 336, 336, - 336, 330, 339, 7, 330, 330, 330, 330, 330, 330, - - 342, 6, 339, 339, 339, 339, 339, 339, 5, 0, - 342, 342, 342, 342, 342, 342, 346, 346, 346, 346, - 346, 347, 0, 0, 0, 0, 0, 0, 346, 0, - 0, 347, 347, 347, 347, 347, 347, 358, 0, 0, - 0, 0, 346, 0, 0, 0, 0, 358, 358, 358, - 358, 358, 358, 359, 359, 359, 359, 359, 362, 0, - 0, 0, 0, 0, 359, 0, 359, 0, 362, 362, - 362, 362, 362, 362, 363, 0, 0, 368, 0, 359, - 0, 0, 0, 368, 363, 363, 363, 363, 363, 363, - 368, 0, 368, 372, 0, 0, 0, 368, 368, 373, - - 0, 368, 0, 372, 372, 372, 372, 372, 372, 373, - 373, 373, 373, 373, 373, 374, 0, 0, 0, 0, - 0, 375, 0, 0, 0, 374, 374, 374, 374, 374, - 374, 375, 375, 375, 375, 375, 375, 387, 0, 0, - 0, 0, 0, 388, 0, 0, 0, 387, 387, 387, - 387, 387, 387, 388, 388, 388, 388, 388, 388, 389, - 0, 0, 0, 0, 0, 397, 0, 0, 0, 389, - 389, 389, 389, 389, 389, 397, 397, 397, 397, 397, - 397, 398, 0, 0, 0, 0, 0, 399, 0, 0, - 0, 398, 398, 398, 398, 398, 398, 399, 399, 399, - - 399, 399, 399, 400, 400, 400, 400, 400, 0, 0, - 409, 0, 0, 0, 0, 0, 0, 0, 0, 400, - 409, 409, 409, 409, 409, 409, 410, 0, 0, 400, - 411, 411, 411, 411, 411, 0, 410, 410, 410, 410, - 410, 410, 0, 0, 0, 0, 411, 413, 0, 0, - 414, 414, 414, 414, 414, 0, 411, 413, 413, 413, - 413, 413, 413, 414, 423, 423, 423, 423, 423, 0, - 427, 427, 427, 427, 427, 0, 414, 423, 0, 0, - 0, 0, 0, 427, 0, 0, 0, 428, 0, 0, - 423, 424, 424, 424, 424, 424, 427, 428, 428, 428, - - 428, 428, 428, 0, 424, 436, 436, 436, 436, 436, - 424, 0, 0, 0, 0, 0, 0, 424, 436, 0, - 424, 424, 424, 424, 424, 424, 437, 0, 0, 0, - 0, 436, 0, 0, 0, 0, 437, 437, 437, 437, - 437, 437, 438, 438, 438, 438, 438, 445, 0, 0, - 446, 446, 446, 446, 446, 438, 0, 445, 445, 445, - 445, 445, 445, 446, 0, 0, 0, 447, 438, 439, - 439, 439, 439, 439, 0, 0, 446, 447, 447, 447, - 447, 447, 447, 0, 0, 0, 0, 0, 439, 0, - 0, 0, 0, 0, 452, 0, 0, 0, 439, 439, - - 439, 439, 439, 439, 452, 452, 452, 452, 452, 452, - 453, 0, 0, 0, 0, 0, 458, 0, 0, 0, - 453, 453, 453, 453, 453, 453, 458, 458, 458, 458, - 458, 458, 459, 0, 0, 0, 0, 0, 464, 0, - 0, 0, 459, 459, 459, 459, 459, 459, 464, 464, - 464, 464, 464, 464, 465, 0, 0, 0, 0, 0, - 469, 0, 0, 0, 465, 465, 465, 465, 465, 465, - 469, 469, 469, 469, 469, 469, 479, 0, 479, 479, - 479, 479, 479, 479, 479, 479, 479, 480, 480, 0, - 480, 480, 481, 0, 481, 481, 481, 481, 481, 481, - - 481, 481, 481, 482, 482, 0, 482, 482, 483, 0, - 0, 483, 483, 484, 484, 484, 484, 484, 484, 484, - 484, 484, 485, 0, 485, 485, 0, 485, 485, 486, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 90, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 64, 52, + 106, 20, 22, 74, 55, 429, 37, 37, 37, 37, + + 37, 57, 64, 57, 22, 243, 487, 22, 487, 52, + 22, 419, 55, 243, 22, 22, 64, 22, 106, 74, + 67, 66, 74, 57, 72, 72, 385, 127, 22, 67, + 37, 127, 66, 22, 55, 66, 22, 52, 71, 22, + 97, 55, 22, 22, 71, 22, 26, 73, 67, 66, + 82, 57, 71, 26, 26, 26, 26, 26, 26, 37, + 66, 72, 108, 109, 73, 80, 71, 76, 73, 82, + 107, 73, 71, 76, 86, 107, 73, 85, 140, 82, + 97, 384, 26, 26, 26, 26, 26, 26, 41, 41, + 41, 41, 73, 118, 41, 76, 73, 80, 84, 85, + + 86, 80, 87, 86, 348, 175, 85, 41, 108, 109, + 96, 140, 84, 93, 41, 41, 41, 41, 41, 41, + 93, 107, 94, 119, 102, 80, 84, 104, 87, 342, + 250, 87, 103, 119, 118, 96, 317, 105, 161, 316, + 41, 102, 315, 41, 41, 41, 41, 41, 41, 44, + 96, 175, 104, 93, 314, 94, 44, 44, 44, 44, + 44, 44, 94, 96, 102, 103, 120, 104, 105, 125, + 102, 250, 103, 275, 119, 131, 120, 105, 161, 134, + 104, 275, 44, 94, 125, 44, 44, 44, 44, 44, + 44, 46, 144, 103, 150, 131, 105, 145, 46, 46, + + 46, 46, 46, 46, 131, 134, 145, 165, 134, 125, + 137, 137, 148, 125, 156, 144, 150, 120, 192, 153, + 226, 144, 148, 150, 226, 145, 154, 46, 46, 46, + 46, 46, 46, 49, 49, 49, 49, 156, 137, 154, + 148, 157, 155, 156, 49, 153, 158, 165, 153, 174, + 190, 192, 49, 155, 154, 157, 168, 170, 164, 49, + 49, 49, 49, 49, 49, 164, 158, 171, 173, 157, + 155, 172, 182, 190, 235, 158, 184, 174, 216, 190, + 249, 499, 182, 499, 284, 49, 194, 217, 49, 49, + 49, 49, 49, 49, 56, 196, 168, 170, 164, 194, + + 184, 56, 56, 56, 56, 56, 56, 171, 173, 172, + 235, 172, 201, 198, 194, 217, 184, 196, 216, 325, + 293, 201, 202, 182, 196, 284, 249, 203, 184, 202, + 56, 56, 56, 56, 56, 56, 77, 172, 198, 203, + 201, 204, 198, 77, 77, 77, 77, 77, 77, 293, + 202, 231, 232, 234, 390, 203, 281, 320, 390, 204, + 325, 234, 205, 492, 492, 231, 254, 509, 232, 509, + 204, 206, 77, 77, 77, 77, 77, 77, 88, 231, + 232, 234, 224, 236, 205, 88, 88, 88, 88, 88, + 88, 205, 236, 206, 254, 214, 214, 214, 214, 214, + + 206, 214, 281, 320, 224, 265, 214, 313, 214, 237, + 306, 236, 332, 238, 88, 88, 88, 88, 88, 88, + 91, 238, 224, 265, 364, 307, 271, 91, 91, 91, + 91, 91, 91, 224, 265, 237, 306, 271, 237, 306, + 332, 238, 247, 247, 247, 247, 247, 214, 247, 267, + 296, 268, 364, 247, 271, 247, 91, 91, 91, 91, + 91, 91, 98, 98, 98, 98, 98, 279, 511, 337, + 511, 267, 268, 340, 98, 269, 303, 305, 267, 312, + 268, 98, 269, 303, 305, 278, 308, 312, 98, 98, + 98, 98, 98, 98, 247, 248, 248, 248, 248, 248, + + 337, 248, 277, 269, 303, 305, 248, 276, 248, 340, + 463, 515, 308, 515, 98, 308, 270, 98, 98, 98, + 98, 98, 98, 110, 110, 110, 110, 110, 337, 110, + 280, 280, 280, 280, 280, 282, 282, 282, 282, 282, + 321, 343, 110, 280, 246, 321, 463, 248, 282, 110, + 110, 110, 110, 110, 110, 286, 286, 286, 286, 286, + 318, 318, 318, 318, 318, 343, 245, 366, 286, 517, + 343, 517, 370, 318, 394, 110, 344, 366, 110, 110, + 110, 110, 110, 110, 111, 111, 111, 111, 244, 394, + 111, 321, 239, 229, 370, 287, 287, 287, 287, 287, + + 344, 370, 394, 111, 383, 344, 366, 286, 287, 228, + 111, 111, 111, 111, 111, 111, 288, 288, 288, 288, + 288, 289, 289, 289, 289, 289, 356, 225, 326, 288, + 383, 356, 213, 383, 289, 392, 111, 392, 326, 111, + 111, 111, 111, 111, 111, 114, 393, 287, 462, 212, + 462, 403, 114, 114, 114, 114, 114, 114, 322, 322, + 322, 322, 322, 392, 322, 357, 199, 193, 288, 393, + 357, 322, 403, 289, 191, 393, 462, 356, 114, 326, + 403, 114, 114, 114, 114, 114, 114, 115, 189, 327, + 327, 327, 327, 327, 115, 115, 115, 115, 115, 115, + + 327, 187, 327, 331, 331, 331, 331, 331, 185, 179, + 322, 333, 333, 333, 333, 333, 357, 333, 167, 331, + 371, 163, 159, 115, 115, 115, 115, 115, 115, 117, + 117, 117, 117, 117, 346, 346, 346, 346, 346, 151, + 149, 327, 371, 336, 336, 336, 336, 336, 117, 371, + 346, 360, 361, 146, 336, 117, 117, 117, 117, 117, + 117, 360, 361, 333, 365, 365, 365, 365, 365, 416, + 345, 345, 345, 345, 345, 367, 367, 367, 367, 367, + 143, 142, 416, 377, 117, 117, 117, 117, 117, 117, + 121, 121, 121, 121, 121, 336, 524, 416, 524, 141, + + 441, 121, 360, 361, 369, 369, 369, 369, 369, 121, + 377, 378, 379, 139, 441, 380, 121, 121, 121, 121, + 121, 121, 345, 355, 355, 355, 355, 355, 441, 355, + 527, 415, 527, 378, 379, 138, 355, 380, 377, 415, + 378, 379, 121, 395, 380, 121, 121, 121, 121, 121, + 121, 122, 122, 122, 122, 381, 369, 136, 395, 415, + 418, 381, 122, 359, 359, 359, 359, 359, 382, 391, + 122, 395, 391, 402, 359, 355, 359, 122, 122, 122, + 122, 122, 122, 381, 135, 401, 418, 133, 407, 418, + 382, 402, 132, 391, 407, 130, 405, 382, 391, 396, + + 401, 391, 402, 122, 128, 396, 122, 122, 122, 122, + 122, 122, 129, 401, 396, 359, 407, 406, 405, 129, + 129, 129, 129, 129, 129, 405, 537, 396, 537, 544, + 545, 544, 545, 396, 399, 399, 399, 399, 399, 406, + 126, 404, 408, 116, 113, 95, 406, 399, 129, 129, + 129, 129, 129, 129, 147, 147, 147, 147, 147, 404, + 408, 92, 81, 79, 410, 410, 410, 410, 410, 417, + 404, 408, 75, 147, 63, 410, 420, 61, 417, 421, + 147, 147, 147, 147, 147, 147, 399, 400, 400, 400, + 400, 400, 409, 409, 409, 409, 409, 417, 409, 60, + + 420, 421, 59, 400, 58, 420, 147, 51, 421, 147, + 147, 147, 147, 147, 147, 152, 410, 411, 411, 411, + 411, 411, 152, 152, 152, 152, 152, 152, 413, 413, + 413, 413, 413, 411, 45, 29, 28, 422, 27, 400, + 21, 413, 430, 19, 409, 435, 412, 412, 412, 412, + 412, 152, 152, 152, 152, 152, 152, 160, 160, 160, + 160, 160, 412, 422, 430, 18, 422, 432, 431, 411, + 435, 430, 433, 16, 435, 442, 160, 432, 468, 433, + 413, 442, 448, 160, 160, 160, 160, 160, 160, 423, + 423, 423, 423, 423, 431, 432, 443, 431, 412, 14, + + 433, 468, 423, 442, 448, 449, 7, 468, 443, 160, + 444, 448, 160, 160, 160, 160, 160, 160, 162, 162, + 162, 162, 162, 0, 443, 444, 0, 449, 425, 425, + 425, 425, 425, 450, 449, 0, 454, 162, 444, 0, + 451, 425, 450, 0, 162, 162, 162, 162, 162, 162, + 427, 427, 427, 427, 427, 436, 436, 436, 436, 436, + 0, 450, 451, 427, 454, 466, 0, 0, 436, 451, + 0, 466, 454, 162, 162, 162, 162, 162, 162, 169, + 425, 438, 438, 438, 438, 438, 169, 169, 169, 169, + 169, 169, 454, 466, 438, 0, 0, 0, 457, 0, + + 455, 460, 427, 476, 0, 0, 457, 436, 471, 455, + 460, 476, 472, 0, 473, 169, 169, 169, 169, 169, + 169, 176, 176, 176, 176, 176, 457, 176, 455, 460, + 471, 476, 0, 438, 472, 0, 0, 471, 473, 0, + 176, 472, 0, 473, 0, 0, 0, 176, 176, 176, + 176, 176, 176, 445, 445, 445, 445, 445, 465, 465, + 465, 465, 465, 0, 0, 0, 445, 0, 0, 0, + 0, 465, 0, 176, 0, 0, 176, 176, 176, 176, + 176, 176, 178, 469, 469, 469, 469, 469, 470, 178, + 178, 178, 178, 178, 178, 0, 469, 0, 0, 0, + + 0, 0, 475, 470, 0, 445, 0, 0, 0, 0, + 465, 0, 0, 0, 0, 0, 470, 475, 178, 178, + 178, 178, 178, 178, 180, 180, 180, 180, 180, 0, + 475, 0, 0, 0, 0, 469, 0, 0, 0, 0, + 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, + 180, 180, 180, 180, 180, 180, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, + 180, 180, 180, 180, 180, 181, 181, 181, 181, 181, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 181, 0, 0, 0, 0, 0, + 0, 181, 181, 181, 181, 181, 181, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 181, 181, 181, 181, 181, 181, 183, 183, 183, 183, + 183, 0, 0, 0, 0, 0, 0, 183, 0, 0, + 0, 0, 0, 0, 0, 183, 0, 0, 0, 0, + 0, 0, 183, 183, 183, 183, 183, 183, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 183, 0, + + 0, 183, 183, 183, 183, 183, 183, 188, 188, 188, + 188, 188, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 188, 0, 0, 0, + 0, 0, 0, 188, 188, 188, 188, 188, 188, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 188, 188, 188, 188, 188, 188, 195, 0, + 0, 0, 0, 0, 0, 195, 195, 195, 195, 195, + 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 195, 195, 195, 195, 195, 195, + 200, 200, 200, 200, 200, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, + 0, 0, 0, 0, 0, 0, 200, 200, 200, 200, + 200, 200, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 200, 200, 200, 200, 200, + 200, 207, 0, 0, 0, 0, 0, 0, 207, 207, + 207, 207, 207, 207, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 207, 207, 207, + 207, 207, 207, 208, 208, 208, 208, 208, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 208, 0, 0, 0, 0, 0, 0, 208, + 208, 208, 208, 208, 208, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 208, 208, + 208, 208, 208, 208, 215, 0, 0, 0, 0, 0, + 0, 215, 215, 215, 215, 215, 215, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 215, 215, 215, 215, 215, 215, 218, 218, 218, 218, + 218, 0, 218, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 218, 0, 0, 0, 0, + 0, 0, 218, 218, 218, 218, 218, 218, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 218, 0, + 0, 218, 218, 218, 218, 218, 218, 220, 0, 0, + 0, 0, 0, 0, 220, 220, 220, 220, 220, 220, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 220, 220, 220, 220, 220, 220, 221, + 221, 221, 221, 221, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 221, 0, + 0, 0, 0, 0, 0, 221, 221, 221, 221, 221, + 221, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 221, 221, 221, 221, 221, 221, + 222, 222, 222, 222, 222, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 222, + + 0, 0, 0, 0, 0, 0, 222, 222, 222, 222, + 222, 222, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 222, 222, 222, 222, 222, + 222, 223, 223, 223, 223, 223, 0, 0, 0, 0, + 0, 0, 223, 0, 0, 0, 0, 0, 0, 0, + 223, 0, 0, 0, 0, 0, 0, 223, 223, 223, + 223, 223, 223, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 223, 0, 0, 223, 223, 223, 223, + + 223, 223, 227, 227, 227, 227, 227, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 227, 0, 0, 0, 0, 0, 0, 227, 227, + 227, 227, 227, 227, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 227, 227, 227, + 227, 227, 227, 230, 0, 0, 0, 0, 0, 0, + 230, 230, 230, 230, 230, 230, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, + + 230, 230, 230, 230, 230, 233, 233, 233, 233, 233, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, + 0, 233, 233, 233, 233, 233, 233, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 233, 233, 233, 233, 233, 233, 240, 0, 0, 0, + 0, 0, 0, 240, 240, 240, 240, 240, 240, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 240, 240, 240, 240, 240, 240, 241, 241, + 241, 241, 241, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 241, 0, 0, + 0, 0, 0, 0, 241, 241, 241, 241, 241, 241, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 241, 241, 241, 241, 241, 241, 252, + 252, 252, 252, 252, 0, 252, 0, 0, 0, 0, + 252, 252, 252, 0, 0, 0, 0, 0, 252, 0, + 0, 0, 0, 0, 0, 252, 252, 252, 252, 252, + + 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 252, 0, 0, 252, 252, 252, 252, 252, 252, + 253, 0, 0, 0, 0, 0, 0, 253, 253, 253, + 253, 253, 253, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 253, 253, 253, 253, + 253, 253, 255, 255, 255, 255, 255, 0, 255, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 255, 0, 0, 0, 0, 0, 0, 255, 255, + + 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 255, 0, 0, 255, 255, 255, + 255, 255, 255, 257, 0, 0, 0, 0, 0, 0, + 257, 257, 257, 257, 257, 257, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 257, 0, 0, 257, + 257, 257, 257, 257, 257, 258, 258, 258, 258, 258, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 258, 0, 0, 0, 0, 0, + + 0, 258, 258, 258, 258, 258, 258, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 258, 0, 0, + 258, 258, 258, 258, 258, 258, 259, 259, 259, 259, + 259, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, + 0, 0, 259, 259, 259, 259, 259, 259, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 259, 259, 259, 259, 259, 259, 260, 260, 260, + + 260, 260, 0, 0, 0, 0, 0, 0, 260, 0, + 0, 0, 0, 0, 0, 0, 260, 0, 0, 0, + 0, 0, 0, 260, 260, 260, 260, 260, 260, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 260, + 0, 0, 260, 260, 260, 260, 260, 260, 261, 261, + 261, 261, 261, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 261, 0, 0, + 0, 0, 0, 0, 261, 261, 261, 261, 261, 261, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 261, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 261, 261, 261, 261, 261, 261, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 261, 262, 262, 262, 262, 262, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 262, 0, 0, 0, 0, 0, 0, 262, 262, + 262, 262, 262, 262, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 262, 262, 262, + 262, 262, 262, 263, 0, 0, 0, 0, 0, 0, + + 263, 263, 263, 263, 263, 263, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 263, + 263, 263, 263, 263, 263, 264, 264, 264, 264, 264, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 264, 0, 0, 0, 0, 0, + 0, 264, 264, 264, 264, 264, 264, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 264, 264, 264, 264, 264, 264, 266, 266, 266, 266, + + 266, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 266, 0, 0, 0, 0, + 0, 0, 266, 266, 266, 266, 266, 266, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 266, 266, 266, 266, 266, 266, 272, 0, 0, + 0, 0, 0, 0, 272, 272, 272, 272, 272, 272, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 272, 272, 272, 272, 272, 272, 273, + + 273, 273, 273, 273, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 273, 0, + 0, 0, 0, 0, 0, 273, 273, 273, 273, 273, + 273, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 273, 273, 273, 273, 273, 273, + 283, 283, 283, 283, 0, 0, 283, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 283, + 0, 0, 0, 0, 0, 0, 283, 283, 283, 283, + 283, 283, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 283, 0, 0, 283, 283, 283, 283, 283, + 283, 285, 285, 285, 285, 0, 0, 0, 0, 0, + 0, 0, 285, 0, 0, 0, 0, 0, 0, 0, + 285, 0, 0, 0, 0, 0, 0, 285, 285, 285, + 285, 285, 285, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 285, 0, 0, 285, 285, 285, 285, + 285, 285, 290, 290, 290, 290, 290, 0, 0, 0, + 0, 0, 0, 0, 0, 290, 0, 0, 0, 0, + + 0, 290, 0, 0, 0, 0, 0, 0, 290, 290, + 290, 290, 290, 290, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 290, 0, 0, 290, 290, 290, + 290, 290, 290, 291, 291, 291, 291, 291, 0, 291, + 0, 0, 0, 0, 291, 291, 291, 0, 0, 0, + 0, 0, 291, 0, 0, 0, 0, 0, 0, 291, + 291, 291, 291, 291, 291, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 291, 0, 0, 291, 291, + + 291, 291, 291, 291, 292, 0, 0, 0, 0, 0, + 0, 292, 292, 292, 292, 292, 292, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 292, 292, 292, 292, 292, 292, 294, 294, 294, 294, + 294, 0, 294, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 294, 0, 0, 0, 0, + 0, 0, 294, 294, 294, 294, 294, 294, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 294, 0, + + 0, 294, 294, 294, 294, 294, 294, 297, 297, 297, + 297, 297, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 297, 0, 0, 0, + 0, 0, 0, 297, 297, 297, 297, 297, 297, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 297, + 0, 0, 297, 297, 297, 297, 297, 297, 298, 298, + 298, 298, 298, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 298, 0, 0, + 0, 0, 0, 0, 298, 298, 298, 298, 298, 298, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 298, 298, 298, 298, 298, 298, 299, + 299, 299, 299, 299, 0, 0, 0, 0, 0, 0, + 299, 0, 0, 0, 0, 0, 0, 0, 299, 0, + 0, 0, 0, 0, 0, 299, 299, 299, 299, 299, + 299, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 299, 0, 0, 299, 299, 299, 299, 299, 299, + 300, 300, 300, 300, 300, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 300, 0, 0, 300, + 0, 0, 0, 0, 0, 0, 300, 300, 300, 300, + 300, 300, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 300, 300, 300, 300, 300, + 300, 301, 301, 301, 301, 301, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 301, 0, 0, 0, 0, 0, 0, 301, 301, 301, + 301, 301, 301, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 301, 301, 301, 301, + 301, 301, 302, 302, 302, 302, 302, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 302, 0, 0, 0, 0, 0, 0, 302, 302, + 302, 302, 302, 302, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 302, 302, 302, + 302, 302, 302, 304, 304, 304, 304, 304, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 304, 0, 0, 0, 0, 0, 0, 304, + + 304, 304, 304, 304, 304, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 304, 304, + 304, 304, 304, 304, 309, 0, 0, 0, 0, 0, + 0, 309, 309, 309, 309, 309, 309, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 309, 309, 309, 309, 309, 309, 310, 310, 310, 310, + 310, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 310, 0, 0, 0, 0, + + 0, 0, 310, 310, 310, 310, 310, 310, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 310, 310, 310, 310, 310, 310, 323, 323, 323, + 323, 323, 0, 323, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 323, 0, 0, 0, + 0, 0, 0, 323, 323, 323, 323, 323, 323, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 323, + 0, 0, 323, 323, 323, 323, 323, 323, 324, 324, + + 324, 324, 0, 0, 324, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 324, 0, 0, + 0, 0, 0, 0, 324, 324, 324, 324, 324, 324, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 324, 0, 0, 324, 324, 324, 324, 324, 324, 328, + 328, 328, 328, 328, 0, 0, 0, 0, 0, 0, + 328, 0, 0, 0, 0, 0, 0, 0, 328, 0, + 0, 0, 0, 0, 0, 328, 328, 328, 328, 328, + 328, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 328, 0, 0, 328, 328, 328, 328, 328, 328, + 329, 329, 329, 329, 0, 0, 0, 0, 0, 0, + 0, 329, 0, 0, 0, 0, 0, 0, 0, 329, + 0, 0, 0, 0, 0, 0, 329, 329, 329, 329, + 329, 329, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 329, 0, 0, 329, 329, 329, 329, 329, + 329, 330, 330, 330, 330, 330, 0, 0, 0, 0, + 0, 0, 0, 0, 330, 0, 0, 0, 0, 0, + + 330, 0, 0, 0, 0, 0, 0, 330, 330, 330, + 330, 330, 330, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 330, 0, 0, 330, 330, 330, 330, + 330, 330, 334, 0, 0, 0, 0, 0, 0, 334, + 334, 334, 334, 334, 334, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 334, 334, + 334, 334, 334, 334, 335, 0, 0, 0, 0, 0, + 0, 335, 335, 335, 335, 335, 335, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 335, 335, 335, 335, 335, 335, 338, 0, 0, 0, + 0, 0, 0, 338, 338, 338, 338, 338, 338, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 338, 338, 338, 338, 338, 338, 339, 339, + 339, 339, 339, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 339, 0, 0, + 0, 0, 0, 0, 339, 339, 339, 339, 339, 339, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 339, 339, 339, 339, 339, 339, 341, + 341, 341, 341, 341, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 341, 0, + 0, 0, 0, 0, 0, 341, 341, 341, 341, 341, + 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 341, 341, 341, 341, 341, 341, + 358, 0, 0, 0, 0, 0, 0, 358, 358, 358, + + 358, 358, 358, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 358, 358, 358, 358, + 358, 358, 362, 0, 0, 0, 0, 0, 0, 362, + 362, 362, 362, 362, 362, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 362, 362, + 362, 362, 362, 362, 363, 363, 363, 363, 363, 0, + 0, 0, 0, 0, 0, 0, 0, 363, 0, 0, + 0, 0, 0, 363, 0, 0, 0, 0, 0, 0, + + 363, 363, 363, 363, 363, 363, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 363, 0, 0, 363, + 363, 363, 363, 363, 363, 368, 0, 0, 0, 0, + 0, 0, 368, 0, 368, 0, 0, 0, 0, 368, + 368, 0, 0, 368, 0, 0, 0, 0, 368, 0, + 0, 0, 0, 0, 368, 0, 0, 0, 0, 0, + 368, 0, 368, 0, 0, 0, 0, 368, 368, 0, + 0, 368, 373, 0, 0, 0, 0, 0, 0, 373, + 373, 373, 373, 373, 373, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 373, 373, + 373, 373, 373, 373, 374, 0, 0, 0, 0, 0, + 0, 374, 374, 374, 374, 374, 374, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 374, 374, 374, 374, 374, 374, 375, 0, 0, 0, + 0, 0, 0, 375, 375, 375, 375, 375, 375, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 375, 375, 375, 375, 375, 375, 387, 0, + 0, 0, 0, 0, 0, 387, 387, 387, 387, 387, + 387, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 387, 387, 387, 387, 387, 387, + 388, 0, 0, 0, 0, 0, 0, 388, 388, 388, + 388, 388, 388, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 388, 388, 388, 388, + 388, 388, 389, 0, 0, 0, 0, 0, 0, 389, + + 389, 389, 389, 389, 389, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 389, 389, + 389, 389, 389, 389, 397, 0, 0, 0, 0, 0, + 0, 397, 397, 397, 397, 397, 397, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 397, 397, 397, 397, 397, 397, 398, 0, 0, 0, + 0, 0, 0, 398, 398, 398, 398, 398, 398, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 398, 398, 398, 398, 398, 398, 414, 0, + 0, 0, 0, 0, 0, 414, 414, 414, 414, 414, + 414, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 414, 414, 414, 414, 414, 414, + 426, 0, 0, 0, 0, 0, 0, 426, 426, 426, + 426, 426, 426, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 426, 426, 426, 426, + + 426, 426, 428, 428, 428, 428, 428, 0, 0, 0, + 0, 0, 0, 0, 0, 428, 0, 0, 0, 0, + 0, 428, 0, 0, 0, 0, 0, 0, 428, 428, + 428, 428, 428, 428, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 428, 0, 0, 428, 428, 428, + 428, 428, 428, 437, 437, 437, 437, 437, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 437, 0, 0, 0, 0, 0, 0, 437, + 437, 437, 437, 437, 437, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 437, 437, + 437, 437, 437, 437, 439, 0, 0, 0, 0, 0, + 0, 439, 439, 439, 439, 439, 439, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 439, 439, 439, 439, 439, 439, 446, 0, 0, 0, + 0, 0, 0, 446, 446, 446, 446, 446, 446, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 446, 446, 446, 446, 446, 446, 447, 0, + 0, 0, 0, 0, 0, 447, 447, 447, 447, 447, + 447, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 447, 447, 447, 447, 447, 447, + 452, 0, 0, 0, 0, 0, 0, 452, 452, 452, + 452, 452, 452, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 452, 452, 452, 452, + 452, 452, 453, 0, 0, 0, 0, 0, 0, 453, + + 453, 453, 453, 453, 453, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 453, 453, + 453, 453, 453, 453, 458, 0, 0, 0, 0, 0, + 0, 458, 458, 458, 458, 458, 458, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 458, 458, 458, 458, 458, 458, 459, 0, 0, 0, + 0, 0, 0, 459, 459, 459, 459, 459, 459, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 459, 459, 459, 459, 459, 459, 464, 0, + 0, 0, 0, 0, 0, 464, 464, 464, 464, 464, + 464, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 464, 464, 464, 464, 464, 464, + 479, 0, 0, 479, 479, 479, 479, 479, 479, 479, + 479, 479, 479, 480, 480, 0, 480, 480, 481, 0, + 0, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 482, 482, 0, 482, 482, 483, 0, 0, 483, + + 483, 484, 0, 484, 484, 0, 484, 484, 485, 485, + 485, 485, 485, 485, 485, 485, 485, 485, 486, 486, 486, 486, 486, 486, 486, 486, 486, 486, 486, 486, - 487, 487, 487, 487, 487, 487, 487, 487, 487, 488, - 488, 0, 488, 488, 489, 489, 489, 489, 489, 489, - 489, 489, 489, 489, 489, 490, 490, 490, 490, 490, - 490, 490, 490, 490, 490, 490, 490, 491, 491, 492, - 492, 492, 492, 492, 492, 492, 492, 492, 493, 493, - 0, 493, 493, 494, 494, 494, 494, 494, 494, 494, - - 494, 494, 495, 495, 0, 495, 495, 496, 496, 496, - 496, 496, 496, 496, 496, 496, 497, 497, 497, 497, - 497, 497, 497, 497, 497, 498, 498, 498, 498, 498, - 498, 498, 498, 498, 498, 498, 498, 499, 499, 499, - 499, 499, 499, 499, 499, 499, 500, 500, 500, 500, - 500, 500, 500, 500, 500, 501, 501, 501, 0, 501, + 486, 488, 488, 0, 488, 488, 489, 489, 489, 489, + 489, 489, 489, 489, 489, 489, 490, 490, 490, 490, + 490, 490, 490, 490, 490, 490, 490, 490, 490, 491, + 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, + 491, 491, 491, 493, 493, 0, 493, 493, 494, 494, + 494, 494, 494, 494, 494, 494, 494, 494, 495, 495, + 0, 495, 495, 496, 496, 496, 496, 496, 496, 496, + + 496, 496, 496, 497, 497, 497, 497, 497, 497, 497, + 497, 497, 497, 498, 498, 498, 500, 500, 500, 500, + 500, 500, 500, 500, 500, 500, 501, 501, 0, 501, + 501, 501, 501, 501, 501, 501, 501, 501, 501, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, - 502, 502, 503, 503, 503, 0, 503, 504, 504, 504, - 504, 0, 504, 504, 504, 504, 504, 504, 505, 505, - 505, 0, 505, 506, 0, 506, 506, 506, 506, 506, - - 506, 506, 506, 506, 507, 0, 507, 507, 507, 507, - 507, 507, 507, 507, 507, 508, 508, 508, 508, 508, - 508, 508, 508, 508, 508, 508, 509, 509, 509, 0, - 509, 510, 510, 510, 510, 510, 510, 510, 510, 510, - 510, 510, 511, 511, 511, 511, 511, 511, 511, 511, - 511, 511, 511, 512, 512, 512, 0, 512, 513, 513, - 513, 0, 0, 0, 513, 0, 0, 513, 513, 514, - 514, 514, 514, 514, 514, 514, 514, 514, 515, 515, - 515, 0, 0, 515, 515, 515, 0, 515, 515, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 478, 478, + 502, 502, 503, 503, 503, 503, 503, 503, 503, 503, + 503, 503, 503, 503, 503, 503, 504, 504, 504, 504, + 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, + 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, + 506, 506, 506, 506, 506, 506, 506, 506, 506, 506, + + 507, 507, 507, 507, 508, 0, 0, 508, 508, 508, + 508, 508, 508, 508, 508, 508, 508, 510, 510, 510, + 510, 510, 510, 510, 510, 510, 510, 510, 510, 510, + 510, 512, 512, 512, 512, 513, 513, 513, 513, 513, + 513, 0, 513, 513, 513, 513, 513, 513, 514, 514, + 514, 514, 514, 514, 514, 514, 514, 514, 514, 514, + 514, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 518, 518, 518, 518, 519, + 519, 519, 519, 519, 519, 0, 519, 519, 519, 519, + 519, 519, 520, 0, 0, 520, 520, 520, 520, 520, + + 520, 520, 520, 520, 520, 521, 0, 0, 521, 521, + 521, 521, 521, 521, 521, 521, 521, 521, 522, 522, + 522, 522, 522, 522, 522, 522, 522, 522, 522, 522, + 522, 523, 523, 523, 523, 523, 523, 523, 523, 523, + 523, 523, 523, 523, 525, 525, 0, 525, 525, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 528, 528, 528, 528, 529, 529, 529, 529, + 529, 529, 529, 529, 529, 529, 529, 529, 529, 530, + 0, 0, 530, 530, 530, 530, 530, 530, 530, 530, + 530, 530, 531, 531, 531, 531, 531, 531, 531, 531, + + 531, 531, 531, 531, 531, 532, 532, 532, 532, 532, + 0, 0, 532, 532, 532, 532, 532, 532, 533, 533, + 533, 533, 533, 533, 533, 533, 533, 533, 533, 533, + 533, 534, 534, 534, 534, 534, 534, 534, 534, 534, + 534, 534, 534, 534, 535, 535, 0, 535, 535, 536, + 536, 536, 536, 536, 536, 536, 536, 536, 536, 536, + 536, 536, 538, 538, 538, 538, 539, 539, 0, 539, + 539, 539, 539, 539, 539, 539, 539, 539, 539, 540, + 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 541, 541, 0, 541, 541, 541, 541, 541, + + 541, 541, 541, 541, 541, 542, 542, 542, 542, 542, + 542, 542, 542, 542, 542, 542, 542, 542, 543, 543, + 543, 543, 543, 0, 0, 543, 543, 543, 543, 543, + 543, 546, 546, 546, 546, 0, 0, 0, 0, 546, + 0, 0, 546, 546, 547, 547, 547, 547, 0, 0, + 0, 547, 547, 547, 0, 547, 547, 548, 548, 548, + 548, 548, 548, 548, 548, 548, 548, 549, 549, 549, + 549, 549, 549, 549, 549, 549, 549, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478 + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478 } ; #line 1 "" @@ -878,7 +1813,7 @@ YY_DECL yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 2399 ); + while ( yy_base[yy_current_state] != 6578 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -1250,7 +2185,7 @@ YY_RULE_SETUP #line 110 "" ECHO; YY_BREAK -#line 1761 "" +#line 2738 "" case YY_STATE_EOF(INITIAL): case YY_END_OF_BUFFER: case YY_STATE_EOF(mediaquery): diff --git a/src/3rdparty/webkit/WebCore/page/DOMWindow.cpp b/src/3rdparty/webkit/WebCore/page/DOMWindow.cpp index 42d2e90..dd14fb9 100644 --- a/src/3rdparty/webkit/WebCore/page/DOMWindow.cpp +++ b/src/3rdparty/webkit/WebCore/page/DOMWindow.cpp @@ -333,6 +333,9 @@ Storage* DOMWindow::sessionStorage() const Storage* DOMWindow::localStorage() const { + if (m_localStorage) + return m_localStorage.get(); + Document* document = this->document(); if (!document) return 0; diff --git a/src/3rdparty/webkit/WebCore/page/DOMWindow.h b/src/3rdparty/webkit/WebCore/page/DOMWindow.h index 0277441..e7fab18 100644 --- a/src/3rdparty/webkit/WebCore/page/DOMWindow.h +++ b/src/3rdparty/webkit/WebCore/page/DOMWindow.h @@ -265,7 +265,7 @@ namespace WebCore { Location* optionalLocation() const { return m_location.get(); } #if ENABLE(DOM_STORAGE) Storage* optionalSessionStorage() const { return m_sessionStorage.get(); } - Storage* optionalLocalStorage() const { return m_sessionStorage.get(); } + Storage* optionalLocalStorage() const { return m_localStorage.get(); } #endif #if ENABLE(OFFLINE_WEB_APPLICATIONS) DOMApplicationCache* optionalApplicationCache() const { return m_applicationCache.get(); } diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageBufferQt.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageBufferQt.cpp index d4ab59f..cea255e 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageBufferQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageBufferQt.cpp @@ -35,6 +35,8 @@ #include "StillImageQt.h" #include +#include +#include #include #include #include @@ -79,10 +81,57 @@ Image* ImageBuffer::image() const return m_image.get(); } -PassRefPtr ImageBuffer::getImageData(const IntRect&) const +PassRefPtr ImageBuffer::getImageData(const IntRect& rect) const { - notImplemented(); - return 0; + PassRefPtr result = ImageData::create(rect.width(), rect.height()); + unsigned char* data = result->data()->data(); + + if (rect.x() < 0 || rect.y() < 0 || (rect.x() + rect.width()) > m_size.width() || (rect.y() + rect.height()) > m_size.height()) + memset(data, 0, result->data()->length()); + + int originx = rect.x(); + int destx = 0; + if (originx < 0) { + destx = -originx; + originx = 0; + } + int endx = rect.x() + rect.width(); + if (endx > m_size.width()) + endx = m_size.width(); + int numColumns = endx - originx; + + int originy = rect.y(); + int desty = 0; + if (originy < 0) { + desty = -originy; + originy = 0; + } + int endy = rect.y() + rect.height(); + if (endy > m_size.height()) + endy = m_size.height(); + int numRows = endy - originy; + + QImage image = m_data.m_pixmap.toImage(); + if (image.format() != QImage::Format_ARGB32) + image = image.convertToFormat(QImage::Format_ARGB32); + ASSERT(image); + + unsigned destBytesPerRow = 4 * rect.width(); + unsigned char* destRows = data + desty * destBytesPerRow + destx * 4; + for (int y = 0; y < numRows; ++y) { + for (int x = 0; x < numColumns; x++) { + QRgb value = image.pixel(x + originx, y + originy); + int basex = x * 4; + + destRows[basex] = qRed(value); + destRows[basex + 1] = qGreen(value); + destRows[basex + 2] = qBlue(value); + destRows[basex + 3] = qAlpha(value); + } + destRows += destBytesPerRow; + } + + return result; } void ImageBuffer::putImageData(ImageData*, const IntRect&, const IntPoint&) diff --git a/src/3rdparty/webkit/WebCore/platform/network/qt/ResourceRequestQt.cpp b/src/3rdparty/webkit/WebCore/platform/network/qt/ResourceRequestQt.cpp index 9308878..c8f6ad5 100644 --- a/src/3rdparty/webkit/WebCore/platform/network/qt/ResourceRequestQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/network/qt/ResourceRequestQt.cpp @@ -41,6 +41,22 @@ QNetworkRequest ResourceRequest::toNetworkRequest() const request.setRawHeader(name, value); } + switch (cachePolicy()) { + case ReloadIgnoringCacheData: + request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork); + break; + case ReturnCacheDataElseLoad: + request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); + break; + case ReturnCacheDataDontLoad: + request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysCache); + break; + case UseProtocolCachePolicy: + // QNetworkRequest::PreferNetwork + default: + break; + } + return request; } diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp index d85e880..fe74fac 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp @@ -106,6 +106,8 @@ private slots: void textSelection(); void textEditing(); + void requestCache(); + private: @@ -989,6 +991,32 @@ void tst_QWebPage::textEditing() delete page; } +void tst_QWebPage::requestCache() +{ + TestPage page; + QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool))); + + page.mainFrame()->setUrl(QString("data:text/html,Click me")); + QTRY_COMPARE(loadSpy.count(), 1); + QTRY_COMPARE(page.navigations.count(), 1); + + page.mainFrame()->setUrl(QString("data:text/html,Click me2")); + QTRY_COMPARE(loadSpy.count(), 2); + QTRY_COMPARE(page.navigations.count(), 2); + + page.triggerAction(QWebPage::Stop); + QVERIFY(page.history()->canGoBack()); + page.triggerAction(QWebPage::Back); + + QTRY_COMPARE(loadSpy.count(), 3); + QTRY_COMPARE(page.navigations.count(), 3); + QCOMPARE(page.navigations.at(0).request.attribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork).toInt(), + (int)QNetworkRequest::PreferNetwork); + QCOMPARE(page.navigations.at(1).request.attribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork).toInt(), + (int)QNetworkRequest::PreferNetwork); + QCOMPARE(page.navigations.at(2).request.attribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork).toInt(), + (int)QNetworkRequest::PreferCache); +} QTEST_MAIN(tst_QWebPage) #include "tst_qwebpage.moc" -- cgit v0.12 From a55f477b2a40b89e690fe6b61509cf665e96243b Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Wed, 15 Apr 2009 12:08:35 +0200 Subject: BT: Fix a crash on certain theme changes in GNOME We did not update initGtkWidgets on theme changes which could lead to crashes as the contents of the widget hash depend on certain properties in the style. A simple way to reproduce this would be to change between the redmond gtk theme and cleanlooks. Task-number: 251115 Reviewed-by: paul --- src/gui/styles/gtksymbols.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/styles/gtksymbols.cpp b/src/gui/styles/gtksymbols.cpp index f7af8f8..acb8437 100644 --- a/src/gui/styles/gtksymbols.cpp +++ b/src/gui/styles/gtksymbols.cpp @@ -549,6 +549,7 @@ void QGtkStyleUpdateScheduler::updateTheme() QPalette newPalette = qApp->style()->standardPalette(); QApplicationPrivate::setSystemPalette(newPalette); QApplication::setPalette(newPalette); + QGtk::initGtkWidgets(); QGtk::applyCustomPaletteHash(); QList widgets = QApplication::allWidgets(); // Notify all widgets that size metrics might have changed -- cgit v0.12 From b4234ab3f4dbd8c7017d749888b2d8effd3c5983 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Wed, 15 Apr 2009 12:11:39 +0200 Subject: BT: Fix Cocoa bug w/OpenGL widgets in dock widgets would disappear. The NSOpenGLContext seems to be tied to the window. So if the view changes from one window to another, the OpenGL context needs to be cleared. We can do this by hooking into the viewWillChangeWindow and viewDidChangeWindow events and clear and reset the drawable respectively. We also found out that QCocoaOpenGLView was not being used at all, so just remove it to get rid of any confusion. Task-number: 250066 Reviewed-by: Trond --- src/corelib/kernel/qcoreevent.h | 1 + src/gui/kernel/qcocoaview_mac.mm | 21 +++++++++++++++++++++ src/opengl/qgl.cpp | 4 ++++ src/opengl/qgl_mac.mm | 28 +++++----------------------- src/opengl/qgl_p.h | 1 + 5 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h index 5487703..fa472e6 100644 --- a/src/corelib/kernel/qcoreevent.h +++ b/src/corelib/kernel/qcoreevent.h @@ -264,6 +264,7 @@ public: GrabKeyboard = 188, UngrabKeyboard = 189, CocoaRequestModal = 190, // Internal for requesting an application modal Cocoa Window + MacGLClearDrawable = 191, // Internal Cocoa, the window has changed, so we must clear // 512 reserved for Qt Jambi's MetaCall event // 513 reserved for Qt Jambi's DeleteOnMainThread event diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index bcbd1bf..7668d66 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -944,6 +944,27 @@ extern "C" { } } +- (void)viewWillMoveToWindow:(NSWindow *)window +{ + if (qwidget->windowFlags() & Qt::MSWindowsOwnDC + && (window != [self window])) { // OpenGL Widget + // Create a stupid ClearDrawable Event + QEvent event(QEvent::MacGLClearDrawable); + qApp->sendEvent(qwidget, &event); + } +} + +- (void)viewDidMoveToWindow +{ + if (qwidget->windowFlags() & Qt::MSWindowsOwnDC && [self window]) { + // call update paint event + qwidgetprivate->needWindowChange = true; + QEvent event(QEvent::MacGLWindowChange); + qApp->sendEvent(qwidget, &event); + } +} + + // NSTextInput Protocol implementation - (void) insertText:(id)aString diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 6d75d02..b4a0e5c 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -3234,6 +3234,10 @@ bool QGLWidget::event(QEvent *e) update(); } return true; +# if defined(QT_MAC_USE_COCOA) + } else if (e->type() == QEvent::MacGLClearDrawable) { + d->glcx->d_ptr->clearDrawable(); +# endif } #endif diff --git a/src/opengl/qgl_mac.mm b/src/opengl/qgl_mac.mm index 314c659..3dbdaec 100644 --- a/src/opengl/qgl_mac.mm +++ b/src/opengl/qgl_mac.mm @@ -87,29 +87,6 @@ QT_FORWARD_DECLARE_CLASS(QWidget) QT_FORWARD_DECLARE_CLASS(QWidgetPrivate) QT_FORWARD_DECLARE_CLASS(QGLWidgetPrivate) -@interface QT_MANGLE_NAMESPACE(QCocoaOpenGLView) : QT_MANGLE_NAMESPACE(QCocoaView) -{ -} -- (id)initWithQWidget:(QWidget *)widget widgetPrivate:(QWidgetPrivate *)widgetprivate; -@end - -@implementation QT_MANGLE_NAMESPACE(QCocoaOpenGLView) -- (id)initWithQWidget:(QWidget *)widget widgetPrivate:(QWidgetPrivate *)widgetprivate -{ - self = [super initWithQWidget:widget widgetPrivate:widgetprivate]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(_surfaceNeedsUpdate:) - name:NSViewGlobalFrameDidChangeNotification - object:self]; - return self; -} - -- (void) _surfaceNeedsUpdate:(NSNotification*)notification -{ - Q_UNUSED(notification); - static_cast(qwidgetprivate)->glcx->updatePaintDevice(); -} -@end QT_BEGIN_NAMESPACE void *qt_current_nsopengl_context() @@ -435,6 +412,11 @@ void *QGLContextPrivate::tryFormat(const QGLFormat &format) #endif } +void QGLContextPrivate::clearDrawable() +{ + [static_cast(cx) clearDrawable]; +} + /*! \bold{Mac OS X only:} This virtual function tries to find a visual that matches the format, reducing the demands if the original request diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index b8bbeaf..16aaa96 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -234,6 +234,7 @@ public: #if defined(Q_WS_MAC) bool update; void *tryFormat(const QGLFormat &format); + void clearDrawable(); #endif QGLFormat glFormat; QGLFormat reqFormat; -- cgit v0.12 From e0706ca2fbce063c263bad9a1eee24f057f170bd Mon Sep 17 00:00:00 2001 From: Morten Engvoldsen Date: Wed, 15 Apr 2009 12:27:05 +0200 Subject: Added remark about XML input Stated a remark about the need to use well-formed XML as input to the example. Rev-by: Geir Vattekar --- doc/src/examples/qxmlstreambookmarks.qdoc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/doc/src/examples/qxmlstreambookmarks.qdoc b/doc/src/examples/qxmlstreambookmarks.qdoc index 7059043..47d5654 100644 --- a/doc/src/examples/qxmlstreambookmarks.qdoc +++ b/doc/src/examples/qxmlstreambookmarks.qdoc @@ -103,8 +103,11 @@ The \c read() function accepts a QIODevice and sets it using \l{QXmlStreamReader::setDevice()}{setDevice()}. The actual process - of reading only takes place in event the file is a valid XBEL 1.0 - file. Otherwise, the \l{QXmlStreamReader::raiseError()} + of reading only takes place if the file is a valid XBEL 1.0 file. + Note that the XML input needs to be well-formed to be accepted by + QXmlStreamReader. + + Otherwise, the \l{QXmlStreamReader::raiseError()} {raiseError()} function is used to display an error message. \snippet examples/xml/streambookmarks/xbelreader.cpp 1 -- cgit v0.12 From dbb9dc164ccef29ec7cee381706edf8775fcc828 Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Wed, 15 Apr 2009 12:27:50 +0200 Subject: Doc - changed "MAY NOT" to an italicized version of 'may not' for some consistency. --- doc/src/qnamespace.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/qnamespace.qdoc b/doc/src/qnamespace.qdoc index e6a1a36..d9f001e 100644 --- a/doc/src/qnamespace.qdoc +++ b/doc/src/qnamespace.qdoc @@ -142,7 +142,7 @@ QAction::iconVisibleInMenu property. Menus that are currently open or menus already created in the native - Mac OS X menubar MAY NOT pick up a change in this attribute. Changes + Mac OS X menubar \e{may not} pick up a change in this attribute. Changes in the QAction::iconVisibleInMenu property will always be picked up. \value AA_NativeWindows Ensures that widgets have native windows. -- cgit v0.12 From 9f6146dd3a7c111923e79c490c9504f39b205f0b Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 15 Apr 2009 11:59:56 +0200 Subject: BT: OpenGL ES 2.0 now compiles properly for Windows CE glpixmapfilter should not be compiled for OpenGL ES 2.0 on nay platform Reviewed-by: Tom Cooksey --- src/opengl/opengl.pro | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro index 48d7caf..78aaddb 100644 --- a/src/opengl/opengl.pro +++ b/src/opengl/opengl.pro @@ -25,18 +25,16 @@ HEADERS += qgl.h \ qglcolormap.h \ qglpixelbuffer.h \ qglframebufferobject.h \ - qglpixmapfilter_p.h SOURCES += qgl.cpp \ qglcolormap.cpp \ qglpixelbuffer.cpp \ qglframebufferobject.cpp \ qglextensions.cpp \ - qglpixmapfilter.cpp !contains(QT_CONFIG, opengles2) { - HEADERS += qpaintengine_opengl_p.h - SOURCES += qpaintengine_opengl.cpp + HEADERS += qpaintengine_opengl_p.h qglpixmapfilter_p.h + SOURCES += qpaintengine_opengl.cpp qglpixmapfilter.cpp } contains(QT_CONFIG, opengles2) { @@ -130,6 +128,10 @@ wince*: { contains(QT_CONFIG,opengles1cl) { QMAKE_LIBS += "libGLES_CL.lib" } + contains(QT_CONFIG,opengles2) { + QMAKE_LIBS += "libGLESv2.lib" + } + } else { QMAKE_LIBS += $$QMAKE_LIBS_OPENGL } -- cgit v0.12 From 809b192f245f24e3e17655e4f5f335bee4bcad79 Mon Sep 17 00:00:00 2001 From: Morten Engvoldsen Date: Wed, 15 Apr 2009 12:37:32 +0200 Subject: Correcting paragraph Made a mistake when pushing e0706ca2fbce063c263bad9a1eee24f057f170bd I Corrected this. Task-number: 250254 Rev-by: Frans Englich Rev-by: Geir Vattekar --- doc/src/examples/qxmlstreambookmarks.qdoc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/doc/src/examples/qxmlstreambookmarks.qdoc b/doc/src/examples/qxmlstreambookmarks.qdoc index 47d5654..fb3a1c1 100644 --- a/doc/src/examples/qxmlstreambookmarks.qdoc +++ b/doc/src/examples/qxmlstreambookmarks.qdoc @@ -105,9 +105,7 @@ \l{QXmlStreamReader::setDevice()}{setDevice()}. The actual process of reading only takes place if the file is a valid XBEL 1.0 file. Note that the XML input needs to be well-formed to be accepted by - QXmlStreamReader. - - Otherwise, the \l{QXmlStreamReader::raiseError()} + QXmlStreamReader. Otherwise, the \l{QXmlStreamReader::raiseError()} {raiseError()} function is used to display an error message. \snippet examples/xml/streambookmarks/xbelreader.cpp 1 -- cgit v0.12 From 8fc0d4ed0d306e131276ce6e4dd236ca42582d9a Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Wed, 15 Apr 2009 12:45:09 +0200 Subject: My ChangeLog. Reviewed-by: Trust Me --- dist/changes-4.5.1 | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index e8595ff..68edc78 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -25,6 +25,9 @@ General Improvements - Documentation and Examples +- Embedded Dialogs demo + * [246517] Fixed warnings and bugs in hover handling on Mac OS X + Third party components ---------------------- @@ -69,7 +72,12 @@ Third party components - QGraphicsItem * [247890] Cached QGraphicsItems are not updated if update() is called when they are hidden - * [250272] When an item is deleted it does not get removed from the sceneeventfilters meaning a crash can occur + * [250272] When an item is deleted it does not get removed from the + sceneeventfilters meaning a crash can occur + * Fixed slowdown regression in QGraphicsItem::ItemCoordinateCache + +- QGraphicsScene + * [243707] Fixed crash when adding child before parent to scene -QGraphicsView * [245766] Rubber Band drag mode not updated correctly when scrolling -- cgit v0.12 From 61abefeb649fdbc4653bd69415431cabd640e4ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 15 Apr 2009 11:01:24 +0200 Subject: My changes for 4.5.1 BT: yes --- dist/changes-4.5.1 | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index 68edc78..bbf0bf1 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -49,6 +49,9 @@ Third party components - QAuthenticator * [237979] fix implemenation of md5-sess +- QByteArray + * [246233] QByteArray::fromHex() fails with input of size 1 + - QColorDialog * [247349] Fixed bug causing the wrong alpha value to be returned. @@ -62,6 +65,10 @@ Third party components - QDirIterator * [247645] Fix a bug that may loose all cached data inside the QFileInfo +- QFile + * [244500] QFile::rename() doesn't always return false when the method fails + * [244485] Renaming a file does not change QFile::fileName() + - QFileInfo * [205244] return valid file info also for relative UNC paths @@ -301,6 +308,7 @@ Qt for Windows CE - moc + * [240368] moc parsing issue with "unsigned" subphrase - uic * [244998] Fixed include file generation for phonon widgets. @@ -314,6 +322,8 @@ Qt for Windows CE - qmake * [248806] Ensure that the Xcode generator includes the right path to frameworks. + * [201495] Comment processing in qmake prevented file from being moc'ed + * On Mac OS, properly escape file names in QMAKE_BUNDLE_DATA - configure -- cgit v0.12 From 869c85e2f965a226416f0a142572ff749b30ba9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Wed, 15 Apr 2009 13:25:22 +0200 Subject: My changes --- dist/changes-4.5.1 | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index bbf0bf1..8d90ac9 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -46,6 +46,11 @@ Third party components - QAbstractSocket * [192037] Emit disconnected only if we were connected before +- QAccessible + * [241161] Fixed bug in browsing menus with the keyboard. + * [221731] Fixed bug where the accessibility plugin could crash if there + was an "&" at the end or spin forever if a label had a sequence of "&&". + - QAuthenticator * [237979] fix implemenation of md5-sess @@ -83,12 +88,20 @@ Third party components sceneeventfilters meaning a crash can occur * Fixed slowdown regression in QGraphicsItem::ItemCoordinateCache +- QGraphicsGridLayout + * [242472] Fix a bug where the calculation of the maximum width of a column + was not calculated correctly. + - QGraphicsScene * [243707] Fixed crash when adding child before parent to scene -QGraphicsView * [245766] Rubber Band drag mode not updated correctly when scrolling +- QGraphicsWidget + * [246215] Fixed a regression where we could cache the wrong size hint + because we called the virtual sizeHint() from the constructor. + - QHttp * [208445] cancel request upon receiving unknown authentication method @@ -142,7 +155,7 @@ Third party components * Fixed crash that may occurs when event are processed just after QSortFilterProxyModel has been invalidated * [246025] Fixed auto-expand that occurs while quicly collapsing an item after clicking on a child - * [248805] Calling programatically QTreeView::sortByColumn was not working if manual + * [248805] Calling programatically QTreeView::sortByColumn was not working if manual sorting is disabled * [248163] Fixed possible crash in the paintEvent when spans are used. @@ -184,13 +197,13 @@ Qt for Linux/X11 CD playback. - QGtkStyle - * The system palette is no longer strictly forced. Also behavior related + * The system palette is no longer strictly forced. Also behavior related to system theme changes have been improved. * [249363] QFrame is now styled as a GtkScrolledWindow. * [247653] Fixed a compilation issue on solaris. - * Fixed palette and styling issues with the background color of + * Fixed palette and styling issues with the background color of combo box popups. - * [239829] Disabled alt-key navigation for QGtkStyle to follow + * [239829] Disabled alt-key navigation for QGtkStyle to follow GTK+ behavior. * [238196] Allow middle click to set scrollbar position to follow GTK+ behavior. @@ -250,8 +263,8 @@ Qt for Mac OS X - Fix a crash when showing a widget that is window modal but has no parent. - [248803] Showing two dialogs at the same time don't get shared activation. -- Added QSysInfo::MV_10_6 as an enum to test against. -- Various compile fixes for Snow Leopard (preliminary support). +- Added QSysInfo::MV_10_6 as an enum to test against. +- Various compile fixes for Snow Leopard (preliminary support). - The uninstall-qt.py script included in the binary package no longer complains about removing itself multiple times. -- cgit v0.12 From d7e8586e6ab009a6da1eb63aa6798d7c6a34c30d Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Wed, 15 Apr 2009 13:14:31 +0200 Subject: BT: Namespace compile fixes for Cocoa. It worked in 4.5.0, so it should work in 4.5.1 too. --- src/gui/kernel/qcocoapanel_mac.mm | 8 +++++--- src/gui/kernel/qcocoawindow_mac.mm | 7 ++++--- src/gui/widgets/qcocoamenu_mac.mm | 6 ++++++ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/gui/kernel/qcocoapanel_mac.mm b/src/gui/kernel/qcocoapanel_mac.mm index 95e20af..c69826f 100644 --- a/src/gui/kernel/qcocoapanel_mac.mm +++ b/src/gui/kernel/qcocoapanel_mac.mm @@ -49,8 +49,10 @@ #include +QT_FORWARD_DECLARE_CLASS(QWidget); +QT_BEGIN_NAMESPACE extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.mm - +QT_END_NAMESPACE QT_USE_NAMESPACE @implementation QT_MANGLE_NAMESPACE(QCocoaPanel) @@ -108,7 +110,7 @@ QT_USE_NAMESPACE [self retain]; QWidget *widget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self]; - QCocoaView *view = static_cast(qt_mac_nativeview_for(widget)); + QT_MANGLE_NAMESPACE(QCocoaView) *view = static_cast(qt_mac_nativeview_for(widget)); Qt::MouseButton mouseButton = cocoaButton2QtButton([event buttonNumber]); // sometimes need to redirect mouse events to the popup. @@ -172,7 +174,7 @@ QT_USE_NAMESPACE + (Class)frameViewClassForStyleMask:(NSUInteger)styleMask { if (styleMask & QtMacCustomizeWindow) - return [QCocoaWindowCustomThemeFrame class]; + return [QT_MANGLE_NAMESPACE(QCocoaWindowCustomThemeFrame) class]; return [super frameViewClassForStyleMask:styleMask]; } diff --git a/src/gui/kernel/qcocoawindow_mac.mm b/src/gui/kernel/qcocoawindow_mac.mm index 972e477..89f481f 100644 --- a/src/gui/kernel/qcocoawindow_mac.mm +++ b/src/gui/kernel/qcocoawindow_mac.mm @@ -53,9 +53,10 @@ #include QT_FORWARD_DECLARE_CLASS(QWidget); -QT_USE_NAMESPACE - +QT_BEGIN_NAMESPACE extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.mm +QT_END_NAMESPACE +QT_USE_NAMESPACE @implementation NSWindow (QT_MANGLE_NAMESPACE(QWidgetIntegration)) @@ -130,7 +131,7 @@ extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview. [self retain]; QWidget *widget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self]; - QCocoaView *view = static_cast(qt_mac_nativeview_for(widget)); + QT_MANGLE_NAMESPACE(QCocoaView) *view = static_cast(qt_mac_nativeview_for(widget)); Qt::MouseButton mouseButton = cocoaButton2QtButton([event buttonNumber]); // sometimes need to redirect mouse events to the popup. diff --git a/src/gui/widgets/qcocoamenu_mac.mm b/src/gui/widgets/qcocoamenu_mac.mm index c5fee66..6434289 100644 --- a/src/gui/widgets/qcocoamenu_mac.mm +++ b/src/gui/widgets/qcocoamenu_mac.mm @@ -55,11 +55,17 @@ QT_FORWARD_DECLARE_CLASS(QAction) QT_FORWARD_DECLARE_CLASS(QWidget) QT_FORWARD_DECLARE_CLASS(QApplication) +QT_FORWARD_DECLARE_CLASS(QCoreApplication) +QT_FORWARD_DECLARE_CLASS(QApplicationPrivate) +QT_FORWARD_DECLARE_CLASS(QKeyEvent) +QT_FORWARD_DECLARE_CLASS(QEvent) QT_BEGIN_NAMESPACE extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); //qapplication.cpp QT_END_NAMESPACE +QT_USE_NAMESPACE + @implementation QT_MANGLE_NAMESPACE(QCocoaMenu) - (id)initWithQMenu:(QMenu*)menu -- cgit v0.12 From b646787cf0d67f4df00212f62a83432c641eae95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Wed, 15 Apr 2009 13:34:09 +0200 Subject: Reparenting QGLWidgets did sometimes caused warnings to be printed on Mac/Cocoa. Check if the view is visible before attaching it to a context. Task-number: related to 250066 Reviewed-by: Norwegian Rock Cat BT: yes --- src/opengl/qgl_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengl/qgl_mac.mm b/src/opengl/qgl_mac.mm index 3dbdaec..1319396 100644 --- a/src/opengl/qgl_mac.mm +++ b/src/opengl/qgl_mac.mm @@ -629,7 +629,7 @@ void QGLContext::updatePaintDevice() // ideally we would use QWidget::isVisible(), but we get "invalid drawable" errors if (![(NSWindow *)qt_mac_window_for(w) isVisible]) return; - if ([static_cast(d->cx) view] != view) + if ([static_cast(d->cx) view] != view && ![view isHidden]) [static_cast(d->cx) setView:view]; } else if (d->paintDevice->devType() == QInternal::Pixmap) { const QPixmap *pm = static_cast(d->paintDevice); -- cgit v0.12 From 4cb80de7ade662deb5542f77cd3a36517fa9cd9b Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 15 Apr 2009 13:49:57 +0200 Subject: BT: Updated configure for OpenGL ES 2.0 Windows CE --- configure.exe | Bin 1134592 -> 860160 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/configure.exe b/configure.exe index 13ca0e5..ff71f08 100644 Binary files a/configure.exe and b/configure.exe differ -- cgit v0.12 From 36b16a126e24cb8d8e5c34cfd807bc7c51ea49cf Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 15 Apr 2009 14:14:27 +0200 Subject: Update the item if the text has changed but the boundingRect is the same. updateBoudingRect update the item only if the boundingRect change but if we have 123 as an initial text and then we set 321 as the new text, then nothing happen because the rect is the same. In case the boundingRect change then we call update 2 times but the item is already dirty so the second call will just return. BT:yes Reviewed-by: Andreas --- src/gui/graphicsview/qgraphicsitem.cpp | 1 + tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 34 ++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index e6bcaa6..d1b8393 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -8489,6 +8489,7 @@ void QGraphicsSimpleTextItem::setText(const QString &text) return; d->text = text; d->updateBoundingRect(); + update(); } /*! diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 2d1be37..d500182 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -222,6 +222,7 @@ private slots: // task specific tests below me void task141694_textItemEnsureVisible(); void task128696_textItemEnsureMovable(); + void ensureUpdateOnTextItem(); void task177918_lineItemUndetected(); void task240400_clickOnTextItem_data(); void task240400_clickOnTextItem(); @@ -5272,6 +5273,39 @@ void tst_QGraphicsItem::task240400_clickOnTextItem() QCOMPARE(item->textCursor().columnNumber(), 0); } +class TextItem : public QGraphicsSimpleTextItem +{ +public: + TextItem(const QString& text) : QGraphicsSimpleTextItem(text) + { + updates = 0; + } + + void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) + { + updates++; + QGraphicsSimpleTextItem::paint(painter, option, widget); + } + + int updates; +}; + +void tst_QGraphicsItem::ensureUpdateOnTextItem() +{ + QGraphicsScene scene; + TextItem *text1 = new TextItem(QLatin1String("123")); + scene.addItem(text1); + QGraphicsView view(&scene); + view.show(); + QTest::qWait(250); + QCOMPARE(text1->updates,1); + + //same bouding rect but we have to update + text1->setText(QLatin1String("321")); + QTest::qWait(250); + QCOMPARE(text1->updates,2); +} + void tst_QGraphicsItem::task243707_addChildBeforeParent() { // Task reports that adding the child before the parent leads to an -- cgit v0.12 From 4e9c2364e8e9580aa317e9387338d45207ac4baa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20S=C3=B8rvig?= Date: Wed, 15 Apr 2009 14:35:32 +0200 Subject: My 4.5.1 changes. --- dist/changes-4.5.1 | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index 8d90ac9..4fb155a 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -67,6 +67,9 @@ Third party components * [250064] Fixed focus policy propagation regression. * [246056] Fixed assertion failure in setCompletionPrefix(). +- QtConcurrent + * [244718] Reduce the number of calls to QThread::idealThreadCount(). + - QDirIterator * [247645] Fix a bug that may loose all cached data inside the QFileInfo @@ -260,13 +263,24 @@ Qt for Mac OS X * Modify the colliding mice example to work better with coalesced updates. * Fixed a bug where the drag cursor was not updated when modifier keys are used. * [247947] Fixed a crash in drag and drop. + * The command + h shortcut is now enabled. (Hides the current window.) + +- QDesktopWidget + * [244004] Support multiple screens that have different sizes properly. + +- macdeployqt + * The binary packages now includes the macdeployqt tool. + * macdeployqt now runs 'strip' on the deployed binaries. + * Fixed issue preventing the QtSvg from being deployed. + +- configure script + * Now supports "-arch i386" as an alias for "-arch x86". + * Detects invalid arch arguemnts and exits. - Fix a crash when showing a widget that is window modal but has no parent. - [248803] Showing two dialogs at the same time don't get shared activation. - Added QSysInfo::MV_10_6 as an enum to test against. - Various compile fixes for Snow Leopard (preliminary support). - - - The uninstall-qt.py script included in the binary package no longer complains about removing itself multiple times. - Document a bit clearer how qt_mac_set_dock_menu() works. -- cgit v0.12 From 9da65ead69c92df717b1a63fe3c98c0cc73270f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 15 Apr 2009 14:03:49 +0200 Subject: Prevent crash in qt_scrollRectInImage. Clip both against the source and target device rectangles. Task-number: 247937 Reviewed-by: Trond BT: yes --- dist/changes-4.5.1 | 4 ++++ src/gui/painting/qwindowsurface.cpp | 7 +++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index 4fb155a..bda151f 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -162,6 +162,10 @@ Third party components sorting is disabled * [248163] Fixed possible crash in the paintEvent when spans are used. +- QWidget + * [250388] Fixed potential crash in QWidget::scroll() when using the raster + graphics system. + - QWizard * [248107] Fixed bug on Vista causing Back button to connect twice to the back() signal. diff --git a/src/gui/painting/qwindowsurface.cpp b/src/gui/painting/qwindowsurface.cpp index bcb0380..d941a24 100644 --- a/src/gui/painting/qwindowsurface.cpp +++ b/src/gui/painting/qwindowsurface.cpp @@ -310,10 +310,13 @@ void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset) int lineskip = img.bytesPerLine(); int depth = img.depth() >> 3; - - const QRect r = rect & QRect(0, 0, img.width(), img.height()); + const QRect imageRect(0, 0, img.width(), img.height()); + const QRect r = rect & imageRect & imageRect.translated(-offset); const QPoint p = rect.topLeft() + offset; + if (r.isEmpty()) + return; + const uchar *src; uchar *dest; -- cgit v0.12 From bbad83a64373b7e01f6abee98d854380f03aa6b6 Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Wed, 15 Apr 2009 14:26:59 +0200 Subject: Doc - clarified that on Windows, for 32-bit programs running in WOW64 mode, the settings are stored in HKEY_LOCAL_MACHINE\Software\WOW6432node. Task-number: 232011 Reviewed-by: Martin Petersson --- src/corelib/io/qsettings.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 62b4ed5..484e79a 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -2330,6 +2330,10 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile, \o \c{HKEY_LOCAL_MACHINE\Software\MySoft} \endlist + \note On Windows, for 32-bit programs running in WOW64 mode, settings are + stored in the following registry path: + \c{HKEY_LOCAL_MACHINE\Software\WOW6432node}. + If the file format is IniFormat, the following files are used on Unix and Mac OS X: -- cgit v0.12 From ea5991e330282a5b18301d653ccb5a7d960a7db5 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Wed, 15 Apr 2009 14:46:59 +0200 Subject: Fixed painting issues with draggable tabs This fixes a few of the remaining glitches tabbar animations have: * We no longer grab tabs but paint them through QStyle. This makes tabs work and animate correctly when they are outside the visible region. * Buttons now correctly follow tabs when dropped * Gtkstyle recieved some polish to make it look more native. Task-number: 247694, 251166 Reviewed-by: nrc --- src/gui/styles/qgtkstyle.cpp | 9 +++-- src/gui/widgets/qtabbar.cpp | 90 +++++++++++++++++++++++--------------------- src/gui/widgets/qtabbar_p.h | 33 ++-------------- 3 files changed, 57 insertions(+), 75 deletions(-) diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index 519fed7..541415f 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -2760,10 +2760,13 @@ void QGtkStyle::drawControl(ControlElement element, if (tab->state & State_Selected) state = GTK_STATE_NORMAL; - bool first = tab->position == QStyleOptionTab::Beginning || tab->position == QStyleOptionTab::OnlyOneTab; - bool last = tab->position == QStyleOptionTab::End || tab->position == QStyleOptionTab::OnlyOneTab; bool selected = (tab->state & State_Selected); - if (option->direction == Qt::RightToLeft) { + bool first = false, last = false; + if (widget) { + // This is most accurate and avoids resizing tabs while moving + first = tab->rect.left() == widget->rect().left(); + last = tab->rect.right() == widget->rect().right(); + } else if (option->direction == Qt::RightToLeft) { bool tmp = first; first = last; last = tmp; diff --git a/src/gui/widgets/qtabbar.cpp b/src/gui/widgets/qtabbar.cpp index 7d970ad..b6e6b6d 100644 --- a/src/gui/widgets/qtabbar.cpp +++ b/src/gui/widgets/qtabbar.cpp @@ -131,7 +131,7 @@ void QTabBar::initStyleOption(QStyleOptionTab *option, int tabIndex) const option->state &= ~QStyle::State_Enabled; if (isActiveWindow()) option->state |= QStyle::State_Active; - if (option->rect == d->hoverRect) + if (!d->dragInProgress && option->rect == d->hoverRect) option->state |= QStyle::State_MouseOver; option->shape = d->shape; option->text = tab.text; @@ -454,9 +454,6 @@ void QTabBarPrivate::layoutTabs() maxExtent = maxWidth; } - if (pressedIndex != -1 && movable) - grabCache(0, tabList.count(), true); - Q_ASSERT(tabChainIndex == tabChain.count() - 1); // add an assert just to make sure. // Mirror our front item. tabChain[tabChainIndex].init(); @@ -1484,6 +1481,8 @@ void QTabBar::paintEvent(QPaintEvent *) bool vertical = verticalTabs(d->shape); QStyleOptionTab cutTab; selected = d->currentIndex; + if (d->dragInProgress) + selected = d->pressedIndex; for (int i = 0; i < d->tabList.count(); ++i) optTabBase.tabBarRect |= tabRect(i); @@ -1522,11 +1521,7 @@ void QTabBar::paintEvent(QPaintEvent *) if (i == selected) continue; - if (!d->tabList[i].animatingCache.isNull() && d->paintWithOffsets) { - p.drawPixmap(tab.rect, d->tabList[i].animatingCache); - } else { - p.drawControl(QStyle::CE_TabBarTab, tab); - } + p.drawControl(QStyle::CE_TabBarTab, tab); } // Draw the selected tab last to get it "on top" @@ -1539,7 +1534,11 @@ void QTabBar::paintEvent(QPaintEvent *) else tab.rect.moveLeft(tab.rect.x() + d->tabList[selected].dragOffset); } - p.drawControl(QStyle::CE_TabBarTab, tab); + if (!d->dragInProgress) + p.drawControl(QStyle::CE_TabBarTab, tab); + else + d->movingTab->setGeometry(tab.rect); + } // Only draw the tear indicator if necessary. Most of the time we don't need too. @@ -1680,6 +1679,7 @@ void QTabBarPrivate::_q_moveTab(int offset) if (!validIndex(index)) return; tabList[index].dragOffset = offset; + layoutTab(index); // Make buttons follow tab q->update(); } } @@ -1727,8 +1727,7 @@ void QTabBar::mouseMoveEvent(QMouseEvent *event) if (!d->dragInProgress && d->pressedIndex != -1) { if ((event->pos() - d->dragStartPosition).manhattanLength() > QApplication::startDragDistance()) { d->dragInProgress = true; - if (d->animations.isEmpty()) - d->grabCache(0, d->tabList.count(), false); + d->setupMovableTab(); } } @@ -1773,7 +1772,6 @@ void QTabBar::mouseMoveEvent(QMouseEvent *event) if (dragDistance > needsToBeOver) d->slide(i + offset, d->pressedIndex); } - } // Buttons needs to follow the dragged tab d->layoutTab(d->pressedIndex); @@ -1801,32 +1799,41 @@ void QTabBarPrivate::_q_moveTabFinished() } } -void QTabBarPrivate::grabCache(int start, int end, bool unhide) +void QTabBarPrivate::setupMovableTab() { Q_Q(QTabBar); - paintWithOffsets = false; - bool showButtonsAgain = rightB->isVisible(); - rightB->hide(); - leftB->hide(); - - QWidget *topLevel = q->window(); - QPoint topLevelOffset(q->mapTo(topLevel, QPoint())); - for (int i = start; i < end; ++i) { - QRect tabRect = q->tabRect(i); - tabRect.translate(topLevelOffset); - if (unhide) { - tabList[i].unHideWidgets(); - layoutWidgets(i); - } - tabList[i].animatingCache = QPixmap::grabWidget(topLevel, tabRect); - if (i != pressedIndex) - tabList[i].hideWidgets(); - } - if (showButtonsAgain) { - rightB->show(); - leftB->show(); - } - paintWithOffsets = true; + if (!movingTab) + movingTab = new QWidget(q); + + QRect grabRect = q->tabRect(pressedIndex); + + QPixmap grabImage(grabRect.size()); + grabImage.fill(Qt::transparent); + QStylePainter p(&grabImage, q); + + QStyleOptionTabV3 tab; + q->initStyleOption(&tab, pressedIndex); + tab.rect.moveTopLeft(QPoint(0, 0)); + p.drawControl(QStyle::CE_TabBarTab, tab); + p.end(); + + QPalette pal; + pal.setBrush(QPalette::All, QPalette::Window, grabImage); + movingTab->setPalette(pal); + movingTab->setGeometry(grabRect); + movingTab->setAutoFillBackground(true); + movingTab->raise(); + + // Re-arrange widget order to avoid overlaps + if (tabList[pressedIndex].leftWidget) + tabList[pressedIndex].leftWidget->raise(); + if (tabList[pressedIndex].rightWidget) + tabList[pressedIndex].rightWidget->raise(); + if (leftB) + leftB->raise(); + if (rightB) + rightB->raise(); + movingTab->setVisible(true); } void QTabBarPrivate::_q_moveTabFinished(int index) @@ -1834,10 +1841,9 @@ void QTabBarPrivate::_q_moveTabFinished(int index) Q_Q(QTabBar); bool cleanup = (pressedIndex == index) || (pressedIndex == -1) || !validIndex(index); if (animations.isEmpty() && cleanup) { + movingTab->setVisible(false); // We might not get a mouse release for (int i = 0; i < tabList.count(); ++i) { tabList[i].dragOffset = 0; - tabList[i].unHideWidgets(); - tabList[i].animatingCache = QPixmap(); } if (pressedIndex != -1 && movable) { pressedIndex = -1; @@ -1881,6 +1887,7 @@ void QTabBar::mouseReleaseEvent(QMouseEvent *event) d->_q_moveTabFinished(d->pressedIndex); } d->dragInProgress = false; + d->movingTab->setVisible(false); d->dragStartPosition = QPoint(); } @@ -2203,19 +2210,16 @@ void QTabBar::setTabButton(int index, ButtonPosition position, QWidget *widget) widget->setParent(this); // make sure our left and right widgets stay on top widget->lower(); + widget->show(); } if (position == LeftSide) { if (d->tabList[index].leftWidget) d->tabList[index].leftWidget->hide(); d->tabList[index].leftWidget = widget; - if(!d->tabList[index].hidLeft && widget) - widget->show(); } else { if (d->tabList[index].rightWidget) d->tabList[index].rightWidget->hide(); d->tabList[index].rightWidget = widget; - if(!d->tabList[index].hidRight && widget) - widget->show(); } d->layoutTabs(); update(); diff --git a/src/gui/widgets/qtabbar_p.h b/src/gui/widgets/qtabbar_p.h index a117aa3..cb1a15b 100644 --- a/src/gui/widgets/qtabbar_p.h +++ b/src/gui/widgets/qtabbar_p.h @@ -70,7 +70,6 @@ QT_BEGIN_NAMESPACE - class QTabBarPrivate : public QWidgetPrivate { Q_DECLARE_PUBLIC(QTabBar) @@ -78,7 +77,7 @@ public: QTabBarPrivate() :currentIndex(-1), pressedIndex(-1), shape(QTabBar::RoundedNorth), - layoutDirty(false), drawBase(true), scrollOffset(0), expanding(true), closeButtonOnTabs(false), selectionBehaviorOnRemove(QTabBar::SelectRightTab), paintWithOffsets(true), movable(false), dragInProgress(false), documentMode(false) {} + layoutDirty(false), drawBase(true), scrollOffset(0), expanding(true), closeButtonOnTabs(false), selectionBehaviorOnRemove(QTabBar::SelectRightTab), paintWithOffsets(true), movable(false), dragInProgress(false), documentMode(false), movingTab(0) {} int currentIndex; int pressedIndex; @@ -98,8 +97,6 @@ public: , lastTab(-1) , timeLine(0) , dragOffset(0) - , hidLeft(false) - , hidRight(false) {} bool enabled; int shortcutId; @@ -123,9 +120,6 @@ public: QTimeLine *timeLine; int dragOffset; - QPixmap animatingCache; - bool hidLeft; - bool hidRight; void makeTimeLine(QWidget *q) { if (timeLine) @@ -135,27 +129,6 @@ public: q->connect(timeLine, SIGNAL(finished()), q, SLOT(_q_moveTabFinished())); } - void hideWidgets() { - if (!hidRight && rightWidget) { - hidRight = rightWidget->isVisible(); - rightWidget->hide(); - } - - if (!hidLeft && leftWidget) { - hidLeft = leftWidget->isVisible(); - leftWidget->hide(); - } - } - - void unHideWidgets() { - if (leftWidget && hidLeft) - leftWidget->show(); - hidLeft = false; - if (rightWidget && hidRight) - rightWidget->show(); - hidRight = false; - } - }; QList tabList; QHash animations; @@ -184,12 +157,12 @@ public: void _q_moveTabFinished(int offset); QRect hoverRect; - void grabCache(int start, int end, bool unhide); void refresh(); void layoutTabs(); void layoutWidgets(int index = -1); void layoutTab(int index); void updateMacBorderMetrics(); + void setupMovableTab(); void makeVisible(int index); QSize iconSize; @@ -206,6 +179,8 @@ public: bool dragInProgress; bool documentMode; + QWidget *movingTab; + // shared by tabwidget and qtabbar static void initStyleBaseOption(QStyleOptionTabBarBaseV2 *optTabBase, QTabBar *tabbar, QSize size) { -- cgit v0.12 From cca58cff45ea248ab9c65fd8ce088433af1c0fe0 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 15 Apr 2009 15:15:25 +0200 Subject: Make the configured namespace part of QT_BUILD_KEY_COMPAT too. The eclipse integration is namespaced, but it still pulled in system plugins like the oxygen style through QT_BUILD_KEY_COMPAT check in QLibraryPrivate::isPlugin() Task: 250185 Reviewed-by: dt BT: yes --- configure | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configure b/configure index 730c84a..a3a7b2d 100755 --- a/configure +++ b/configure @@ -6213,6 +6213,9 @@ QT_BUILD_KEY_COMPAT= if [ "$QT_CROSS_COMPILE" = "no" ]; then # previous versions of Qt used a build key built from the uname QT_BUILD_KEY_COMPAT="$CFG_USER_BUILD_KEY $UNAME_MACHINE $UNAME_SYSTEM $COMPILER $BUILD_OPTIONS" + if [ -n "$QT_NAMESPACE" ]; then + QT_BUILD_KEY_COMPAT="$QT_BUILD_KEY_COMPAT $QT_NAMESPACE" + fi fi # strip out leading/trailing/extra whitespace QT_BUILD_KEY=`echo $QT_BUILD_KEY | sed -e "s, *, ,g" -e "s,^ *,," -e "s, *$,,"` -- cgit v0.12 From 0da501b644c0799d4e5e357b27847cb7a58583e4 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Wed, 15 Apr 2009 15:16:17 +0200 Subject: Update changelog with my changes --- dist/changes-4.5.1 | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index bda151f..9a64352 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -51,6 +51,9 @@ Third party components * [221731] Fixed bug where the accessibility plugin could crash if there was an "&" at the end or spin forever if a label had a sequence of "&&". +- QAtomicInt + * [216492] Fix compilation on 64-bit PowerPC machines with gcc 4.3. + - QAuthenticator * [237979] fix implemenation of md5-sess @@ -108,6 +111,13 @@ Third party components - QHttp * [208445] cancel request upon receiving unknown authentication method +- QHostAddress + * [247330] Fix compilation on MinGW by adding a missing QPair include. + +- QLocalSocket + * Fix a bug that would cause QLocalSocket to disconnect 30 seconds + after a succesful delayed connection on UNIX. + - QMacStyle * [248769] Fix regression where QMacStyle would only draw tabs when passed a QStyleOptionTabV3. * Adjust the opacity value for popups. @@ -115,6 +125,14 @@ Third party components - QMainWindow * [248048] Fix a regression that would cause tooltips to disappear when using the unified toolbar. +- QMetaType + * [248890] Detailed description of QMetaType no longer contradicts + documentation of QMetaType::type() + +- QMutex + * Fix performance regression for contended mutexes as reported on + the qt4-preview-feedback list. + - QPainter * [247492] Fix rendering bug in raster paint engine causing one-pixel offset when drawing premultiplied ARGB32 images on RGB16 images. @@ -131,6 +149,10 @@ Third party components * [249175] Fix QPixmap::fromImage() of monochrome images to result in black/white pixels and not transparent/white pixels. +- QProcess + * [247865] Fix a crash when calling QProcess::start() and + startDetached() with an empty program string. + - QScrollBar * [247985] Stylesheet: added ability to style scrollbar menus. @@ -154,6 +176,10 @@ Third party components * Fixed crash while styling the title bar of a QMdiArea. * [246542] Fixed QToolButton::hover{ color:.... } +- QThread + * [249997] Add documentation indicating that the priority set by + the programmer may be ignored, for example on Linux. + - QTreeView * Fixed crash that may occurs when event are processed just after QSortFilterProxyModel has been invalidated -- cgit v0.12 From 1eaa669a6e94124a2644d10acdf890a3c21d1ad4 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 15 Apr 2009 15:34:59 +0200 Subject: Make choosing a file path for a QUrl-type property work on Windows. Use QUrl::fromLocalFile to construct the url string. Reviewed-by: Jarek Kobus --- .../designer/src/components/propertyeditor/designerpropertymanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/designer/src/components/propertyeditor/designerpropertymanager.cpp b/tools/designer/src/components/propertyeditor/designerpropertymanager.cpp index 1b267aa..346da18 100644 --- a/tools/designer/src/components/propertyeditor/designerpropertymanager.cpp +++ b/tools/designer/src/components/propertyeditor/designerpropertymanager.cpp @@ -271,7 +271,7 @@ void TextEditor::fileActionActivated() const QString newPath = m_core->dialogGui()->getOpenFileName(this, tr("Choose a File"), oldPath); if (newPath.isEmpty() || newPath == oldPath) return; - const QString newText = QLatin1String("file:") + newPath; + const QString newText = QUrl::fromLocalFile(newPath).toString(); m_editor->setText(newText); emit textChanged(newText); } -- cgit v0.12 From 0da3eabece2d33e2f8cdf421bbd8e95787c170f7 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Wed, 15 Apr 2009 16:14:09 +0200 Subject: Updated changes --- dist/changes-4.5.1 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index 9a64352..dd81f7c 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -168,6 +168,9 @@ Third party components * [245668] set also protocol, verifyMode and verifyDepth in setSslConfiguration() +- QString + * [249517] Fixed regression in replace(int, int, QChar) when string is empty + - QStyleSheetStyle * Improved support for setting background and foreground roles in styles such as the text color in a combo box popup on Mac and Cleanlooks, or -- cgit v0.12 From a1a3dd96aef2b2edd7eb7c563fabee124cdbfe5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Wed, 15 Apr 2009 16:15:14 +0200 Subject: Fixed and improved the example code --- examples/layouts/flowlayout/flowlayout.cpp | 63 ++++++++++++++++++++++++------ examples/layouts/flowlayout/flowlayout.h | 9 ++++- 2 files changed, 58 insertions(+), 14 deletions(-) diff --git a/examples/layouts/flowlayout/flowlayout.cpp b/examples/layouts/flowlayout/flowlayout.cpp index d1e857d..be6b476 100644 --- a/examples/layouts/flowlayout/flowlayout.cpp +++ b/examples/layouts/flowlayout/flowlayout.cpp @@ -43,16 +43,16 @@ #include "flowlayout.h" -FlowLayout::FlowLayout(QWidget *parent, int margin, int spacing) - : QLayout(parent) +FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing) + : QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing) { setMargin(margin); - setSpacing(spacing); } -FlowLayout::FlowLayout(int spacing) +FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing) + : m_hSpace(hSpacing), m_vSpace(vSpacing) { - setSpacing(spacing); + setMargin(margin); } FlowLayout::~FlowLayout() @@ -67,6 +67,24 @@ void FlowLayout::addItem(QLayoutItem *item) itemList.append(item); } +int FlowLayout::horizontalSpacing() const +{ + if (m_hSpace >= 0) { + return m_hSpace; + } else { + return smartSpacing(QStyle::PM_LayoutHorizontalSpacing); + } +} + +int FlowLayout::verticalSpacing() const +{ + if (m_vSpace >= 0) { + return m_vSpace; + } else { + return smartSpacing(QStyle::PM_LayoutVerticalSpacing); + } +} + int FlowLayout::count() const { return itemList.size(); @@ -125,20 +143,27 @@ QSize FlowLayout::minimumSize() const int FlowLayout::doLayout(const QRect &rect, bool testOnly) const { - int x = rect.x(); - int y = rect.y(); + int left, top, right, bottom; + getContentsMargins(&left, &top, &right, &bottom); + QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom); + int x = effectiveRect.x(); + int y = effectiveRect.y(); int lineHeight = 0; QLayoutItem *item; foreach (item, itemList) { QWidget *wid = item->widget(); - int spaceX = spacing() + wid->style()->layoutSpacing( + int spaceX = horizontalSpacing(); + if (spaceX == -1) + spaceX = wid->style()->layoutSpacing( QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal); - int spaceY = spacing() + wid->style()->layoutSpacing( + int spaceY = verticalSpacing(); + if (spaceY == -1) + spaceY = wid->style()->layoutSpacing( QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical); int nextX = x + item->sizeHint().width() + spaceX; - if (nextX - spaceX > rect.right() && lineHeight > 0) { - x = rect.x(); + if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) { + x = effectiveRect.x(); y = y + lineHeight + spaceY; nextX = x + item->sizeHint().width() + spaceX; lineHeight = 0; @@ -150,5 +175,19 @@ int FlowLayout::doLayout(const QRect &rect, bool testOnly) const x = nextX; lineHeight = qMax(lineHeight, item->sizeHint().height()); } - return y + lineHeight - rect.y(); + return y + lineHeight - rect.y() + bottom; } + +int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const +{ + QObject *parent = this->parent(); + if (!parent) { + return -1; + } else if (parent->isWidgetType()) { + QWidget *pw = static_cast(parent); + return pw->style()->pixelMetric(pm, 0, pw); + } else { + return static_cast(parent)->spacing(); + } +} + diff --git a/examples/layouts/flowlayout/flowlayout.h b/examples/layouts/flowlayout/flowlayout.h index f864d8e..9940e55 100644 --- a/examples/layouts/flowlayout/flowlayout.h +++ b/examples/layouts/flowlayout/flowlayout.h @@ -49,11 +49,13 @@ class FlowLayout : public QLayout { public: - FlowLayout(QWidget *parent, int margin = -1, int spacing = 0); - FlowLayout(int spacing = 0); + FlowLayout(QWidget *parent, int margin = -1, int hSpacing = -1, int vSpacing = -1); + FlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1); ~FlowLayout(); void addItem(QLayoutItem *item); + int horizontalSpacing() const; + int verticalSpacing() const; Qt::Orientations expandingDirections() const; bool hasHeightForWidth() const; int heightForWidth(int) const; @@ -66,8 +68,11 @@ public: private: int doLayout(const QRect &rect, bool testOnly) const; + int smartSpacing(QStyle::PixelMetric pm) const; QList itemList; + int m_hSpace; + int m_vSpace; }; #endif -- cgit v0.12 From d07207c2fe77f5c4f732dddc34c0089f1e6b9f1d Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 15 Apr 2009 16:30:30 +0200 Subject: QFileDialog : Fix filters that doesn't work if whitespaces at the end The fix is basically remove the whitespaces at the end otherwise the reg exp will be wrong. Task-number: 240789 Reviewed-by: jasplin --- src/gui/dialogs/qfiledialog.cpp | 16 ++++++++++------ tests/auto/qfiledialog/tst_qfiledialog.cpp | 16 ++++++++++++++++ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp index 5131271..b20321f 100644 --- a/src/gui/dialogs/qfiledialog.cpp +++ b/src/gui/dialogs/qfiledialog.cpp @@ -957,25 +957,29 @@ void QFileDialog::setNameFilters(const QStringList &filters) { Q_D(QFileDialog); d->defaultFileTypes = (filters == QStringList(QFileDialog::tr("All Files (*)"))); - d->nameFilters = filters; + QStringList cleanedFilters; + for (int i = 0; i < filters.count(); ++i) { + cleanedFilters << filters[i].simplified(); + } + d->nameFilters = cleanedFilters; if (d->nativeDialogInUse){ - d->setNameFilters_sys(filters); + d->setNameFilters_sys(cleanedFilters); return; } d->qFileDialogUi->fileTypeCombo->clear(); - if (filters.isEmpty()) + if (cleanedFilters.isEmpty()) return; if (testOption(HideNameFilterDetails)) { QStringList strippedFilters; - for (int i = 0; i < filters.count(); ++i) { - strippedFilters.append(filters[i].mid(0, filters[i].indexOf(QLatin1String(" (")))); + for (int i = 0; i < cleanedFilters.count(); ++i) { + strippedFilters.append(cleanedFilters[i].mid(0, cleanedFilters[i].indexOf(QLatin1String(" (")))); } d->qFileDialogUi->fileTypeCombo->addItems(strippedFilters); } else { - d->qFileDialogUi->fileTypeCombo->addItems(filters); + d->qFileDialogUi->fileTypeCombo->addItems(cleanedFilters); } d->_q_useNameFilter(0); } diff --git a/tests/auto/qfiledialog/tst_qfiledialog.cpp b/tests/auto/qfiledialog/tst_qfiledialog.cpp index bade586..695bfe7 100644 --- a/tests/auto/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/qfiledialog/tst_qfiledialog.cpp @@ -681,6 +681,22 @@ void tst_QFiledialog::filters() for (int i = views.at(0)->currentIndex(); i < views.at(0)->count(); ++i) views.at(0)->setCurrentIndex(i); QCOMPARE(spyFilterSelected.count(), 0); + + //Let check if filters with whitespaces + QNonNativeFileDialog fd2; + QStringList expected; + expected << "C++ Source Files(*.cpp)"; + expected << "Any(*.*)"; + fd2.setFilter("C++ Source Files(*.cpp);;Any(*.*)"); + QCOMPARE(expected, fd2.filters()); + fd2.setFilter("C++ Source Files(*.cpp) ;;Any(*.*)"); + QCOMPARE(expected, fd2.filters()); + fd2.setFilter("C++ Source Files(*.cpp);; Any(*.*)"); + QCOMPARE(expected, fd2.filters()); + fd2.setFilter(" C++ Source Files(*.cpp);; Any(*.*)"); + QCOMPARE(expected, fd2.filters()); + fd2.setFilter("C++ Source Files(*.cpp) ;; Any(*.*)"); + QCOMPARE(expected, fd2.filters()); } void tst_QFiledialog::selectFilter() -- cgit v0.12 From ea45426ab6942d3deb736ee429ae7bc4ae8713e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 15 Apr 2009 14:15:46 +0200 Subject: Silence warning about unused static function on Windows Reviewed-by: mariusSO --- src/corelib/io/qtemporaryfile.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index 3cfce83..6a7b067 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -268,11 +268,13 @@ static int _gettemp(char *path, int *doopen, int domkdir, int slen) /*NOTREACHED*/ } +#ifndef Q_WS_WIN static int qt_mkstemps(char *path, int slen) { int fd = 0; return (_gettemp(path, &fd, 0, slen) ? fd : -1); } +#endif //************* QTemporaryFileEngine class QTemporaryFileEngine : public QFSFileEngine -- cgit v0.12 From 8ec0109a5d5ce5e81a45ca8b294369a8a991f7f2 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Wed, 15 Apr 2009 16:39:58 +0200 Subject: Make QIcon update after palette changes We have to add the palette cacheKey to ensure that the icon is properly regenerated after a system palette change. Task-number: 250542 Reviewed-by: nrc --- src/gui/image/qicon.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index 3c71f15..0514567 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -304,6 +304,8 @@ QPixmap QPixmapIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::St QString key = QLatin1String("$qt_icon_") + QString::number(pm.cacheKey()) + QString::number(pe->mode) + + QString::number(qApp->palette().cacheKey()) + + QLatin1Char('_') + QString::number(actualSize.width()) + QLatin1Char('_') + QString::number(actualSize.height()) -- cgit v0.12 From 897ef5d44556dcb1faa81594d713b62f246215cd Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Wed, 15 Apr 2009 17:12:53 +0200 Subject: GTK: Fix line edit background color with custom brush We should allways use the brush and not the color if possible. Task-number: 240842 Reviewed-by: nrc --- src/gui/styles/qgtkstyle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index 541415f..b7fa575 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -977,7 +977,7 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, if (widget && widget->testAttribute(Qt::WA_SetPalette) && resolve_mask & (1 << QPalette::Base)) // Palette overridden by user - painter->fillRect(textRect, option->palette.base().color()); + painter->fillRect(textRect, option->palette.base()); else gtkPainter.paintFlatBox( gtkEntry, "entry_bg", textRect, option->state & State_Enabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE, GTK_SHADOW_NONE, gtkEntry->style); -- cgit v0.12 From c4846a0e62482abb28cdc973fb4823be3e71f4f7 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Tue, 14 Apr 2009 13:09:00 +0200 Subject: Changelog for 4.5.1 --- dist/changes-4.5.1 | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index dd81f7c..0b06315 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -195,6 +195,14 @@ Third party components * [250388] Fixed potential crash in QWidget::scroll() when using the raster graphics system. +- QWidget + * [246852] Better handling WindowMaximizeButtonHint for widget with + layouts. + +-QLocale + * String-to-number conversion functions are now ignore trailing and + leading whitespaces in all locales as it is documented. + - QWizard * [248107] Fixed bug on Vista causing Back button to connect twice to the back() signal. @@ -222,6 +230,37 @@ Third party components Qt for Linux/X11 ---------------- + * Proper resetting input contexts when switching between multiple + input context plugins. + + * [244337] Improved input method handling when the widgets native + window id is recreated. + + * Input methods preedit strings are properly reset when user + switches focus without commiting a string. + + * [244607] Current focus widget is properly set and input method is + properly initialized when showing a toplevel that accepts + keyboard input. + + * Unicode conversion functions will handle Latin-1 character set + only if they are used before QCoreApplication/QApplication is + constructed. + + * Improved handling of failed unicode conversion. + + * [232632] Fixed reparenting widgets to a difference X11 screen. + + * [241888] The background of the drag-n-drop cursor is respected + according to the stylesheet. + + * Fixed clipboard handling when the user manually creates an + instance of the QDesktopWidget. + + * [226048] Fixed emitting a QDesktopWidget::resized() signal when + new screen appears or screen geometry is changed without + affecting the whole desktop geometry. + - Phonon/GStreamer * [244259] Fixed a problem where the backend would fail to indicate an error when streaming fails. @@ -263,6 +302,9 @@ Qt for Linux/X11 Qt for Windows -------------- + * [243583] Improved drag-and-drop handling when switching mouse + buttons fast. + - QCoreApplication * [247401] Fixed a bug that would cause a restarted timer to fire too early, causing Javascript in QtWebKit to consume 100% CPU on -- cgit v0.12 From 7cee817b4989ccff6f70b0fd9b87a250bb1ff9e3 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Wed, 15 Apr 2009 11:51:17 +0200 Subject: The submenu of a multicolumn menu have an incorrect position The submenu would always appear to the side of the menu instead of its right. Task-number: 250673 Reviewed-by: ogoffart --- src/gui/widgets/qmenu.cpp | 4 ++-- tests/auto/qmenu/tst_qmenu.cpp | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index ed3e338..7396a9d 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -2889,8 +2889,8 @@ void QMenu::internalDelayedPopup() int subMenuOffset = style()->pixelMetric(QStyle::PM_SubMenuOverlap, 0, this); const QRect actionRect(d->actionRect(d->currentAction)); const QSize menuSize(d->activeMenu->sizeHint()); - const QPoint rightPos(mapToGlobal(QPoint(rect().right() + subMenuOffset + 1, actionRect.top()))); - const QPoint leftPos(mapToGlobal(QPoint(rect().left() - subMenuOffset - menuSize.width(), actionRect.top()))); + const QPoint rightPos(mapToGlobal(QPoint(actionRect.right() + subMenuOffset + 1, actionRect.top()))); + const QPoint leftPos(mapToGlobal(QPoint(actionRect.left() - subMenuOffset - menuSize.width(), actionRect.top()))); QPoint pos(rightPos); QMenu *caused = qobject_cast(d->activeMenu->d_func()->causedPopup.widget); diff --git a/tests/auto/qmenu/tst_qmenu.cpp b/tests/auto/qmenu/tst_qmenu.cpp index 7607838..a86b754 100644 --- a/tests/auto/qmenu/tst_qmenu.cpp +++ b/tests/auto/qmenu/tst_qmenu.cpp @@ -92,6 +92,7 @@ private slots: void activeSubMenuPosition(); void task242454_sizeHint(); void task176201_clear(); + void task250673_activeMutliColumnSubMenuPosition(); protected slots: void onActivated(QAction*); void onHighlighted(QAction*); @@ -678,6 +679,39 @@ void tst_QMenu::task176201_clear() QTest::mouseClick(&menu, Qt::LeftButton, 0, menu.rect().center()); } +void tst_QMenu::task250673_activeMutliColumnSubMenuPosition() +{ + class MyMenu : public QMenu + { + public: + friend class tst_QMenu; + }; + + QMenu sub; + sub.addAction("Sub-Item1"); + QAction *subAction = sub.addAction("Sub-Item2"); + + MyMenu main; + main.addAction("Item 1"); + QAction *menuAction = main.addMenu(&sub); + main.popup(QPoint(200,200)); + + uint i = 2; + while (main.columnCount() < 2) { + main.addAction(QString("Item %1").arg(i)); + ++i; + Q_ASSERT(i<1000); + } + main.setActiveAction(menuAction); + sub.setActiveAction(subAction); + QVERIFY(main.isVisible()); + QCOMPARE(main.activeAction(), menuAction); + QVERIFY(sub.isVisible()); + QVERIFY(sub.pos().x() > main.pos().x()); + + const int subMenuOffset = main.style()->pixelMetric(QStyle::PM_SubMenuOverlap, 0, &main); + QVERIFY((sub.geometry().left() - subMenuOffset + 5) < main.geometry().right()); +} QTEST_MAIN(tst_QMenu) #include "tst_qmenu.moc" -- cgit v0.12 From d2dd145e96ecf4801e39db56a37e21ddea45c8dc Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Wed, 15 Apr 2009 11:58:54 +0200 Subject: BT: QAbstractSocket: fix check for closing state (typo) emit disconnected() if we were in ConnectedState or in ClosingState before Reviewed-by: Thiago Task-number: 250976 --- src/network/socket/qabstractsocket.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 910e30a..f8cf4ca 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -2279,7 +2279,7 @@ void QAbstractSocket::disconnectFromHostImplementation() emit delayedCloseFinished(); // compat signal #endif // only emit disconnected if we were connected before - if (previousState == ConnectedState || ClosingState) + if (previousState == ConnectedState || previousState == ClosingState) emit disconnected(); d->localPort = 0; -- cgit v0.12 From 1b2ea4af58ca5cd6ba504ea9af3337677cbfe89e Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 15 Apr 2009 12:05:00 +0200 Subject: Updated WebKit from /home/shausman/src/webkit/trunk to origin/qtwebkit-4.5 ( e446518445c51c56471e41b1697e2a9e9f3adf36 ) Changes in WebKit since the last update: ++ b/WebCore/ChangeLog 2009-02-03 Dirk Schulze Reviewed by Sam Weinig. This is a follow up of r40546. Call toImage() once speeds up ImageBuffer::getImageData() * platform/graphics/qt/ImageBufferQt.cpp: (WebCore::ImageBuffer::getImageData): 2009-02-03 Dirk Schulze Reviewed by Sam Weinig and Oliver Hunt. Added getImageData() support for QtWebKit. [QT] lacks getImageData / putImageData support in Canvas https://bugs.webkit.org/show_bug.cgi?id=22186 * platform/graphics/qt/ImageBufferQt.cpp: (WebCore::ImageBuffer::getImageData): 2009-04-14 Benjamin C Meyer Reviewed by George Staikos. https://bugs.webkit.org/show_bug.cgi?id=25099 When creating a QNetworkRequest make sure to populate the CacheLoadControlAttribute with the value set by the ResourceRequest::cachePolicy() so that the cache will be used as WebKit expects. * WebKit/qt/tests/qwebpage/tst_qwebpage.cpp: (tst_QWebPage::requestCache): * platform/network/qt/ResourceRequestQt.cpp: (WebCore::ResourceRequest::toNetworkRequest): 2009-04-07 Brady Eidson Reviewed by Darin Adler While working on , noticed some glaring problems with LocalStorage. * page/DOMWindow.cpp: (WebCore::DOMWindow::localStorage): Return the cached m_localStorage object if it exists to avoid creating multiple representations for the same underlying StorageArea. * page/DOMWindow.h: (WebCore::DOMWindow::optionalLocalStorage): Return m_localStorage, not m_sessionStorage. ++ b/WebKitTools/ChangeLog 2009-02-25 Adam Treat Reviewed by Alexey Proskuryakov. Do not queue the calls to 'DumpRenderTree::dump()' as this can result in more than one call as a test that calls 'notifyDone()' can then be subsequently fully loaded and initiate a second dump. Also make sure to stop any existing page load that is happening before running the next test. Combined this serves to produce 217 more passing tests for the Qt port or roughly 5% at this point. * DumpRenderTree/qt/DumpRenderTree.cpp: (WebCore::DumpRenderTree::DumpRenderTree): (WebCore::DumpRenderTree::open): --- src/3rdparty/webkit/VERSION | 2 +- src/3rdparty/webkit/WebCore/ChangeLog | 48 + .../webkit/WebCore/generated/CSSPropertyNames.cpp | 5 +- .../webkit/WebCore/generated/CSSValueKeywords.c | 5 +- src/3rdparty/webkit/WebCore/generated/ColorData.c | 5 +- .../webkit/WebCore/generated/DocTypeStrings.cpp | 5 +- .../webkit/WebCore/generated/HTMLEntityNames.c | 5 +- .../webkit/WebCore/generated/tokenizer.cpp | 2315 ++++++++++++++------ src/3rdparty/webkit/WebCore/page/DOMWindow.cpp | 3 + src/3rdparty/webkit/WebCore/page/DOMWindow.h | 2 +- .../WebCore/platform/graphics/qt/ImageBufferQt.cpp | 55 +- .../platform/network/qt/ResourceRequestQt.cpp | 16 + .../WebKit/qt/tests/qwebpage/tst_qwebpage.cpp | 28 + 13 files changed, 1794 insertions(+), 700 deletions(-) diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index 9decb66..1762ecd 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -8,4 +8,4 @@ The commit imported was from the and has the sha1 checksum - f72c14123c593dc9d649d25b7186334bba0026b5 + e446518445c51c56471e41b1697e2a9e9f3adf36 diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index d0382f2..3774ea5 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,51 @@ +2009-02-03 Dirk Schulze + + Reviewed by Sam Weinig. + + This is a follow up of r40546. Call toImage() once speeds up ImageBuffer::getImageData() + + * platform/graphics/qt/ImageBufferQt.cpp: + (WebCore::ImageBuffer::getImageData): + +2009-02-03 Dirk Schulze + + Reviewed by Sam Weinig and Oliver Hunt. + + Added getImageData() support for QtWebKit. + + [QT] lacks getImageData / putImageData support in Canvas + https://bugs.webkit.org/show_bug.cgi?id=22186 + + * platform/graphics/qt/ImageBufferQt.cpp: + (WebCore::ImageBuffer::getImageData): + +2009-04-14 Benjamin C Meyer + + Reviewed by George Staikos. + + https://bugs.webkit.org/show_bug.cgi?id=25099 + + When creating a QNetworkRequest make sure to populate the + CacheLoadControlAttribute with the value set by the ResourceRequest::cachePolicy() so that the cache will be used as WebKit expects. + + * WebKit/qt/tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::requestCache): + + * platform/network/qt/ResourceRequestQt.cpp: + (WebCore::ResourceRequest::toNetworkRequest): + +2009-04-07 Brady Eidson + + Reviewed by Darin Adler + + While working on , noticed some glaring problems with LocalStorage. + + * page/DOMWindow.cpp: + (WebCore::DOMWindow::localStorage): Return the cached m_localStorage object if it exists to + avoid creating multiple representations for the same underlying StorageArea. + * page/DOMWindow.h: + (WebCore::DOMWindow::optionalLocalStorage): Return m_localStorage, not m_sessionStorage. + 2009-04-06 Tor Arne Vestbø Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/WebCore/generated/CSSPropertyNames.cpp b/src/3rdparty/webkit/WebCore/generated/CSSPropertyNames.cpp index ca4ea5a..25313ac 100644 --- a/src/3rdparty/webkit/WebCore/generated/CSSPropertyNames.cpp +++ b/src/3rdparty/webkit/WebCore/generated/CSSPropertyNames.cpp @@ -1,4 +1,4 @@ -/* ANSI-C code produced by gperf version 3.0.2 */ +/* ANSI-C code produced by gperf version 3.0.3 */ /* Command-line: gperf -a -L ANSI-C -E -C -c -o -t --key-positions='*' -NfindProp -Hhash_prop -Wwordlist_prop -D -s 2 CSSPropertyNames.gperf */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ @@ -217,6 +217,9 @@ hash_prop (register const char *str, register unsigned int len) #ifdef __GNUC__ __inline +#ifdef __GNUC_STDC_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif #endif const struct props * findProp (register const char *str, register unsigned int len) diff --git a/src/3rdparty/webkit/WebCore/generated/CSSValueKeywords.c b/src/3rdparty/webkit/WebCore/generated/CSSValueKeywords.c index d0433e0..5ff0858 100644 --- a/src/3rdparty/webkit/WebCore/generated/CSSValueKeywords.c +++ b/src/3rdparty/webkit/WebCore/generated/CSSValueKeywords.c @@ -1,4 +1,4 @@ -/* ANSI-C code produced by gperf version 3.0.2 */ +/* ANSI-C code produced by gperf version 3.0.3 */ /* Command-line: gperf -L ANSI-C -E -C -n -o -t --key-positions='*' -NfindValue -Hhash_val -Wwordlist_value -D CSSValueKeywords.gperf */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ @@ -179,6 +179,9 @@ hash_val (register const char *str, register unsigned int len) #ifdef __GNUC__ __inline +#ifdef __GNUC_STDC_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif #endif const struct css_value * findValue (register const char *str, register unsigned int len) diff --git a/src/3rdparty/webkit/WebCore/generated/ColorData.c b/src/3rdparty/webkit/WebCore/generated/ColorData.c index 18d9926..478566c 100644 --- a/src/3rdparty/webkit/WebCore/generated/ColorData.c +++ b/src/3rdparty/webkit/WebCore/generated/ColorData.c @@ -1,5 +1,5 @@ #include // bogus -/* ANSI-C code produced by gperf version 3.0.2 */ +/* ANSI-C code produced by gperf version 3.0.3 */ /* Command-line: gperf -CDEot -L ANSI-C --key-positions='*' -N findColor -D -s 2 */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ @@ -141,6 +141,9 @@ hash (register const char *str, register unsigned int len) #ifdef __GNUC__ __inline +#ifdef __GNUC_STDC_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif #endif const struct NamedColor * findColor (register const char *str, register unsigned int len) diff --git a/src/3rdparty/webkit/WebCore/generated/DocTypeStrings.cpp b/src/3rdparty/webkit/WebCore/generated/DocTypeStrings.cpp index ad63b9e..686629c 100644 --- a/src/3rdparty/webkit/WebCore/generated/DocTypeStrings.cpp +++ b/src/3rdparty/webkit/WebCore/generated/DocTypeStrings.cpp @@ -1,5 +1,5 @@ #include // bogus -/* ANSI-C code produced by gperf version 3.0.2 */ +/* ANSI-C code produced by gperf version 3.0.3 */ /* Command-line: gperf -CEot -L ANSI-C --key-positions='*' -N findDoctypeEntry -F ,PubIDInfo::eAlmostStandards,PubIDInfo::eAlmostStandards */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ @@ -331,6 +331,9 @@ hash (register const char *str, register unsigned int len) #ifdef __GNUC__ __inline +#ifdef __GNUC_STDC_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif #endif const struct PubIDInfo * findDoctypeEntry (register const char *str, register unsigned int len) diff --git a/src/3rdparty/webkit/WebCore/generated/HTMLEntityNames.c b/src/3rdparty/webkit/WebCore/generated/HTMLEntityNames.c index 470c4cd..993e106 100644 --- a/src/3rdparty/webkit/WebCore/generated/HTMLEntityNames.c +++ b/src/3rdparty/webkit/WebCore/generated/HTMLEntityNames.c @@ -1,4 +1,4 @@ -/* ANSI-C code produced by gperf version 3.0.2 */ +/* ANSI-C code produced by gperf version 3.0.3 */ /* Command-line: gperf -a -L ANSI-C -C -G -c -o -t --key-positions='*' -N findEntity -D -s 2 */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ @@ -520,6 +520,9 @@ static const short lookup[] = #ifdef __GNUC__ __inline +#ifdef __GNUC_STDC_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif #endif const struct Entity * findEntity (register const char *str, register unsigned int len) diff --git a/src/3rdparty/webkit/WebCore/generated/tokenizer.cpp b/src/3rdparty/webkit/WebCore/generated/tokenizer.cpp index 1da1a0b..8462f51 100644 --- a/src/3rdparty/webkit/WebCore/generated/tokenizer.cpp +++ b/src/3rdparty/webkit/WebCore/generated/tokenizer.cpp @@ -78,42 +78,42 @@ static yyconst flex_int16_t yy_accept[479] = { 0, 0, 0, 0, 0, 0, 0, 69, 67, 2, 2, 67, 67, 67, 67, 67, 67, 67, 67, 67, 56, - 67, 67, 67, 67, 15, 15, 15, 67, 67, 66, + 67, 67, 15, 15, 15, 67, 67, 67, 67, 66, 15, 15, 15, 65, 15, 2, 0, 0, 0, 14, - 0, 0, 0, 0, 18, 18, 8, 0, 0, 9, - 0, 0, 0, 15, 15, 15, 57, 0, 55, 0, - 0, 56, 0, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 16, 54, 54, 51, 54, 0, 0, - 0, 35, 35, 35, 35, 35, 35, 35, 15, 15, - 7, 62, 15, 0, 0, 15, 15, 0, 15, 6, + 0, 0, 0, 18, 18, 0, 8, 0, 0, 9, + 0, 0, 15, 15, 15, 0, 57, 0, 55, 0, + 0, 56, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 16, 54, 54, 51, 54, 0, 54, 0, 0, + 35, 35, 35, 35, 35, 35, 35, 0, 62, 15, + 0, 0, 15, 15, 0, 15, 15, 15, 7, 6, 5, 15, 15, 15, 15, 0, 0, 0, 14, 0, - 0, 0, 18, 18, 18, 0, 18, 0, 0, 14, - 0, 0, 4, 16, 15, 0, 0, 54, 54, 54, - 0, 54, 41, 54, 37, 39, 54, 52, 43, 54, - 42, 50, 54, 45, 44, 40, 54, 54, 0, 35, - 35, 35, 35, 0, 35, 35, 35, 35, 35, 35, - 15, 15, 15, 16, 15, 15, 63, 63, 15, 12, - 10, 15, 13, 0, 0, 0, 17, 18, 18, 18, - 17, 0, 0, 15, 0, 1, 54, 54, 54, 54, - 46, 54, 53, 16, 47, 54, 3, 35, 35, 35, - - 35, 35, 35, 35, 35, 35, 35, 15, 15, 58, - 0, 63, 63, 63, 62, 11, 0, 0, 0, 18, - 18, 18, 0, 15, 0, 0, 54, 54, 54, 48, - 49, 35, 35, 35, 35, 35, 35, 35, 35, 20, - 15, 15, 64, 63, 63, 63, 63, 0, 0, 0, - 0, 60, 0, 0, 0, 0, 18, 18, 18, 0, - 15, 54, 54, 38, 35, 35, 35, 35, 35, 35, - 21, 35, 15, 15, 64, 63, 63, 63, 63, 63, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, - 0, 0, 0, 0, 17, 18, 18, 17, 0, 15, - - 54, 54, 35, 35, 35, 35, 35, 19, 35, 15, - 15, 64, 63, 63, 63, 63, 63, 63, 0, 59, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 18, 18, 0, 15, 54, 54, 35, - 35, 35, 23, 35, 35, 15, 64, 63, 63, 63, + 0, 0, 18, 18, 0, 18, 18, 0, 0, 14, + 0, 0, 4, 16, 15, 0, 0, 54, 0, 41, + 54, 37, 39, 54, 52, 43, 54, 42, 50, 54, + 45, 44, 40, 54, 54, 54, 54, 54, 0, 35, + 35, 0, 35, 35, 35, 35, 35, 35, 35, 35, + 15, 15, 16, 15, 15, 63, 63, 15, 15, 12, + 10, 15, 13, 0, 0, 0, 17, 17, 18, 18, + 18, 0, 0, 15, 0, 1, 54, 54, 46, 54, + 53, 16, 47, 54, 54, 54, 3, 35, 35, 35, + + 35, 35, 35, 35, 35, 35, 35, 15, 58, 0, + 63, 63, 63, 62, 15, 11, 0, 0, 0, 18, + 18, 18, 0, 15, 0, 0, 54, 48, 49, 54, + 54, 35, 35, 35, 35, 35, 35, 35, 20, 35, + 15, 64, 63, 63, 63, 63, 0, 0, 0, 0, + 60, 0, 15, 0, 0, 0, 18, 18, 18, 0, + 15, 54, 54, 38, 35, 35, 35, 35, 35, 21, + 35, 35, 15, 64, 63, 63, 63, 63, 63, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, + 0, 15, 0, 0, 17, 17, 18, 18, 0, 15, + + 54, 54, 35, 35, 35, 35, 19, 35, 35, 15, + 64, 63, 63, 63, 63, 63, 63, 0, 59, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 15, 0, 0, 18, 18, 0, 15, 54, 54, 35, + 35, 23, 35, 35, 35, 15, 64, 63, 63, 63, 63, 63, 63, 63, 0, 59, 0, 0, 0, 59, 0, 0, 0, 0, 18, 15, 54, 35, 35, 35, 35, 64, 0, 0, 0, 36, 15, 35, 35, 35, @@ -122,7 +122,7 @@ static yyconst flex_int16_t yy_accept[479] = 35, 35, 35, 35, 35, 35, 35, 35, 0, 0, 0, 0, 0, 0, 35, 35, 35, 35, 25, 35, - 35, 35, 0, 0, 0, 61, 0, 0, 26, 35, + 35, 35, 0, 61, 0, 0, 0, 0, 26, 35, 35, 35, 35, 27, 35, 0, 0, 0, 0, 31, 35, 35, 35, 35, 0, 0, 0, 35, 35, 35, 35, 0, 0, 35, 35, 29, 35, 0, 0, 35, @@ -138,437 +138,909 @@ static yyconst flex_int32_t yy_ec[256] = 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 12, 18, 19, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 12, 22, 23, - 24, 25, 26, 27, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 12, 28, 12, 29, 30, 12, 31, 32, 33, 34, - - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 12, 59, 1, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, - 60, 60, 60, 60, 60 + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 12, 54, 12, 55, 56, 12, 57, 58, 59, 60, + + 61, 62, 63, 64, 65, 37, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 12, 84, 1, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85 } ; -static yyconst flex_int32_t yy_meta[61] = +static yyconst flex_int32_t yy_meta[86] = { 0, - 1, 2, 3, 3, 3, 4, 5, 5, 5, 5, - 5, 5, 5, 6, 7, 5, 5, 8, 5, 5, - 9, 5, 5, 5, 5, 10, 5, 11, 5, 11, - 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 5, 5, 5, 11 + 1, 2, 3, 4, 4, 5, 6, 7, 6, 6, + 6, 6, 7, 8, 9, 6, 6, 10, 6, 6, + 11, 6, 6, 6, 6, 12, 6, 13, 13, 13, + 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 6, 14, 13, 13, 13, 13, + 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 6, 6, 6, 14 } ; -static yyconst flex_int16_t yy_base[517] = +static yyconst flex_int16_t yy_base[550] = { 0, - 0, 0, 39, 41, 1573, 1566, 1594, 2399, 62, 71, - 76, 61, 69, 1560, 78, 1559, 89, 1561, 1565, 132, - 1573, 91, 123, 1555, 80, 104, 97, 1554, 1551, 2399, - 85, 176, 175, 2399, 177, 193, 204, 1531, 84, 2399, - 242, 110, 180, 196, 1545, 205, 2399, 113, 277, 2399, - 1547, 72, 221, 133, 206, 234, 181, 1555, 1548, 1530, - 1528, 0, 268, 118, 1515, 221, 60, 240, 92, 230, - 95, 223, 244, 267, 238, 286, 1512, 268, 1521, 279, - 294, 1510, 278, 190, 290, 232, 292, 293, 308, 335, - 2399, 2399, 317, 326, 1516, 351, 336, 356, 366, 2399, - - 2399, 320, 367, 369, 370, 1478, 393, 327, 345, 420, - 455, 398, 1495, 490, 1481, 446, 481, 372, 365, 386, - 525, 560, 2399, 325, 388, 1491, 387, 1477, 595, 1476, - 516, 399, 1475, 34, 1472, 1461, 378, 1438, 1430, 318, - 1429, 1426, 323, 1424, 1423, 1422, 231, 387, 1430, 377, - 1411, 630, 1396, 551, 382, 108, 415, 408, 419, 412, - 586, 436, 665, 1400, 624, 456, 419, 1382, 457, 490, - 491, 625, 492, 1362, 526, 656, 672, 681, 1378, 716, - 707, 527, 723, 561, 1374, 2399, 732, 1346, 767, 437, - 1322, 410, 1312, 445, 1311, 546, 2399, 469, 758, 1303, - - 802, 576, 482, 580, 470, 440, 472, 793, 809, 2399, - 818, 515, 1288, 1273, 853, 552, 1205, 839, 855, 861, - 877, 883, 899, 645, 1227, 483, 905, 921, 612, 1183, - 1168, 609, 927, 943, 626, 517, 628, 508, 629, 1167, - 949, 965, 971, 550, 1167, 1157, 1123, 1006, 1020, 666, - 682, 2399, 1047, 1091, 1006, 1038, 1055, 1063, 1071, 1079, - 632, 1087, 1095, 1105, 539, 1103, 1111, 542, 543, 681, - 1097, 683, 1119, 1127, 1135, 585, 1091, 1083, 1067, 1039, - 721, 752, 772, 1170, 717, 1205, 1184, 1217, 1244, 1258, - 1285, 1320, 984, 1244, 2399, 1276, 1311, 917, 1328, 767, - - 1336, 1344, 733, 1352, 1360, 734, 578, 899, 582, 1395, - 1381, 1397, 623, 853, 822, 794, 793, 760, 807, 2399, - 875, 788, 1432, 1459, 1494, 818, 769, 1440, 1529, 1564, - 1438, 702, 1485, 919, 1520, 1555, 849, 963, 1572, 587, - 1299, 1580, 706, 441, 614, 1615, 1601, 715, 2399, 2399, - 2399, 2399, 2399, 2399, 1473, 839, 856, 1617, 1652, 804, - 852, 1638, 1654, 633, 1480, 871, 1508, 1650, 1542, 644, - 834, 1673, 1679, 1695, 1701, 2399, 1015, 872, 915, 916, - 877, 959, 704, 616, 586, 2399, 1717, 1723, 1739, 1002, - 1148, 514, 961, 989, 990, 1016, 1745, 1761, 1767, 1802, - - 1137, 1008, 1018, 1017, 985, 1129, 878, 1038, 1790, 1806, - 1829, 1211, 1827, 1849, 944, 1057, 1152, 787, 584, 615, - 1196, 918, 1863, 1890, 1279, 2399, 1869, 1867, 516, 1199, - 1154, 943, 1242, 515, 653, 1904, 1906, 1941, 1968, 480, - 945, 1200, 1149, 1214, 1927, 1949, 1947, 1239, 1301, 1207, - 1302, 1974, 1990, 1392, 1267, 411, 1354, 1996, 2012, 1310, - 376, 1241, 1039, 2018, 2034, 1338, 348, 1377, 2040, 1216, - 1391, 1421, 1394, 324, 1226, 1376, 263, 2399, 2075, 2080, - 2091, 2096, 2101, 2110, 2117, 2128, 2137, 2142, 2153, 2165, - 2167, 2176, 2181, 2190, 2195, 2204, 2213, 2225, 2234, 2243, - - 2248, 2260, 2265, 2276, 2281, 2292, 2303, 2314, 2319, 2330, - 2341, 2346, 2357, 2366, 2377, 2386 + 0, 0, 64, 66, 54, 56, 1407, 6578, 93, 98, + 107, 83, 155, 1376, 77, 1350, 99, 1345, 1328, 207, + 1334, 275, 100, 108, 125, 326, 1315, 1313, 1312, 6578, + 141, 110, 151, 6578, 105, 197, 295, 89, 107, 6578, + 387, 120, 0, 429, 1281, 471, 6578, 117, 532, 6578, + 1283, 269, 137, 176, 281, 574, 283, 1289, 1292, 1246, + 1257, 0, 1221, 249, 135, 282, 276, 153, 91, 169, + 299, 308, 318, 266, 1219, 320, 616, 102, 1246, 348, + 1209, 316, 127, 359, 346, 347, 375, 658, 6578, 208, + 700, 1241, 400, 409, 1220, 397, 327, 761, 6578, 6578, + + 6578, 411, 419, 414, 424, 248, 368, 355, 356, 822, + 883, 0, 1191, 925, 967, 1190, 1028, 381, 421, 464, + 1089, 1150, 6578, 214, 456, 1225, 312, 1151, 1192, 1142, + 442, 1139, 1134, 452, 1131, 1104, 458, 1082, 1060, 358, + 1046, 1028, 1027, 462, 453, 1000, 1253, 469, 1023, 463, + 986, 1295, 492, 486, 500, 484, 502, 513, 969, 1356, + 425, 1417, 1001, 545, 494, 193, 993, 543, 1459, 544, + 554, 558, 555, 508, 398, 1520, 0, 1562, 956, 1623, + 1684, 570, 1745, 563, 993, 6578, 948, 1806, 935, 520, + 921, 498, 914, 546, 1848, 564, 6578, 585, 913, 1909, + + 568, 576, 586, 606, 631, 640, 1951, 2012, 6578, 0, + 203, 924, 907, 694, 2054, 565, 543, 2115, 0, 2157, + 2218, 2279, 2340, 669, 912, 505, 2401, 856, 840, 2443, + 612, 615, 2504, 608, 557, 639, 682, 668, 839, 2546, + 2607, 0, 288, 863, 841, 819, 741, 794, 573, 418, + 6578, 2668, 2710, 620, 2771, 0, 2813, 2874, 2935, 2996, + 3057, 3131, 3173, 3234, 670, 3295, 718, 719, 729, 763, + 684, 3337, 3398, 0, 456, 782, 777, 760, 742, 829, + 649, 834, 3459, 572, 3520, 854, 894, 915, 920, 3581, + 3642, 3684, 593, 3745, 6578, 697, 3806, 3867, 3928, 3989, + + 4050, 4111, 730, 4172, 731, 683, 672, 759, 4214, 4275, + 0, 762, 682, 429, 417, 414, 411, 859, 6578, 650, + 838, 957, 4336, 4397, 607, 926, 988, 4458, 4519, 4580, + 1002, 672, 1010, 4622, 4664, 1042, 752, 4706, 4767, 756, + 4828, 376, 812, 847, 1069, 1033, 0, 387, 6578, 6578, + 6578, 6578, 6578, 6578, 1122, 924, 963, 4870, 1162, 1049, + 1050, 4912, 4973, 678, 1063, 850, 1074, 5005, 1103, 841, + 989, 0, 5062, 5104, 5146, 6578, 1066, 1080, 1081, 1084, + 1108, 1137, 877, 328, 273, 6578, 5188, 5230, 5272, 641, + 1140, 884, 916, 836, 1105, 1161, 5314, 5356, 1233, 1286, + + 1147, 1138, 919, 1206, 1165, 1186, 1141, 1207, 1291, 1263, + 1316, 1345, 1327, 5398, 1086, 1029, 1225, 1133, 258, 1247, + 1248, 1310, 1388, 6578, 1427, 5440, 1449, 5501, 242, 1311, + 1341, 1324, 1326, 173, 1317, 1454, 5562, 1480, 5604, 170, + 1061, 1328, 1355, 1372, 1552, 5646, 5688, 1351, 1374, 1389, + 1409, 5730, 5772, 1419, 1456, 154, 1453, 5814, 5856, 1457, + 112, 897, 793, 5898, 1557, 1418, 109, 1348, 1582, 1550, + 1477, 1481, 1485, 90, 1564, 1458, 39, 6578, 5959, 5964, + 5977, 5982, 5987, 5994, 6004, 6017, 296, 6022, 6032, 6045, + 6059, 651, 6064, 6074, 6079, 6089, 6099, 6103, 571, 6112, + + 6125, 6138, 6152, 6166, 6176, 6186, 6191, 6203, 657, 6217, + 758, 6222, 6234, 6247, 801, 6261, 859, 6266, 6278, 6291, + 6304, 6317, 6330, 1086, 6335, 6348, 1120, 6353, 6365, 6378, + 6391, 6404, 6417, 6430, 6435, 6448, 1216, 6453, 6465, 6478, + 6491, 6504, 6517, 1219, 1220, 6530, 6543, 6553, 6563 } ; -static yyconst flex_int16_t yy_def[517] = +static yyconst flex_int16_t yy_def[550] = { 0, 478, 1, 1, 1, 1, 1, 478, 478, 478, 478, 478, 479, 480, 478, 481, 478, 482, 478, 478, 478, - 478, 483, 484, 478, 485, 485, 485, 478, 478, 478, - 485, 485, 485, 478, 485, 478, 478, 478, 479, 478, - 486, 480, 478, 487, 488, 488, 478, 481, 489, 478, - 478, 478, 484, 485, 485, 485, 20, 490, 478, 491, - 478, 20, 492, 493, 493, 493, 493, 493, 493, 493, - 493, 493, 493, 493, 493, 493, 493, 493, 478, 483, - 494, 495, 495, 495, 495, 495, 495, 495, 485, 485, - 478, 478, 485, 496, 478, 485, 485, 478, 485, 478, - - 478, 485, 485, 485, 485, 478, 479, 479, 479, 479, - 486, 478, 488, 46, 488, 497, 46, 481, 481, 481, - 481, 489, 478, 478, 485, 490, 498, 493, 493, 493, - 499, 493, 493, 493, 493, 493, 493, 493, 493, 493, + 478, 483, 484, 484, 484, 485, 478, 478, 478, 478, + 484, 484, 484, 478, 484, 478, 478, 478, 479, 478, + 486, 480, 487, 488, 488, 489, 478, 481, 490, 478, + 478, 478, 484, 484, 484, 485, 20, 491, 478, 492, + 478, 20, 493, 493, 493, 493, 493, 493, 493, 493, + 493, 493, 493, 493, 493, 493, 494, 493, 478, 483, + 495, 495, 495, 495, 495, 495, 495, 496, 478, 484, + 497, 478, 484, 484, 498, 484, 484, 484, 478, 478, + + 478, 484, 484, 484, 484, 478, 479, 479, 479, 479, + 486, 499, 488, 488, 500, 488, 114, 501, 501, 501, + 501, 502, 478, 478, 484, 503, 504, 493, 505, 493, + 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 478, 495, - 495, 495, 495, 500, 495, 495, 495, 495, 495, 495, - 90, 485, 90, 478, 485, 485, 501, 478, 485, 485, - 485, 485, 485, 478, 479, 110, 478, 114, 488, 114, - 46, 481, 121, 485, 502, 478, 129, 493, 129, 493, - 493, 493, 493, 493, 493, 493, 478, 495, 152, 495, - - 152, 495, 495, 495, 495, 495, 495, 90, 163, 478, - 478, 503, 478, 478, 504, 485, 478, 110, 478, 114, - 180, 46, 121, 485, 502, 498, 129, 189, 493, 493, - 493, 495, 152, 201, 495, 495, 495, 495, 495, 495, - 90, 163, 478, 505, 478, 478, 478, 504, 504, 506, - 507, 478, 508, 478, 110, 478, 114, 180, 46, 121, - 485, 129, 189, 493, 495, 152, 201, 495, 495, 495, - 495, 495, 90, 163, 478, 509, 478, 478, 478, 478, - 478, 506, 478, 510, 507, 511, 504, 504, 504, 504, - 504, 508, 478, 110, 478, 114, 180, 488, 121, 485, - - 129, 189, 495, 152, 201, 495, 495, 495, 495, 485, - 163, 478, 512, 478, 478, 478, 478, 478, 478, 478, - 506, 506, 506, 506, 510, 507, 507, 507, 507, 511, - 291, 478, 110, 488, 180, 121, 485, 493, 189, 495, - 495, 201, 495, 495, 495, 485, 478, 478, 478, 478, - 478, 478, 478, 478, 506, 506, 506, 324, 507, 507, - 507, 329, 291, 478, 488, 485, 493, 495, 495, 495, - 495, 478, 324, 329, 291, 478, 485, 495, 495, 495, - 495, 495, 495, 495, 495, 478, 324, 329, 291, 485, - 495, 495, 495, 495, 495, 495, 324, 329, 291, 513, - - 495, 495, 495, 495, 495, 495, 495, 495, 324, 329, - 513, 411, 514, 515, 495, 495, 495, 495, 495, 495, - 495, 495, 515, 515, 478, 478, 515, 516, 495, 495, - 495, 495, 495, 495, 495, 515, 424, 515, 424, 495, - 495, 495, 495, 495, 424, 515, 439, 495, 495, 495, - 495, 424, 439, 495, 495, 495, 495, 424, 439, 495, - 495, 495, 495, 424, 439, 495, 495, 495, 439, 495, + 495, 506, 495, 495, 495, 495, 495, 495, 495, 495, + 484, 98, 478, 484, 484, 507, 478, 484, 98, 484, + 484, 484, 484, 478, 508, 508, 509, 114, 488, 114, + 114, 501, 501, 484, 510, 478, 493, 147, 493, 493, + 493, 493, 493, 493, 147, 493, 478, 495, 495, 160, + + 495, 495, 495, 495, 495, 495, 160, 98, 478, 511, + 512, 478, 478, 513, 98, 484, 478, 514, 515, 114, + 114, 114, 501, 484, 510, 516, 147, 493, 493, 147, + 493, 495, 160, 495, 495, 495, 495, 495, 495, 160, + 98, 517, 518, 478, 478, 478, 519, 519, 520, 521, + 478, 522, 98, 478, 523, 524, 525, 525, 258, 526, + 98, 147, 147, 147, 495, 160, 495, 495, 495, 495, + 495, 160, 98, 527, 528, 478, 478, 478, 478, 478, + 520, 478, 529, 530, 531, 532, 532, 532, 532, 532, + 533, 98, 478, 534, 478, 535, 535, 297, 536, 98, + + 147, 301, 495, 160, 495, 495, 495, 495, 160, 98, + 537, 538, 478, 478, 478, 478, 478, 478, 478, 539, + 539, 539, 539, 540, 541, 541, 541, 541, 542, 543, + 300, 478, 534, 297, 298, 536, 300, 301, 301, 495, + 160, 495, 495, 495, 495, 300, 544, 478, 478, 478, + 478, 478, 478, 478, 539, 539, 539, 323, 541, 541, + 541, 328, 543, 478, 335, 300, 339, 495, 495, 495, + 495, 545, 323, 328, 363, 478, 300, 495, 495, 495, + 495, 495, 495, 495, 495, 478, 323, 328, 363, 300, + 495, 495, 495, 495, 495, 495, 323, 328, 543, 546, + + 495, 495, 495, 495, 495, 495, 495, 495, 539, 541, + 546, 546, 547, 548, 495, 495, 495, 495, 495, 495, + 495, 495, 478, 478, 547, 549, 547, 547, 495, 495, + 495, 495, 495, 495, 495, 547, 428, 547, 428, 495, + 495, 495, 495, 495, 547, 437, 428, 495, 495, 495, + 495, 437, 428, 495, 495, 495, 495, 437, 428, 495, + 495, 495, 495, 437, 547, 495, 495, 495, 547, 495, 495, 495, 495, 495, 495, 495, 495, 0, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478 + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478 } ; -static yyconst flex_int16_t yy_nxt[2460] = +static yyconst flex_int16_t yy_nxt[6664] = { 0, 8, 9, 10, 9, 9, 9, 11, 12, 13, 14, 8, 8, 15, 8, 8, 16, 8, 17, 18, 19, - 20, 8, 21, 8, 8, 8, 22, 23, 24, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 26, 25, 25, 25, 25, 25, 25, - 27, 25, 25, 25, 25, 25, 8, 28, 29, 25, - 30, 131, 30, 36, 36, 36, 36, 36, 40, 31, - 191, 31, 36, 36, 36, 36, 36, 37, 37, 37, - 37, 37, 32, 33, 32, 33, 42, 131, 41, 43, - 40, 40, 52, 92, 134, 34, 44, 34, 92, 46, - - 46, 46, 46, 46, 46, 49, 51, 94, 80, 52, - 92, 41, 94, 98, 38, 124, 53, 92, 81, 131, - 95, 96, 131, 83, 94, 40, 84, 478, 102, 85, - 478, 94, 55, 86, 87, 154, 88, 44, 139, 137, - 49, 56, 59, 90, 99, 131, 92, 132, 97, 60, - 61, 203, 62, 90, 90, 90, 90, 90, 90, 63, - 94, 64, 65, 65, 66, 67, 68, 65, 69, 70, - 71, 65, 72, 65, 73, 74, 65, 75, 65, 76, - 77, 78, 65, 65, 65, 65, 65, 65, 92, 92, - 92, 65, 95, 96, 36, 36, 36, 36, 36, 478, - - 112, 57, 94, 94, 94, 37, 37, 37, 37, 37, - 112, 112, 112, 112, 112, 112, 114, 154, 104, 92, - 103, 105, 95, 96, 65, 117, 114, 114, 114, 114, - 114, 114, 116, 94, 156, 117, 117, 117, 117, 117, - 117, 90, 38, 39, 39, 39, 107, 92, 131, 109, - 131, 90, 90, 90, 90, 90, 90, 131, 131, 154, - 140, 94, 110, 133, 195, 131, 158, 131, 125, 111, - 144, 131, 110, 110, 110, 110, 110, 110, 48, 48, - 48, 118, 135, 95, 143, 138, 141, 145, 129, 120, - 154, 146, 142, 136, 131, 131, 478, 121, 129, 129, - - 129, 129, 129, 129, 122, 154, 81, 121, 121, 121, - 121, 121, 121, 131, 152, 155, 147, 154, 148, 154, - 154, 92, 159, 160, 152, 152, 152, 152, 152, 152, - 92, 150, 157, 92, 40, 94, 89, 89, 89, 89, - 89, 95, 95, 194, 94, 131, 163, 94, 92, 92, - 131, 154, 40, 170, 41, 161, 163, 163, 163, 163, - 163, 163, 94, 94, 92, 161, 161, 161, 161, 161, - 161, 165, 41, 193, 48, 154, 167, 40, 94, 92, - 92, 168, 92, 92, 40, 166, 167, 167, 167, 167, - 167, 167, 49, 94, 94, 39, 94, 94, 40, 49, - - 40, 92, 127, 154, 154, 131, 186, 169, 192, 154, - 172, 198, 202, 49, 131, 94, 171, 173, 177, 184, - 41, 108, 175, 175, 175, 108, 131, 40, 177, 177, - 177, 177, 177, 177, 196, 154, 211, 131, 154, 154, - 176, 205, 154, 230, 213, 190, 154, 41, 207, 92, - 176, 176, 176, 176, 176, 176, 39, 39, 39, 107, - 204, 206, 109, 94, 131, 194, 180, 154, 154, 210, - 215, 229, 131, 370, 239, 110, 180, 180, 180, 180, - 180, 180, 111, 94, 94, 110, 110, 110, 110, 110, - 110, 113, 113, 113, 113, 113, 154, 154, 226, 154, - - 232, 181, 186, 92, 210, 92, 240, 154, 238, 154, - 178, 181, 181, 181, 181, 181, 181, 94, 94, 94, - 178, 178, 178, 178, 178, 178, 119, 182, 182, 182, - 119, 236, 211, 40, 269, 154, 189, 40, 271, 40, - 245, 154, 154, 154, 154, 183, 189, 189, 189, 189, - 189, 189, 49, 41, 49, 183, 183, 183, 183, 183, - 183, 48, 48, 48, 118, 92, 154, 211, 403, 154, - 154, 201, 120, 131, 92, 277, 306, 303, 307, 94, - 121, 201, 201, 201, 201, 201, 201, 122, 94, 231, - 121, 121, 121, 121, 121, 121, 128, 128, 128, 128, - - 128, 224, 211, 154, 368, 154, 208, 154, 344, 154, - 314, 154, 345, 154, 154, 187, 208, 208, 208, 208, - 208, 208, 131, 235, 237, 187, 187, 187, 187, 187, - 187, 151, 151, 151, 151, 151, 154, 92, 92, 131, - 211, 154, 154, 154, 165, 92, 371, 433, 349, 265, - 199, 94, 94, 154, 264, 154, 154, 154, 92, 94, - 199, 199, 199, 199, 199, 199, 162, 162, 162, 162, - 162, 154, 94, 283, 268, 270, 218, 272, 384, 216, - 154, 300, 376, 261, 444, 209, 218, 218, 218, 218, - 218, 218, 219, 284, 283, 209, 209, 209, 209, 209, - - 209, 220, 219, 219, 219, 219, 219, 219, 154, 286, - 154, 220, 220, 220, 220, 220, 220, 179, 179, 179, - 179, 179, 281, 281, 281, 281, 281, 222, 309, 283, - 308, 154, 211, 154, 396, 252, 221, 222, 222, 222, - 222, 222, 222, 223, 286, 364, 221, 221, 221, 221, - 221, 221, 227, 223, 223, 223, 223, 223, 223, 283, - 154, 154, 227, 227, 227, 227, 227, 227, 188, 188, - 188, 188, 188, 319, 319, 319, 319, 319, 233, 284, - 92, 283, 340, 343, 337, 354, 320, 228, 233, 233, - 233, 233, 233, 233, 94, 283, 286, 228, 228, 228, - - 228, 228, 228, 200, 200, 200, 200, 200, 319, 319, - 319, 319, 319, 241, 154, 284, 283, 432, 353, 352, - 285, 320, 234, 241, 241, 241, 241, 241, 241, 242, - 283, 286, 234, 234, 234, 234, 234, 234, 243, 242, - 242, 242, 242, 242, 242, 286, 283, 351, 243, 243, - 243, 243, 243, 243, 248, 248, 248, 248, 248, 255, - 250, 154, 92, 283, 283, 251, 284, 252, 385, 255, - 255, 255, 255, 255, 255, 256, 94, 282, 350, 286, - 253, 257, 283, 284, 92, 256, 256, 256, 256, 256, - 256, 257, 257, 257, 257, 257, 257, 258, 94, 154, - - 366, 377, 284, 259, 154, 154, 391, 258, 258, 258, - 258, 258, 258, 259, 259, 259, 259, 259, 259, 260, - 113, 113, 113, 113, 113, 262, 154, 394, 421, 260, - 260, 260, 260, 260, 260, 262, 262, 262, 262, 262, - 262, 263, 154, 154, 116, 154, 116, 266, 435, 392, - 393, 263, 263, 263, 263, 263, 263, 266, 266, 266, - 266, 266, 266, 267, 128, 128, 128, 128, 128, 273, - 154, 154, 154, 267, 267, 267, 267, 267, 267, 273, - 273, 273, 273, 273, 273, 274, 154, 448, 154, 442, - 131, 275, 429, 395, 404, 274, 274, 274, 274, 274, - - 274, 275, 275, 275, 275, 275, 275, 248, 248, 248, - 248, 248, 154, 250, 332, 400, 154, 154, 251, 419, - 252, 281, 281, 281, 281, 281, 294, 478, 92, 94, - 405, 406, 478, 253, 252, 154, 294, 294, 294, 294, - 294, 294, 94, 154, 154, 154, 416, 253, 281, 281, - 281, 281, 287, 417, 289, 418, 468, 407, 295, 289, - 289, 290, 390, 408, 318, 154, 154, 291, 295, 295, - 295, 295, 295, 295, 292, 296, 422, 291, 291, 291, - 291, 291, 291, 297, 154, 296, 296, 296, 296, 296, - 296, 298, 317, 297, 297, 297, 297, 297, 297, 299, - - 430, 298, 298, 298, 298, 298, 298, 301, 316, 299, - 299, 299, 299, 299, 299, 302, 315, 301, 301, 301, - 301, 301, 301, 304, 154, 302, 302, 302, 302, 302, - 302, 305, 131, 304, 304, 304, 304, 304, 304, 310, - 293, 305, 305, 305, 305, 305, 305, 311, 280, 310, - 310, 310, 310, 310, 310, 312, 154, 311, 311, 311, - 311, 311, 311, 420, 154, 312, 312, 312, 312, 312, - 312, 282, 282, 282, 321, 154, 154, 323, 415, 154, - 401, 154, 279, 402, 441, 281, 281, 281, 281, 281, - 324, 478, 278, 450, 154, 131, 478, 325, 252, 431, - - 324, 324, 324, 324, 324, 324, 285, 285, 285, 326, - 131, 253, 478, 478, 478, 478, 478, 328, 281, 281, - 281, 281, 281, 154, 478, 329, 154, 154, 478, 478, - 434, 252, 330, 440, 154, 329, 329, 329, 329, 329, - 329, 154, 226, 154, 253, 281, 281, 281, 281, 281, - 449, 478, 254, 154, 456, 451, 478, 472, 252, 281, - 281, 281, 281, 281, 333, 478, 154, 476, 154, 154, - 478, 253, 252, 454, 333, 333, 333, 333, 333, 333, - 425, 425, 425, 425, 425, 253, 287, 287, 287, 287, - 287, 443, 478, 426, 154, 467, 334, 478, 247, 252, - - 151, 151, 151, 151, 151, 331, 334, 334, 334, 334, - 334, 334, 253, 246, 462, 331, 331, 331, 331, 331, - 331, 281, 281, 281, 281, 287, 154, 289, 154, 154, - 154, 335, 289, 289, 290, 455, 457, 154, 131, 131, - 291, 335, 335, 335, 335, 335, 335, 292, 336, 131, - 291, 291, 291, 291, 291, 291, 338, 466, 336, 336, - 336, 336, 336, 336, 339, 154, 338, 338, 338, 338, - 338, 338, 341, 131, 339, 339, 339, 339, 339, 339, - 342, 154, 341, 341, 341, 341, 341, 341, 470, 226, - 342, 342, 342, 342, 342, 342, 89, 89, 89, 89, - - 89, 346, 463, 154, 154, 116, 217, 214, 92, 460, - 471, 346, 346, 346, 346, 346, 346, 347, 154, 154, - 164, 154, 94, 154, 477, 473, 475, 347, 347, 347, - 347, 347, 347, 355, 319, 319, 319, 355, 154, 283, - 461, 359, 319, 319, 319, 359, 356, 197, 154, 131, - 131, 131, 283, 131, 360, 474, 131, 131, 363, 284, - 322, 357, 357, 357, 322, 131, 283, 286, 363, 363, - 363, 363, 363, 363, 355, 319, 319, 319, 355, 358, - 283, 179, 179, 179, 179, 179, 284, 356, 131, 358, - 358, 358, 358, 358, 358, 282, 282, 282, 321, 131, - - 284, 323, 131, 131, 131, 39, 127, 116, 116, 188, - 188, 188, 188, 188, 324, 39, 39, 39, 39, 39, - 39, 325, 116, 174, 324, 324, 324, 324, 324, 324, - 327, 361, 361, 361, 327, 131, 164, 154, 149, 131, - 365, 283, 131, 200, 200, 200, 200, 200, 57, 362, - 365, 365, 365, 365, 365, 365, 286, 63, 59, 362, - 362, 362, 362, 362, 362, 285, 285, 285, 326, 154, - 127, 123, 116, 106, 101, 48, 328, 100, 91, 79, - 58, 57, 50, 47, 329, 48, 48, 48, 48, 48, - 48, 330, 367, 478, 329, 329, 329, 329, 329, 329, - - 369, 35, 367, 367, 367, 367, 367, 367, 35, 478, - 369, 369, 369, 369, 369, 369, 162, 162, 162, 162, - 162, 372, 478, 478, 478, 478, 478, 478, 92, 478, - 478, 372, 372, 372, 372, 372, 372, 373, 478, 478, - 478, 478, 94, 478, 478, 478, 478, 373, 373, 373, - 373, 373, 373, 359, 319, 319, 319, 359, 374, 478, - 478, 478, 478, 478, 283, 478, 360, 478, 374, 374, - 374, 374, 374, 374, 375, 478, 478, 154, 478, 286, - 478, 478, 478, 378, 375, 375, 375, 375, 375, 375, - 379, 478, 380, 386, 478, 478, 478, 381, 382, 387, - - 478, 383, 478, 386, 386, 386, 386, 386, 386, 387, - 387, 387, 387, 387, 387, 388, 478, 478, 478, 478, - 478, 389, 478, 478, 478, 388, 388, 388, 388, 388, - 388, 389, 389, 389, 389, 389, 389, 397, 478, 478, - 478, 478, 478, 398, 478, 478, 478, 397, 397, 397, - 397, 397, 397, 398, 398, 398, 398, 398, 398, 399, - 478, 478, 478, 478, 478, 409, 478, 478, 478, 399, - 399, 399, 399, 399, 399, 409, 409, 409, 409, 409, - 409, 410, 478, 478, 478, 478, 478, 249, 478, 478, - 478, 410, 410, 410, 410, 410, 410, 249, 249, 249, - - 249, 249, 249, 411, 411, 411, 411, 411, 478, 478, - 282, 478, 478, 478, 478, 478, 478, 478, 478, 412, - 282, 282, 282, 282, 282, 282, 285, 478, 478, 413, - 411, 411, 411, 411, 411, 478, 285, 285, 285, 285, - 285, 285, 478, 478, 478, 478, 412, 424, 478, 478, - 425, 425, 425, 425, 425, 478, 413, 424, 424, 424, - 424, 424, 424, 426, 425, 425, 425, 425, 425, 478, - 425, 425, 425, 425, 425, 478, 428, 426, 478, 478, - 478, 478, 478, 426, 478, 478, 478, 439, 478, 478, - 428, 436, 436, 436, 436, 436, 428, 439, 439, 439, - - 439, 439, 439, 478, 426, 425, 425, 425, 425, 425, - 437, 478, 478, 478, 478, 478, 478, 428, 426, 478, - 437, 437, 437, 437, 437, 437, 445, 478, 478, 478, - 478, 428, 478, 478, 478, 478, 445, 445, 445, 445, - 445, 445, 425, 425, 425, 425, 425, 452, 478, 478, - 425, 425, 425, 425, 425, 426, 478, 452, 452, 452, - 452, 452, 452, 426, 478, 478, 478, 453, 428, 446, - 446, 446, 446, 446, 478, 478, 428, 453, 453, 453, - 453, 453, 453, 478, 478, 478, 478, 478, 447, 478, - 478, 478, 478, 478, 458, 478, 478, 478, 447, 447, - - 447, 447, 447, 447, 458, 458, 458, 458, 458, 458, - 459, 478, 478, 478, 478, 478, 464, 478, 478, 478, - 459, 459, 459, 459, 459, 459, 464, 464, 464, 464, - 464, 464, 465, 478, 478, 478, 478, 478, 427, 478, - 478, 478, 465, 465, 465, 465, 465, 465, 427, 427, - 427, 427, 427, 427, 469, 478, 478, 478, 478, 478, - 427, 478, 478, 478, 469, 469, 469, 469, 469, 469, - 427, 427, 427, 427, 427, 427, 39, 478, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 45, 45, 478, - 45, 45, 48, 478, 48, 48, 48, 48, 48, 48, - - 48, 48, 48, 54, 54, 478, 54, 54, 82, 478, - 478, 82, 82, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 93, 478, 93, 93, 478, 93, 93, 108, + 20, 8, 21, 8, 8, 8, 22, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 24, 23, 23, 23, 23, 23, 23, 25, 23, 23, + 23, 23, 23, 26, 27, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 24, 23, + 23, 23, 23, 23, 23, 25, 23, 23, 23, 23, + 23, 8, 28, 29, 23, 30, 35, 30, 35, 40, + 40, 31, 152, 31, 36, 36, 36, 36, 36, 36, + + 36, 36, 36, 36, 32, 33, 32, 33, 37, 37, + 37, 37, 37, 89, 40, 35, 51, 35, 89, 52, + 31, 89, 31, 89, 92, 93, 92, 93, 106, 40, + 49, 136, 32, 33, 32, 33, 41, 478, 89, 54, + 478, 95, 38, 152, 129, 34, 105, 34, 55, 94, + 89, 103, 56, 91, 89, 129, 106, 148, 91, 136, + 41, 91, 152, 91, 89, 152, 131, 54, 154, 96, + 49, 38, 42, 46, 105, 43, 55, 94, 91, 103, + 152, 102, 44, 44, 44, 44, 44, 44, 129, 89, + 91, 104, 92, 93, 91, 131, 154, 96, 36, 36, + + 36, 36, 36, 137, 91, 135, 129, 152, 46, 102, + 210, 44, 44, 44, 44, 44, 44, 59, 212, 104, + 210, 89, 129, 152, 60, 61, 152, 62, 244, 91, + 92, 92, 137, 135, 63, 63, 64, 65, 66, 63, + 67, 68, 69, 63, 70, 63, 71, 72, 63, 73, + 63, 74, 75, 76, 63, 63, 63, 63, 63, 63, + 77, 91, 78, 63, 63, 64, 65, 66, 63, 67, + 68, 69, 70, 63, 71, 72, 63, 73, 63, 74, + 75, 76, 63, 63, 63, 63, 63, 63, 130, 52, + 174, 63, 80, 144, 89, 152, 37, 37, 37, 37, + + 37, 478, 129, 57, 82, 210, 112, 83, 112, 124, + 84, 152, 125, 276, 85, 86, 130, 87, 174, 129, + 134, 132, 144, 63, 92, 140, 152, 127, 88, 129, + 38, 186, 133, 82, 91, 129, 83, 124, 138, 84, + 89, 125, 85, 86, 139, 87, 98, 141, 134, 132, + 153, 63, 129, 98, 98, 98, 98, 98, 98, 38, + 133, 129, 40, 40, 142, 478, 138, 145, 143, 152, + 39, 129, 139, 129, 157, 40, 141, 156, 192, 153, + 91, 152, 98, 98, 98, 98, 98, 98, 39, 39, + 39, 107, 142, 40, 109, 145, 143, 150, 155, 152, + + 152, 88, 158, 157, 210, 40, 156, 110, 41, 41, + 89, 129, 152, 89, 110, 110, 110, 110, 110, 110, + 164, 41, 89, 478, 89, 150, 155, 89, 152, 152, + 282, 158, 89, 40, 49, 168, 354, 89, 89, 353, + 111, 170, 352, 110, 110, 110, 110, 110, 110, 114, + 91, 41, 172, 91, 351, 165, 114, 114, 114, 114, + 114, 114, 91, 168, 91, 171, 478, 91, 173, 89, + 170, 285, 91, 210, 49, 189, 40, 91, 91, 190, + 172, 313, 115, 165, 184, 114, 114, 114, 114, 114, + 114, 117, 193, 171, 198, 129, 173, 194, 117, 117, + + 117, 117, 117, 117, 189, 129, 129, 209, 190, 91, + 191, 129, 196, 184, 204, 129, 152, 49, 192, 201, + 226, 193, 129, 198, 186, 194, 202, 117, 117, 117, + 117, 117, 117, 48, 48, 48, 118, 152, 191, 152, + 196, 205, 203, 204, 120, 152, 206, 91, 201, 217, + 228, 129, 121, 152, 202, 152, 214, 89, 89, 121, + 121, 121, 121, 121, 121, 164, 152, 209, 89, 205, + 203, 89, 478, 129, 268, 206, 89, 217, 89, 228, + 282, 177, 40, 177, 282, 122, 229, 254, 121, 121, + 121, 121, 121, 121, 98, 231, 91, 91, 91, 129, + + 224, 98, 98, 98, 98, 98, 98, 91, 91, 216, + 152, 91, 234, 232, 229, 254, 91, 129, 91, 282, + 332, 152, 235, 49, 231, 285, 283, 236, 224, 152, + 98, 98, 98, 98, 98, 98, 147, 216, 152, 152, + 234, 237, 232, 147, 147, 147, 147, 147, 147, 332, + 235, 264, 265, 267, 400, 236, 282, 282, 90, 152, + 285, 152, 238, 63, 63, 129, 293, 219, 152, 219, + 237, 239, 147, 147, 147, 147, 147, 147, 160, 264, + 265, 267, 89, 269, 152, 160, 160, 160, 160, 160, + 160, 238, 152, 152, 293, 247, 247, 247, 247, 247, + + 239, 249, 283, 283, 261, 303, 250, 350, 251, 270, + 343, 269, 364, 271, 160, 160, 160, 160, 160, 160, + 162, 152, 91, 152, 376, 152, 308, 162, 162, 162, + 162, 162, 162, 261, 303, 152, 152, 152, 270, 343, + 364, 271, 247, 247, 247, 247, 247, 252, 249, 305, + 115, 306, 376, 250, 308, 251, 162, 162, 162, 162, + 162, 162, 97, 97, 97, 97, 97, 317, 242, 90, + 242, 152, 152, 368, 89, 307, 340, 342, 305, 210, + 306, 169, 152, 152, 152, 316, 344, 349, 169, 169, + 169, 169, 169, 169, 252, 280, 280, 280, 280, 280, + + 366, 478, 315, 307, 340, 342, 478, 314, 251, 152, + 468, 256, 152, 256, 91, 344, 152, 169, 169, 169, + 169, 169, 169, 108, 175, 175, 175, 108, 366, 40, + 280, 280, 280, 280, 280, 318, 318, 318, 318, 318, + 478, 370, 176, 251, 279, 282, 152, 252, 319, 176, + 176, 176, 176, 176, 176, 280, 280, 280, 280, 280, + 318, 318, 318, 318, 318, 152, 278, 90, 251, 274, + 370, 274, 384, 319, 405, 41, 371, 377, 176, 176, + 176, 176, 176, 176, 39, 39, 39, 107, 277, 152, + 109, 283, 152, 129, 152, 280, 280, 280, 280, 280, + + 152, 384, 405, 110, 396, 371, 377, 252, 251, 129, + 110, 110, 110, 110, 110, 110, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 478, 226, 478, 251, + 152, 282, 246, 396, 251, 403, 111, 152, 282, 110, + 110, 110, 110, 110, 110, 178, 404, 252, 467, 245, + 152, 417, 178, 178, 178, 178, 178, 178, 355, 318, + 318, 318, 355, 403, 282, 478, 152, 129, 252, 152, + 282, 356, 152, 252, 129, 404, 467, 283, 115, 285, + 417, 178, 178, 178, 178, 178, 178, 180, 129, 359, + 318, 318, 318, 359, 180, 180, 180, 180, 180, 180, + + 282, 129, 360, 97, 97, 97, 97, 97, 226, 115, + 283, 108, 175, 175, 175, 108, 283, 40, 213, 90, + 385, 163, 152, 180, 180, 180, 180, 180, 180, 116, + 116, 116, 116, 116, 161, 161, 161, 161, 161, 152, + 197, 285, 152, 119, 182, 182, 182, 119, 181, 385, + 90, 478, 478, 129, 40, 181, 181, 181, 181, 181, + 181, 282, 282, 41, 179, 179, 179, 179, 179, 430, + 159, 159, 159, 159, 159, 187, 187, 187, 187, 187, + 129, 129, 152, 90, 181, 181, 181, 181, 181, 181, + 119, 182, 182, 182, 119, 49, 295, 430, 295, 129, + + 448, 40, 285, 285, 199, 199, 199, 199, 199, 183, + 390, 391, 392, 129, 152, 393, 183, 183, 183, 183, + 183, 183, 152, 355, 318, 318, 318, 355, 448, 282, + 311, 429, 311, 152, 152, 129, 356, 152, 390, 152, + 391, 392, 49, 406, 393, 183, 183, 183, 183, 183, + 183, 48, 48, 48, 118, 394, 152, 129, 152, 429, + 432, 152, 120, 359, 318, 318, 318, 359, 395, 401, + 121, 406, 402, 416, 282, 283, 360, 121, 121, 121, + 121, 121, 121, 394, 129, 415, 152, 129, 421, 432, + 152, 152, 129, 152, 152, 129, 419, 395, 401, 407, + + 152, 402, 416, 122, 129, 408, 121, 121, 121, 121, + 121, 121, 188, 415, 152, 285, 421, 420, 152, 188, + 188, 188, 188, 188, 188, 419, 347, 407, 347, 372, + 386, 372, 386, 408, 286, 286, 286, 286, 286, 152, + 127, 418, 422, 115, 115, 167, 420, 251, 188, 188, + 188, 188, 188, 188, 146, 146, 146, 146, 146, 152, + 152, 163, 152, 149, 326, 361, 361, 361, 326, 431, + 418, 422, 129, 195, 129, 282, 433, 57, 152, 434, + 195, 195, 195, 195, 195, 195, 252, 411, 411, 411, + 411, 411, 321, 357, 357, 357, 321, 431, 282, 77, + + 152, 152, 59, 412, 127, 433, 129, 123, 434, 195, + 195, 195, 195, 195, 195, 200, 285, 411, 411, 411, + 411, 411, 200, 200, 200, 200, 200, 200, 423, 423, + 423, 423, 423, 412, 115, 101, 100, 435, 99, 414, + 79, 424, 440, 58, 283, 444, 478, 478, 478, 478, + 478, 200, 200, 200, 200, 200, 200, 159, 159, 159, + 159, 159, 478, 152, 152, 57, 435, 442, 441, 414, + 152, 440, 443, 50, 444, 449, 207, 152, 471, 152, + 426, 152, 454, 207, 207, 207, 207, 207, 207, 423, + 423, 423, 423, 423, 152, 442, 450, 441, 414, 47, + + 443, 152, 424, 449, 152, 455, 478, 471, 152, 152, + 451, 454, 207, 207, 207, 207, 207, 207, 161, 161, + 161, 161, 161, 478, 450, 152, 478, 152, 423, 423, + 423, 423, 423, 456, 455, 478, 460, 208, 451, 478, + 457, 424, 152, 478, 208, 208, 208, 208, 208, 208, + 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, + 478, 456, 152, 424, 461, 470, 478, 478, 424, 457, + 478, 152, 152, 208, 208, 208, 208, 208, 208, 215, + 426, 423, 423, 423, 423, 423, 215, 215, 215, 215, + 215, 215, 461, 470, 424, 478, 478, 478, 463, 478, + + 462, 466, 426, 477, 478, 478, 152, 426, 473, 152, + 152, 152, 474, 478, 475, 215, 215, 215, 215, 215, + 215, 108, 175, 175, 175, 108, 463, 40, 462, 466, + 152, 477, 478, 426, 152, 478, 478, 473, 152, 478, + 218, 474, 478, 475, 478, 478, 478, 218, 218, 218, + 218, 218, 218, 423, 423, 423, 423, 423, 438, 438, + 438, 438, 438, 478, 478, 478, 424, 478, 478, 478, + 478, 424, 478, 41, 478, 478, 218, 218, 218, 218, + 218, 218, 220, 445, 445, 445, 445, 445, 472, 220, + 220, 220, 220, 220, 220, 478, 424, 478, 478, 478, + + 478, 478, 476, 152, 478, 426, 478, 478, 478, 478, + 426, 478, 478, 478, 478, 478, 472, 152, 220, 220, + 220, 220, 220, 220, 179, 179, 179, 179, 179, 478, + 476, 478, 478, 478, 478, 426, 478, 478, 478, 478, + 478, 478, 478, 221, 478, 478, 478, 478, 478, 478, + 221, 221, 221, 221, 221, 221, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 221, + 221, 221, 221, 221, 221, 116, 116, 116, 116, 116, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 478, 478, 222, 478, 478, 478, 478, 478, + 478, 222, 222, 222, 222, 222, 222, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 222, 222, 222, 222, 222, 222, 119, 182, 182, 182, + 119, 478, 478, 478, 478, 478, 478, 40, 478, 478, + 478, 478, 478, 478, 478, 223, 478, 478, 478, 478, + 478, 478, 223, 223, 223, 223, 223, 223, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 49, 478, + + 478, 223, 223, 223, 223, 223, 223, 187, 187, 187, + 187, 187, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 227, 478, 478, 478, + 478, 478, 478, 227, 227, 227, 227, 227, 227, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 227, 227, 227, 227, 227, 227, 230, 478, + 478, 478, 478, 478, 478, 230, 230, 230, 230, 230, + 230, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 478, 478, 230, 230, 230, 230, 230, 230, + 199, 199, 199, 199, 199, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 233, + 478, 478, 478, 478, 478, 478, 233, 233, 233, 233, + 233, 233, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 233, 233, 233, 233, 233, + 233, 240, 478, 478, 478, 478, 478, 478, 240, 240, + 240, 240, 240, 240, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 478, 478, 478, 478, 478, 240, 240, 240, + 240, 240, 240, 161, 161, 161, 161, 161, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 241, 478, 478, 478, 478, 478, 478, 241, + 241, 241, 241, 241, 241, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 241, 241, + 241, 241, 241, 241, 253, 478, 478, 478, 478, 478, + 478, 253, 253, 253, 253, 253, 253, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 253, 253, 253, 253, 253, 253, 108, 175, 175, 175, + 108, 478, 40, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 255, 478, 478, 478, 478, + 478, 478, 255, 255, 255, 255, 255, 255, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 41, 478, + 478, 255, 255, 255, 255, 255, 255, 257, 478, 478, + 478, 478, 478, 478, 257, 257, 257, 257, 257, 257, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 257, 257, 257, 257, 257, 257, 179, + 179, 179, 179, 179, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 258, 478, + 478, 478, 478, 478, 478, 258, 258, 258, 258, 258, + 258, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 258, 258, 258, 258, 258, 258, + 116, 116, 116, 116, 116, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 259, + + 478, 478, 478, 478, 478, 478, 259, 259, 259, 259, + 259, 259, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 259, 259, 259, 259, 259, + 259, 119, 182, 182, 182, 119, 478, 478, 478, 478, + 478, 478, 40, 478, 478, 478, 478, 478, 478, 478, + 260, 478, 478, 478, 478, 478, 478, 260, 260, 260, + 260, 260, 260, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 49, 478, 478, 260, 260, 260, 260, + + 260, 260, 187, 187, 187, 187, 187, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 262, 478, 478, 478, 478, 478, 478, 262, 262, + 262, 262, 262, 262, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 262, 262, 262, + 262, 262, 262, 263, 478, 478, 478, 478, 478, 478, + 263, 263, 263, 263, 263, 263, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 263, + + 263, 263, 263, 263, 263, 199, 199, 199, 199, 199, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 266, 478, 478, 478, 478, 478, + 478, 266, 266, 266, 266, 266, 266, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 266, 266, 266, 266, 266, 266, 272, 478, 478, 478, + 478, 478, 478, 272, 272, 272, 272, 272, 272, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 272, 272, 272, 272, 272, 272, 161, 161, + 161, 161, 161, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 273, 478, 478, + 478, 478, 478, 478, 273, 273, 273, 273, 273, 273, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 273, 273, 273, 273, 273, 273, 280, + 280, 280, 280, 286, 478, 288, 478, 478, 478, 478, + 288, 288, 289, 478, 478, 478, 478, 478, 290, 478, + 478, 478, 478, 478, 478, 290, 290, 290, 290, 290, + + 290, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 291, 478, 478, 290, 290, 290, 290, 290, 290, + 292, 478, 478, 478, 478, 478, 478, 292, 292, 292, + 292, 292, 292, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 292, 292, 292, 292, + 292, 292, 108, 175, 175, 175, 108, 478, 40, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 294, 478, 478, 478, 478, 478, 478, 294, 294, + + 294, 294, 294, 294, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 41, 478, 478, 294, 294, 294, + 294, 294, 294, 296, 478, 478, 478, 478, 478, 478, + 296, 296, 296, 296, 296, 296, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 115, 478, 478, 296, + 296, 296, 296, 296, 296, 179, 179, 179, 179, 179, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 297, 478, 478, 478, 478, 478, + + 478, 297, 297, 297, 297, 297, 297, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 115, 478, 478, + 297, 297, 297, 297, 297, 297, 116, 116, 116, 116, + 116, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 298, 478, 478, 478, 478, + 478, 478, 298, 298, 298, 298, 298, 298, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 298, 298, 298, 298, 298, 298, 119, 182, 182, + + 182, 119, 478, 478, 478, 478, 478, 478, 40, 478, + 478, 478, 478, 478, 478, 478, 299, 478, 478, 478, + 478, 478, 478, 299, 299, 299, 299, 299, 299, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 49, + 478, 478, 299, 299, 299, 299, 299, 299, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 90, 478, 478, + 478, 478, 478, 478, 90, 90, 90, 90, 90, 90, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 478, 300, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 90, 90, 90, 90, 90, 90, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 300, 187, 187, 187, 187, 187, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 301, 478, 478, 478, 478, 478, 478, 301, 301, + 301, 301, 301, 301, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 301, 301, 301, + 301, 301, 301, 302, 478, 478, 478, 478, 478, 478, + + 302, 302, 302, 302, 302, 302, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 302, + 302, 302, 302, 302, 302, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 128, 478, 478, 478, 478, 478, + 478, 128, 128, 128, 128, 128, 128, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 128, 128, 128, 128, 128, 128, 199, 199, 199, 199, + + 199, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 304, 478, 478, 478, 478, + 478, 478, 304, 304, 304, 304, 304, 304, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 304, 304, 304, 304, 304, 304, 309, 478, 478, + 478, 478, 478, 478, 309, 309, 309, 309, 309, 309, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 309, 309, 309, 309, 309, 309, 161, + + 161, 161, 161, 161, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 310, 478, + 478, 478, 478, 478, 478, 310, 310, 310, 310, 310, + 310, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 310, 310, 310, 310, 310, 310, + 281, 281, 281, 320, 478, 478, 322, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 323, + 478, 478, 478, 478, 478, 478, 323, 323, 323, 323, + 323, 323, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 324, 478, 478, 323, 323, 323, 323, 323, + 323, 284, 284, 284, 325, 478, 478, 478, 478, 478, + 478, 478, 327, 478, 478, 478, 478, 478, 478, 478, + 328, 478, 478, 478, 478, 478, 478, 328, 328, 328, + 328, 328, 328, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 329, 478, 478, 328, 328, 328, 328, + 328, 328, 286, 286, 286, 286, 286, 478, 478, 478, + 478, 478, 478, 478, 478, 251, 478, 478, 478, 478, + + 478, 330, 478, 478, 478, 478, 478, 478, 330, 330, + 330, 330, 330, 330, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 252, 478, 478, 330, 330, 330, + 330, 330, 330, 280, 280, 280, 280, 286, 478, 288, + 478, 478, 478, 478, 288, 288, 289, 478, 478, 478, + 478, 478, 290, 478, 478, 478, 478, 478, 478, 290, + 290, 290, 290, 290, 290, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 291, 478, 478, 290, 290, + + 290, 290, 290, 290, 331, 478, 478, 478, 478, 478, + 478, 331, 331, 331, 331, 331, 331, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 331, 331, 331, 331, 331, 331, 108, 175, 175, 175, + 108, 478, 40, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 333, 478, 478, 478, 478, + 478, 478, 333, 333, 333, 333, 333, 333, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 41, 478, + + 478, 333, 333, 333, 333, 333, 333, 179, 179, 179, + 179, 179, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 334, 478, 478, 478, + 478, 478, 478, 334, 334, 334, 334, 334, 334, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 115, + 478, 478, 334, 334, 334, 334, 334, 334, 116, 116, + 116, 116, 116, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 335, 478, 478, + 478, 478, 478, 478, 335, 335, 335, 335, 335, 335, + + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 335, 335, 335, 335, 335, 335, 119, + 182, 182, 182, 119, 478, 478, 478, 478, 478, 478, + 40, 478, 478, 478, 478, 478, 478, 478, 336, 478, + 478, 478, 478, 478, 478, 336, 336, 336, 336, 336, + 336, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 49, 478, 478, 336, 336, 336, 336, 336, 336, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 478, 478, 478, 478, 337, 478, 478, 90, + 478, 478, 478, 478, 478, 478, 90, 90, 90, 90, + 90, 90, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 90, 90, 90, 90, 90, + 90, 187, 187, 187, 187, 187, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 338, 478, 478, 478, 478, 478, 478, 338, 338, 338, + 338, 338, 338, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 478, 478, 478, 478, 338, 338, 338, 338, + 338, 338, 146, 146, 146, 146, 146, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 339, 478, 478, 478, 478, 478, 478, 339, 339, + 339, 339, 339, 339, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 339, 339, 339, + 339, 339, 339, 199, 199, 199, 199, 199, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 341, 478, 478, 478, 478, 478, 478, 341, + + 341, 341, 341, 341, 341, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 341, 341, + 341, 341, 341, 341, 345, 478, 478, 478, 478, 478, + 478, 345, 345, 345, 345, 345, 345, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 345, 345, 345, 345, 345, 345, 161, 161, 161, 161, + 161, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 346, 478, 478, 478, 478, + + 478, 478, 346, 346, 346, 346, 346, 346, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 346, 346, 346, 346, 346, 346, 321, 357, 357, + 357, 321, 478, 282, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 358, 478, 478, 478, + 478, 478, 478, 358, 358, 358, 358, 358, 358, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 283, + 478, 478, 358, 358, 358, 358, 358, 358, 281, 281, + + 281, 320, 478, 478, 322, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 323, 478, 478, + 478, 478, 478, 478, 323, 323, 323, 323, 323, 323, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 324, 478, 478, 323, 323, 323, 323, 323, 323, 326, + 361, 361, 361, 326, 478, 478, 478, 478, 478, 478, + 282, 478, 478, 478, 478, 478, 478, 478, 362, 478, + 478, 478, 478, 478, 478, 362, 362, 362, 362, 362, + 362, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 285, 478, 478, 362, 362, 362, 362, 362, 362, + 284, 284, 284, 325, 478, 478, 478, 478, 478, 478, + 478, 327, 478, 478, 478, 478, 478, 478, 478, 328, + 478, 478, 478, 478, 478, 478, 328, 328, 328, 328, + 328, 328, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 329, 478, 478, 328, 328, 328, 328, 328, + 328, 286, 286, 286, 286, 286, 478, 478, 478, 478, + 478, 478, 478, 478, 251, 478, 478, 478, 478, 478, + + 363, 478, 478, 478, 478, 478, 478, 363, 363, 363, + 363, 363, 363, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 252, 478, 478, 363, 363, 363, 363, + 363, 363, 365, 478, 478, 478, 478, 478, 478, 365, + 365, 365, 365, 365, 365, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 365, 365, + 365, 365, 365, 365, 113, 478, 478, 478, 478, 478, + 478, 113, 113, 113, 113, 113, 113, 478, 478, 478, + + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 113, 113, 113, 113, 113, 113, 367, 478, 478, 478, + 478, 478, 478, 367, 367, 367, 367, 367, 367, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 367, 367, 367, 367, 367, 367, 146, 146, + 146, 146, 146, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 128, 478, 478, + 478, 478, 478, 478, 128, 128, 128, 128, 128, 128, + + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 128, 128, 128, 128, 128, 128, 199, + 199, 199, 199, 199, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 369, 478, + 478, 478, 478, 478, 478, 369, 369, 369, 369, 369, + 369, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 369, 369, 369, 369, 369, 369, + 373, 478, 478, 478, 478, 478, 478, 373, 373, 373, + + 373, 373, 373, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 373, 373, 373, 373, + 373, 373, 374, 478, 478, 478, 478, 478, 478, 374, + 374, 374, 374, 374, 374, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 374, 374, + 374, 374, 374, 374, 286, 286, 286, 286, 286, 478, + 478, 478, 478, 478, 478, 478, 478, 251, 478, 478, + 478, 478, 478, 375, 478, 478, 478, 478, 478, 478, + + 375, 375, 375, 375, 375, 375, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 252, 478, 478, 375, + 375, 375, 375, 375, 375, 378, 478, 478, 478, 478, + 478, 478, 379, 478, 380, 478, 478, 478, 478, 381, + 382, 478, 478, 383, 478, 478, 478, 478, 152, 478, + 478, 478, 478, 478, 378, 478, 478, 478, 478, 478, + 379, 478, 380, 478, 478, 478, 478, 381, 382, 478, + 478, 383, 387, 478, 478, 478, 478, 478, 478, 387, + 387, 387, 387, 387, 387, 478, 478, 478, 478, 478, + + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 387, 387, + 387, 387, 387, 387, 388, 478, 478, 478, 478, 478, + 478, 388, 388, 388, 388, 388, 388, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 388, 388, 388, 388, 388, 388, 389, 478, 478, 478, + 478, 478, 478, 389, 389, 389, 389, 389, 389, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 389, 389, 389, 389, 389, 389, 397, 478, + 478, 478, 478, 478, 478, 397, 397, 397, 397, 397, + 397, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 397, 397, 397, 397, 397, 397, + 398, 478, 478, 478, 478, 478, 478, 398, 398, 398, + 398, 398, 398, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 398, 398, 398, 398, + 398, 398, 399, 478, 478, 478, 478, 478, 478, 399, + + 399, 399, 399, 399, 399, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 399, 399, + 399, 399, 399, 399, 409, 478, 478, 478, 478, 478, + 478, 409, 409, 409, 409, 409, 409, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 409, 409, 409, 409, 409, 409, 410, 478, 478, 478, + 478, 478, 478, 410, 410, 410, 410, 410, 410, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 410, 410, 410, 410, 410, 410, 428, 478, + 478, 478, 478, 478, 478, 428, 428, 428, 428, 428, + 428, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 428, 428, 428, 428, 428, 428, + 437, 478, 478, 478, 478, 478, 478, 437, 437, 437, + 437, 437, 437, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 437, 437, 437, 437, + + 437, 437, 438, 438, 438, 438, 438, 478, 478, 478, + 478, 478, 478, 478, 478, 424, 478, 478, 478, 478, + 478, 439, 478, 478, 478, 478, 478, 478, 439, 439, + 439, 439, 439, 439, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 426, 478, 478, 439, 439, 439, + 439, 439, 439, 445, 445, 445, 445, 445, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 446, 478, 478, 478, 478, 478, 478, 446, + 446, 446, 446, 446, 446, 478, 478, 478, 478, 478, + + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 446, 446, + 446, 446, 446, 446, 447, 478, 478, 478, 478, 478, + 478, 447, 447, 447, 447, 447, 447, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 447, 447, 447, 447, 447, 447, 452, 478, 478, 478, + 478, 478, 478, 452, 452, 452, 452, 452, 452, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 452, 452, 452, 452, 452, 452, 453, 478, + 478, 478, 478, 478, 478, 453, 453, 453, 453, 453, + 453, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 453, 453, 453, 453, 453, 453, + 458, 478, 478, 478, 478, 478, 478, 458, 458, 458, + 458, 458, 458, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 458, 458, 458, 458, + 458, 458, 459, 478, 478, 478, 478, 478, 478, 459, + + 459, 459, 459, 459, 459, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 459, 459, + 459, 459, 459, 459, 464, 478, 478, 478, 478, 478, + 478, 464, 464, 464, 464, 464, 464, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 464, 464, 464, 464, 464, 464, 465, 478, 478, 478, + 478, 478, 478, 465, 465, 465, 465, 465, 465, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 465, 465, 465, 465, 465, 465, 469, 478, + 478, 478, 478, 478, 478, 469, 469, 469, 469, 469, + 469, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 469, 469, 469, 469, 469, 469, + 39, 478, 478, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 45, 45, 478, 45, 45, 48, 478, + 478, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 53, 53, 478, 53, 53, 81, 478, 478, 81, + + 81, 90, 478, 90, 90, 478, 90, 90, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 115, - 115, 478, 115, 115, 119, 119, 119, 119, 119, 119, - 119, 119, 119, 119, 119, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 65, 65, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 130, 130, - 478, 130, 130, 151, 151, 151, 151, 151, 151, 151, - - 151, 151, 153, 153, 478, 153, 153, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 185, 185, 185, 185, 185, - 185, 185, 185, 185, 185, 185, 185, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 200, 200, 200, 200, - 200, 200, 200, 200, 200, 212, 212, 212, 478, 212, + 108, 113, 113, 478, 113, 113, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 119, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 128, 128, 478, 128, 128, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, 151, 151, + 478, 151, 151, 159, 159, 159, 159, 159, 159, 159, + + 159, 159, 159, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 166, 166, 166, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 48, 48, 478, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, + 119, 119, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, + 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + + 211, 211, 211, 211, 39, 478, 478, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, - 225, 225, 244, 244, 244, 478, 244, 249, 249, 249, - 249, 478, 249, 249, 249, 249, 249, 249, 276, 276, - 276, 478, 276, 282, 478, 282, 282, 282, 282, 282, - - 282, 282, 282, 282, 285, 478, 285, 285, 285, 285, - 285, 285, 285, 285, 285, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 288, 288, 313, 313, 313, 478, - 313, 322, 322, 322, 322, 322, 322, 322, 322, 322, - 322, 322, 327, 327, 327, 327, 327, 327, 327, 327, - 327, 327, 327, 348, 348, 348, 478, 348, 414, 414, - 414, 478, 478, 478, 414, 478, 478, 414, 414, 423, - 423, 423, 423, 423, 423, 423, 423, 423, 427, 427, - 427, 478, 478, 427, 427, 427, 478, 427, 427, 438, - 438, 438, 438, 438, 438, 438, 438, 438, 7, 478, + 225, 243, 243, 243, 243, 248, 248, 248, 248, 248, + 248, 478, 248, 248, 248, 248, 248, 248, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 185, 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 275, 275, 275, 275, 248, + 248, 248, 248, 248, 248, 478, 248, 248, 248, 248, + 248, 248, 281, 478, 478, 281, 281, 281, 281, 281, + + 281, 281, 281, 281, 281, 284, 478, 478, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, + 287, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 113, 113, 478, 113, 113, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 312, 312, 312, 312, 321, 321, 321, 321, + 321, 321, 321, 321, 321, 321, 321, 321, 321, 284, + 478, 478, 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 326, 326, 326, 326, 326, 326, 326, 326, + + 326, 326, 326, 326, 326, 248, 248, 248, 248, 248, + 478, 478, 248, 248, 248, 248, 248, 248, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, + 287, 39, 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 113, 113, 478, 113, 113, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 348, 348, 348, 348, 281, 281, 478, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 321, + 321, 321, 321, 321, 321, 321, 321, 321, 321, 321, + 321, 321, 284, 284, 478, 284, 284, 284, 284, 284, + + 284, 284, 284, 284, 284, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, 248, 248, + 248, 248, 248, 478, 478, 248, 248, 248, 248, 248, + 248, 413, 413, 413, 413, 478, 478, 478, 478, 413, + 478, 478, 413, 413, 425, 425, 425, 425, 478, 478, + 478, 425, 425, 425, 478, 425, 425, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 7, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478 + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478 } ; -static yyconst flex_int16_t yy_chk[2460] = +static yyconst flex_int16_t yy_chk[6664] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -576,270 +1048,733 @@ static yyconst flex_int16_t yy_chk[2460] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 3, 134, 4, 9, 9, 9, 9, 9, 12, 3, - 134, 4, 10, 10, 10, 10, 10, 11, 11, 11, - 11, 11, 3, 3, 4, 4, 13, 67, 12, 13, - 15, 39, 52, 25, 67, 3, 13, 4, 31, 13, - - 13, 13, 13, 13, 13, 15, 17, 25, 22, 17, - 27, 39, 31, 27, 11, 52, 17, 26, 22, 69, - 26, 26, 71, 22, 27, 48, 22, 42, 31, 22, - 42, 26, 17, 22, 22, 156, 22, 42, 71, 69, - 48, 17, 20, 23, 27, 64, 54, 64, 26, 20, - 20, 156, 20, 23, 23, 23, 23, 23, 23, 20, - 54, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 3, 5, 4, 6, 15, + 12, 3, 477, 4, 9, 9, 9, 9, 9, 10, + + 10, 10, 10, 10, 3, 3, 4, 4, 11, 11, + 11, 11, 11, 23, 39, 5, 17, 6, 35, 17, + 3, 24, 4, 32, 24, 24, 32, 32, 38, 48, + 15, 69, 3, 3, 4, 4, 12, 42, 25, 17, + 42, 25, 11, 474, 69, 3, 35, 4, 17, 24, + 53, 32, 17, 23, 31, 78, 38, 78, 35, 69, + 39, 24, 467, 32, 33, 461, 65, 17, 83, 25, + 48, 11, 13, 42, 35, 13, 17, 24, 25, 32, + 83, 31, 13, 13, 13, 13, 13, 13, 65, 54, + 53, 33, 54, 54, 31, 65, 83, 25, 36, 36, + + 36, 36, 36, 70, 33, 68, 68, 456, 13, 31, + 166, 13, 13, 13, 13, 13, 13, 20, 166, 33, + 211, 90, 70, 440, 20, 20, 434, 20, 211, 54, + 124, 124, 70, 68, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 33, 32, - 35, 20, 32, 32, 36, 36, 36, 36, 36, 57, - - 43, 57, 33, 32, 35, 37, 37, 37, 37, 37, - 43, 43, 43, 43, 43, 43, 44, 84, 33, 55, - 32, 35, 55, 55, 57, 46, 44, 44, 44, 44, - 44, 44, 46, 55, 84, 46, 46, 46, 46, 46, - 46, 53, 37, 41, 41, 41, 41, 56, 66, 41, - 72, 53, 53, 53, 53, 53, 53, 70, 147, 86, - 72, 56, 41, 66, 147, 75, 86, 68, 56, 41, - 75, 73, 41, 41, 41, 41, 41, 41, 49, 49, - 49, 49, 68, 74, 74, 70, 73, 75, 63, 49, - 477, 75, 73, 68, 74, 78, 80, 49, 63, 63, - - 63, 63, 63, 63, 49, 83, 80, 49, 49, 49, - 49, 49, 49, 76, 81, 83, 76, 85, 78, 87, - 88, 89, 87, 88, 81, 81, 81, 81, 81, 81, - 93, 80, 85, 102, 108, 89, 90, 90, 90, 90, - 90, 124, 124, 143, 93, 140, 94, 102, 90, 97, - 143, 474, 109, 102, 108, 90, 94, 94, 94, 94, - 94, 94, 90, 97, 96, 90, 90, 90, 90, 90, - 90, 96, 109, 140, 118, 467, 98, 119, 96, 99, - 103, 98, 104, 105, 118, 97, 98, 98, 98, 98, - 98, 98, 119, 99, 103, 107, 104, 105, 120, 118, - - 107, 125, 127, 461, 150, 137, 127, 99, 137, 155, - 104, 150, 155, 120, 148, 125, 103, 105, 112, 125, - 107, 110, 110, 110, 110, 110, 132, 110, 112, 112, - 112, 112, 112, 112, 148, 158, 167, 192, 456, 160, - 110, 158, 157, 192, 167, 132, 159, 110, 160, 162, - 110, 110, 110, 110, 110, 110, 111, 111, 111, 111, - 157, 159, 111, 162, 190, 194, 116, 206, 344, 166, - 169, 190, 194, 344, 206, 111, 116, 116, 116, 116, - 116, 116, 111, 166, 169, 111, 111, 111, 111, 111, - 111, 114, 114, 114, 114, 114, 198, 205, 226, 207, - - 198, 117, 226, 170, 171, 173, 207, 440, 205, 203, - 114, 117, 117, 117, 117, 117, 117, 170, 171, 173, - 114, 114, 114, 114, 114, 114, 121, 121, 121, 121, - 121, 203, 212, 175, 236, 238, 131, 121, 238, 182, - 212, 392, 434, 429, 236, 121, 131, 131, 131, 131, - 131, 131, 121, 175, 182, 121, 121, 121, 121, 121, - 121, 122, 122, 122, 122, 216, 265, 244, 392, 268, - 269, 154, 122, 196, 184, 244, 268, 265, 269, 216, - 122, 154, 154, 154, 154, 154, 154, 122, 184, 196, - 122, 122, 122, 122, 122, 122, 129, 129, 129, 129, - - 129, 184, 276, 202, 340, 307, 161, 204, 307, 309, - 276, 419, 309, 385, 340, 129, 161, 161, 161, 161, - 161, 161, 129, 202, 204, 129, 129, 129, 129, 129, - 129, 152, 152, 152, 152, 152, 232, 165, 172, 229, - 313, 345, 420, 384, 165, 261, 345, 420, 313, 232, - 152, 165, 172, 235, 229, 237, 239, 152, 224, 261, - 152, 152, 152, 152, 152, 152, 163, 163, 163, 163, - 163, 370, 224, 250, 235, 237, 176, 239, 370, 172, - 435, 261, 364, 224, 435, 163, 176, 176, 176, 176, - 176, 176, 177, 250, 251, 163, 163, 163, 163, 163, - - 163, 178, 177, 177, 177, 177, 177, 177, 270, 251, - 272, 178, 178, 178, 178, 178, 178, 180, 180, 180, - 180, 180, 281, 281, 281, 281, 281, 181, 272, 285, - 270, 383, 348, 343, 383, 281, 180, 181, 181, 181, - 181, 181, 181, 183, 285, 332, 180, 180, 180, 180, - 180, 180, 187, 183, 183, 183, 183, 183, 183, 282, - 303, 306, 187, 187, 187, 187, 187, 187, 189, 189, - 189, 189, 189, 283, 283, 283, 283, 283, 199, 282, - 300, 327, 303, 306, 300, 318, 283, 189, 199, 199, - 199, 199, 199, 199, 300, 322, 327, 189, 189, 189, - - 189, 189, 189, 201, 201, 201, 201, 201, 319, 319, - 319, 319, 319, 208, 418, 322, 360, 418, 317, 316, - 326, 319, 201, 208, 208, 208, 208, 208, 208, 209, - 326, 360, 201, 201, 201, 201, 201, 201, 211, 209, - 209, 209, 209, 209, 209, 326, 356, 315, 211, 211, - 211, 211, 211, 211, 215, 215, 215, 215, 215, 218, - 215, 371, 337, 357, 361, 215, 356, 215, 371, 218, - 218, 218, 218, 218, 218, 219, 337, 321, 314, 361, - 215, 220, 321, 357, 366, 219, 219, 219, 219, 219, - 219, 220, 220, 220, 220, 220, 220, 221, 366, 378, - - 337, 366, 321, 222, 381, 407, 378, 221, 221, 221, - 221, 221, 221, 222, 222, 222, 222, 222, 222, 223, - 334, 334, 334, 334, 334, 227, 308, 381, 407, 223, - 223, 223, 223, 223, 223, 227, 227, 227, 227, 227, - 227, 228, 379, 380, 298, 422, 334, 233, 422, 379, - 380, 228, 228, 228, 228, 228, 228, 233, 233, 233, - 233, 233, 233, 234, 338, 338, 338, 338, 338, 241, - 432, 415, 441, 234, 234, 234, 234, 234, 234, 241, - 241, 241, 241, 241, 241, 242, 382, 441, 393, 432, - 338, 243, 415, 382, 393, 242, 242, 242, 242, 242, - - 242, 243, 243, 243, 243, 243, 243, 248, 248, 248, - 248, 248, 405, 248, 293, 390, 394, 395, 248, 405, - 248, 249, 249, 249, 249, 249, 255, 249, 377, 390, - 394, 395, 249, 248, 249, 402, 255, 255, 255, 255, - 255, 255, 377, 396, 404, 403, 402, 249, 253, 253, - 253, 253, 253, 403, 253, 404, 463, 396, 256, 253, - 253, 253, 377, 396, 280, 408, 463, 253, 256, 256, - 256, 256, 256, 256, 253, 257, 408, 253, 253, 253, - 253, 253, 253, 258, 416, 257, 257, 257, 257, 257, - 257, 259, 279, 258, 258, 258, 258, 258, 258, 260, - - 416, 259, 259, 259, 259, 259, 259, 262, 278, 260, - 260, 260, 260, 260, 260, 263, 277, 262, 262, 262, - 262, 262, 262, 266, 271, 263, 263, 263, 263, 263, - 263, 267, 264, 266, 266, 266, 266, 266, 266, 273, - 254, 267, 267, 267, 267, 267, 267, 274, 247, 273, - 273, 273, 273, 273, 273, 275, 406, 274, 274, 274, - 274, 274, 274, 406, 401, 275, 275, 275, 275, 275, - 275, 284, 284, 284, 284, 391, 443, 284, 401, 417, - 391, 431, 246, 391, 431, 287, 287, 287, 287, 287, - 284, 287, 245, 443, 240, 231, 287, 284, 287, 417, - - 284, 284, 284, 284, 284, 284, 286, 286, 286, 286, - 230, 287, 412, 412, 412, 412, 412, 286, 288, 288, - 288, 288, 288, 421, 288, 286, 430, 442, 412, 288, - 421, 288, 286, 430, 450, 286, 286, 286, 286, 286, - 286, 444, 225, 470, 288, 289, 289, 289, 289, 289, - 442, 289, 217, 475, 450, 444, 289, 470, 289, 290, - 290, 290, 290, 290, 294, 290, 448, 475, 462, 433, - 290, 289, 290, 448, 294, 294, 294, 294, 294, 294, - 425, 425, 425, 425, 425, 290, 291, 291, 291, 291, - 291, 433, 291, 425, 455, 462, 296, 291, 214, 291, - - 341, 341, 341, 341, 341, 291, 296, 296, 296, 296, - 296, 296, 291, 213, 455, 291, 291, 291, 291, 291, - 291, 292, 292, 292, 292, 292, 341, 292, 449, 451, - 200, 297, 292, 292, 292, 449, 451, 460, 195, 193, - 292, 297, 297, 297, 297, 297, 297, 292, 299, 191, - 292, 292, 292, 292, 292, 292, 301, 460, 299, 299, - 299, 299, 299, 299, 302, 466, 301, 301, 301, 301, - 301, 301, 304, 188, 302, 302, 302, 302, 302, 302, - 305, 457, 304, 304, 304, 304, 304, 304, 466, 185, - 305, 305, 305, 305, 305, 305, 310, 310, 310, 310, - - 310, 311, 457, 476, 468, 179, 174, 168, 310, 454, - 468, 311, 311, 311, 311, 311, 311, 312, 471, 454, - 164, 473, 310, 153, 476, 471, 473, 312, 312, 312, - 312, 312, 312, 323, 323, 323, 323, 323, 151, 323, - 454, 328, 328, 328, 328, 328, 323, 149, 472, 146, - 145, 144, 328, 142, 328, 472, 141, 139, 331, 323, - 324, 324, 324, 324, 324, 138, 324, 328, 331, 331, - 331, 331, 331, 331, 355, 355, 355, 355, 355, 324, - 355, 365, 365, 365, 365, 365, 324, 355, 136, 324, - 324, 324, 324, 324, 324, 325, 325, 325, 325, 135, - - 355, 325, 133, 130, 128, 333, 126, 365, 115, 367, - 367, 367, 367, 367, 325, 333, 333, 333, 333, 333, - 333, 325, 113, 106, 325, 325, 325, 325, 325, 325, - 329, 329, 329, 329, 329, 367, 95, 82, 79, 77, - 335, 329, 65, 369, 369, 369, 369, 369, 61, 329, - 335, 335, 335, 335, 335, 335, 329, 60, 59, 329, - 329, 329, 329, 329, 329, 330, 330, 330, 330, 369, - 58, 51, 45, 38, 29, 336, 330, 28, 24, 21, - 19, 18, 16, 14, 330, 336, 336, 336, 336, 336, - 336, 330, 339, 7, 330, 330, 330, 330, 330, 330, - - 342, 6, 339, 339, 339, 339, 339, 339, 5, 0, - 342, 342, 342, 342, 342, 342, 346, 346, 346, 346, - 346, 347, 0, 0, 0, 0, 0, 0, 346, 0, - 0, 347, 347, 347, 347, 347, 347, 358, 0, 0, - 0, 0, 346, 0, 0, 0, 0, 358, 358, 358, - 358, 358, 358, 359, 359, 359, 359, 359, 362, 0, - 0, 0, 0, 0, 359, 0, 359, 0, 362, 362, - 362, 362, 362, 362, 363, 0, 0, 368, 0, 359, - 0, 0, 0, 368, 363, 363, 363, 363, 363, 363, - 368, 0, 368, 372, 0, 0, 0, 368, 368, 373, - - 0, 368, 0, 372, 372, 372, 372, 372, 372, 373, - 373, 373, 373, 373, 373, 374, 0, 0, 0, 0, - 0, 375, 0, 0, 0, 374, 374, 374, 374, 374, - 374, 375, 375, 375, 375, 375, 375, 387, 0, 0, - 0, 0, 0, 388, 0, 0, 0, 387, 387, 387, - 387, 387, 387, 388, 388, 388, 388, 388, 388, 389, - 0, 0, 0, 0, 0, 397, 0, 0, 0, 389, - 389, 389, 389, 389, 389, 397, 397, 397, 397, 397, - 397, 398, 0, 0, 0, 0, 0, 399, 0, 0, - 0, 398, 398, 398, 398, 398, 398, 399, 399, 399, - - 399, 399, 399, 400, 400, 400, 400, 400, 0, 0, - 409, 0, 0, 0, 0, 0, 0, 0, 0, 400, - 409, 409, 409, 409, 409, 409, 410, 0, 0, 400, - 411, 411, 411, 411, 411, 0, 410, 410, 410, 410, - 410, 410, 0, 0, 0, 0, 411, 413, 0, 0, - 414, 414, 414, 414, 414, 0, 411, 413, 413, 413, - 413, 413, 413, 414, 423, 423, 423, 423, 423, 0, - 427, 427, 427, 427, 427, 0, 414, 423, 0, 0, - 0, 0, 0, 427, 0, 0, 0, 428, 0, 0, - 423, 424, 424, 424, 424, 424, 427, 428, 428, 428, - - 428, 428, 428, 0, 424, 436, 436, 436, 436, 436, - 424, 0, 0, 0, 0, 0, 0, 424, 436, 0, - 424, 424, 424, 424, 424, 424, 437, 0, 0, 0, - 0, 436, 0, 0, 0, 0, 437, 437, 437, 437, - 437, 437, 438, 438, 438, 438, 438, 445, 0, 0, - 446, 446, 446, 446, 446, 438, 0, 445, 445, 445, - 445, 445, 445, 446, 0, 0, 0, 447, 438, 439, - 439, 439, 439, 439, 0, 0, 446, 447, 447, 447, - 447, 447, 447, 0, 0, 0, 0, 0, 439, 0, - 0, 0, 0, 0, 452, 0, 0, 0, 439, 439, - - 439, 439, 439, 439, 452, 452, 452, 452, 452, 452, - 453, 0, 0, 0, 0, 0, 458, 0, 0, 0, - 453, 453, 453, 453, 453, 453, 458, 458, 458, 458, - 458, 458, 459, 0, 0, 0, 0, 0, 464, 0, - 0, 0, 459, 459, 459, 459, 459, 459, 464, 464, - 464, 464, 464, 464, 465, 0, 0, 0, 0, 0, - 469, 0, 0, 0, 465, 465, 465, 465, 465, 465, - 469, 469, 469, 469, 469, 469, 479, 0, 479, 479, - 479, 479, 479, 479, 479, 479, 479, 480, 480, 0, - 480, 480, 481, 0, 481, 481, 481, 481, 481, 481, - - 481, 481, 481, 482, 482, 0, 482, 482, 483, 0, - 0, 483, 483, 484, 484, 484, 484, 484, 484, 484, - 484, 484, 485, 0, 485, 485, 0, 485, 485, 486, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 90, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 64, 52, + 106, 20, 22, 74, 55, 429, 37, 37, 37, 37, + + 37, 57, 64, 57, 22, 243, 487, 22, 487, 52, + 22, 419, 55, 243, 22, 22, 64, 22, 106, 74, + 67, 66, 74, 57, 72, 72, 385, 127, 22, 67, + 37, 127, 66, 22, 55, 66, 22, 52, 71, 22, + 97, 55, 22, 22, 71, 22, 26, 73, 67, 66, + 82, 57, 71, 26, 26, 26, 26, 26, 26, 37, + 66, 72, 108, 109, 73, 80, 71, 76, 73, 82, + 107, 73, 71, 76, 86, 107, 73, 85, 140, 82, + 97, 384, 26, 26, 26, 26, 26, 26, 41, 41, + 41, 41, 73, 118, 41, 76, 73, 80, 84, 85, + + 86, 80, 87, 86, 348, 175, 85, 41, 108, 109, + 96, 140, 84, 93, 41, 41, 41, 41, 41, 41, + 93, 107, 94, 119, 102, 80, 84, 104, 87, 342, + 250, 87, 103, 119, 118, 96, 317, 105, 161, 316, + 41, 102, 315, 41, 41, 41, 41, 41, 41, 44, + 96, 175, 104, 93, 314, 94, 44, 44, 44, 44, + 44, 44, 94, 96, 102, 103, 120, 104, 105, 125, + 102, 250, 103, 275, 119, 131, 120, 105, 161, 134, + 104, 275, 44, 94, 125, 44, 44, 44, 44, 44, + 44, 46, 144, 103, 150, 131, 105, 145, 46, 46, + + 46, 46, 46, 46, 131, 134, 145, 165, 134, 125, + 137, 137, 148, 125, 156, 144, 150, 120, 192, 153, + 226, 144, 148, 150, 226, 145, 154, 46, 46, 46, + 46, 46, 46, 49, 49, 49, 49, 156, 137, 154, + 148, 157, 155, 156, 49, 153, 158, 165, 153, 174, + 190, 192, 49, 155, 154, 157, 168, 170, 164, 49, + 49, 49, 49, 49, 49, 164, 158, 171, 173, 157, + 155, 172, 182, 190, 235, 158, 184, 174, 216, 190, + 249, 499, 182, 499, 284, 49, 194, 217, 49, 49, + 49, 49, 49, 49, 56, 196, 168, 170, 164, 194, + + 184, 56, 56, 56, 56, 56, 56, 171, 173, 172, + 235, 172, 201, 198, 194, 217, 184, 196, 216, 325, + 293, 201, 202, 182, 196, 284, 249, 203, 184, 202, + 56, 56, 56, 56, 56, 56, 77, 172, 198, 203, + 201, 204, 198, 77, 77, 77, 77, 77, 77, 293, + 202, 231, 232, 234, 390, 203, 281, 320, 390, 204, + 325, 234, 205, 492, 492, 231, 254, 509, 232, 509, + 204, 206, 77, 77, 77, 77, 77, 77, 88, 231, + 232, 234, 224, 236, 205, 88, 88, 88, 88, 88, + 88, 205, 236, 206, 254, 214, 214, 214, 214, 214, + + 206, 214, 281, 320, 224, 265, 214, 313, 214, 237, + 306, 236, 332, 238, 88, 88, 88, 88, 88, 88, + 91, 238, 224, 265, 364, 307, 271, 91, 91, 91, + 91, 91, 91, 224, 265, 237, 306, 271, 237, 306, + 332, 238, 247, 247, 247, 247, 247, 214, 247, 267, + 296, 268, 364, 247, 271, 247, 91, 91, 91, 91, + 91, 91, 98, 98, 98, 98, 98, 279, 511, 337, + 511, 267, 268, 340, 98, 269, 303, 305, 267, 312, + 268, 98, 269, 303, 305, 278, 308, 312, 98, 98, + 98, 98, 98, 98, 247, 248, 248, 248, 248, 248, + + 337, 248, 277, 269, 303, 305, 248, 276, 248, 340, + 463, 515, 308, 515, 98, 308, 270, 98, 98, 98, + 98, 98, 98, 110, 110, 110, 110, 110, 337, 110, + 280, 280, 280, 280, 280, 282, 282, 282, 282, 282, + 321, 343, 110, 280, 246, 321, 463, 248, 282, 110, + 110, 110, 110, 110, 110, 286, 286, 286, 286, 286, + 318, 318, 318, 318, 318, 343, 245, 366, 286, 517, + 343, 517, 370, 318, 394, 110, 344, 366, 110, 110, + 110, 110, 110, 110, 111, 111, 111, 111, 244, 394, + 111, 321, 239, 229, 370, 287, 287, 287, 287, 287, + + 344, 370, 394, 111, 383, 344, 366, 286, 287, 228, + 111, 111, 111, 111, 111, 111, 288, 288, 288, 288, + 288, 289, 289, 289, 289, 289, 356, 225, 326, 288, + 383, 356, 213, 383, 289, 392, 111, 392, 326, 111, + 111, 111, 111, 111, 111, 114, 393, 287, 462, 212, + 462, 403, 114, 114, 114, 114, 114, 114, 322, 322, + 322, 322, 322, 392, 322, 357, 199, 193, 288, 393, + 357, 322, 403, 289, 191, 393, 462, 356, 114, 326, + 403, 114, 114, 114, 114, 114, 114, 115, 189, 327, + 327, 327, 327, 327, 115, 115, 115, 115, 115, 115, + + 327, 187, 327, 331, 331, 331, 331, 331, 185, 179, + 322, 333, 333, 333, 333, 333, 357, 333, 167, 331, + 371, 163, 159, 115, 115, 115, 115, 115, 115, 117, + 117, 117, 117, 117, 346, 346, 346, 346, 346, 151, + 149, 327, 371, 336, 336, 336, 336, 336, 117, 371, + 346, 360, 361, 146, 336, 117, 117, 117, 117, 117, + 117, 360, 361, 333, 365, 365, 365, 365, 365, 416, + 345, 345, 345, 345, 345, 367, 367, 367, 367, 367, + 143, 142, 416, 377, 117, 117, 117, 117, 117, 117, + 121, 121, 121, 121, 121, 336, 524, 416, 524, 141, + + 441, 121, 360, 361, 369, 369, 369, 369, 369, 121, + 377, 378, 379, 139, 441, 380, 121, 121, 121, 121, + 121, 121, 345, 355, 355, 355, 355, 355, 441, 355, + 527, 415, 527, 378, 379, 138, 355, 380, 377, 415, + 378, 379, 121, 395, 380, 121, 121, 121, 121, 121, + 121, 122, 122, 122, 122, 381, 369, 136, 395, 415, + 418, 381, 122, 359, 359, 359, 359, 359, 382, 391, + 122, 395, 391, 402, 359, 355, 359, 122, 122, 122, + 122, 122, 122, 381, 135, 401, 418, 133, 407, 418, + 382, 402, 132, 391, 407, 130, 405, 382, 391, 396, + + 401, 391, 402, 122, 128, 396, 122, 122, 122, 122, + 122, 122, 129, 401, 396, 359, 407, 406, 405, 129, + 129, 129, 129, 129, 129, 405, 537, 396, 537, 544, + 545, 544, 545, 396, 399, 399, 399, 399, 399, 406, + 126, 404, 408, 116, 113, 95, 406, 399, 129, 129, + 129, 129, 129, 129, 147, 147, 147, 147, 147, 404, + 408, 92, 81, 79, 410, 410, 410, 410, 410, 417, + 404, 408, 75, 147, 63, 410, 420, 61, 417, 421, + 147, 147, 147, 147, 147, 147, 399, 400, 400, 400, + 400, 400, 409, 409, 409, 409, 409, 417, 409, 60, + + 420, 421, 59, 400, 58, 420, 147, 51, 421, 147, + 147, 147, 147, 147, 147, 152, 410, 411, 411, 411, + 411, 411, 152, 152, 152, 152, 152, 152, 413, 413, + 413, 413, 413, 411, 45, 29, 28, 422, 27, 400, + 21, 413, 430, 19, 409, 435, 412, 412, 412, 412, + 412, 152, 152, 152, 152, 152, 152, 160, 160, 160, + 160, 160, 412, 422, 430, 18, 422, 432, 431, 411, + 435, 430, 433, 16, 435, 442, 160, 432, 468, 433, + 413, 442, 448, 160, 160, 160, 160, 160, 160, 423, + 423, 423, 423, 423, 431, 432, 443, 431, 412, 14, + + 433, 468, 423, 442, 448, 449, 7, 468, 443, 160, + 444, 448, 160, 160, 160, 160, 160, 160, 162, 162, + 162, 162, 162, 0, 443, 444, 0, 449, 425, 425, + 425, 425, 425, 450, 449, 0, 454, 162, 444, 0, + 451, 425, 450, 0, 162, 162, 162, 162, 162, 162, + 427, 427, 427, 427, 427, 436, 436, 436, 436, 436, + 0, 450, 451, 427, 454, 466, 0, 0, 436, 451, + 0, 466, 454, 162, 162, 162, 162, 162, 162, 169, + 425, 438, 438, 438, 438, 438, 169, 169, 169, 169, + 169, 169, 454, 466, 438, 0, 0, 0, 457, 0, + + 455, 460, 427, 476, 0, 0, 457, 436, 471, 455, + 460, 476, 472, 0, 473, 169, 169, 169, 169, 169, + 169, 176, 176, 176, 176, 176, 457, 176, 455, 460, + 471, 476, 0, 438, 472, 0, 0, 471, 473, 0, + 176, 472, 0, 473, 0, 0, 0, 176, 176, 176, + 176, 176, 176, 445, 445, 445, 445, 445, 465, 465, + 465, 465, 465, 0, 0, 0, 445, 0, 0, 0, + 0, 465, 0, 176, 0, 0, 176, 176, 176, 176, + 176, 176, 178, 469, 469, 469, 469, 469, 470, 178, + 178, 178, 178, 178, 178, 0, 469, 0, 0, 0, + + 0, 0, 475, 470, 0, 445, 0, 0, 0, 0, + 465, 0, 0, 0, 0, 0, 470, 475, 178, 178, + 178, 178, 178, 178, 180, 180, 180, 180, 180, 0, + 475, 0, 0, 0, 0, 469, 0, 0, 0, 0, + 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, + 180, 180, 180, 180, 180, 180, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, + 180, 180, 180, 180, 180, 181, 181, 181, 181, 181, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 181, 0, 0, 0, 0, 0, + 0, 181, 181, 181, 181, 181, 181, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 181, 181, 181, 181, 181, 181, 183, 183, 183, 183, + 183, 0, 0, 0, 0, 0, 0, 183, 0, 0, + 0, 0, 0, 0, 0, 183, 0, 0, 0, 0, + 0, 0, 183, 183, 183, 183, 183, 183, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 183, 0, + + 0, 183, 183, 183, 183, 183, 183, 188, 188, 188, + 188, 188, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 188, 0, 0, 0, + 0, 0, 0, 188, 188, 188, 188, 188, 188, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 188, 188, 188, 188, 188, 188, 195, 0, + 0, 0, 0, 0, 0, 195, 195, 195, 195, 195, + 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 195, 195, 195, 195, 195, 195, + 200, 200, 200, 200, 200, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 200, + 0, 0, 0, 0, 0, 0, 200, 200, 200, 200, + 200, 200, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 200, 200, 200, 200, 200, + 200, 207, 0, 0, 0, 0, 0, 0, 207, 207, + 207, 207, 207, 207, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 207, 207, 207, + 207, 207, 207, 208, 208, 208, 208, 208, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 208, 0, 0, 0, 0, 0, 0, 208, + 208, 208, 208, 208, 208, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 208, 208, + 208, 208, 208, 208, 215, 0, 0, 0, 0, 0, + 0, 215, 215, 215, 215, 215, 215, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 215, 215, 215, 215, 215, 215, 218, 218, 218, 218, + 218, 0, 218, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 218, 0, 0, 0, 0, + 0, 0, 218, 218, 218, 218, 218, 218, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 218, 0, + 0, 218, 218, 218, 218, 218, 218, 220, 0, 0, + 0, 0, 0, 0, 220, 220, 220, 220, 220, 220, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 220, 220, 220, 220, 220, 220, 221, + 221, 221, 221, 221, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 221, 0, + 0, 0, 0, 0, 0, 221, 221, 221, 221, 221, + 221, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 221, 221, 221, 221, 221, 221, + 222, 222, 222, 222, 222, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 222, + + 0, 0, 0, 0, 0, 0, 222, 222, 222, 222, + 222, 222, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 222, 222, 222, 222, 222, + 222, 223, 223, 223, 223, 223, 0, 0, 0, 0, + 0, 0, 223, 0, 0, 0, 0, 0, 0, 0, + 223, 0, 0, 0, 0, 0, 0, 223, 223, 223, + 223, 223, 223, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 223, 0, 0, 223, 223, 223, 223, + + 223, 223, 227, 227, 227, 227, 227, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 227, 0, 0, 0, 0, 0, 0, 227, 227, + 227, 227, 227, 227, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 227, 227, 227, + 227, 227, 227, 230, 0, 0, 0, 0, 0, 0, + 230, 230, 230, 230, 230, 230, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, + + 230, 230, 230, 230, 230, 233, 233, 233, 233, 233, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 233, 0, 0, 0, 0, 0, + 0, 233, 233, 233, 233, 233, 233, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 233, 233, 233, 233, 233, 233, 240, 0, 0, 0, + 0, 0, 0, 240, 240, 240, 240, 240, 240, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 240, 240, 240, 240, 240, 240, 241, 241, + 241, 241, 241, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 241, 0, 0, + 0, 0, 0, 0, 241, 241, 241, 241, 241, 241, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 241, 241, 241, 241, 241, 241, 252, + 252, 252, 252, 252, 0, 252, 0, 0, 0, 0, + 252, 252, 252, 0, 0, 0, 0, 0, 252, 0, + 0, 0, 0, 0, 0, 252, 252, 252, 252, 252, + + 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 252, 0, 0, 252, 252, 252, 252, 252, 252, + 253, 0, 0, 0, 0, 0, 0, 253, 253, 253, + 253, 253, 253, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 253, 253, 253, 253, + 253, 253, 255, 255, 255, 255, 255, 0, 255, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 255, 0, 0, 0, 0, 0, 0, 255, 255, + + 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 255, 0, 0, 255, 255, 255, + 255, 255, 255, 257, 0, 0, 0, 0, 0, 0, + 257, 257, 257, 257, 257, 257, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 257, 0, 0, 257, + 257, 257, 257, 257, 257, 258, 258, 258, 258, 258, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 258, 0, 0, 0, 0, 0, + + 0, 258, 258, 258, 258, 258, 258, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 258, 0, 0, + 258, 258, 258, 258, 258, 258, 259, 259, 259, 259, + 259, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 259, 0, 0, 0, 0, + 0, 0, 259, 259, 259, 259, 259, 259, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 259, 259, 259, 259, 259, 259, 260, 260, 260, + + 260, 260, 0, 0, 0, 0, 0, 0, 260, 0, + 0, 0, 0, 0, 0, 0, 260, 0, 0, 0, + 0, 0, 0, 260, 260, 260, 260, 260, 260, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 260, + 0, 0, 260, 260, 260, 260, 260, 260, 261, 261, + 261, 261, 261, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 261, 0, 0, + 0, 0, 0, 0, 261, 261, 261, 261, 261, 261, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 261, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 261, 261, 261, 261, 261, 261, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 261, 262, 262, 262, 262, 262, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 262, 0, 0, 0, 0, 0, 0, 262, 262, + 262, 262, 262, 262, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 262, 262, 262, + 262, 262, 262, 263, 0, 0, 0, 0, 0, 0, + + 263, 263, 263, 263, 263, 263, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 263, + 263, 263, 263, 263, 263, 264, 264, 264, 264, 264, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 264, 0, 0, 0, 0, 0, + 0, 264, 264, 264, 264, 264, 264, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 264, 264, 264, 264, 264, 264, 266, 266, 266, 266, + + 266, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 266, 0, 0, 0, 0, + 0, 0, 266, 266, 266, 266, 266, 266, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 266, 266, 266, 266, 266, 266, 272, 0, 0, + 0, 0, 0, 0, 272, 272, 272, 272, 272, 272, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 272, 272, 272, 272, 272, 272, 273, + + 273, 273, 273, 273, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 273, 0, + 0, 0, 0, 0, 0, 273, 273, 273, 273, 273, + 273, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 273, 273, 273, 273, 273, 273, + 283, 283, 283, 283, 0, 0, 283, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 283, + 0, 0, 0, 0, 0, 0, 283, 283, 283, 283, + 283, 283, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 283, 0, 0, 283, 283, 283, 283, 283, + 283, 285, 285, 285, 285, 0, 0, 0, 0, 0, + 0, 0, 285, 0, 0, 0, 0, 0, 0, 0, + 285, 0, 0, 0, 0, 0, 0, 285, 285, 285, + 285, 285, 285, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 285, 0, 0, 285, 285, 285, 285, + 285, 285, 290, 290, 290, 290, 290, 0, 0, 0, + 0, 0, 0, 0, 0, 290, 0, 0, 0, 0, + + 0, 290, 0, 0, 0, 0, 0, 0, 290, 290, + 290, 290, 290, 290, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 290, 0, 0, 290, 290, 290, + 290, 290, 290, 291, 291, 291, 291, 291, 0, 291, + 0, 0, 0, 0, 291, 291, 291, 0, 0, 0, + 0, 0, 291, 0, 0, 0, 0, 0, 0, 291, + 291, 291, 291, 291, 291, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 291, 0, 0, 291, 291, + + 291, 291, 291, 291, 292, 0, 0, 0, 0, 0, + 0, 292, 292, 292, 292, 292, 292, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 292, 292, 292, 292, 292, 292, 294, 294, 294, 294, + 294, 0, 294, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 294, 0, 0, 0, 0, + 0, 0, 294, 294, 294, 294, 294, 294, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 294, 0, + + 0, 294, 294, 294, 294, 294, 294, 297, 297, 297, + 297, 297, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 297, 0, 0, 0, + 0, 0, 0, 297, 297, 297, 297, 297, 297, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 297, + 0, 0, 297, 297, 297, 297, 297, 297, 298, 298, + 298, 298, 298, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 298, 0, 0, + 0, 0, 0, 0, 298, 298, 298, 298, 298, 298, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 298, 298, 298, 298, 298, 298, 299, + 299, 299, 299, 299, 0, 0, 0, 0, 0, 0, + 299, 0, 0, 0, 0, 0, 0, 0, 299, 0, + 0, 0, 0, 0, 0, 299, 299, 299, 299, 299, + 299, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 299, 0, 0, 299, 299, 299, 299, 299, 299, + 300, 300, 300, 300, 300, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 300, 0, 0, 300, + 0, 0, 0, 0, 0, 0, 300, 300, 300, 300, + 300, 300, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 300, 300, 300, 300, 300, + 300, 301, 301, 301, 301, 301, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 301, 0, 0, 0, 0, 0, 0, 301, 301, 301, + 301, 301, 301, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 301, 301, 301, 301, + 301, 301, 302, 302, 302, 302, 302, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 302, 0, 0, 0, 0, 0, 0, 302, 302, + 302, 302, 302, 302, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 302, 302, 302, + 302, 302, 302, 304, 304, 304, 304, 304, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 304, 0, 0, 0, 0, 0, 0, 304, + + 304, 304, 304, 304, 304, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 304, 304, + 304, 304, 304, 304, 309, 0, 0, 0, 0, 0, + 0, 309, 309, 309, 309, 309, 309, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 309, 309, 309, 309, 309, 309, 310, 310, 310, 310, + 310, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 310, 0, 0, 0, 0, + + 0, 0, 310, 310, 310, 310, 310, 310, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 310, 310, 310, 310, 310, 310, 323, 323, 323, + 323, 323, 0, 323, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 323, 0, 0, 0, + 0, 0, 0, 323, 323, 323, 323, 323, 323, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 323, + 0, 0, 323, 323, 323, 323, 323, 323, 324, 324, + + 324, 324, 0, 0, 324, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 324, 0, 0, + 0, 0, 0, 0, 324, 324, 324, 324, 324, 324, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 324, 0, 0, 324, 324, 324, 324, 324, 324, 328, + 328, 328, 328, 328, 0, 0, 0, 0, 0, 0, + 328, 0, 0, 0, 0, 0, 0, 0, 328, 0, + 0, 0, 0, 0, 0, 328, 328, 328, 328, 328, + 328, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 328, 0, 0, 328, 328, 328, 328, 328, 328, + 329, 329, 329, 329, 0, 0, 0, 0, 0, 0, + 0, 329, 0, 0, 0, 0, 0, 0, 0, 329, + 0, 0, 0, 0, 0, 0, 329, 329, 329, 329, + 329, 329, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 329, 0, 0, 329, 329, 329, 329, 329, + 329, 330, 330, 330, 330, 330, 0, 0, 0, 0, + 0, 0, 0, 0, 330, 0, 0, 0, 0, 0, + + 330, 0, 0, 0, 0, 0, 0, 330, 330, 330, + 330, 330, 330, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 330, 0, 0, 330, 330, 330, 330, + 330, 330, 334, 0, 0, 0, 0, 0, 0, 334, + 334, 334, 334, 334, 334, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 334, 334, + 334, 334, 334, 334, 335, 0, 0, 0, 0, 0, + 0, 335, 335, 335, 335, 335, 335, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 335, 335, 335, 335, 335, 335, 338, 0, 0, 0, + 0, 0, 0, 338, 338, 338, 338, 338, 338, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 338, 338, 338, 338, 338, 338, 339, 339, + 339, 339, 339, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 339, 0, 0, + 0, 0, 0, 0, 339, 339, 339, 339, 339, 339, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 339, 339, 339, 339, 339, 339, 341, + 341, 341, 341, 341, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 341, 0, + 0, 0, 0, 0, 0, 341, 341, 341, 341, 341, + 341, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 341, 341, 341, 341, 341, 341, + 358, 0, 0, 0, 0, 0, 0, 358, 358, 358, + + 358, 358, 358, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 358, 358, 358, 358, + 358, 358, 362, 0, 0, 0, 0, 0, 0, 362, + 362, 362, 362, 362, 362, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 362, 362, + 362, 362, 362, 362, 363, 363, 363, 363, 363, 0, + 0, 0, 0, 0, 0, 0, 0, 363, 0, 0, + 0, 0, 0, 363, 0, 0, 0, 0, 0, 0, + + 363, 363, 363, 363, 363, 363, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 363, 0, 0, 363, + 363, 363, 363, 363, 363, 368, 0, 0, 0, 0, + 0, 0, 368, 0, 368, 0, 0, 0, 0, 368, + 368, 0, 0, 368, 0, 0, 0, 0, 368, 0, + 0, 0, 0, 0, 368, 0, 0, 0, 0, 0, + 368, 0, 368, 0, 0, 0, 0, 368, 368, 0, + 0, 368, 373, 0, 0, 0, 0, 0, 0, 373, + 373, 373, 373, 373, 373, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 373, 373, + 373, 373, 373, 373, 374, 0, 0, 0, 0, 0, + 0, 374, 374, 374, 374, 374, 374, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 374, 374, 374, 374, 374, 374, 375, 0, 0, 0, + 0, 0, 0, 375, 375, 375, 375, 375, 375, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 375, 375, 375, 375, 375, 375, 387, 0, + 0, 0, 0, 0, 0, 387, 387, 387, 387, 387, + 387, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 387, 387, 387, 387, 387, 387, + 388, 0, 0, 0, 0, 0, 0, 388, 388, 388, + 388, 388, 388, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 388, 388, 388, 388, + 388, 388, 389, 0, 0, 0, 0, 0, 0, 389, + + 389, 389, 389, 389, 389, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 389, 389, + 389, 389, 389, 389, 397, 0, 0, 0, 0, 0, + 0, 397, 397, 397, 397, 397, 397, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 397, 397, 397, 397, 397, 397, 398, 0, 0, 0, + 0, 0, 0, 398, 398, 398, 398, 398, 398, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 398, 398, 398, 398, 398, 398, 414, 0, + 0, 0, 0, 0, 0, 414, 414, 414, 414, 414, + 414, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 414, 414, 414, 414, 414, 414, + 426, 0, 0, 0, 0, 0, 0, 426, 426, 426, + 426, 426, 426, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 426, 426, 426, 426, + + 426, 426, 428, 428, 428, 428, 428, 0, 0, 0, + 0, 0, 0, 0, 0, 428, 0, 0, 0, 0, + 0, 428, 0, 0, 0, 0, 0, 0, 428, 428, + 428, 428, 428, 428, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 428, 0, 0, 428, 428, 428, + 428, 428, 428, 437, 437, 437, 437, 437, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 437, 0, 0, 0, 0, 0, 0, 437, + 437, 437, 437, 437, 437, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 437, 437, + 437, 437, 437, 437, 439, 0, 0, 0, 0, 0, + 0, 439, 439, 439, 439, 439, 439, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 439, 439, 439, 439, 439, 439, 446, 0, 0, 0, + 0, 0, 0, 446, 446, 446, 446, 446, 446, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 446, 446, 446, 446, 446, 446, 447, 0, + 0, 0, 0, 0, 0, 447, 447, 447, 447, 447, + 447, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 447, 447, 447, 447, 447, 447, + 452, 0, 0, 0, 0, 0, 0, 452, 452, 452, + 452, 452, 452, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 452, 452, 452, 452, + 452, 452, 453, 0, 0, 0, 0, 0, 0, 453, + + 453, 453, 453, 453, 453, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 453, 453, + 453, 453, 453, 453, 458, 0, 0, 0, 0, 0, + 0, 458, 458, 458, 458, 458, 458, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 458, 458, 458, 458, 458, 458, 459, 0, 0, 0, + 0, 0, 0, 459, 459, 459, 459, 459, 459, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 459, 459, 459, 459, 459, 459, 464, 0, + 0, 0, 0, 0, 0, 464, 464, 464, 464, 464, + 464, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 464, 464, 464, 464, 464, 464, + 479, 0, 0, 479, 479, 479, 479, 479, 479, 479, + 479, 479, 479, 480, 480, 0, 480, 480, 481, 0, + 0, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 482, 482, 0, 482, 482, 483, 0, 0, 483, + + 483, 484, 0, 484, 484, 0, 484, 484, 485, 485, + 485, 485, 485, 485, 485, 485, 485, 485, 486, 486, 486, 486, 486, 486, 486, 486, 486, 486, 486, 486, - 487, 487, 487, 487, 487, 487, 487, 487, 487, 488, - 488, 0, 488, 488, 489, 489, 489, 489, 489, 489, - 489, 489, 489, 489, 489, 490, 490, 490, 490, 490, - 490, 490, 490, 490, 490, 490, 490, 491, 491, 492, - 492, 492, 492, 492, 492, 492, 492, 492, 493, 493, - 0, 493, 493, 494, 494, 494, 494, 494, 494, 494, - - 494, 494, 495, 495, 0, 495, 495, 496, 496, 496, - 496, 496, 496, 496, 496, 496, 497, 497, 497, 497, - 497, 497, 497, 497, 497, 498, 498, 498, 498, 498, - 498, 498, 498, 498, 498, 498, 498, 499, 499, 499, - 499, 499, 499, 499, 499, 499, 500, 500, 500, 500, - 500, 500, 500, 500, 500, 501, 501, 501, 0, 501, + 486, 488, 488, 0, 488, 488, 489, 489, 489, 489, + 489, 489, 489, 489, 489, 489, 490, 490, 490, 490, + 490, 490, 490, 490, 490, 490, 490, 490, 490, 491, + 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, + 491, 491, 491, 493, 493, 0, 493, 493, 494, 494, + 494, 494, 494, 494, 494, 494, 494, 494, 495, 495, + 0, 495, 495, 496, 496, 496, 496, 496, 496, 496, + + 496, 496, 496, 497, 497, 497, 497, 497, 497, 497, + 497, 497, 497, 498, 498, 498, 500, 500, 500, 500, + 500, 500, 500, 500, 500, 500, 501, 501, 0, 501, + 501, 501, 501, 501, 501, 501, 501, 501, 501, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, - 502, 502, 503, 503, 503, 0, 503, 504, 504, 504, - 504, 0, 504, 504, 504, 504, 504, 504, 505, 505, - 505, 0, 505, 506, 0, 506, 506, 506, 506, 506, - - 506, 506, 506, 506, 507, 0, 507, 507, 507, 507, - 507, 507, 507, 507, 507, 508, 508, 508, 508, 508, - 508, 508, 508, 508, 508, 508, 509, 509, 509, 0, - 509, 510, 510, 510, 510, 510, 510, 510, 510, 510, - 510, 510, 511, 511, 511, 511, 511, 511, 511, 511, - 511, 511, 511, 512, 512, 512, 0, 512, 513, 513, - 513, 0, 0, 0, 513, 0, 0, 513, 513, 514, - 514, 514, 514, 514, 514, 514, 514, 514, 515, 515, - 515, 0, 0, 515, 515, 515, 0, 515, 515, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 478, 478, + 502, 502, 503, 503, 503, 503, 503, 503, 503, 503, + 503, 503, 503, 503, 503, 503, 504, 504, 504, 504, + 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, + 505, 505, 505, 505, 505, 505, 505, 505, 505, 505, + 506, 506, 506, 506, 506, 506, 506, 506, 506, 506, + + 507, 507, 507, 507, 508, 0, 0, 508, 508, 508, + 508, 508, 508, 508, 508, 508, 508, 510, 510, 510, + 510, 510, 510, 510, 510, 510, 510, 510, 510, 510, + 510, 512, 512, 512, 512, 513, 513, 513, 513, 513, + 513, 0, 513, 513, 513, 513, 513, 513, 514, 514, + 514, 514, 514, 514, 514, 514, 514, 514, 514, 514, + 514, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 518, 518, 518, 518, 519, + 519, 519, 519, 519, 519, 0, 519, 519, 519, 519, + 519, 519, 520, 0, 0, 520, 520, 520, 520, 520, + + 520, 520, 520, 520, 520, 521, 0, 0, 521, 521, + 521, 521, 521, 521, 521, 521, 521, 521, 522, 522, + 522, 522, 522, 522, 522, 522, 522, 522, 522, 522, + 522, 523, 523, 523, 523, 523, 523, 523, 523, 523, + 523, 523, 523, 523, 525, 525, 0, 525, 525, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 528, 528, 528, 528, 529, 529, 529, 529, + 529, 529, 529, 529, 529, 529, 529, 529, 529, 530, + 0, 0, 530, 530, 530, 530, 530, 530, 530, 530, + 530, 530, 531, 531, 531, 531, 531, 531, 531, 531, + + 531, 531, 531, 531, 531, 532, 532, 532, 532, 532, + 0, 0, 532, 532, 532, 532, 532, 532, 533, 533, + 533, 533, 533, 533, 533, 533, 533, 533, 533, 533, + 533, 534, 534, 534, 534, 534, 534, 534, 534, 534, + 534, 534, 534, 534, 535, 535, 0, 535, 535, 536, + 536, 536, 536, 536, 536, 536, 536, 536, 536, 536, + 536, 536, 538, 538, 538, 538, 539, 539, 0, 539, + 539, 539, 539, 539, 539, 539, 539, 539, 539, 540, + 540, 540, 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 541, 541, 0, 541, 541, 541, 541, 541, + + 541, 541, 541, 541, 541, 542, 542, 542, 542, 542, + 542, 542, 542, 542, 542, 542, 542, 542, 543, 543, + 543, 543, 543, 0, 0, 543, 543, 543, 543, 543, + 543, 546, 546, 546, 546, 0, 0, 0, 0, 546, + 0, 0, 546, 546, 547, 547, 547, 547, 0, 0, + 0, 547, 547, 547, 0, 547, 547, 548, 548, 548, + 548, 548, 548, 548, 548, 548, 548, 549, 549, 549, + 549, 549, 549, 549, 549, 549, 549, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478 + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 478, 478 } ; #line 1 "" @@ -878,7 +1813,7 @@ YY_DECL yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 2399 ); + while ( yy_base[yy_current_state] != 6578 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -1250,7 +2185,7 @@ YY_RULE_SETUP #line 110 "" ECHO; YY_BREAK -#line 1761 "" +#line 2738 "" case YY_STATE_EOF(INITIAL): case YY_END_OF_BUFFER: case YY_STATE_EOF(mediaquery): diff --git a/src/3rdparty/webkit/WebCore/page/DOMWindow.cpp b/src/3rdparty/webkit/WebCore/page/DOMWindow.cpp index 42d2e90..dd14fb9 100644 --- a/src/3rdparty/webkit/WebCore/page/DOMWindow.cpp +++ b/src/3rdparty/webkit/WebCore/page/DOMWindow.cpp @@ -333,6 +333,9 @@ Storage* DOMWindow::sessionStorage() const Storage* DOMWindow::localStorage() const { + if (m_localStorage) + return m_localStorage.get(); + Document* document = this->document(); if (!document) return 0; diff --git a/src/3rdparty/webkit/WebCore/page/DOMWindow.h b/src/3rdparty/webkit/WebCore/page/DOMWindow.h index 0277441..e7fab18 100644 --- a/src/3rdparty/webkit/WebCore/page/DOMWindow.h +++ b/src/3rdparty/webkit/WebCore/page/DOMWindow.h @@ -265,7 +265,7 @@ namespace WebCore { Location* optionalLocation() const { return m_location.get(); } #if ENABLE(DOM_STORAGE) Storage* optionalSessionStorage() const { return m_sessionStorage.get(); } - Storage* optionalLocalStorage() const { return m_sessionStorage.get(); } + Storage* optionalLocalStorage() const { return m_localStorage.get(); } #endif #if ENABLE(OFFLINE_WEB_APPLICATIONS) DOMApplicationCache* optionalApplicationCache() const { return m_applicationCache.get(); } diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageBufferQt.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageBufferQt.cpp index d4ab59f..cea255e 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageBufferQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageBufferQt.cpp @@ -35,6 +35,8 @@ #include "StillImageQt.h" #include +#include +#include #include #include #include @@ -79,10 +81,57 @@ Image* ImageBuffer::image() const return m_image.get(); } -PassRefPtr ImageBuffer::getImageData(const IntRect&) const +PassRefPtr ImageBuffer::getImageData(const IntRect& rect) const { - notImplemented(); - return 0; + PassRefPtr result = ImageData::create(rect.width(), rect.height()); + unsigned char* data = result->data()->data(); + + if (rect.x() < 0 || rect.y() < 0 || (rect.x() + rect.width()) > m_size.width() || (rect.y() + rect.height()) > m_size.height()) + memset(data, 0, result->data()->length()); + + int originx = rect.x(); + int destx = 0; + if (originx < 0) { + destx = -originx; + originx = 0; + } + int endx = rect.x() + rect.width(); + if (endx > m_size.width()) + endx = m_size.width(); + int numColumns = endx - originx; + + int originy = rect.y(); + int desty = 0; + if (originy < 0) { + desty = -originy; + originy = 0; + } + int endy = rect.y() + rect.height(); + if (endy > m_size.height()) + endy = m_size.height(); + int numRows = endy - originy; + + QImage image = m_data.m_pixmap.toImage(); + if (image.format() != QImage::Format_ARGB32) + image = image.convertToFormat(QImage::Format_ARGB32); + ASSERT(image); + + unsigned destBytesPerRow = 4 * rect.width(); + unsigned char* destRows = data + desty * destBytesPerRow + destx * 4; + for (int y = 0; y < numRows; ++y) { + for (int x = 0; x < numColumns; x++) { + QRgb value = image.pixel(x + originx, y + originy); + int basex = x * 4; + + destRows[basex] = qRed(value); + destRows[basex + 1] = qGreen(value); + destRows[basex + 2] = qBlue(value); + destRows[basex + 3] = qAlpha(value); + } + destRows += destBytesPerRow; + } + + return result; } void ImageBuffer::putImageData(ImageData*, const IntRect&, const IntPoint&) diff --git a/src/3rdparty/webkit/WebCore/platform/network/qt/ResourceRequestQt.cpp b/src/3rdparty/webkit/WebCore/platform/network/qt/ResourceRequestQt.cpp index 9308878..c8f6ad5 100644 --- a/src/3rdparty/webkit/WebCore/platform/network/qt/ResourceRequestQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/network/qt/ResourceRequestQt.cpp @@ -41,6 +41,22 @@ QNetworkRequest ResourceRequest::toNetworkRequest() const request.setRawHeader(name, value); } + switch (cachePolicy()) { + case ReloadIgnoringCacheData: + request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork); + break; + case ReturnCacheDataElseLoad: + request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); + break; + case ReturnCacheDataDontLoad: + request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysCache); + break; + case UseProtocolCachePolicy: + // QNetworkRequest::PreferNetwork + default: + break; + } + return request; } diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp index d85e880..fe74fac 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp @@ -106,6 +106,8 @@ private slots: void textSelection(); void textEditing(); + void requestCache(); + private: @@ -989,6 +991,32 @@ void tst_QWebPage::textEditing() delete page; } +void tst_QWebPage::requestCache() +{ + TestPage page; + QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool))); + + page.mainFrame()->setUrl(QString("data:text/html,Click me")); + QTRY_COMPARE(loadSpy.count(), 1); + QTRY_COMPARE(page.navigations.count(), 1); + + page.mainFrame()->setUrl(QString("data:text/html,Click me2")); + QTRY_COMPARE(loadSpy.count(), 2); + QTRY_COMPARE(page.navigations.count(), 2); + + page.triggerAction(QWebPage::Stop); + QVERIFY(page.history()->canGoBack()); + page.triggerAction(QWebPage::Back); + + QTRY_COMPARE(loadSpy.count(), 3); + QTRY_COMPARE(page.navigations.count(), 3); + QCOMPARE(page.navigations.at(0).request.attribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork).toInt(), + (int)QNetworkRequest::PreferNetwork); + QCOMPARE(page.navigations.at(1).request.attribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork).toInt(), + (int)QNetworkRequest::PreferNetwork); + QCOMPARE(page.navigations.at(2).request.attribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork).toInt(), + (int)QNetworkRequest::PreferCache); +} QTEST_MAIN(tst_QWebPage) #include "tst_qwebpage.moc" -- cgit v0.12 From 87a19963529a3974ae5fda3822c49cdc9a973a93 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Wed, 15 Apr 2009 12:08:35 +0200 Subject: BT: Fix a crash on certain theme changes in GNOME We did not update initGtkWidgets on theme changes which could lead to crashes as the contents of the widget hash depend on certain properties in the style. A simple way to reproduce this would be to change between the redmond gtk theme and cleanlooks. Task-number: 251115 Reviewed-by: paul --- src/gui/styles/gtksymbols.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/styles/gtksymbols.cpp b/src/gui/styles/gtksymbols.cpp index f7af8f8..acb8437 100644 --- a/src/gui/styles/gtksymbols.cpp +++ b/src/gui/styles/gtksymbols.cpp @@ -549,6 +549,7 @@ void QGtkStyleUpdateScheduler::updateTheme() QPalette newPalette = qApp->style()->standardPalette(); QApplicationPrivate::setSystemPalette(newPalette); QApplication::setPalette(newPalette); + QGtk::initGtkWidgets(); QGtk::applyCustomPaletteHash(); QList widgets = QApplication::allWidgets(); // Notify all widgets that size metrics might have changed -- cgit v0.12 From aa082287ab51dd42c749e92431527c69f6adc078 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Wed, 15 Apr 2009 12:11:39 +0200 Subject: BT: Fix Cocoa bug w/OpenGL widgets in dock widgets would disappear. The NSOpenGLContext seems to be tied to the window. So if the view changes from one window to another, the OpenGL context needs to be cleared. We can do this by hooking into the viewWillChangeWindow and viewDidChangeWindow events and clear and reset the drawable respectively. We also found out that QCocoaOpenGLView was not being used at all, so just remove it to get rid of any confusion. Task-number: 250066 Reviewed-by: Trond --- src/corelib/kernel/qcoreevent.h | 1 + src/gui/kernel/qcocoaview_mac.mm | 21 +++++++++++++++++++++ src/opengl/qgl.cpp | 4 ++++ src/opengl/qgl_mac.mm | 28 +++++----------------------- src/opengl/qgl_p.h | 1 + 5 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h index 5487703..fa472e6 100644 --- a/src/corelib/kernel/qcoreevent.h +++ b/src/corelib/kernel/qcoreevent.h @@ -264,6 +264,7 @@ public: GrabKeyboard = 188, UngrabKeyboard = 189, CocoaRequestModal = 190, // Internal for requesting an application modal Cocoa Window + MacGLClearDrawable = 191, // Internal Cocoa, the window has changed, so we must clear // 512 reserved for Qt Jambi's MetaCall event // 513 reserved for Qt Jambi's DeleteOnMainThread event diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 118d54c..670226b 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -946,6 +946,27 @@ extern "C" { } } +- (void)viewWillMoveToWindow:(NSWindow *)window +{ + if (qwidget->windowFlags() & Qt::MSWindowsOwnDC + && (window != [self window])) { // OpenGL Widget + // Create a stupid ClearDrawable Event + QEvent event(QEvent::MacGLClearDrawable); + qApp->sendEvent(qwidget, &event); + } +} + +- (void)viewDidMoveToWindow +{ + if (qwidget->windowFlags() & Qt::MSWindowsOwnDC && [self window]) { + // call update paint event + qwidgetprivate->needWindowChange = true; + QEvent event(QEvent::MacGLWindowChange); + qApp->sendEvent(qwidget, &event); + } +} + + // NSTextInput Protocol implementation - (void) insertText:(id)aString diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 303b5e2..99df658 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -3235,6 +3235,10 @@ bool QGLWidget::event(QEvent *e) update(); } return true; +# if defined(QT_MAC_USE_COCOA) + } else if (e->type() == QEvent::MacGLClearDrawable) { + d->glcx->d_ptr->clearDrawable(); +# endif } #endif diff --git a/src/opengl/qgl_mac.mm b/src/opengl/qgl_mac.mm index 314c659..3dbdaec 100644 --- a/src/opengl/qgl_mac.mm +++ b/src/opengl/qgl_mac.mm @@ -87,29 +87,6 @@ QT_FORWARD_DECLARE_CLASS(QWidget) QT_FORWARD_DECLARE_CLASS(QWidgetPrivate) QT_FORWARD_DECLARE_CLASS(QGLWidgetPrivate) -@interface QT_MANGLE_NAMESPACE(QCocoaOpenGLView) : QT_MANGLE_NAMESPACE(QCocoaView) -{ -} -- (id)initWithQWidget:(QWidget *)widget widgetPrivate:(QWidgetPrivate *)widgetprivate; -@end - -@implementation QT_MANGLE_NAMESPACE(QCocoaOpenGLView) -- (id)initWithQWidget:(QWidget *)widget widgetPrivate:(QWidgetPrivate *)widgetprivate -{ - self = [super initWithQWidget:widget widgetPrivate:widgetprivate]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(_surfaceNeedsUpdate:) - name:NSViewGlobalFrameDidChangeNotification - object:self]; - return self; -} - -- (void) _surfaceNeedsUpdate:(NSNotification*)notification -{ - Q_UNUSED(notification); - static_cast(qwidgetprivate)->glcx->updatePaintDevice(); -} -@end QT_BEGIN_NAMESPACE void *qt_current_nsopengl_context() @@ -435,6 +412,11 @@ void *QGLContextPrivate::tryFormat(const QGLFormat &format) #endif } +void QGLContextPrivate::clearDrawable() +{ + [static_cast(cx) clearDrawable]; +} + /*! \bold{Mac OS X only:} This virtual function tries to find a visual that matches the format, reducing the demands if the original request diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index b15eebc..1214f20 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -234,6 +234,7 @@ public: #if defined(Q_WS_MAC) bool update; void *tryFormat(const QGLFormat &format); + void clearDrawable(); #endif QGLFormat glFormat; QGLFormat reqFormat; -- cgit v0.12 From c88a6e3b4f49c8e79f617b0ac9e04a95a3db5764 Mon Sep 17 00:00:00 2001 From: Morten Engvoldsen Date: Wed, 15 Apr 2009 12:27:05 +0200 Subject: Added remark about XML input Stated a remark about the need to use well-formed XML as input to the example. Rev-by: Geir Vattekar --- doc/src/examples/qxmlstreambookmarks.qdoc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/doc/src/examples/qxmlstreambookmarks.qdoc b/doc/src/examples/qxmlstreambookmarks.qdoc index 7059043..47d5654 100644 --- a/doc/src/examples/qxmlstreambookmarks.qdoc +++ b/doc/src/examples/qxmlstreambookmarks.qdoc @@ -103,8 +103,11 @@ The \c read() function accepts a QIODevice and sets it using \l{QXmlStreamReader::setDevice()}{setDevice()}. The actual process - of reading only takes place in event the file is a valid XBEL 1.0 - file. Otherwise, the \l{QXmlStreamReader::raiseError()} + of reading only takes place if the file is a valid XBEL 1.0 file. + Note that the XML input needs to be well-formed to be accepted by + QXmlStreamReader. + + Otherwise, the \l{QXmlStreamReader::raiseError()} {raiseError()} function is used to display an error message. \snippet examples/xml/streambookmarks/xbelreader.cpp 1 -- cgit v0.12 From 3ad5e5546c48bc1a4dd47107367963c77ea290ff Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Wed, 15 Apr 2009 12:27:50 +0200 Subject: Doc - changed "MAY NOT" to an italicized version of 'may not' for some consistency. --- doc/src/qnamespace.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/qnamespace.qdoc b/doc/src/qnamespace.qdoc index e6a1a36..d9f001e 100644 --- a/doc/src/qnamespace.qdoc +++ b/doc/src/qnamespace.qdoc @@ -142,7 +142,7 @@ QAction::iconVisibleInMenu property. Menus that are currently open or menus already created in the native - Mac OS X menubar MAY NOT pick up a change in this attribute. Changes + Mac OS X menubar \e{may not} pick up a change in this attribute. Changes in the QAction::iconVisibleInMenu property will always be picked up. \value AA_NativeWindows Ensures that widgets have native windows. -- cgit v0.12 From d006962a56d3f8d8ff305870128c8806c839cba9 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 15 Apr 2009 11:59:56 +0200 Subject: BT: OpenGL ES 2.0 now compiles properly for Windows CE glpixmapfilter should not be compiled for OpenGL ES 2.0 on nay platform Reviewed-by: Tom Cooksey --- src/opengl/opengl.pro | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro index 48d7caf..78aaddb 100644 --- a/src/opengl/opengl.pro +++ b/src/opengl/opengl.pro @@ -25,18 +25,16 @@ HEADERS += qgl.h \ qglcolormap.h \ qglpixelbuffer.h \ qglframebufferobject.h \ - qglpixmapfilter_p.h SOURCES += qgl.cpp \ qglcolormap.cpp \ qglpixelbuffer.cpp \ qglframebufferobject.cpp \ qglextensions.cpp \ - qglpixmapfilter.cpp !contains(QT_CONFIG, opengles2) { - HEADERS += qpaintengine_opengl_p.h - SOURCES += qpaintengine_opengl.cpp + HEADERS += qpaintengine_opengl_p.h qglpixmapfilter_p.h + SOURCES += qpaintengine_opengl.cpp qglpixmapfilter.cpp } contains(QT_CONFIG, opengles2) { @@ -130,6 +128,10 @@ wince*: { contains(QT_CONFIG,opengles1cl) { QMAKE_LIBS += "libGLES_CL.lib" } + contains(QT_CONFIG,opengles2) { + QMAKE_LIBS += "libGLESv2.lib" + } + } else { QMAKE_LIBS += $$QMAKE_LIBS_OPENGL } -- cgit v0.12 From 3ffcf436e5233a6e07e3bbbfdef9da9e3bf43052 Mon Sep 17 00:00:00 2001 From: Morten Engvoldsen Date: Wed, 15 Apr 2009 12:37:32 +0200 Subject: Correcting paragraph Made a mistake when pushing e0706ca2fbce063c263bad9a1eee24f057f170bd I Corrected this. Task-number: 250254 Rev-by: Frans Englich Rev-by: Geir Vattekar --- doc/src/examples/qxmlstreambookmarks.qdoc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/doc/src/examples/qxmlstreambookmarks.qdoc b/doc/src/examples/qxmlstreambookmarks.qdoc index 47d5654..fb3a1c1 100644 --- a/doc/src/examples/qxmlstreambookmarks.qdoc +++ b/doc/src/examples/qxmlstreambookmarks.qdoc @@ -105,9 +105,7 @@ \l{QXmlStreamReader::setDevice()}{setDevice()}. The actual process of reading only takes place if the file is a valid XBEL 1.0 file. Note that the XML input needs to be well-formed to be accepted by - QXmlStreamReader. - - Otherwise, the \l{QXmlStreamReader::raiseError()} + QXmlStreamReader. Otherwise, the \l{QXmlStreamReader::raiseError()} {raiseError()} function is used to display an error message. \snippet examples/xml/streambookmarks/xbelreader.cpp 1 -- cgit v0.12 From 5d3341c1be672502c1cf13fc02ad0ebafc4e1439 Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Wed, 15 Apr 2009 12:45:09 +0200 Subject: My ChangeLog. Reviewed-by: Trust Me --- dist/changes-4.5.1 | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index e8595ff..68edc78 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -25,6 +25,9 @@ General Improvements - Documentation and Examples +- Embedded Dialogs demo + * [246517] Fixed warnings and bugs in hover handling on Mac OS X + Third party components ---------------------- @@ -69,7 +72,12 @@ Third party components - QGraphicsItem * [247890] Cached QGraphicsItems are not updated if update() is called when they are hidden - * [250272] When an item is deleted it does not get removed from the sceneeventfilters meaning a crash can occur + * [250272] When an item is deleted it does not get removed from the + sceneeventfilters meaning a crash can occur + * Fixed slowdown regression in QGraphicsItem::ItemCoordinateCache + +- QGraphicsScene + * [243707] Fixed crash when adding child before parent to scene -QGraphicsView * [245766] Rubber Band drag mode not updated correctly when scrolling -- cgit v0.12 From f688bdbe3b6039f4dd0dd65d286a030f65b42833 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 15 Apr 2009 11:01:24 +0200 Subject: My changes for 4.5.1 BT: yes --- dist/changes-4.5.1 | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index 68edc78..bbf0bf1 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -49,6 +49,9 @@ Third party components - QAuthenticator * [237979] fix implemenation of md5-sess +- QByteArray + * [246233] QByteArray::fromHex() fails with input of size 1 + - QColorDialog * [247349] Fixed bug causing the wrong alpha value to be returned. @@ -62,6 +65,10 @@ Third party components - QDirIterator * [247645] Fix a bug that may loose all cached data inside the QFileInfo +- QFile + * [244500] QFile::rename() doesn't always return false when the method fails + * [244485] Renaming a file does not change QFile::fileName() + - QFileInfo * [205244] return valid file info also for relative UNC paths @@ -301,6 +308,7 @@ Qt for Windows CE - moc + * [240368] moc parsing issue with "unsigned" subphrase - uic * [244998] Fixed include file generation for phonon widgets. @@ -314,6 +322,8 @@ Qt for Windows CE - qmake * [248806] Ensure that the Xcode generator includes the right path to frameworks. + * [201495] Comment processing in qmake prevented file from being moc'ed + * On Mac OS, properly escape file names in QMAKE_BUNDLE_DATA - configure -- cgit v0.12 From 8f79eebb365dbeaa4bb6da148cba1dedbd15a950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Wed, 15 Apr 2009 13:25:22 +0200 Subject: My changes --- dist/changes-4.5.1 | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index bbf0bf1..8d90ac9 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -46,6 +46,11 @@ Third party components - QAbstractSocket * [192037] Emit disconnected only if we were connected before +- QAccessible + * [241161] Fixed bug in browsing menus with the keyboard. + * [221731] Fixed bug where the accessibility plugin could crash if there + was an "&" at the end or spin forever if a label had a sequence of "&&". + - QAuthenticator * [237979] fix implemenation of md5-sess @@ -83,12 +88,20 @@ Third party components sceneeventfilters meaning a crash can occur * Fixed slowdown regression in QGraphicsItem::ItemCoordinateCache +- QGraphicsGridLayout + * [242472] Fix a bug where the calculation of the maximum width of a column + was not calculated correctly. + - QGraphicsScene * [243707] Fixed crash when adding child before parent to scene -QGraphicsView * [245766] Rubber Band drag mode not updated correctly when scrolling +- QGraphicsWidget + * [246215] Fixed a regression where we could cache the wrong size hint + because we called the virtual sizeHint() from the constructor. + - QHttp * [208445] cancel request upon receiving unknown authentication method @@ -142,7 +155,7 @@ Third party components * Fixed crash that may occurs when event are processed just after QSortFilterProxyModel has been invalidated * [246025] Fixed auto-expand that occurs while quicly collapsing an item after clicking on a child - * [248805] Calling programatically QTreeView::sortByColumn was not working if manual + * [248805] Calling programatically QTreeView::sortByColumn was not working if manual sorting is disabled * [248163] Fixed possible crash in the paintEvent when spans are used. @@ -184,13 +197,13 @@ Qt for Linux/X11 CD playback. - QGtkStyle - * The system palette is no longer strictly forced. Also behavior related + * The system palette is no longer strictly forced. Also behavior related to system theme changes have been improved. * [249363] QFrame is now styled as a GtkScrolledWindow. * [247653] Fixed a compilation issue on solaris. - * Fixed palette and styling issues with the background color of + * Fixed palette and styling issues with the background color of combo box popups. - * [239829] Disabled alt-key navigation for QGtkStyle to follow + * [239829] Disabled alt-key navigation for QGtkStyle to follow GTK+ behavior. * [238196] Allow middle click to set scrollbar position to follow GTK+ behavior. @@ -250,8 +263,8 @@ Qt for Mac OS X - Fix a crash when showing a widget that is window modal but has no parent. - [248803] Showing two dialogs at the same time don't get shared activation. -- Added QSysInfo::MV_10_6 as an enum to test against. -- Various compile fixes for Snow Leopard (preliminary support). +- Added QSysInfo::MV_10_6 as an enum to test against. +- Various compile fixes for Snow Leopard (preliminary support). - The uninstall-qt.py script included in the binary package no longer complains about removing itself multiple times. -- cgit v0.12 From d02f862d2ff106517c2ad3fab6d6f089dbd9f367 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Wed, 15 Apr 2009 13:14:31 +0200 Subject: BT: Namespace compile fixes for Cocoa. It worked in 4.5.0, so it should work in 4.5.1 too. --- src/gui/kernel/qcocoapanel_mac.mm | 8 +++++--- src/gui/kernel/qcocoawindow_mac.mm | 7 ++++--- src/gui/widgets/qcocoamenu_mac.mm | 6 ++++++ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/gui/kernel/qcocoapanel_mac.mm b/src/gui/kernel/qcocoapanel_mac.mm index 95e20af..c69826f 100644 --- a/src/gui/kernel/qcocoapanel_mac.mm +++ b/src/gui/kernel/qcocoapanel_mac.mm @@ -49,8 +49,10 @@ #include +QT_FORWARD_DECLARE_CLASS(QWidget); +QT_BEGIN_NAMESPACE extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.mm - +QT_END_NAMESPACE QT_USE_NAMESPACE @implementation QT_MANGLE_NAMESPACE(QCocoaPanel) @@ -108,7 +110,7 @@ QT_USE_NAMESPACE [self retain]; QWidget *widget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self]; - QCocoaView *view = static_cast(qt_mac_nativeview_for(widget)); + QT_MANGLE_NAMESPACE(QCocoaView) *view = static_cast(qt_mac_nativeview_for(widget)); Qt::MouseButton mouseButton = cocoaButton2QtButton([event buttonNumber]); // sometimes need to redirect mouse events to the popup. @@ -172,7 +174,7 @@ QT_USE_NAMESPACE + (Class)frameViewClassForStyleMask:(NSUInteger)styleMask { if (styleMask & QtMacCustomizeWindow) - return [QCocoaWindowCustomThemeFrame class]; + return [QT_MANGLE_NAMESPACE(QCocoaWindowCustomThemeFrame) class]; return [super frameViewClassForStyleMask:styleMask]; } diff --git a/src/gui/kernel/qcocoawindow_mac.mm b/src/gui/kernel/qcocoawindow_mac.mm index 972e477..89f481f 100644 --- a/src/gui/kernel/qcocoawindow_mac.mm +++ b/src/gui/kernel/qcocoawindow_mac.mm @@ -53,9 +53,10 @@ #include QT_FORWARD_DECLARE_CLASS(QWidget); -QT_USE_NAMESPACE - +QT_BEGIN_NAMESPACE extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.mm +QT_END_NAMESPACE +QT_USE_NAMESPACE @implementation NSWindow (QT_MANGLE_NAMESPACE(QWidgetIntegration)) @@ -130,7 +131,7 @@ extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview. [self retain]; QWidget *widget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self]; - QCocoaView *view = static_cast(qt_mac_nativeview_for(widget)); + QT_MANGLE_NAMESPACE(QCocoaView) *view = static_cast(qt_mac_nativeview_for(widget)); Qt::MouseButton mouseButton = cocoaButton2QtButton([event buttonNumber]); // sometimes need to redirect mouse events to the popup. diff --git a/src/gui/widgets/qcocoamenu_mac.mm b/src/gui/widgets/qcocoamenu_mac.mm index c5fee66..6434289 100644 --- a/src/gui/widgets/qcocoamenu_mac.mm +++ b/src/gui/widgets/qcocoamenu_mac.mm @@ -55,11 +55,17 @@ QT_FORWARD_DECLARE_CLASS(QAction) QT_FORWARD_DECLARE_CLASS(QWidget) QT_FORWARD_DECLARE_CLASS(QApplication) +QT_FORWARD_DECLARE_CLASS(QCoreApplication) +QT_FORWARD_DECLARE_CLASS(QApplicationPrivate) +QT_FORWARD_DECLARE_CLASS(QKeyEvent) +QT_FORWARD_DECLARE_CLASS(QEvent) QT_BEGIN_NAMESPACE extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); //qapplication.cpp QT_END_NAMESPACE +QT_USE_NAMESPACE + @implementation QT_MANGLE_NAMESPACE(QCocoaMenu) - (id)initWithQMenu:(QMenu*)menu -- cgit v0.12 From a1905a8050432ea35ac20ffc615c4fe430f62183 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Wed, 15 Apr 2009 13:34:09 +0200 Subject: Reparenting QGLWidgets did sometimes caused warnings to be printed on Mac/Cocoa. Check if the view is visible before attaching it to a context. Task-number: related to 250066 Reviewed-by: Norwegian Rock Cat BT: yes --- src/opengl/qgl_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengl/qgl_mac.mm b/src/opengl/qgl_mac.mm index 3dbdaec..1319396 100644 --- a/src/opengl/qgl_mac.mm +++ b/src/opengl/qgl_mac.mm @@ -629,7 +629,7 @@ void QGLContext::updatePaintDevice() // ideally we would use QWidget::isVisible(), but we get "invalid drawable" errors if (![(NSWindow *)qt_mac_window_for(w) isVisible]) return; - if ([static_cast(d->cx) view] != view) + if ([static_cast(d->cx) view] != view && ![view isHidden]) [static_cast(d->cx) setView:view]; } else if (d->paintDevice->devType() == QInternal::Pixmap) { const QPixmap *pm = static_cast(d->paintDevice); -- cgit v0.12 From 305b64b551a5c1b708434033e56e7c6a0efb54dc Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 15 Apr 2009 13:49:57 +0200 Subject: BT: Updated configure for OpenGL ES 2.0 Windows CE --- configure.exe | Bin 1134592 -> 860160 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/configure.exe b/configure.exe index 13ca0e5..ff71f08 100644 Binary files a/configure.exe and b/configure.exe differ -- cgit v0.12 From a0c67f25dfa722af7a321cf1814bdbba6d7fa947 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 15 Apr 2009 14:14:27 +0200 Subject: Update the item if the text has changed but the boundingRect is the same. updateBoudingRect update the item only if the boundingRect change but if we have 123 as an initial text and then we set 321 as the new text, then nothing happen because the rect is the same. In case the boundingRect change then we call update 2 times but the item is already dirty so the second call will just return. BT:yes Reviewed-by: Andreas --- src/gui/graphicsview/qgraphicsitem.cpp | 1 + tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 34 ++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 7aba576..3aa74f3 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -8617,6 +8617,7 @@ void QGraphicsSimpleTextItem::setText(const QString &text) return; d->text = text; d->updateBoundingRect(); + update(); } /*! diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 439dc2b..09b209d 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -223,6 +223,7 @@ private slots: // task specific tests below me void task141694_textItemEnsureVisible(); void task128696_textItemEnsureMovable(); + void ensureUpdateOnTextItem(); void task177918_lineItemUndetected(); void task240400_clickOnTextItem_data(); void task240400_clickOnTextItem(); @@ -5294,6 +5295,39 @@ void tst_QGraphicsItem::task240400_clickOnTextItem() QCOMPARE(item->textCursor().columnNumber(), 0); } +class TextItem : public QGraphicsSimpleTextItem +{ +public: + TextItem(const QString& text) : QGraphicsSimpleTextItem(text) + { + updates = 0; + } + + void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) + { + updates++; + QGraphicsSimpleTextItem::paint(painter, option, widget); + } + + int updates; +}; + +void tst_QGraphicsItem::ensureUpdateOnTextItem() +{ + QGraphicsScene scene; + TextItem *text1 = new TextItem(QLatin1String("123")); + scene.addItem(text1); + QGraphicsView view(&scene); + view.show(); + QTest::qWait(250); + QCOMPARE(text1->updates,1); + + //same bouding rect but we have to update + text1->setText(QLatin1String("321")); + QTest::qWait(250); + QCOMPARE(text1->updates,2); +} + void tst_QGraphicsItem::task243707_addChildBeforeParent() { // Task reports that adding the child before the parent leads to an -- cgit v0.12 From 49122ec5f25f2ffdf61908c0e4bb1a7ff42ee2b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20S=C3=B8rvig?= Date: Wed, 15 Apr 2009 14:35:32 +0200 Subject: My 4.5.1 changes. --- dist/changes-4.5.1 | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index 8d90ac9..4fb155a 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -67,6 +67,9 @@ Third party components * [250064] Fixed focus policy propagation regression. * [246056] Fixed assertion failure in setCompletionPrefix(). +- QtConcurrent + * [244718] Reduce the number of calls to QThread::idealThreadCount(). + - QDirIterator * [247645] Fix a bug that may loose all cached data inside the QFileInfo @@ -260,13 +263,24 @@ Qt for Mac OS X * Modify the colliding mice example to work better with coalesced updates. * Fixed a bug where the drag cursor was not updated when modifier keys are used. * [247947] Fixed a crash in drag and drop. + * The command + h shortcut is now enabled. (Hides the current window.) + +- QDesktopWidget + * [244004] Support multiple screens that have different sizes properly. + +- macdeployqt + * The binary packages now includes the macdeployqt tool. + * macdeployqt now runs 'strip' on the deployed binaries. + * Fixed issue preventing the QtSvg from being deployed. + +- configure script + * Now supports "-arch i386" as an alias for "-arch x86". + * Detects invalid arch arguemnts and exits. - Fix a crash when showing a widget that is window modal but has no parent. - [248803] Showing two dialogs at the same time don't get shared activation. - Added QSysInfo::MV_10_6 as an enum to test against. - Various compile fixes for Snow Leopard (preliminary support). - - - The uninstall-qt.py script included in the binary package no longer complains about removing itself multiple times. - Document a bit clearer how qt_mac_set_dock_menu() works. -- cgit v0.12 From 2419f501558d1ca457c06e9225bde5d0502d8a02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 15 Apr 2009 14:03:49 +0200 Subject: Prevent crash in qt_scrollRectInImage. Clip both against the source and target device rectangles. Task-number: 247937 Reviewed-by: Trond BT: yes --- dist/changes-4.5.1 | 4 ++++ src/gui/painting/qwindowsurface.cpp | 7 +++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index 4fb155a..bda151f 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -162,6 +162,10 @@ Third party components sorting is disabled * [248163] Fixed possible crash in the paintEvent when spans are used. +- QWidget + * [250388] Fixed potential crash in QWidget::scroll() when using the raster + graphics system. + - QWizard * [248107] Fixed bug on Vista causing Back button to connect twice to the back() signal. diff --git a/src/gui/painting/qwindowsurface.cpp b/src/gui/painting/qwindowsurface.cpp index bcb0380..d941a24 100644 --- a/src/gui/painting/qwindowsurface.cpp +++ b/src/gui/painting/qwindowsurface.cpp @@ -310,10 +310,13 @@ void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset) int lineskip = img.bytesPerLine(); int depth = img.depth() >> 3; - - const QRect r = rect & QRect(0, 0, img.width(), img.height()); + const QRect imageRect(0, 0, img.width(), img.height()); + const QRect r = rect & imageRect & imageRect.translated(-offset); const QPoint p = rect.topLeft() + offset; + if (r.isEmpty()) + return; + const uchar *src; uchar *dest; -- cgit v0.12 From 1e123c84179f5be291e47178f81a37cbede8717e Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Wed, 15 Apr 2009 14:26:59 +0200 Subject: Doc - clarified that on Windows, for 32-bit programs running in WOW64 mode, the settings are stored in HKEY_LOCAL_MACHINE\Software\WOW6432node. Task-number: 232011 Reviewed-by: Martin Petersson --- src/corelib/io/qsettings.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 62b4ed5..484e79a 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -2330,6 +2330,10 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile, \o \c{HKEY_LOCAL_MACHINE\Software\MySoft} \endlist + \note On Windows, for 32-bit programs running in WOW64 mode, settings are + stored in the following registry path: + \c{HKEY_LOCAL_MACHINE\Software\WOW6432node}. + If the file format is IniFormat, the following files are used on Unix and Mac OS X: -- cgit v0.12 From b89a87ca0d14d882250688260b21fb1567273b34 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Wed, 15 Apr 2009 14:46:59 +0200 Subject: Fixed painting issues with draggable tabs This fixes a few of the remaining glitches tabbar animations have: * We no longer grab tabs but paint them through QStyle. This makes tabs work and animate correctly when they are outside the visible region. * Buttons now correctly follow tabs when dropped * Gtkstyle recieved some polish to make it look more native. Task-number: 247694, 251166 Reviewed-by: nrc --- src/gui/styles/qgtkstyle.cpp | 9 +++-- src/gui/widgets/qtabbar.cpp | 90 +++++++++++++++++++++++--------------------- src/gui/widgets/qtabbar_p.h | 33 ++-------------- 3 files changed, 57 insertions(+), 75 deletions(-) diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index 519fed7..541415f 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -2760,10 +2760,13 @@ void QGtkStyle::drawControl(ControlElement element, if (tab->state & State_Selected) state = GTK_STATE_NORMAL; - bool first = tab->position == QStyleOptionTab::Beginning || tab->position == QStyleOptionTab::OnlyOneTab; - bool last = tab->position == QStyleOptionTab::End || tab->position == QStyleOptionTab::OnlyOneTab; bool selected = (tab->state & State_Selected); - if (option->direction == Qt::RightToLeft) { + bool first = false, last = false; + if (widget) { + // This is most accurate and avoids resizing tabs while moving + first = tab->rect.left() == widget->rect().left(); + last = tab->rect.right() == widget->rect().right(); + } else if (option->direction == Qt::RightToLeft) { bool tmp = first; first = last; last = tmp; diff --git a/src/gui/widgets/qtabbar.cpp b/src/gui/widgets/qtabbar.cpp index 7d970ad..b6e6b6d 100644 --- a/src/gui/widgets/qtabbar.cpp +++ b/src/gui/widgets/qtabbar.cpp @@ -131,7 +131,7 @@ void QTabBar::initStyleOption(QStyleOptionTab *option, int tabIndex) const option->state &= ~QStyle::State_Enabled; if (isActiveWindow()) option->state |= QStyle::State_Active; - if (option->rect == d->hoverRect) + if (!d->dragInProgress && option->rect == d->hoverRect) option->state |= QStyle::State_MouseOver; option->shape = d->shape; option->text = tab.text; @@ -454,9 +454,6 @@ void QTabBarPrivate::layoutTabs() maxExtent = maxWidth; } - if (pressedIndex != -1 && movable) - grabCache(0, tabList.count(), true); - Q_ASSERT(tabChainIndex == tabChain.count() - 1); // add an assert just to make sure. // Mirror our front item. tabChain[tabChainIndex].init(); @@ -1484,6 +1481,8 @@ void QTabBar::paintEvent(QPaintEvent *) bool vertical = verticalTabs(d->shape); QStyleOptionTab cutTab; selected = d->currentIndex; + if (d->dragInProgress) + selected = d->pressedIndex; for (int i = 0; i < d->tabList.count(); ++i) optTabBase.tabBarRect |= tabRect(i); @@ -1522,11 +1521,7 @@ void QTabBar::paintEvent(QPaintEvent *) if (i == selected) continue; - if (!d->tabList[i].animatingCache.isNull() && d->paintWithOffsets) { - p.drawPixmap(tab.rect, d->tabList[i].animatingCache); - } else { - p.drawControl(QStyle::CE_TabBarTab, tab); - } + p.drawControl(QStyle::CE_TabBarTab, tab); } // Draw the selected tab last to get it "on top" @@ -1539,7 +1534,11 @@ void QTabBar::paintEvent(QPaintEvent *) else tab.rect.moveLeft(tab.rect.x() + d->tabList[selected].dragOffset); } - p.drawControl(QStyle::CE_TabBarTab, tab); + if (!d->dragInProgress) + p.drawControl(QStyle::CE_TabBarTab, tab); + else + d->movingTab->setGeometry(tab.rect); + } // Only draw the tear indicator if necessary. Most of the time we don't need too. @@ -1680,6 +1679,7 @@ void QTabBarPrivate::_q_moveTab(int offset) if (!validIndex(index)) return; tabList[index].dragOffset = offset; + layoutTab(index); // Make buttons follow tab q->update(); } } @@ -1727,8 +1727,7 @@ void QTabBar::mouseMoveEvent(QMouseEvent *event) if (!d->dragInProgress && d->pressedIndex != -1) { if ((event->pos() - d->dragStartPosition).manhattanLength() > QApplication::startDragDistance()) { d->dragInProgress = true; - if (d->animations.isEmpty()) - d->grabCache(0, d->tabList.count(), false); + d->setupMovableTab(); } } @@ -1773,7 +1772,6 @@ void QTabBar::mouseMoveEvent(QMouseEvent *event) if (dragDistance > needsToBeOver) d->slide(i + offset, d->pressedIndex); } - } // Buttons needs to follow the dragged tab d->layoutTab(d->pressedIndex); @@ -1801,32 +1799,41 @@ void QTabBarPrivate::_q_moveTabFinished() } } -void QTabBarPrivate::grabCache(int start, int end, bool unhide) +void QTabBarPrivate::setupMovableTab() { Q_Q(QTabBar); - paintWithOffsets = false; - bool showButtonsAgain = rightB->isVisible(); - rightB->hide(); - leftB->hide(); - - QWidget *topLevel = q->window(); - QPoint topLevelOffset(q->mapTo(topLevel, QPoint())); - for (int i = start; i < end; ++i) { - QRect tabRect = q->tabRect(i); - tabRect.translate(topLevelOffset); - if (unhide) { - tabList[i].unHideWidgets(); - layoutWidgets(i); - } - tabList[i].animatingCache = QPixmap::grabWidget(topLevel, tabRect); - if (i != pressedIndex) - tabList[i].hideWidgets(); - } - if (showButtonsAgain) { - rightB->show(); - leftB->show(); - } - paintWithOffsets = true; + if (!movingTab) + movingTab = new QWidget(q); + + QRect grabRect = q->tabRect(pressedIndex); + + QPixmap grabImage(grabRect.size()); + grabImage.fill(Qt::transparent); + QStylePainter p(&grabImage, q); + + QStyleOptionTabV3 tab; + q->initStyleOption(&tab, pressedIndex); + tab.rect.moveTopLeft(QPoint(0, 0)); + p.drawControl(QStyle::CE_TabBarTab, tab); + p.end(); + + QPalette pal; + pal.setBrush(QPalette::All, QPalette::Window, grabImage); + movingTab->setPalette(pal); + movingTab->setGeometry(grabRect); + movingTab->setAutoFillBackground(true); + movingTab->raise(); + + // Re-arrange widget order to avoid overlaps + if (tabList[pressedIndex].leftWidget) + tabList[pressedIndex].leftWidget->raise(); + if (tabList[pressedIndex].rightWidget) + tabList[pressedIndex].rightWidget->raise(); + if (leftB) + leftB->raise(); + if (rightB) + rightB->raise(); + movingTab->setVisible(true); } void QTabBarPrivate::_q_moveTabFinished(int index) @@ -1834,10 +1841,9 @@ void QTabBarPrivate::_q_moveTabFinished(int index) Q_Q(QTabBar); bool cleanup = (pressedIndex == index) || (pressedIndex == -1) || !validIndex(index); if (animations.isEmpty() && cleanup) { + movingTab->setVisible(false); // We might not get a mouse release for (int i = 0; i < tabList.count(); ++i) { tabList[i].dragOffset = 0; - tabList[i].unHideWidgets(); - tabList[i].animatingCache = QPixmap(); } if (pressedIndex != -1 && movable) { pressedIndex = -1; @@ -1881,6 +1887,7 @@ void QTabBar::mouseReleaseEvent(QMouseEvent *event) d->_q_moveTabFinished(d->pressedIndex); } d->dragInProgress = false; + d->movingTab->setVisible(false); d->dragStartPosition = QPoint(); } @@ -2203,19 +2210,16 @@ void QTabBar::setTabButton(int index, ButtonPosition position, QWidget *widget) widget->setParent(this); // make sure our left and right widgets stay on top widget->lower(); + widget->show(); } if (position == LeftSide) { if (d->tabList[index].leftWidget) d->tabList[index].leftWidget->hide(); d->tabList[index].leftWidget = widget; - if(!d->tabList[index].hidLeft && widget) - widget->show(); } else { if (d->tabList[index].rightWidget) d->tabList[index].rightWidget->hide(); d->tabList[index].rightWidget = widget; - if(!d->tabList[index].hidRight && widget) - widget->show(); } d->layoutTabs(); update(); diff --git a/src/gui/widgets/qtabbar_p.h b/src/gui/widgets/qtabbar_p.h index a117aa3..cb1a15b 100644 --- a/src/gui/widgets/qtabbar_p.h +++ b/src/gui/widgets/qtabbar_p.h @@ -70,7 +70,6 @@ QT_BEGIN_NAMESPACE - class QTabBarPrivate : public QWidgetPrivate { Q_DECLARE_PUBLIC(QTabBar) @@ -78,7 +77,7 @@ public: QTabBarPrivate() :currentIndex(-1), pressedIndex(-1), shape(QTabBar::RoundedNorth), - layoutDirty(false), drawBase(true), scrollOffset(0), expanding(true), closeButtonOnTabs(false), selectionBehaviorOnRemove(QTabBar::SelectRightTab), paintWithOffsets(true), movable(false), dragInProgress(false), documentMode(false) {} + layoutDirty(false), drawBase(true), scrollOffset(0), expanding(true), closeButtonOnTabs(false), selectionBehaviorOnRemove(QTabBar::SelectRightTab), paintWithOffsets(true), movable(false), dragInProgress(false), documentMode(false), movingTab(0) {} int currentIndex; int pressedIndex; @@ -98,8 +97,6 @@ public: , lastTab(-1) , timeLine(0) , dragOffset(0) - , hidLeft(false) - , hidRight(false) {} bool enabled; int shortcutId; @@ -123,9 +120,6 @@ public: QTimeLine *timeLine; int dragOffset; - QPixmap animatingCache; - bool hidLeft; - bool hidRight; void makeTimeLine(QWidget *q) { if (timeLine) @@ -135,27 +129,6 @@ public: q->connect(timeLine, SIGNAL(finished()), q, SLOT(_q_moveTabFinished())); } - void hideWidgets() { - if (!hidRight && rightWidget) { - hidRight = rightWidget->isVisible(); - rightWidget->hide(); - } - - if (!hidLeft && leftWidget) { - hidLeft = leftWidget->isVisible(); - leftWidget->hide(); - } - } - - void unHideWidgets() { - if (leftWidget && hidLeft) - leftWidget->show(); - hidLeft = false; - if (rightWidget && hidRight) - rightWidget->show(); - hidRight = false; - } - }; QList tabList; QHash animations; @@ -184,12 +157,12 @@ public: void _q_moveTabFinished(int offset); QRect hoverRect; - void grabCache(int start, int end, bool unhide); void refresh(); void layoutTabs(); void layoutWidgets(int index = -1); void layoutTab(int index); void updateMacBorderMetrics(); + void setupMovableTab(); void makeVisible(int index); QSize iconSize; @@ -206,6 +179,8 @@ public: bool dragInProgress; bool documentMode; + QWidget *movingTab; + // shared by tabwidget and qtabbar static void initStyleBaseOption(QStyleOptionTabBarBaseV2 *optTabBase, QTabBar *tabbar, QSize size) { -- cgit v0.12 From e380893442fb5863bcd082de4785565d6f9e8414 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 15 Apr 2009 15:15:25 +0200 Subject: Make the configured namespace part of QT_BUILD_KEY_COMPAT too. The eclipse integration is namespaced, but it still pulled in system plugins like the oxygen style through QT_BUILD_KEY_COMPAT check in QLibraryPrivate::isPlugin() Task: 250185 Reviewed-by: dt BT: yes --- configure | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configure b/configure index e27ac5a..7ab3e22 100755 --- a/configure +++ b/configure @@ -6216,6 +6216,9 @@ QT_BUILD_KEY_COMPAT= if [ "$QT_CROSS_COMPILE" = "no" ]; then # previous versions of Qt used a build key built from the uname QT_BUILD_KEY_COMPAT="$CFG_USER_BUILD_KEY $UNAME_MACHINE $UNAME_SYSTEM $COMPILER $BUILD_OPTIONS" + if [ -n "$QT_NAMESPACE" ]; then + QT_BUILD_KEY_COMPAT="$QT_BUILD_KEY_COMPAT $QT_NAMESPACE" + fi fi # strip out leading/trailing/extra whitespace QT_BUILD_KEY=`echo $QT_BUILD_KEY | sed -e "s, *, ,g" -e "s,^ *,," -e "s, *$,,"` -- cgit v0.12 From 94676b7950074d5233e47b43bf6c924762f43b7c Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Wed, 15 Apr 2009 15:16:17 +0200 Subject: Update changelog with my changes --- dist/changes-4.5.1 | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index bda151f..9a64352 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -51,6 +51,9 @@ Third party components * [221731] Fixed bug where the accessibility plugin could crash if there was an "&" at the end or spin forever if a label had a sequence of "&&". +- QAtomicInt + * [216492] Fix compilation on 64-bit PowerPC machines with gcc 4.3. + - QAuthenticator * [237979] fix implemenation of md5-sess @@ -108,6 +111,13 @@ Third party components - QHttp * [208445] cancel request upon receiving unknown authentication method +- QHostAddress + * [247330] Fix compilation on MinGW by adding a missing QPair include. + +- QLocalSocket + * Fix a bug that would cause QLocalSocket to disconnect 30 seconds + after a succesful delayed connection on UNIX. + - QMacStyle * [248769] Fix regression where QMacStyle would only draw tabs when passed a QStyleOptionTabV3. * Adjust the opacity value for popups. @@ -115,6 +125,14 @@ Third party components - QMainWindow * [248048] Fix a regression that would cause tooltips to disappear when using the unified toolbar. +- QMetaType + * [248890] Detailed description of QMetaType no longer contradicts + documentation of QMetaType::type() + +- QMutex + * Fix performance regression for contended mutexes as reported on + the qt4-preview-feedback list. + - QPainter * [247492] Fix rendering bug in raster paint engine causing one-pixel offset when drawing premultiplied ARGB32 images on RGB16 images. @@ -131,6 +149,10 @@ Third party components * [249175] Fix QPixmap::fromImage() of monochrome images to result in black/white pixels and not transparent/white pixels. +- QProcess + * [247865] Fix a crash when calling QProcess::start() and + startDetached() with an empty program string. + - QScrollBar * [247985] Stylesheet: added ability to style scrollbar menus. @@ -154,6 +176,10 @@ Third party components * Fixed crash while styling the title bar of a QMdiArea. * [246542] Fixed QToolButton::hover{ color:.... } +- QThread + * [249997] Add documentation indicating that the priority set by + the programmer may be ignored, for example on Linux. + - QTreeView * Fixed crash that may occurs when event are processed just after QSortFilterProxyModel has been invalidated -- cgit v0.12 From cec175cea389ef2d680b2c4fcc0db1d9a4ba9cfb Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 15 Apr 2009 15:34:59 +0200 Subject: Make choosing a file path for a QUrl-type property work on Windows. Use QUrl::fromLocalFile to construct the url string. Reviewed-by: Jarek Kobus --- .../designer/src/components/propertyeditor/designerpropertymanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/designer/src/components/propertyeditor/designerpropertymanager.cpp b/tools/designer/src/components/propertyeditor/designerpropertymanager.cpp index 2460ee8..1dd5bd6 100644 --- a/tools/designer/src/components/propertyeditor/designerpropertymanager.cpp +++ b/tools/designer/src/components/propertyeditor/designerpropertymanager.cpp @@ -271,7 +271,7 @@ void TextEditor::fileActionActivated() const QString newPath = m_core->dialogGui()->getOpenFileName(this, tr("Choose a File"), oldPath); if (newPath.isEmpty() || newPath == oldPath) return; - const QString newText = QLatin1String("file:") + newPath; + const QString newText = QUrl::fromLocalFile(newPath).toString(); m_editor->setText(newText); emit textChanged(newText); } -- cgit v0.12 From 95b14d54428e6a740163843974c97fa2845995b5 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Wed, 15 Apr 2009 16:14:09 +0200 Subject: Updated changes --- dist/changes-4.5.1 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index 9a64352..dd81f7c 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -168,6 +168,9 @@ Third party components * [245668] set also protocol, verifyMode and verifyDepth in setSslConfiguration() +- QString + * [249517] Fixed regression in replace(int, int, QChar) when string is empty + - QStyleSheetStyle * Improved support for setting background and foreground roles in styles such as the text color in a combo box popup on Mac and Cleanlooks, or -- cgit v0.12 From 5e397de5254005f26fb1b26f65e610653d39e9fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Wed, 15 Apr 2009 16:15:14 +0200 Subject: Fixed and improved the example code --- examples/layouts/flowlayout/flowlayout.cpp | 63 ++++++++++++++++++++++++------ examples/layouts/flowlayout/flowlayout.h | 9 ++++- 2 files changed, 58 insertions(+), 14 deletions(-) diff --git a/examples/layouts/flowlayout/flowlayout.cpp b/examples/layouts/flowlayout/flowlayout.cpp index d1e857d..be6b476 100644 --- a/examples/layouts/flowlayout/flowlayout.cpp +++ b/examples/layouts/flowlayout/flowlayout.cpp @@ -43,16 +43,16 @@ #include "flowlayout.h" -FlowLayout::FlowLayout(QWidget *parent, int margin, int spacing) - : QLayout(parent) +FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing) + : QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing) { setMargin(margin); - setSpacing(spacing); } -FlowLayout::FlowLayout(int spacing) +FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing) + : m_hSpace(hSpacing), m_vSpace(vSpacing) { - setSpacing(spacing); + setMargin(margin); } FlowLayout::~FlowLayout() @@ -67,6 +67,24 @@ void FlowLayout::addItem(QLayoutItem *item) itemList.append(item); } +int FlowLayout::horizontalSpacing() const +{ + if (m_hSpace >= 0) { + return m_hSpace; + } else { + return smartSpacing(QStyle::PM_LayoutHorizontalSpacing); + } +} + +int FlowLayout::verticalSpacing() const +{ + if (m_vSpace >= 0) { + return m_vSpace; + } else { + return smartSpacing(QStyle::PM_LayoutVerticalSpacing); + } +} + int FlowLayout::count() const { return itemList.size(); @@ -125,20 +143,27 @@ QSize FlowLayout::minimumSize() const int FlowLayout::doLayout(const QRect &rect, bool testOnly) const { - int x = rect.x(); - int y = rect.y(); + int left, top, right, bottom; + getContentsMargins(&left, &top, &right, &bottom); + QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom); + int x = effectiveRect.x(); + int y = effectiveRect.y(); int lineHeight = 0; QLayoutItem *item; foreach (item, itemList) { QWidget *wid = item->widget(); - int spaceX = spacing() + wid->style()->layoutSpacing( + int spaceX = horizontalSpacing(); + if (spaceX == -1) + spaceX = wid->style()->layoutSpacing( QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal); - int spaceY = spacing() + wid->style()->layoutSpacing( + int spaceY = verticalSpacing(); + if (spaceY == -1) + spaceY = wid->style()->layoutSpacing( QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical); int nextX = x + item->sizeHint().width() + spaceX; - if (nextX - spaceX > rect.right() && lineHeight > 0) { - x = rect.x(); + if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) { + x = effectiveRect.x(); y = y + lineHeight + spaceY; nextX = x + item->sizeHint().width() + spaceX; lineHeight = 0; @@ -150,5 +175,19 @@ int FlowLayout::doLayout(const QRect &rect, bool testOnly) const x = nextX; lineHeight = qMax(lineHeight, item->sizeHint().height()); } - return y + lineHeight - rect.y(); + return y + lineHeight - rect.y() + bottom; } + +int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const +{ + QObject *parent = this->parent(); + if (!parent) { + return -1; + } else if (parent->isWidgetType()) { + QWidget *pw = static_cast(parent); + return pw->style()->pixelMetric(pm, 0, pw); + } else { + return static_cast(parent)->spacing(); + } +} + diff --git a/examples/layouts/flowlayout/flowlayout.h b/examples/layouts/flowlayout/flowlayout.h index f864d8e..9940e55 100644 --- a/examples/layouts/flowlayout/flowlayout.h +++ b/examples/layouts/flowlayout/flowlayout.h @@ -49,11 +49,13 @@ class FlowLayout : public QLayout { public: - FlowLayout(QWidget *parent, int margin = -1, int spacing = 0); - FlowLayout(int spacing = 0); + FlowLayout(QWidget *parent, int margin = -1, int hSpacing = -1, int vSpacing = -1); + FlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1); ~FlowLayout(); void addItem(QLayoutItem *item); + int horizontalSpacing() const; + int verticalSpacing() const; Qt::Orientations expandingDirections() const; bool hasHeightForWidth() const; int heightForWidth(int) const; @@ -66,8 +68,11 @@ public: private: int doLayout(const QRect &rect, bool testOnly) const; + int smartSpacing(QStyle::PixelMetric pm) const; QList itemList; + int m_hSpace; + int m_vSpace; }; #endif -- cgit v0.12 From 50d030e78386c7871a3e15029673db4591c8f8e5 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 15 Apr 2009 16:30:30 +0200 Subject: QFileDialog : Fix filters that doesn't work if whitespaces at the end The fix is basically remove the whitespaces at the end otherwise the reg exp will be wrong. Task-number: 240789 Reviewed-by: jasplin --- src/gui/dialogs/qfiledialog.cpp | 16 ++++++++++------ tests/auto/qfiledialog/tst_qfiledialog.cpp | 16 ++++++++++++++++ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp index 5131271..b20321f 100644 --- a/src/gui/dialogs/qfiledialog.cpp +++ b/src/gui/dialogs/qfiledialog.cpp @@ -957,25 +957,29 @@ void QFileDialog::setNameFilters(const QStringList &filters) { Q_D(QFileDialog); d->defaultFileTypes = (filters == QStringList(QFileDialog::tr("All Files (*)"))); - d->nameFilters = filters; + QStringList cleanedFilters; + for (int i = 0; i < filters.count(); ++i) { + cleanedFilters << filters[i].simplified(); + } + d->nameFilters = cleanedFilters; if (d->nativeDialogInUse){ - d->setNameFilters_sys(filters); + d->setNameFilters_sys(cleanedFilters); return; } d->qFileDialogUi->fileTypeCombo->clear(); - if (filters.isEmpty()) + if (cleanedFilters.isEmpty()) return; if (testOption(HideNameFilterDetails)) { QStringList strippedFilters; - for (int i = 0; i < filters.count(); ++i) { - strippedFilters.append(filters[i].mid(0, filters[i].indexOf(QLatin1String(" (")))); + for (int i = 0; i < cleanedFilters.count(); ++i) { + strippedFilters.append(cleanedFilters[i].mid(0, cleanedFilters[i].indexOf(QLatin1String(" (")))); } d->qFileDialogUi->fileTypeCombo->addItems(strippedFilters); } else { - d->qFileDialogUi->fileTypeCombo->addItems(filters); + d->qFileDialogUi->fileTypeCombo->addItems(cleanedFilters); } d->_q_useNameFilter(0); } diff --git a/tests/auto/qfiledialog/tst_qfiledialog.cpp b/tests/auto/qfiledialog/tst_qfiledialog.cpp index bade586..695bfe7 100644 --- a/tests/auto/qfiledialog/tst_qfiledialog.cpp +++ b/tests/auto/qfiledialog/tst_qfiledialog.cpp @@ -681,6 +681,22 @@ void tst_QFiledialog::filters() for (int i = views.at(0)->currentIndex(); i < views.at(0)->count(); ++i) views.at(0)->setCurrentIndex(i); QCOMPARE(spyFilterSelected.count(), 0); + + //Let check if filters with whitespaces + QNonNativeFileDialog fd2; + QStringList expected; + expected << "C++ Source Files(*.cpp)"; + expected << "Any(*.*)"; + fd2.setFilter("C++ Source Files(*.cpp);;Any(*.*)"); + QCOMPARE(expected, fd2.filters()); + fd2.setFilter("C++ Source Files(*.cpp) ;;Any(*.*)"); + QCOMPARE(expected, fd2.filters()); + fd2.setFilter("C++ Source Files(*.cpp);; Any(*.*)"); + QCOMPARE(expected, fd2.filters()); + fd2.setFilter(" C++ Source Files(*.cpp);; Any(*.*)"); + QCOMPARE(expected, fd2.filters()); + fd2.setFilter("C++ Source Files(*.cpp) ;; Any(*.*)"); + QCOMPARE(expected, fd2.filters()); } void tst_QFiledialog::selectFilter() -- cgit v0.12 From 4378554647e3ab56cb9bceda9ceae962aab8e639 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 15 Apr 2009 14:15:46 +0200 Subject: Silence warning about unused static function on Windows Reviewed-by: mariusSO --- src/corelib/io/qtemporaryfile.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index 3cfce83..6a7b067 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -268,11 +268,13 @@ static int _gettemp(char *path, int *doopen, int domkdir, int slen) /*NOTREACHED*/ } +#ifndef Q_WS_WIN static int qt_mkstemps(char *path, int slen) { int fd = 0; return (_gettemp(path, &fd, 0, slen) ? fd : -1); } +#endif //************* QTemporaryFileEngine class QTemporaryFileEngine : public QFSFileEngine -- cgit v0.12 From 48042622b4ad184917216041db40f443b4a6ee52 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Wed, 15 Apr 2009 17:12:53 +0200 Subject: GTK: Fix line edit background color with custom brush We should allways use the brush and not the color if possible. Task-number: 240842 Reviewed-by: nrc --- src/gui/styles/qgtkstyle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index 541415f..b7fa575 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -977,7 +977,7 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, if (widget && widget->testAttribute(Qt::WA_SetPalette) && resolve_mask & (1 << QPalette::Base)) // Palette overridden by user - painter->fillRect(textRect, option->palette.base().color()); + painter->fillRect(textRect, option->palette.base()); else gtkPainter.paintFlatBox( gtkEntry, "entry_bg", textRect, option->state & State_Enabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE, GTK_SHADOW_NONE, gtkEntry->style); -- cgit v0.12 From cf9358a739b3d12c575b572ef6bba7c64f4c4b4a Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Tue, 14 Apr 2009 13:09:00 +0200 Subject: Changelog for 4.5.1 --- dist/changes-4.5.1 | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/dist/changes-4.5.1 b/dist/changes-4.5.1 index dd81f7c..0b06315 100644 --- a/dist/changes-4.5.1 +++ b/dist/changes-4.5.1 @@ -195,6 +195,14 @@ Third party components * [250388] Fixed potential crash in QWidget::scroll() when using the raster graphics system. +- QWidget + * [246852] Better handling WindowMaximizeButtonHint for widget with + layouts. + +-QLocale + * String-to-number conversion functions are now ignore trailing and + leading whitespaces in all locales as it is documented. + - QWizard * [248107] Fixed bug on Vista causing Back button to connect twice to the back() signal. @@ -222,6 +230,37 @@ Third party components Qt for Linux/X11 ---------------- + * Proper resetting input contexts when switching between multiple + input context plugins. + + * [244337] Improved input method handling when the widgets native + window id is recreated. + + * Input methods preedit strings are properly reset when user + switches focus without commiting a string. + + * [244607] Current focus widget is properly set and input method is + properly initialized when showing a toplevel that accepts + keyboard input. + + * Unicode conversion functions will handle Latin-1 character set + only if they are used before QCoreApplication/QApplication is + constructed. + + * Improved handling of failed unicode conversion. + + * [232632] Fixed reparenting widgets to a difference X11 screen. + + * [241888] The background of the drag-n-drop cursor is respected + according to the stylesheet. + + * Fixed clipboard handling when the user manually creates an + instance of the QDesktopWidget. + + * [226048] Fixed emitting a QDesktopWidget::resized() signal when + new screen appears or screen geometry is changed without + affecting the whole desktop geometry. + - Phonon/GStreamer * [244259] Fixed a problem where the backend would fail to indicate an error when streaming fails. @@ -263,6 +302,9 @@ Qt for Linux/X11 Qt for Windows -------------- + * [243583] Improved drag-and-drop handling when switching mouse + buttons fast. + - QCoreApplication * [247401] Fixed a bug that would cause a restarted timer to fire too early, causing Javascript in QtWebKit to consume 100% CPU on -- cgit v0.12 From 4f66b3c550ca1c90c33952ad8603cc6c1a702280 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 15 Apr 2009 15:26:16 +0200 Subject: add some comments --- tools/linguist/shared/ui.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/linguist/shared/ui.cpp b/tools/linguist/shared/ui.cpp index 23a73e7..4f4d4cd 100644 --- a/tools/linguist/shared/ui.cpp +++ b/tools/linguist/shared/ui.cpp @@ -95,7 +95,7 @@ bool UiReader::startElement(const QString &namespaceURI, Q_UNUSED(namespaceURI); Q_UNUSED(localName); - if (qName == QLatin1String("item")) { + if (qName == QLatin1String("item")) { // UI3 menu entries flush(); if (!atts.value(QLatin1String("text")).isEmpty()) m_source = atts.value(QLatin1String("text")); @@ -123,15 +123,15 @@ bool UiReader::endElement(const QString &namespaceURI, m_accum.replace(QLatin1String("\r\n"), QLatin1String("\n")); - if (qName == QLatin1String("class")) { + if (qName == QLatin1String("class")) { // UI "header" if (m_context.isEmpty()) m_context = m_accum; } else if (qName == QLatin1String("string") && m_isTrString) { m_source = m_accum; - } else if (qName == QLatin1String("comment")) { + } else if (qName == QLatin1String("comment")) { // FIXME: what's that? m_comment = m_accum; flush(); - } else if (qName == QLatin1String("function")) { + } else if (qName == QLatin1String("function")) { // UI3 embedded code fetchtrInlinedCpp(m_accum, m_translator, m_context); } else { flush(); -- cgit v0.12 From a089be0d09c64e698d2fa404cf5eedb21dde6406 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 15 Apr 2009 15:26:23 +0200 Subject: fix uninitialized variable read --- tools/linguist/shared/ui.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/tools/linguist/shared/ui.cpp b/tools/linguist/shared/ui.cpp index 4f4d4cd..ff98a90 100644 --- a/tools/linguist/shared/ui.cpp +++ b/tools/linguist/shared/ui.cpp @@ -60,7 +60,7 @@ class UiReader : public QXmlDefaultHandler { public: UiReader(Translator &translator, ConversionData &cd) - : m_translator(translator), m_cd(cd), m_lineNumber(-1), + : m_translator(translator), m_cd(cd), m_lineNumber(-1), m_isTrString(false), m_needUtf8(translator.codecName() != "UTF-8") {} @@ -81,6 +81,7 @@ private: QString m_context; QString m_source; QString m_comment; + QString m_extracomment; QXmlLocator *m_locator; QString m_accum; @@ -97,20 +98,25 @@ bool UiReader::startElement(const QString &namespaceURI, if (qName == QLatin1String("item")) { // UI3 menu entries flush(); - if (!atts.value(QLatin1String("text")).isEmpty()) + if (!atts.value(QLatin1String("text")).isEmpty()) { m_source = atts.value(QLatin1String("text")); + m_isTrString = true; + if (!m_cd.m_noUiLines) + m_lineNumber = m_locator->lineNumber(); + } } else if (qName == QLatin1String("string")) { flush(); if (atts.value(QLatin1String("notr")).isEmpty() || atts.value(QLatin1String("notr")) != QLatin1String("true")) { m_isTrString = true; m_comment = atts.value(QLatin1String("comment")); + m_extracomment = atts.value(QLatin1String("extracomment")); + if (!m_cd.m_noUiLines) + m_lineNumber = m_locator->lineNumber(); } else { m_isTrString = false; } } - if (m_isTrString && !m_cd.m_noUiLines) - m_lineNumber = m_locator->lineNumber(); m_accum.clear(); return true; } @@ -161,12 +167,14 @@ void UiReader::flush() TranslatorMessage msg(m_context, m_source, m_comment, QString(), m_cd.m_sourceFileName, m_lineNumber, QStringList()); + msg.setExtraComment(m_extracomment); if (m_needUtf8 && msg.needs8Bit()) msg.setUtf8(true); m_translator.extend(msg); } m_source.clear(); m_comment.clear(); + m_extracomment.clear(); } bool loadUI(Translator &translator, QIODevice &dev, ConversionData &cd) -- cgit v0.12 From 443f9389f65b05699a10449afc774da3e816f3d1 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 14 Apr 2009 14:35:32 +0200 Subject: do not crash on lines starting with an equal sign --- tools/linguist/shared/profileevaluator.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/linguist/shared/profileevaluator.cpp b/tools/linguist/shared/profileevaluator.cpp index ce53c27..98929c0 100644 --- a/tools/linguist/shared/profileevaluator.cpp +++ b/tools/linguist/shared/profileevaluator.cpp @@ -275,6 +275,9 @@ void ProFileEvaluator::Private::insertVariable(const QString &line, int *i) { ProVariable::VariableOperator opkind; + if (m_proitem.isEmpty()) // Line starting with '=', like a conflict marker + return; + switch (m_proitem.at(m_proitem.length() - 1).unicode()) { case '+': m_proitem.chop(1); -- cgit v0.12 From 287d5e7b349dac0cfdb74e9747752fcadc432064 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 14 Apr 2009 15:31:07 +0200 Subject: protect against circular inclusion of pro/pri files Task-number: 250574 --- tools/linguist/shared/profileevaluator.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/linguist/shared/profileevaluator.cpp b/tools/linguist/shared/profileevaluator.cpp index 98929c0..5440752 100644 --- a/tools/linguist/shared/profileevaluator.cpp +++ b/tools/linguist/shared/profileevaluator.cpp @@ -1476,7 +1476,13 @@ ProFile *ProFileEvaluator::parsedProFile(const QString &fileName) { QFileInfo fi(fileName); if (fi.exists()) { - ProFile *pro = new ProFile(fi.absoluteFilePath()); + QString fn = QDir::cleanPath(fi.absoluteFilePath()); + foreach (const ProFile *pf, d->m_profileStack) + if (pf->fileName() == fn) { + errorMessage(d->format("circular inclusion of %1").arg(fn)); + return 0; + } + ProFile *pro = new ProFile(fn); if (d->read(pro)) return pro; delete pro; -- cgit v0.12 From c51b0e8389f52f895a9d69e9e96c1fd768d78bf4 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Thu, 16 Apr 2009 07:56:08 +1000 Subject: Remove the int constructors from the vector classes The int constructors existed to make fixed-point conversions faster in certain circumstances. With the removal of fixed-point support, they are no longer required. Reviewed-by: trustme --- src/gui/math3d/qquaternion.cpp | 7 ------- src/gui/math3d/qquaternion.h | 3 --- src/gui/math3d/qvector2d.cpp | 6 ------ src/gui/math3d/qvector2d.h | 3 --- src/gui/math3d/qvector3d.cpp | 6 ------ src/gui/math3d/qvector3d.h | 3 --- src/gui/math3d/qvector4d.cpp | 6 ------ src/gui/math3d/qvector4d.h | 3 --- 8 files changed, 37 deletions(-) diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp index efde362..4c6230a 100644 --- a/src/gui/math3d/qquaternion.cpp +++ b/src/gui/math3d/qquaternion.cpp @@ -74,13 +74,6 @@ QT_BEGIN_NAMESPACE and \a scalar. */ -/*! - \fn QQuaternion::QQuaternion(int scalar, int xpos, int ypos, int zpos) - - Constructs a quaternion with the vector (\a xpos, \a ypos, \a zpos) - and \a scalar. -*/ - #ifndef QT_NO_VECTOR3D /*! diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h index f0cb308..a03b53b 100644 --- a/src/gui/math3d/qquaternion.h +++ b/src/gui/math3d/qquaternion.h @@ -60,7 +60,6 @@ class Q_GUI_EXPORT QQuaternion public: QQuaternion(); QQuaternion(qreal scalar, qreal xpos, qreal ypos, qreal zpos); - QQuaternion(int scalar, int xpos, int ypos, int zpos); #ifndef QT_NO_VECTOR3D QQuaternion(qreal scalar, const QVector3D& vector); #endif @@ -143,8 +142,6 @@ inline QQuaternion::QQuaternion(qreal scalar, qreal xpos, qreal ypos, qreal zpos inline QQuaternion::QQuaternion(float scalar, float xpos, float ypos, float zpos, int) : wp(scalar), xp(xpos), yp(ypos), zp(zpos) {} -inline QQuaternion::QQuaternion(int scalar, int xpos, int ypos, int zpos) : wp(scalar), xp(xpos), yp(ypos), zp(zpos) {} - inline bool QQuaternion::isNull() const { return qIsNull(xp) && qIsNull(yp) && qIsNull(zp) && qIsNull(wp); diff --git a/src/gui/math3d/qvector2d.cpp b/src/gui/math3d/qvector2d.cpp index 31e5be6..54e1712 100644 --- a/src/gui/math3d/qvector2d.cpp +++ b/src/gui/math3d/qvector2d.cpp @@ -75,12 +75,6 @@ QT_BEGIN_NAMESPACE */ /*! - \fn QVector2D::QVector2D(int xpos, int ypos) - - Constructs a vector with coordinates (\a xpos, \a ypos). -*/ - -/*! \fn QVector2D::QVector2D(const QPoint& point) Constructs a vector with x and y coordinates from a 2D \a point. diff --git a/src/gui/math3d/qvector2d.h b/src/gui/math3d/qvector2d.h index 5e15de6..b027df4 100644 --- a/src/gui/math3d/qvector2d.h +++ b/src/gui/math3d/qvector2d.h @@ -61,7 +61,6 @@ class Q_GUI_EXPORT QVector2D public: QVector2D(); QVector2D(qreal xpos, qreal ypos); - QVector2D(int xpos, int ypos); explicit QVector2D(const QPoint& point); explicit QVector2D(const QPointF& point); #ifndef QT_NO_VECTOR3D @@ -130,8 +129,6 @@ inline QVector2D::QVector2D(float xpos, float ypos, int) : xp(xpos), yp(ypos) {} inline QVector2D::QVector2D(qreal xpos, qreal ypos) : xp(xpos), yp(ypos) {} -inline QVector2D::QVector2D(int xpos, int ypos) : xp(xpos), yp(ypos) {} - inline QVector2D::QVector2D(const QPoint& point) : xp(point.x()), yp(point.y()) {} inline QVector2D::QVector2D(const QPointF& point) : xp(point.x()), yp(point.y()) {} diff --git a/src/gui/math3d/qvector3d.cpp b/src/gui/math3d/qvector3d.cpp index 814753d..0613aa8 100644 --- a/src/gui/math3d/qvector3d.cpp +++ b/src/gui/math3d/qvector3d.cpp @@ -79,12 +79,6 @@ QT_BEGIN_NAMESPACE */ /*! - \fn QVector3D::QVector3D(int xpos, int ypos, int zpos) - - Constructs a vector with coordinates (\a xpos, \a ypos, \a zpos). -*/ - -/*! \fn QVector3D::QVector3D(const QPoint& point) Constructs a vector with x and y coordinates from a 2D \a point, and a diff --git a/src/gui/math3d/qvector3d.h b/src/gui/math3d/qvector3d.h index 4771d5a..02873f2 100644 --- a/src/gui/math3d/qvector3d.h +++ b/src/gui/math3d/qvector3d.h @@ -63,7 +63,6 @@ class Q_GUI_EXPORT QVector3D public: QVector3D(); QVector3D(qreal xpos, qreal ypos, qreal zpos); - QVector3D(int xpos, int ypos, int zpos); explicit QVector3D(const QPoint& point); explicit QVector3D(const QPointF& point); #ifndef QT_NO_VECTOR2D @@ -149,8 +148,6 @@ inline QVector3D::QVector3D(qreal xpos, qreal ypos, qreal zpos) : xp(xpos), yp(y inline QVector3D::QVector3D(float xpos, float ypos, float zpos, int) : xp(xpos), yp(ypos), zp(zpos) {} -inline QVector3D::QVector3D(int xpos, int ypos, int zpos) : xp(xpos), yp(ypos), zp(zpos) {} - inline QVector3D::QVector3D(const QPoint& point) : xp(point.x()), yp(point.y()), zp(0.0f) {} inline QVector3D::QVector3D(const QPointF& point) : xp(point.x()), yp(point.y()), zp(0.0f) {} diff --git a/src/gui/math3d/qvector4d.cpp b/src/gui/math3d/qvector4d.cpp index d19665a..8fafbfd 100644 --- a/src/gui/math3d/qvector4d.cpp +++ b/src/gui/math3d/qvector4d.cpp @@ -77,12 +77,6 @@ QT_BEGIN_NAMESPACE */ /*! - \fn QVector4D::QVector4D(int xpos, int ypos, int zpos, int wpos) - - Constructs a vector with coordinates (\a xpos, \a ypos, \a zpos, \a wpos). -*/ - -/*! \fn QVector4D::QVector4D(const QPoint& point) Constructs a vector with x and y coordinates from a 2D \a point, and diff --git a/src/gui/math3d/qvector4d.h b/src/gui/math3d/qvector4d.h index 12efc95..8e673f3 100644 --- a/src/gui/math3d/qvector4d.h +++ b/src/gui/math3d/qvector4d.h @@ -63,7 +63,6 @@ class Q_GUI_EXPORT QVector4D public: QVector4D(); QVector4D(qreal xpos, qreal ypos, qreal zpos, qreal wpos); - QVector4D(int xpos, int ypos, int zpos, int wpos); explicit QVector4D(const QPoint& point); explicit QVector4D(const QPointF& point); #ifndef QT_NO_VECTOR2D @@ -146,8 +145,6 @@ inline QVector4D::QVector4D(qreal xpos, qreal ypos, qreal zpos, qreal wpos) : xp inline QVector4D::QVector4D(float xpos, float ypos, float zpos, float wpos, int) : xp(xpos), yp(ypos), zp(zpos), wp(wpos) {} -inline QVector4D::QVector4D(int xpos, int ypos, int zpos, int wpos) : xp(xpos), yp(ypos), zp(zpos), wp(wpos) {} - inline QVector4D::QVector4D(const QPoint& point) : xp(point.x()), yp(point.y()), zp(0.0f), wp(0.0f) {} inline QVector4D::QVector4D(const QPointF& point) : xp(point.x()), yp(point.y()), zp(0.0f), wp(0.0f) {} -- cgit v0.12 From 10688c0168fc010671abc59f367c19357bb6776c Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Thu, 16 Apr 2009 08:02:54 +1000 Subject: Rename QQuaternion::interpolate() to slerp() slerp() is the more common-place name in the 3D community. Reviewed-by: trustme --- src/gui/math3d/qquaternion.cpp | 2 +- src/gui/math3d/qquaternion.h | 2 +- tests/auto/math3d/qquaternion/tst_qquaternion.cpp | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp index 4c6230a..1348fed 100644 --- a/src/gui/math3d/qquaternion.cpp +++ b/src/gui/math3d/qquaternion.cpp @@ -485,7 +485,7 @@ QQuaternion QQuaternion::fromAxisAndAngle If \a t is less than or equal to 0, then \a q1 will be returned. If \a t is greater than or equal to 1, then \a q2 will be returned. */ -QQuaternion QQuaternion::interpolate +QQuaternion QQuaternion::slerp (const QQuaternion& q1, const QQuaternion& q2, qreal t) { // Handle the easy cases first. diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h index a03b53b..ad6fddf 100644 --- a/src/gui/math3d/qquaternion.h +++ b/src/gui/math3d/qquaternion.h @@ -124,7 +124,7 @@ public: static QQuaternion fromAxisAndAngle (qreal x, qreal y, qreal z, qreal angle); - static QQuaternion interpolate + static QQuaternion slerp (const QQuaternion& q1, const QQuaternion& q2, qreal t); private: diff --git a/tests/auto/math3d/qquaternion/tst_qquaternion.cpp b/tests/auto/math3d/qquaternion/tst_qquaternion.cpp index fd7c7f8..6a69755 100644 --- a/tests/auto/math3d/qquaternion/tst_qquaternion.cpp +++ b/tests/auto/math3d/qquaternion/tst_qquaternion.cpp @@ -88,8 +88,8 @@ private slots: void fromAxisAndAngle_data(); void fromAxisAndAngle(); - void interpolate_data(); - void interpolate(); + void slerp_data(); + void slerp(); }; // qFuzzyCompare isn't quite "fuzzy" enough to handle conversion @@ -693,7 +693,7 @@ void tst_QQuaternion::fromAxisAndAngle() } // Test spherical interpolation of quaternions. -void tst_QQuaternion::interpolate_data() +void tst_QQuaternion::slerp_data() { QTest::addColumn("x1"); QTest::addColumn("y1"); @@ -740,7 +740,7 @@ void tst_QQuaternion::interpolate_data() << (qreal)0.5f << (qreal)1.0f << (qreal)2.0f << (qreal)-3.0f << (qreal)-45.0f; } -void tst_QQuaternion::interpolate() +void tst_QQuaternion::slerp() { QFETCH(qreal, x1); QFETCH(qreal, y1); @@ -760,7 +760,7 @@ void tst_QQuaternion::interpolate() QQuaternion q2 = QQuaternion::fromAxisAndAngle(x2, y2, z2, angle2); QQuaternion q3 = QQuaternion::fromAxisAndAngle(x3, y3, z3, angle3); - QQuaternion result = QQuaternion::interpolate(q1, q2, t); + QQuaternion result = QQuaternion::slerp(q1, q2, t); QVERIFY(fuzzyCompare(result.x(), q3.x())); QVERIFY(fuzzyCompare(result.y(), q3.y())); -- cgit v0.12 From 1cb11b428ef1bee070af72676b7eb1fa325bb980 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Thu, 16 Apr 2009 08:33:32 +1000 Subject: Add the QQuaternion::nlerp() function as a counterpart to slerp() nlerp() implements "normalized linear interpolation", which is faster than slerp() and gives approximate results that are good enough for some applications. Reviewed-by: trustme --- src/gui/math3d/qquaternion.cpp | 39 ++++++++++++++++ src/gui/math3d/qquaternion.h | 2 + tests/auto/math3d/qquaternion/tst_qquaternion.cpp | 57 +++++++++++++++++++++++ 3 files changed, 98 insertions(+) diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp index 1348fed..a91b0b9 100644 --- a/src/gui/math3d/qquaternion.cpp +++ b/src/gui/math3d/qquaternion.cpp @@ -484,6 +484,8 @@ QQuaternion QQuaternion::fromAxisAndAngle If \a t is less than or equal to 0, then \a q1 will be returned. If \a t is greater than or equal to 1, then \a q2 will be returned. + + \sa nlerp() */ QQuaternion QQuaternion::slerp (const QQuaternion& q1, const QQuaternion& q2, qreal t) @@ -522,6 +524,43 @@ QQuaternion QQuaternion::slerp return q1 * factor1 + q2b * factor2; } +/*! + Interpolates along the shortest linear path between the rotational + positions \a q1 and \a q2. The value \a t should be between 0 and 1, + indicating the distance to travel between \a q1 and \a q2. + The result will be normalized(). + + If \a t is less than or equal to 0, then \a q1 will be returned. + If \a t is greater than or equal to 1, then \a q2 will be returned. + + The nlerp() function is typically faster than slerp() and will + give approximate results to spherical interpolation that are + good enough for some applications. + + \sa slerp() +*/ +QQuaternion QQuaternion::nlerp + (const QQuaternion& q1, const QQuaternion& q2, qreal t) +{ + // Handle the easy cases first. + if (t <= 0.0f) + return q1; + else if (t >= 1.0f) + return q2; + + // Determine the angle between the two quaternions. + QQuaternion q2b; + qreal dot; + dot = q1.xp * q2.xp + q1.yp * q2.yp + q1.zp * q2.zp + q1.wp * q2.wp; + if (dot >= 0.0f) + q2b = q2; + else + q2b = -q2; + + // Perform the linear interpolation. + return (q1 * (1.0f - t) + q2b * t).normalized(); +} + #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug dbg, const QQuaternion &q) diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h index ad6fddf..c05c641 100644 --- a/src/gui/math3d/qquaternion.h +++ b/src/gui/math3d/qquaternion.h @@ -126,6 +126,8 @@ public: static QQuaternion slerp (const QQuaternion& q1, const QQuaternion& q2, qreal t); + static QQuaternion nlerp + (const QQuaternion& q1, const QQuaternion& q2, qreal t); private: float wp, xp, yp, zp; diff --git a/tests/auto/math3d/qquaternion/tst_qquaternion.cpp b/tests/auto/math3d/qquaternion/tst_qquaternion.cpp index 6a69755..f25f858 100644 --- a/tests/auto/math3d/qquaternion/tst_qquaternion.cpp +++ b/tests/auto/math3d/qquaternion/tst_qquaternion.cpp @@ -90,6 +90,9 @@ private slots: void slerp_data(); void slerp(); + + void nlerp_data(); + void nlerp(); }; // qFuzzyCompare isn't quite "fuzzy" enough to handle conversion @@ -768,6 +771,60 @@ void tst_QQuaternion::slerp() QVERIFY(fuzzyCompare(result.scalar(), q3.scalar())); } +// Test normalized linear interpolation of quaternions. +void tst_QQuaternion::nlerp_data() +{ + slerp_data(); +} +void tst_QQuaternion::nlerp() +{ + QFETCH(qreal, x1); + QFETCH(qreal, y1); + QFETCH(qreal, z1); + QFETCH(qreal, angle1); + QFETCH(qreal, x2); + QFETCH(qreal, y2); + QFETCH(qreal, z2); + QFETCH(qreal, angle2); + QFETCH(qreal, t); + + QQuaternion q1 = QQuaternion::fromAxisAndAngle(x1, y1, z1, angle1); + QQuaternion q2 = QQuaternion::fromAxisAndAngle(x2, y2, z2, angle2); + + QQuaternion result = QQuaternion::nlerp(q1, q2, t); + + qreal resultx, resulty, resultz, resultscalar; + if (t <= 0.0f) { + resultx = q1.x(); + resulty = q1.y(); + resultz = q1.z(); + resultscalar = q1.scalar(); + } else if (t >= 1.0f) { + resultx = q2.x(); + resulty = q2.y(); + resultz = q2.z(); + resultscalar = q2.scalar(); + } else if (qAbs(angle1 - angle2) <= 180.f) { + resultx = q1.x() * (1 - t) + q2.x() * t; + resulty = q1.y() * (1 - t) + q2.y() * t; + resultz = q1.z() * (1 - t) + q2.z() * t; + resultscalar = q1.scalar() * (1 - t) + q2.scalar() * t; + } else { + // Angle greater than 180 degrees: negate q2. + resultx = q1.x() * (1 - t) - q2.x() * t; + resulty = q1.y() * (1 - t) - q2.y() * t; + resultz = q1.z() * (1 - t) - q2.z() * t; + resultscalar = q1.scalar() * (1 - t) - q2.scalar() * t; + } + + QQuaternion q3 = QQuaternion(resultscalar, resultx, resulty, resultz).normalized(); + + QVERIFY(fuzzyCompare(result.x(), q3.x())); + QVERIFY(fuzzyCompare(result.y(), q3.y())); + QVERIFY(fuzzyCompare(result.z(), q3.z())); + QVERIFY(fuzzyCompare(result.scalar(), q3.scalar())); +} + QTEST_APPLESS_MAIN(tst_QQuaternion) #include "tst_qquaternion.moc" -- cgit v0.12 From c57b1a8629b7fa79f48a35eea2f09d923b665dc0 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Thu, 16 Apr 2009 09:21:44 +1000 Subject: Optimize vector normalize for vectors of length 1 If the square of the length is very close to 1, then avoid the qSqrt(). Reviewed-by: trustme --- src/gui/math3d/qmatrix4x4.cpp | 5 +++-- src/gui/math3d/qquaternion.cpp | 24 +++++++++++++++--------- src/gui/math3d/qvector2d.cpp | 24 +++++++++++++++--------- src/gui/math3d/qvector3d.cpp | 24 +++++++++++++++--------- src/gui/math3d/qvector4d.cpp | 25 +++++++++++++++---------- 5 files changed, 63 insertions(+), 39 deletions(-) diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp index e00d772..649532d 100644 --- a/src/gui/math3d/qmatrix4x4.cpp +++ b/src/gui/math3d/qmatrix4x4.cpp @@ -995,8 +995,9 @@ QMatrix4x4& QMatrix4x4::rotate(qreal angle, qreal x, qreal y, qreal z) quick = true; } if (!quick) { - qreal len = qSqrt(x * x + y * y + z * z); - if (len != 0) { + qreal len = x * x + y * y + z * z; + if (!qFuzzyIsNull(len - 1.0f) && !qFuzzyIsNull(len)) { + len = qSqrt(len); x /= len; y /= len; z /= len; diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp index a91b0b9..96659ea 100644 --- a/src/gui/math3d/qquaternion.cpp +++ b/src/gui/math3d/qquaternion.cpp @@ -230,40 +230,46 @@ qreal QQuaternion::lengthSquared() const } /*! - Returns the normalized unit form of this quaternion. If this quaternion - is not null, the returned quaternion is guaranteed to be 1.0 in length. + Returns the normalized unit form of this quaternion. + If this quaternion is null, then a null quaternion is returned. + If the length of the quaternion is very close to 1, then the quaternion + will be returned as-is. Otherwise the normalized form of the + quaternion of length 1 will be returned. \sa length(), normalize() */ QQuaternion QQuaternion::normalized() const { - qreal len = length(); - if (!qIsNull(len)) - return *this / len; + qreal len = lengthSquared(); + if (qFuzzyIsNull(len - 1.0f)) + return *this; + else if (!qFuzzyIsNull(len)) + return *this / qSqrt(len); else return QQuaternion(0.0f, 0.0f, 0.0f, 0.0f); } /*! Normalizes the currect quaternion in place. Nothing happens if this - is a null quaternion. + is a null quaternion or the length of the quaternion is very close to 1. \sa length(), normalized() */ void QQuaternion::normalize() { - qreal len = length(); - if (qIsNull(len)) + qreal len = lengthSquared(); + if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len)) return; + len = qSqrt(len); + xp /= len; yp /= len; zp /= len; wp /= len; } - /*! \fn QQuaternion QQuaternion::conjugate() const diff --git a/src/gui/math3d/qvector2d.cpp b/src/gui/math3d/qvector2d.cpp index 54e1712..c3aaa42 100644 --- a/src/gui/math3d/qvector2d.cpp +++ b/src/gui/math3d/qvector2d.cpp @@ -179,33 +179,39 @@ qreal QVector2D::lengthSquared() const } /*! - Returns the normalized unit vector form of this vector. If this vector - is not null, the returned vector is guaranteed to be 1.0 in length. - If this vector is null, then a null vector is returned. + Returns the normalized unit vector form of this vector. + + If this vector is null, then a null vector is returned. If the length + of the vector is very close to 1, then the vector will be returned as-is. + Otherwise the normalized form of the vector of length 1 will be returned. \sa length(), normalize() */ QVector2D QVector2D::normalized() const { - qreal len = length(); - if (!qIsNull(len)) - return *this / len; + qreal len = lengthSquared(); + if (qFuzzyIsNull(len - 1.0f)) + return *this; + else if (!qFuzzyIsNull(len)) + return *this / qSqrt(len); else return QVector2D(); } /*! Normalizes the currect vector in place. Nothing happens if this - vector is a null vector. + vector is a null vector or the length of the vector is very close to 1. \sa length(), normalized() */ void QVector2D::normalize() { - qreal len = length(); - if (qIsNull(len)) + qreal len = lengthSquared(); + if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len)) return; + len = qSqrt(len); + xp /= len; yp /= len; } diff --git a/src/gui/math3d/qvector3d.cpp b/src/gui/math3d/qvector3d.cpp index 0613aa8..c83cd60 100644 --- a/src/gui/math3d/qvector3d.cpp +++ b/src/gui/math3d/qvector3d.cpp @@ -195,33 +195,39 @@ QVector3D::QVector3D(const QVector4D& vector) */ /*! - Returns the normalized unit vector form of this vector. If this vector - is not null, the returned vector is guaranteed to be 1.0 in length. - If this vector is null, then a null vector is returned. + Returns the normalized unit vector form of this vector. + + If this vector is null, then a null vector is returned. If the length + of the vector is very close to 1, then the vector will be returned as-is. + Otherwise the normalized form of the vector of length 1 will be returned. \sa length(), normalize() */ QVector3D QVector3D::normalized() const { - qreal len = length(); - if (!qIsNull(len)) - return *this / len; + qreal len = lengthSquared(); + if (qFuzzyIsNull(len - 1.0f)) + return *this; + else if (!qFuzzyIsNull(len)) + return *this / qSqrt(len); else return QVector3D(); } /*! Normalizes the currect vector in place. Nothing happens if this - vector is a null vector. + vector is a null vector or the length of the vector is very close to 1. \sa length(), normalized() */ void QVector3D::normalize() { - qreal len = length(); - if (qIsNull(len)) + qreal len = lengthSquared(); + if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len)) return; + len = qSqrt(len); + xp /= len; yp /= len; zp /= len; diff --git a/src/gui/math3d/qvector4d.cpp b/src/gui/math3d/qvector4d.cpp index 8fafbfd..010fa53 100644 --- a/src/gui/math3d/qvector4d.cpp +++ b/src/gui/math3d/qvector4d.cpp @@ -247,40 +247,45 @@ qreal QVector4D::lengthSquared() const } /*! - Returns the normalized unit vector form of this vector. If this vector - is not null, the returned vector is guaranteed to be 1.0 in length. - If this vector is null, then a null vector is returned. + Returns the normalized unit vector form of this vector. + + If this vector is null, then a null vector is returned. If the length + of the vector is very close to 1, then the vector will be returned as-is. + Otherwise the normalized form of the vector of length 1 will be returned. \sa length(), normalize() */ QVector4D QVector4D::normalized() const { - qreal len = length(); - if (!qIsNull(len)) - return *this / len; + qreal len = lengthSquared(); + if (qFuzzyIsNull(len - 1.0f)) + return *this; + else if (!qFuzzyIsNull(len)) + return *this / qSqrt(len); else return QVector4D(); } /*! Normalizes the currect vector in place. Nothing happens if this - vector is a null vector. + vector is a null vector or the length of the vector is very close to 1. \sa length(), normalized() */ void QVector4D::normalize() { - qreal len = length(); - if (qIsNull(len)) + qreal len = lengthSquared(); + if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len)) return; + len = qSqrt(len); + xp /= len; yp /= len; zp /= len; wp /= len; } - /*! \fn QVector4D &QVector4D::operator+=(const QVector4D &vector) -- cgit v0.12 From 68045615d311c3cb8bcaaaf84b4c8ca52a0fccd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 3 Apr 2009 14:39:35 +0200 Subject: Reduce the number of calls to cleanPath() in QResourceRoot::findNode Move the cleanPath call out of the function and outside the loops to avoid doing the same work over and over. Reviewed-by: Gunnar Sletta --- src/corelib/io/qresource.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index a1f921e..dd24cde 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -101,6 +101,16 @@ protected: } }; +static QString cleanPath(const QString &_path) +{ + QString path = QDir::cleanPath(_path); + // QDir::cleanPath does not remove two trailing slashes under _Windows_ + // due to support for UNC paths. Remove those manually. + if (path.startsWith(QLatin1String("//"))) + path.remove(0, 1); + return path; +} + Q_DECLARE_TYPEINFO(QResourceRoot, Q_MOVABLE_TYPE); Q_GLOBAL_STATIC_WITH_ARGS(QMutex, resourceMutex, (QMutex::Recursive)) @@ -216,9 +226,10 @@ QResourcePrivate::load(const QString &file) related.clear(); QMutexLocker lock(resourceMutex()); const ResourceList *list = resourceList(); + QString cleaned = cleanPath(file); for(int i = 0; i < list->size(); ++i) { QResourceRoot *res = list->at(i); - const int node = res->findNode(file); + const int node = res->findNode(cleaned); if(node != -1) { if(related.isEmpty()) { container = res->isContainer(node); @@ -292,6 +303,7 @@ QResourcePrivate::ensureChildren() const if(path.startsWith(QLatin1Char(':'))) path = path.mid(1); QSet kids; + QString cleaned = cleanPath(path); for(int i = 0; i < related.size(); ++i) { QResourceRoot *res = related.at(i); if(res->mappingRootSubdir(path, &k) && !k.isEmpty()) { @@ -300,7 +312,7 @@ QResourcePrivate::ensureChildren() const kids.insert(k); } } else { - const int node = res->findNode(path); + const int node = res->findNode(cleaned); if(node != -1) { QStringList related_children = res->children(node); for(int kid = 0; kid < related_children.size(); ++kid) { @@ -566,14 +578,10 @@ inline QString QResourceRoot::name(int node) const ret += QChar(names[name_offset+i+1], names[name_offset+i]); return ret; } + int QResourceRoot::findNode(const QString &_path, const QLocale &locale) const { - QString path = QDir::cleanPath(_path); - // QDir::cleanPath does not remove two trailing slashes under _Windows_ - // due to support for UNC paths. Remove those manually. - if (path.startsWith(QLatin1String("//"))) - path.remove(0, 1); - + QString path = _path; { QString root = mappingRoot(); if(!root.isEmpty()) { -- cgit v0.12 From 3e56a4a367c34f032cb8ef225251e330028de650 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Tue, 31 Mar 2009 13:01:12 +0200 Subject: Experimental fix for speeding up QResource::name()... --- src/corelib/io/qresource.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index dd24cde..3bdb352 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -574,8 +574,14 @@ inline QString QResourceRoot::name(int node) const (names[name_offset+1] << 0); name_offset += 2; name_offset += 4; //jump past hash - for(int i = 0; i < name_length*2; i+=2) - ret += QChar(names[name_offset+i+1], names[name_offset+i]); + + ret.resize(name_length); + QChar *strData = ret.data(); + for(int i = 0; i < name_length*2; i+=2) { + QChar c(names[name_offset+i+1], names[name_offset+i]); + *strData = c; + ++strData; + } return ret; } -- cgit v0.12 From 0d433bcb83152c3a67fa81edcce36abf4b3191c4 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Tue, 31 Mar 2009 13:40:56 +0200 Subject: Fixes: Speed up QFileInfo::setFile() a bit... RevBy: Samuel Details: When doing initFileEngine on a operational QFileInfo, it will detach(), which creates copy of the file engine, then we delete this engine and create our own engine. Creating a clean QFileInfo, saves us one temporary file engine.. --- src/corelib/io/qfileinfo.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index 96e0f82..a8d28cb 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -537,8 +537,7 @@ QFileInfo &QFileInfo::operator=(const QFileInfo &fileinfo) void QFileInfo::setFile(const QString &file) { - Q_D(QFileInfo); - d->initFileEngine(file); + *this = QFileInfo(file); } /*! @@ -555,8 +554,7 @@ void QFileInfo::setFile(const QString &file) void QFileInfo::setFile(const QFile &file) { - Q_D(QFileInfo); - d->initFileEngine(file.fileName()); + *this = QFileInfo(file.fileName()); } /*! @@ -574,7 +572,7 @@ void QFileInfo::setFile(const QFile &file) void QFileInfo::setFile(const QDir &dir, const QString &file) { Q_D(QFileInfo); - d->initFileEngine(dir.filePath(file)); + *this = QFileInfo(dir.filePath(file)); } /*! @@ -921,7 +919,7 @@ QString QFileInfo::suffix() const \bold{Note:} The QDir returned always corresponds to the object's parent directory, even if the QFileInfo represents a directory. - + For each of the follwing, dir() returns a QDir for \c{"~/examples/191697"}. -- cgit v0.12 From 80154fbd0aab812c5a16d3675741dd4531e7008a Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Tue, 31 Mar 2009 13:57:16 +0200 Subject: Fixes: Make QDir::cleanPath() slightly faster, by avoiding some detach calls.. RevBy: Samuel Details: We have the size of the array and we don't realloc, so we can use direct pointer access. This saves us a few detach() calls and some refcount checking in the inner loops... Found during S60 Performance week... --- src/corelib/io/qdir.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 6d75c59..d62328f 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -54,6 +54,8 @@ # include "qresource.h" #endif +#include "qvarlengtharray.h" + #include "../kernel/qcoreglobaldata_p.h" #include @@ -2065,11 +2067,13 @@ QString QDir::cleanPath(const QString &path) QString name = path; QChar dir_separator = separator(); if(dir_separator != QLatin1Char('/')) - name.replace(dir_separator, QLatin1Char('/')); + name.replace(dir_separator, QLatin1Char('/')); int used = 0, levels = 0; const int len = name.length(); - QVector out(len); + QVarLengthArray outVector(len); + QChar *out = outVector.data(); + const QChar *p = name.unicode(); for(int i = 0, last = -1, iwrite = 0; i < len; i++) { if(p[i] == QLatin1Char('/')) { @@ -2169,7 +2173,7 @@ QString QDir::cleanPath(const QString &path) if(used == len) ret = name; else - ret = QString(out.data(), used); + ret = QString(out, used); // Strip away last slash except for root directories if (ret.endsWith(QLatin1Char('/')) @@ -2232,7 +2236,7 @@ QStringList QDir::nameFiltersFromString(const QString &nameFilter) \snippet doc/src/snippets/code/src_corelib_io_qdir.cpp 13 - If the file name contains characters that cannot be part of a valid C++ function name + If the file name contains characters that cannot be part of a valid C++ function name (such as '-'), they have to be replaced by the underscore character ('_'). Note: This macro cannot be used in a namespace. It should be called from -- cgit v0.12 From d6d0b4f2b614453ce2ac96067408e0f3b071de78 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Tue, 31 Mar 2009 14:52:30 +0200 Subject: Fixes: Faster string-splitting in QResource::findNode() RevBy: Samuel Details: Creating the intermediate stringlist and appending all the temporary strings to it costs quite a bit. Fix this by introducing a StringSpliter class that is malloc-free and uses QStringRef instead. Found during S60 Performance week --- src/corelib/io/qresource.cpp | 44 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index 3bdb352..779a742 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -60,6 +60,37 @@ QT_BEGIN_NAMESPACE + +class QStringSplitter +{ +public: + QStringSplitter(const QString &s) + : m_string(s), m_data(m_string.constData()), m_len(s.length()), m_pos(0) + { + m_splitChar = QLatin1Char('/'); + } + + inline bool hasNext() { + while (m_pos < m_len && m_data[m_pos] == m_splitChar) + ++m_pos; + return m_pos < m_len; + } + + inline QStringRef next() { + int start = m_pos; + while (m_pos < m_len && m_data[m_pos] != m_splitChar) + ++m_pos; + return QStringRef(&m_string, start, m_pos - start); + } + + QString m_string; + const QChar *m_data; + QChar m_splitChar; + int m_len; + int m_pos; +}; + + //resource glue class QResourceRoot { @@ -618,12 +649,11 @@ int QResourceRoot::findNode(const QString &_path, const QLocale &locale) const //now iterate up the tree int node = -1; - QStringList segments = path.split(QLatin1Char('/'), QString::SkipEmptyParts); -#ifdef DEBUG_RESOURCE_MATCH - qDebug() << "****" << segments; -#endif - for(int i = 0; child_count && i < segments.size(); ++i) { - const QString &segment = segments[i]; + + QStringSplitter splitter(path); + while (child_count && splitter.hasNext()) { + QStringRef segment = splitter.next(); + #ifdef DEBUG_RESOURCE_MATCH qDebug() << " CHILDREN" << segment; for(int j = 0; j < child_count; ++j) { @@ -665,7 +695,7 @@ int QResourceRoot::findNode(const QString &_path, const QLocale &locale) const (tree[offset+1] << 0); offset += 2; - if(i == segments.size()-1) { + if(!splitter.hasNext()) { if(!(flags & Directory)) { const short country = (tree[offset+0] << 8) + (tree[offset+1] << 0); -- cgit v0.12 From 3eeb244251fd3bbfa3c3f421f1362986100d7587 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Thu, 16 Apr 2009 09:50:19 +0200 Subject: Make subpixel antialiasing of text work on Mac OS X under carbon Implement the alphaRGBMapForGlyph function and make use of it in the raster engine. The gamma correction is currently hardcoded to 2.0 which looks very good on two separate displays (iMac and MacBook Pro). Ideally this would be picked from the system settings or computed dynamically, but as long as 2.0 works, we'll stick to that. Reviewed-by: Samuel --- src/gui/painting/qdrawhelper.cpp | 6 ++ src/gui/painting/qpaintengine_raster.cpp | 14 ++-- src/gui/text/qfontengine_mac.mm | 110 +++++++++++++++++++++---------- src/gui/text/qfontengine_p.h | 3 + 4 files changed, 92 insertions(+), 41 deletions(-) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 789d96a..63e14ca 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -6933,6 +6933,12 @@ static void qt_alphamapblit_quint16(QRasterBuffer *rasterBuffer, void qt_build_pow_tables() { qreal smoothing = 1.7; +#ifdef Q_WS_MAC + // decided by testing a few things on an iMac, should probably get this from the + // system... + smoothing = 2.0; +#endif + #ifdef Q_WS_WIN int winSmooth; if (SystemParametersInfo(0x200C /* SPI_GETFONTSMOOTHINGCONTRAST */, 0, &winSmooth, 0)) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 92160f9..8e3d822 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -509,16 +509,20 @@ bool QRasterPaintEngine::begin(QPaintDevice *device) if (d->mono_surface) d->glyphCacheType = QFontEngineGlyphCache::Raster_Mono; -#ifdef Q_WS_WIN - else if (qt_cleartype_enabled) { +#if defined(Q_WS_WIN) + else if (qt_cleartype_enabled) +#elif defined (Q_WS_MAC) + else if (true) +#else + else if (false) +#endif + { QImage::Format format = static_cast(d->device)->format(); if (format == QImage::Format_ARGB32_Premultiplied || format == QImage::Format_RGB32) d->glyphCacheType = QFontEngineGlyphCache::Raster_RGBMask; else d->glyphCacheType = QFontEngineGlyphCache::Raster_A8; - } -#endif - else + } else d->glyphCacheType = QFontEngineGlyphCache::Raster_A8; setActive(true); diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index 425cab2..6b5bd0f 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -135,12 +135,12 @@ QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const ATSFontFamilyRef &, con symbolicTraits |= kCTFontItalicTrait; break; } - + QCFString name; ATSFontGetName(atsFontRef, kATSOptionFlagsDefault, &name); - QCFType descriptor = CTFontDescriptorCreateWithNameAndSize(name, fontDef.pixelSize); - QCFType baseFont = CTFontCreateWithFontDescriptor(descriptor, fontDef.pixelSize, 0); - ctfont = CTFontCreateCopyWithSymbolicTraits(baseFont, fontDef.pixelSize, 0, symbolicTraits, symbolicTraits); + QCFType descriptor = CTFontDescriptorCreateWithNameAndSize(name, fontDef.pointSize); + QCFType baseFont = CTFontCreateWithFontDescriptor(descriptor, fontDef.pointSize, 0); + ctfont = CTFontCreateCopyWithSymbolicTraits(baseFont, fontDef.pointSize, 0, symbolicTraits, symbolicTraits); // CTFontCreateCopyWithSymbolicTraits returns NULL if we ask for a trait that does // not exist for the given font. (for example italic) @@ -162,7 +162,7 @@ QCoreTextFontEngineMulti::QCoreTextFontEngineMulti(const ATSFontFamilyRef &, con QCoreTextFontEngine *fe = new QCoreTextFontEngine(ctfont, fontDef, this); fe->ref.ref(); engines.append(fe); - + } QCoreTextFontEngineMulti::~QCoreTextFontEngineMulti() @@ -176,7 +176,7 @@ uint QCoreTextFontEngineMulti::fontIndexForFont(CTFontRef id) const if (CFEqual(engineAt(i)->ctfont, id)) return i; } - + QCoreTextFontEngineMulti *that = const_cast(this); QCoreTextFontEngine *fe = new QCoreTextFontEngine(id, fontDef, that); fe->ref.ref(); @@ -227,7 +227,7 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay CTFontRef runFont = static_cast(CFDictionaryGetValue(runAttribs, NSFontAttributeName)); const uint fontIndex = (fontIndexForFont(runFont) << 24); //NSLog(@"Run Font Name = %@", CTFontCopyFamilyName(runFont)); - QVarLengthArray cgglyphs(0); + QVarLengthArray cgglyphs(0); const CGGlyph *tmpGlyphs = CTRunGetGlyphsPtr(run); if (!tmpGlyphs) { cgglyphs.resize(glyphCount); @@ -260,7 +260,7 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay CFIndex k = 0; CFIndex i = 0; - for (i = stringRange.location; + for (i = stringRange.location; (i < stringRange.location + stringRange.length) && (k < glyphCount); ++i) { if (tmpIndices[k * rtlSign + rtlOffset] == i || i == stringRange.location) { logClusters[i] = k + firstGlyphIndex; @@ -425,28 +425,28 @@ void QCoreTextFontEngine::draw(CGContextRef ctx, qreal x, qreal y, const QTextIt getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); if (glyphs.size() == 0) return; - + CGContextSetFontSize(ctx, fontDef.pixelSize); - + CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx); - + CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, -1, 0, -paintDeviceHeight); - + CGAffineTransformConcat(cgMatrix, oldTextMatrix); - + if (synthesisFlags & QFontEngine::SynthesizedItalic) cgMatrix = CGAffineTransformConcat(cgMatrix, CGAffineTransformMake(1, 0, -tanf(14 * acosf(0) / 90), 1, 0, 0)); - + // ### cgMatrix = CGAffineTransformConcat(cgMatrix, transform); - + CGContextSetTextMatrix(ctx, cgMatrix); - + CGContextSetTextDrawingMode(ctx, kCGTextFill); - - + + QVarLengthArray advances(glyphs.size()); QVarLengthArray cgGlyphs(glyphs.size()); - + for (int i = 0; i < glyphs.size() - 1; ++i) { advances[i].width = (positions[i + 1].x - positions[i].x).toReal(); advances[i].height = (positions[i + 1].y - positions[i].y).toReal(); @@ -455,21 +455,21 @@ void QCoreTextFontEngine::draw(CGContextRef ctx, qreal x, qreal y, const QTextIt advances[glyphs.size() - 1].width = 0; advances[glyphs.size() - 1].height = 0; cgGlyphs[glyphs.size() - 1] = glyphs[glyphs.size() - 1]; - + CGContextSetFont(ctx, cgFont); //NSLog(@"Font inDraw %@ ctfont %@", CGFontCopyFullName(cgFont), CTFontCopyFamilyName(ctfont)); - + CGContextSetTextPosition(ctx, positions[0].x.toReal(), positions[0].y.toReal()); - + CGContextShowGlyphsWithAdvances(ctx, cgGlyphs.data(), advances.data(), glyphs.size()); - + if (synthesisFlags & QFontEngine::SynthesizedBold) { CGContextSetTextPosition(ctx, positions[0].x.toReal() + 0.5 * lineThickness().toReal(), positions[0].y.toReal()); - + CGContextShowGlyphsWithAdvances(ctx, cgGlyphs.data(), advances.data(), glyphs.size()); } - + CGContextSetTextMatrix(ctx, oldTextMatrix); } @@ -622,7 +622,7 @@ QFontEngine::FaceId QCoreTextFontEngine::faceId() const bool QCoreTextFontEngine::canRender(const QChar *string, int len) { - QCFType retFont = CTFontCreateForString(ctfont, + QCFType retFont = CTFontCreateForString(ctfont, QCFType(CFStringCreateWithCharactersNoCopy(0, reinterpret_cast(string), len, kCFAllocatorNull)), @@ -672,7 +672,7 @@ QFontEngineMacMulti::QFontEngineMacMulti(const ATSFontFamilyRef &atsFamily, cons } else { if (fontDef.weight >= QFont::Bold) fntStyle |= ::bold; - if (fontDef.style != QFont::StyleNormal) + if (fontDef.style != QFont::StyleNormal) fntStyle |= ::italic; FMFontStyle intrinsicStyle; @@ -955,7 +955,7 @@ bool QFontEngineMacMulti::stringToCMap(const QChar *str, int len, QGlyphLayout * tmpItem.length = charCount; tmpItem.glyphs = shaperItem.glyphs.mid(glyphIdx, glyphCount); tmpItem.log_clusters = shaperItem.log_clusters + charIdx; - if (!stringToCMapInternal(tmpItem.string + tmpItem.from, tmpItem.length, + if (!stringToCMapInternal(tmpItem.string + tmpItem.from, tmpItem.length, &tmpItem.glyphs, &glyphCount, flags, &tmpItem)) { *nglyphs = glyphIdx + glyphCount; @@ -1221,12 +1221,12 @@ QFontEngineMac::QFontEngineMac(ATSUStyle baseStyle, ATSUFontID fontID, const QFo transform = multiEngine->transform; else transform = CGAffineTransformIdentity; - + ATSUTextMeasurement metric; ATSUGetAttribute(style, kATSUAscentTag, sizeof(metric), &metric, 0); m_ascent = FixRound(metric); - + ATSUGetAttribute(style, kATSUDescentTag, sizeof(metric), &metric, 0); m_descent = FixRound(metric); @@ -1422,11 +1422,16 @@ void QFontEngineMac::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, in addGlyphsToPathHelper(style, glyphs, positions, numGlyphs, path); } -QImage QFontEngineMac::alphaMapForGlyph(glyph_t glyph) + +/*! + Helper function for alphaMapForGlyph and alphaRGBMapForGlyph. The two are identical, except for + the subpixel antialiasing... +*/ +QImage QFontEngineMac::imageForGlyph(glyph_t glyph, int margin, bool colorful) { const glyph_metrics_t br = boundingBox(glyph); QImage im(qRound(br.width)+2, qRound(br.height)+4, QImage::Format_RGB32); - im.fill(0); + im.fill(0xff000000); CGColorSpaceRef colorspace = QCoreGraphicsPaintEngine::macGenericColorSpace(); #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4) @@ -1444,7 +1449,7 @@ QImage QFontEngineMac::alphaMapForGlyph(glyph_t glyph) CGContextSetFontSize(ctx, fontDef.pixelSize); CGContextSetShouldAntialias(ctx, fontDef.pointSize > qt_antialiasing_threshold && !(fontDef.styleStrategy & QFont::NoAntialias)); // turn off sub-pixel hinting - no support for that in OpenGL - CGContextSetShouldSmoothFonts(ctx, false); + CGContextSetShouldSmoothFonts(ctx, colorful); CGAffineTransform oldTextMatrix = CGContextGetTextMatrix(ctx); CGAffineTransform cgMatrix = CGAffineTransformMake(1, 0, 0, 1, 0, 0); CGAffineTransformConcat(cgMatrix, oldTextMatrix); @@ -1476,6 +1481,13 @@ QImage QFontEngineMac::alphaMapForGlyph(glyph_t glyph) CGContextRelease(ctx); + return im; +} + +QImage QFontEngineMac::alphaMapForGlyph(glyph_t glyph) +{ + QImage im = imageForGlyph(glyph, 2, false); + QImage indexed(im.width(), im.height(), QImage::Format_Indexed8); QVector colors(256); for (int i=0; i<256; ++i) @@ -1495,6 +1507,32 @@ QImage QFontEngineMac::alphaMapForGlyph(glyph_t glyph) return indexed; } +QImage QFontEngineMac::alphaRGBMapForGlyph(glyph_t glyph, int margin, const QTransform &t) +{ + QImage im = imageForGlyph(glyph, margin, true); + + if (t.type() >= QTransform::TxScale) { + im = im.transformed(t); + } + + extern uchar qt_pow_rgb_gamma[256]; + + // gamma correct the pixels back to linear color space... + for (int y=0; y(lw); props.lineWidth = lw; - + // CTFontCopyPostScriptName QCFString psName; if (ATSFontGetPostScriptName(FMGetATSFontRefFromFont(fontID), kATSOptionFlagsDefault, &psName) == noErr) @@ -1663,7 +1701,7 @@ void QFontEngineMac::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_m ATSUCreateAndCopyStyle(style, &unscaledStyle); int emSquare = properties().emSquare.toInt(); - + const int maxAttributeCount = 4; ATSUAttributeTag tags[maxAttributeCount + 1]; ByteCount sizes[maxAttributeCount + 1]; @@ -1675,7 +1713,7 @@ void QFontEngineMac::getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_m sizes[attributeCount] = sizeof(size); values[attributeCount] = &size; ++attributeCount; - + Q_ASSERT(attributeCount < maxAttributeCount + 1); OSStatus err = ATSUSetAttributes(unscaledStyle, attributeCount, tags, sizes, values); Q_ASSERT(err == noErr); diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index 176c728..8f6b92a 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -525,8 +525,11 @@ public: virtual Properties properties() const; virtual void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics); virtual QImage alphaMapForGlyph(glyph_t); + virtual QImage alphaRGBMapForGlyph(glyph_t, int margin, const QTransform &t); private: + QImage imageForGlyph(glyph_t glyph, int margin, bool colorful); + ATSUFontID fontID; QCFType cgFont; ATSUStyle style; -- cgit v0.12 From d43d33eb3121519d0025ad433d5c186365c47ef6 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Thu, 16 Apr 2009 10:12:18 +0200 Subject: QTreeView automatic resize can be broken QTreeView sometimes autoresizes the wrong column Task-number: 210390 Reviewed-by: janarve --- src/gui/itemviews/qheaderview.cpp | 30 ++++++++++++++++-------------- src/gui/itemviews/qheaderview_p.h | 9 +++------ tests/auto/qtreeview/tst_qtreeview.cpp | 18 ++++++++++++++++++ 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/gui/itemviews/qheaderview.cpp b/src/gui/itemviews/qheaderview.cpp index aacfab0..eb36178 100644 --- a/src/gui/itemviews/qheaderview.cpp +++ b/src/gui/itemviews/qheaderview.cpp @@ -1195,7 +1195,7 @@ QHeaderView::ResizeMode QHeaderView::resizeMode(int logicalIndex) const Q_D(const QHeaderView); int visual = visualIndex(logicalIndex); Q_ASSERT(visual != -1); - return d->visualIndexResizeMode(visual); + return d->headerSectionResizeMode(visual); } /*! @@ -1234,7 +1234,7 @@ void QHeaderView::setSortIndicatorShown(bool show) if (sortIndicatorSection() < 0 || sortIndicatorSection() > count()) return; - if (d->visualIndexResizeMode(sortIndicatorSection()) == ResizeToContents) + if (d->headerSectionResizeMode(sortIndicatorSection()) == ResizeToContents) resizeSections(); d->viewport->update(); @@ -2937,22 +2937,25 @@ int QHeaderViewPrivate::lastVisibleVisualIndex() const void QHeaderViewPrivate::resizeSections(QHeaderView::ResizeMode globalMode, bool useGlobalMode) { Q_Q(QHeaderView); + //stop the timer in case it is delayed + delayedResize.stop(); executePostedLayout(); if (sectionCount == 0) return; + + if (resizeRecursionBlock) + return; + resizeRecursionBlock = true; + invalidateCachedSizeHint(); + const int lastVisibleSection = lastVisibleVisualIndex(); + // find stretchLastSection if we have it int stretchSection = -1; - if (stretchLastSection && !useGlobalMode) { - for (int i = sectionCount - 1; i >= 0; --i) { - if (!isVisualIndexHidden(i)) { - stretchSection = i; - break; - } - } - } + if (stretchLastSection && !useGlobalMode) + stretchSection = lastVisibleVisualIndex(); // count up the number of strected sections and how much space left for them int lengthToStrech = (orientation == Qt::Horizontal ? viewport->width() : viewport->height()); @@ -2966,7 +2969,7 @@ void QHeaderViewPrivate::resizeSections(QHeaderView::ResizeMode globalMode, bool if (useGlobalMode && (i != stretchSection)) resizeMode = globalMode; else - resizeMode = (i == stretchSection ? QHeaderView::Stretch : visualIndexResizeMode(i)); + resizeMode = (i == stretchSection ? QHeaderView::Stretch : headerSectionResizeMode(i)); if (resizeMode == QHeaderView::Stretch) { ++numberOfStretchedSections; @@ -2998,7 +3001,6 @@ void QHeaderViewPrivate::resizeSections(QHeaderView::ResizeMode globalMode, bool int spanStartSection = 0; int previousSectionLength = 0; - const int lastVisibleSection = lastVisibleVisualIndex(); QHeaderView::ResizeMode previousSectionResizeMode = QHeaderView::Interactive; @@ -3017,7 +3019,7 @@ void QHeaderViewPrivate::resizeSections(QHeaderView::ResizeMode globalMode, bool else resizeMode = (i == stretchSection ? QHeaderView::Stretch - : visualIndexResizeMode(i)); + : newSectionResizeMode); if (resizeMode == QHeaderView::Stretch && stretchSectionLength != -1) { if (i == lastVisibleSection) newSectionLength = qMax(stretchSectionLength, lastSectionSize); @@ -3054,7 +3056,7 @@ void QHeaderViewPrivate::resizeSections(QHeaderView::ResizeMode globalMode, bool (sectionCount - spanStartSection) * previousSectionLength, previousSectionResizeMode); //Q_ASSERT(headerLength() == length); - + resizeRecursionBlock = false; viewport->update(); } diff --git a/src/gui/itemviews/qheaderview_p.h b/src/gui/itemviews/qheaderview_p.h index fbba69a..95bd84c 100644 --- a/src/gui/itemviews/qheaderview_p.h +++ b/src/gui/itemviews/qheaderview_p.h @@ -91,6 +91,7 @@ public: stretchLastSection(false), cascadingResizing(false), forceInitializing(false), + resizeRecursionBlock(false), stretchSections(0), contentsSections(0), minimumSectionSize(-1), @@ -170,10 +171,6 @@ public: if (!sectionHidden.isEmpty()) sectionHidden.setBit(visual, hidden); } - inline QHeaderView::ResizeMode visualIndexResizeMode(int visual) const { - return headerSectionResizeMode(visual); - } - inline bool hasAutoResizeSections() const { return stretchSections || stretchLastSection || contentsSections; } @@ -211,7 +208,7 @@ public: } inline bool sectionIsCascadable(int visual) const { - return visualIndexResizeMode(visual) == QHeaderView::Interactive; + return headerSectionResizeMode(visual) == QHeaderView::Interactive; } inline int modelSectionCount() const { @@ -231,7 +228,6 @@ public: inline void executePostedResize() const { if (delayedResize.isActive() && state == NoState) { - delayedResize.stop(); const_cast(q_func())->resizeSections(); } } @@ -276,6 +272,7 @@ public: bool stretchLastSection; bool cascadingResizing; bool forceInitializing; + bool resizeRecursionBlock; int stretchSections; int contentsSections; int defaultSectionSize; diff --git a/tests/auto/qtreeview/tst_qtreeview.cpp b/tests/auto/qtreeview/tst_qtreeview.cpp index dfccd9e..a96dbac 100644 --- a/tests/auto/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/qtreeview/tst_qtreeview.cpp @@ -225,6 +225,7 @@ private slots: void task238873_avoidAutoReopening(); void task244304_clickOnDecoration(); void task246536_scrollbarsNotWorking(); + void task250683_wrongSectionSize(); }; class QtTestModel: public QAbstractItemModel @@ -3279,5 +3280,22 @@ void tst_QTreeView::task246536_scrollbarsNotWorking() QVERIFY(o.count > 0); } + +void tst_QTreeView::task250683_wrongSectionSize() +{ + QDirModel model; + QTreeView treeView; + treeView.header()->setResizeMode(QHeaderView::ResizeToContents); + treeView.setModel(&model); + treeView.setColumnHidden(2, true); + treeView.setColumnHidden(3, true); + + treeView.show(); + QTest::qWait(100); + + QCOMPARE(treeView.header()->sectionSize(0) + treeView.header()->sectionSize(1), treeView.viewport()->width()); +} + + QTEST_MAIN(tst_QTreeView) #include "tst_qtreeview.moc" -- cgit v0.12