From 469b9a0f2ddf4bd1d2719619f3e4e52afbc7731f Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 30 Mar 2009 16:44:55 +0200 Subject: Doc: Synchronized the QTransform constructor arguments with the class documentation and updated a diagram. Task-number: 228201 Reviewed-by: TrustMe --- doc/src/diagrams/qtransform-representation.sk | 103 ++++++++++++++++++++++++++ src/gui/painting/qtransform.cpp | 19 +++-- 2 files changed, 114 insertions(+), 8 deletions(-) create mode 100644 doc/src/diagrams/qtransform-representation.sk diff --git a/doc/src/diagrams/qtransform-representation.sk b/doc/src/diagrams/qtransform-representation.sk new file mode 100644 index 0000000..17dcbfe --- /dev/null +++ b/doc/src/diagrams/qtransform-representation.sk @@ -0,0 +1,103 @@ +##Sketch 1 2 +document() +layout('A4',0) +layer('Layer 1',1,1,0,0,(0,0,0)) +lp((0,0,1)) +lw(2) +r(65,0,0,-65,190,760) +lp((0,0,1)) +lw(2) +r(65,0,0,-65,190,695) +lp((0,0,1)) +lw(2) +r(65,0,0,-65,190,630) +lp((0,0,1)) +lw(2) +r(65,0,0,-65,320,760) +lp((0,0,1)) +lw(2) +r(65,0,0,-65,320,695) +lp((0,0,1)) +lw(2) +r(65,0,0,-65,320,630) +lp((0,0,1)) +lw(2) +r(65,0,0,-65,255,760) +lp((0,0,1)) +lw(2) +r(65,0,0,-65,255,695) +lp((0,0,1)) +lw(2) +r(65,0,0,-65,255,630) +fp((0,0,0)) +le() +lw(1) +Fn('Helvetica') +Fs(24) +txt('m33',(329.16,589.968)) +G() +fp((0,0,0)) +le() +lw(1) +Fn('Helvetica') +Fs(24) +txt('dy',(274.828,577.768)) +fp((0,0,0)) +le() +lw(1) +Fn('Helvetica') +Fs(24) +txt('m32',(264.16,602.768)) +G_() +G() +fp((0,0,0)) +le() +lw(1) +Fn('Helvetica') +Fs(24) +txt('m31',(199.16,602.768)) +fp((0,0,0)) +le() +lw(1) +Fn('Helvetica') +Fs(24) +txt('dx',(209.828,577.8)) +G_() +fp((0,0,0)) +le() +lw(1) +Fn('Helvetica') +Fs(24) +txt('m11',(199.16,719.968)) +fp((0,0,0)) +le() +lw(1) +Fn('Helvetica') +Fs(24) +txt('m12',(264.16,719.968)) +fp((0,0,0)) +le() +lw(1) +Fn('Helvetica') +Fs(24) +txt('m13',(329.16,719.968)) +fp((0,0,0)) +le() +lw(1) +Fn('Helvetica') +Fs(24) +txt('m21',(199.16,654.968)) +fp((0,0,0)) +le() +lw(1) +Fn('Helvetica') +Fs(24) +txt('m22',(264.16,654.968)) +fp((0,0,0)) +le() +lw(1) +Fn('Helvetica') +Fs(24) +txt('m23',(329.16,654.968)) +guidelayer('Guide Lines',1,0,0,1,(0,0,1)) +grid((0,0,5,5),1,(0,0,1),'Grid') diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp index da8c428..c70208c 100644 --- a/src/gui/painting/qtransform.cpp +++ b/src/gui/painting/qtransform.cpp @@ -168,10 +168,10 @@ QT_BEGIN_NAMESPACE \image qtransform-representation.png - A QTransform object contains a 3 x 3 matrix. The \c dx and \c dy - elements specify horizontal and vertical translation. The \c m11 - and \c m22 elements specify horizontal and vertical scaling. The - \c m21 and \c m12 elements specify horizontal and vertical \e shearing. + A QTransform object contains a 3 x 3 matrix. The \c m31 (\c dx) and + \c m32 (\c dy) elements specify horizontal and vertical translation. + The \c m11 and \c m22 elements specify horizontal and vertical scaling. + The \c m21 and \c m12 elements specify horizontal and vertical \e shearing. And finally, the \c m13 and \c m23 elements specify horizontal and vertical projection, with \c m33 as an additional projection factor. @@ -246,8 +246,10 @@ QTransform::QTransform() } /*! - Constructs a matrix with the elements, \a h11, \a h12, \a h13, - \a h21, \a h22, \a h23, \a h31, \a h32, \a h33. + \fn QTransform::QTransform(qreal m11, qreal m12, qreal m13, qreal m21, qreal m22, qreal m23, qreal m31, qreal m32, qreal m33) + + Constructs a matrix with the elements, \a m11, \a m12, \a m13, + \a m21, \a m22, \a m23, \a m31, \a m32, \a m33. \sa setMatrix() */ @@ -263,8 +265,9 @@ QTransform::QTransform(qreal h11, qreal h12, qreal h13, } /*! - Constructs a matrix with the elements, \a h11, \a h12, \a h21, \a - h22, \a dx and \a dy. + \fn QTransform::QTransform(qreal m11, qreal m12, qreal m21, qreal m22, qreal dx, qreal dy) + + Constructs a matrix with the elements, \a m11, \a m12, \a m21, \a m22, \a dx and \a dy. \sa setMatrix() */ -- cgit v0.12 From 7ce9e9160ce04e6ab7e4219af9de6c24a9d2889c Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 30 Mar 2009 16:48:26 +0200 Subject: Doc: Synchronized the QTransform constructor arguments with the class documentation and updated a diagram. Task-number: 228201 Reviewed-by: TrustMe --- doc/src/images/qtransform-representation.png | Bin 17892 -> 17385 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/doc/src/images/qtransform-representation.png b/doc/src/images/qtransform-representation.png index 2608872..883d5dc 100644 Binary files a/doc/src/images/qtransform-representation.png and b/doc/src/images/qtransform-representation.png differ -- cgit v0.12 From 259175c6d55d7add0b25fd552b9dadc256e45def Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 30 Mar 2009 17:03:01 +0200 Subject: Doc: Fixed typo. Reviewed-by: TrustMe --- src/corelib/kernel/qmetatype.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 4d7d309..ce10bae 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -1255,7 +1255,7 @@ void QMetaType::destroy(int type, void *data) \relates QMetaType \threadsafe - Registers the type name \a typeName to the type \c{T}. Returns + Registers the type name \a typeName for the type \c{T}. Returns the internal ID used by QMetaType. Any class or struct that has a public default constructor, a public copy constructor and a public destructor can be registered. -- cgit v0.12 From 51a59f48f5b92e1c55dae5da0ffa9fbb492abc6b Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Mon, 30 Mar 2009 17:19:21 +0200 Subject: Explicitely mentioned in the doc that the format string for qDebug, qWarning and qFatal should be in Latin1. Reviewed-by: Thiago --- src/corelib/global/qglobal.cpp | 11 +++++++---- src/corelib/tools/qstring.cpp | 3 ++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 90020f7..08ecf3c 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -2022,7 +2022,8 @@ void qt_message_output(QtMsgType msgType, const char *buf) during compilation. If you pass the function a format string and a list of arguments, - it works in similar way to the C printf() function. + it works in similar way to the C printf() function. The format + should be a Latin-1 string. Example: @@ -2068,7 +2069,8 @@ void qDebug(const char *msg, ...) QT_FATAL_WARNINGS is defined. This function takes a format string and a list of arguments, - similar to the C printf() function. + similar to the C printf() function. The format should be a Latin-1 + string. Example: \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 26 @@ -2106,8 +2108,9 @@ void qWarning(const char *msg, ...) message handler has been installed, the message is printed to stderr. Under Windows, the message is sent to the debugger. - This function takes a format string and a list of arguments, similar - to the C printf() function. + This function takes a format string and a list of arguments, + similar to the C printf() function. The format should be a Latin-1 + string. Example: \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 28 diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 1b29adc..9c637ac 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -4864,7 +4864,8 @@ QString QString::toUpper() const a pointer to a zero-terminated array of unicode characters of type ushort (as returned by QString::utf16()). - \note This function expects a UTF-8 string for %s. + \note This function expects a UTF-8 string for %s and Latin-1 for + the format string. The format string supports most of the conversion specifiers provided by printf() in the standard C++ library. It doesn't -- cgit v0.12 From a9ffdee9c0e8ba092bb20759300157c1e45bc407 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 30 Mar 2009 08:30:23 -0700 Subject: Rename function Everything else capitalizes both the F and the B. s/Fb/FB/g Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp | 2 +- src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h | 2 +- src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp | 6 +++--- src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp | 2 +- src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp index 8dbad53..5e71640 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.cpp @@ -50,7 +50,7 @@ QDirectFBPaintDevice::~QDirectFBPaintDevice() } -IDirectFBSurface *QDirectFBPaintDevice::directFbSurface() const +IDirectFBSurface *QDirectFBPaintDevice::directFBSurface() const { return dfbSurface; } diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h index 7096124..89a3087 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintdevice.h @@ -56,7 +56,7 @@ class QDirectFBPaintDevice : public QCustomRasterPaintDevice public: ~QDirectFBPaintDevice(); - IDirectFBSurface *directFbSurface() const; + IDirectFBSurface *directFBSurface() const; void lockDirectFB(); void unlockDirectFB(); diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 28386e5..da4f367 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -340,7 +340,7 @@ void QDirectFBPaintEnginePrivate::begin(QPaintDevice *device) } if (dfbDevice) - surface = dfbDevice->directFbSurface(); + surface = dfbDevice->directFBSurface(); if (!surface) { qFatal("QDirectFBPaintEngine used on an invalid device: 0x%x", @@ -641,7 +641,7 @@ void QDirectFBPaintEnginePrivate::drawPixmap(const QRectF &dest, QPixmapData *data = pixmap.pixmapData(); Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); QDirectFBPixmapData *dfbData = static_cast(data); - IDirectFBSurface *s = dfbData->directFbSurface(); + IDirectFBSurface *s = dfbData->directFBSurface(); const QRect sr = src.toRect(); const QRect dr = ::mapRect(transform, dest); const DFBRectangle sRect = { sr.x(), sr.y(), sr.width(), sr.height() }; @@ -674,7 +674,7 @@ void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, QPixmapData *data = pixmap.pixmapData(); Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); QDirectFBPixmapData *dfbData = static_cast(data); - IDirectFBSurface *s = dfbData->directFbSurface(); + IDirectFBSurface *s = dfbData->directFBSurface(); const QRect dr = ::mapRect(transform, dest); DFBResult result = DFB_OK; diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index 3099205..9f5c055 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -108,7 +108,7 @@ void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect) return; } - IDirectFBSurface *src = static_cast(data)->directFbSurface(); + IDirectFBSurface *src = static_cast(data)->directFBSurface(); const QImage::Format format = (data->hasAlphaChannel() ? QDirectFBScreen::instance()->alphaPixmapFormat() : QDirectFBScreen::instance()->pixelFormat()); diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index db9672a..87a5910 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -1033,7 +1033,7 @@ void QDirectFBScreen::compose(const QRegion ®ion) if (surface->key() == QLatin1String("directfb")) { QDirectFBSurface *s = static_cast(surface); - blit(s->directFbSurface(), offset, r); + blit(s->directFBSurface(), offset, r); } else { blit(surface->image(), offset, r); } @@ -1082,7 +1082,7 @@ void QDirectFBScreen::compose(const QRegion ®ion) if (surface->key() == QLatin1String("directfb")) { QDirectFBSurface *s = static_cast(surface); - blit(s->directFbSurface(), offset, r); + blit(s->directFBSurface(), offset, r); } else { blit(surface->image(), offset, r); } -- cgit v0.12 From 6a303f13616fe1f54086092952b0d740534ca52a Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 30 Mar 2009 17:40:53 +0200 Subject: Doc: Exclude the internal Phonon classes from the Assistant documentation. Task-number: 247060 Reviewed-by: TrustMe --- tools/qdoc3/test/qt-api-only.qdocconf | 2 +- tools/qdoc3/test/qt-build-docs.qdocconf | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/qdoc3/test/qt-api-only.qdocconf b/tools/qdoc3/test/qt-api-only.qdocconf index 2e91ba2..bc5656b 100644 --- a/tools/qdoc3/test/qt-api-only.qdocconf +++ b/tools/qdoc3/test/qt-api-only.qdocconf @@ -9,7 +9,7 @@ url = ./ # Ensures that the documentation for the tools is not included in the generated # .qhp file. -qhp.Qt.excluded = $QT_SOURCE_TREE/doc/src/assistant-manual.qdoc \ +qhp.Qt.excluded += $QT_SOURCE_TREE/doc/src/assistant-manual.qdoc \ $QT_SOURCE_TREE/doc/src/examples/simpletextviewer.qdoc \ $QT_SOURCE_TREE/doc/src/designer-manual.qdoc \ $QT_SOURCE_TREE/doc/src/examples/calculatorbuilder.qdoc \ diff --git a/tools/qdoc3/test/qt-build-docs.qdocconf b/tools/qdoc3/test/qt-build-docs.qdocconf index a085768..25cdc5a 100644 --- a/tools/qdoc3/test/qt-build-docs.qdocconf +++ b/tools/qdoc3/test/qt-build-docs.qdocconf @@ -92,7 +92,11 @@ excludedirs = $QT_SOURCE_TREE/src/3rdparty/clucene \ $QT_SOURCE_TREE/src/3rdparty/webkit/WebCore \ $QT_SOURCE_TREE/src/3rdparty/wintab \ $QT_SOURCE_TREE/src/3rdparty/zlib \ - $QT_SOURCE_TREE/doc/src/snippets + $QT_SOURCE_TREE/doc/src/snippets \ + $QT_SOURCE_TREE/src/3rdparty/phonon/gstreamer \ + $QT_SOURCE_TREE/src/3rdparty/phonon/ds9 \ + $QT_SOURCE_TREE/src/3rdparty/phonon/qt7 \ + $QT_SOURCE_TREE/src/3rdparty/phonon/waveout sources.fileextensions = "*.cpp *.qdoc *.mm" examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp" -- cgit v0.12 From 2cb93d0c1f80c572c5cfa5074a6cfae81a3b28d2 Mon Sep 17 00:00:00 2001 From: Benjamin C Meyer Date: Thu, 5 Mar 2009 17:34:21 -0500 Subject: Improvements to follow the behavior of web servers and other browsers, specifically match the behavior of Firefox which servers test against. - When updating the cache metadata don't update content-* headers - Don't lowercase headers names when updating them - Fixed a typo in QNETWORKACCESSHTTPBACKEND_DEBUG code Originally seen on http://www.bibelbund.de/htm/99-4-306.htm where on refresh the 304 will set the content type of text/plain. Signed-off-by: Thiago Macieira Signed-off-by: Peter Hartmann --- src/network/access/qnetworkaccesshttpbackend.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index 4b41aa7..227a578 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -951,6 +951,7 @@ QNetworkCacheMetaData QNetworkAccessHttpBackend::fetchCacheMetaData(const QNetwo QList newHeaders = rawHeaderList(); foreach (QByteArray header, newHeaders) { + QByteArray originalHeader = header; header = header.toLower(); bool hop_by_hop = (header == "connection" @@ -974,19 +975,32 @@ QNetworkCacheMetaData QNetworkAccessHttpBackend::fetchCacheMetaData(const QNetwo continue; } + it = cacheHeaders.findRawHeader(header); + if (it != cacheHeaders.rawHeaders.constEnd()) { + // Match the behavior of Firefox and assume Cache-Control: "no-transform" + if (header == "content-encoding" + || header == "content-range" + || header == "content-type") + continue; + + // For MS servers that send "Content-Length: 0" on 304 responses + // ignore this too + if (header == "content-length") + continue; + } + #if defined(QNETWORKACCESSHTTPBACKEND_DEBUG) QByteArray n = rawHeader(header); QByteArray o; - it = cacheHeaders.findRawHeader(header); if (it != cacheHeaders.rawHeaders.constEnd()) o = (*it).second; - if (n != o && header != "Date") { + if (n != o && header != "date") { qDebug() << "replacing" << header; qDebug() << "new" << n; qDebug() << "old" << o; } #endif - cacheHeaders.setRawHeader(header, rawHeader(header)); + cacheHeaders.setRawHeader(originalHeader, rawHeader(header)); } metaData.setRawHeaders(cacheHeaders.rawHeaders); -- cgit v0.12 From ca7651e37599e0743ea37036dd3c7f891565fed8 Mon Sep 17 00:00:00 2001 From: Benjamin C Meyer Date: Fri, 20 Mar 2009 15:11:06 -0400 Subject: When loading a url straight from cache call finished so the QNetworkReply::finished() signal is emited. Signed-off-by: Thiago Macieira Signed-off-by: Peter Hartmann --- src/network/access/qnetworkaccesshttpbackend.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index 227a578..b09e9a6 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -527,8 +527,10 @@ void QNetworkAccessHttpBackend::postRequest() foreach (const QByteArray &header, headers) httpRequest.setHeaderField(header, request().rawHeader(header)); - if (loadedFromCache) + if (loadedFromCache) { + QNetworkAccessBackend::finished(); return; // no need to send the request! :) + } httpReply = http->sendRequest(httpRequest); httpReply->setParent(this); -- cgit v0.12 From fe6f08387f726d45536c13c00604b8290237af51 Mon Sep 17 00:00:00 2001 From: Benjamin C Meyer Date: Thu, 19 Feb 2009 13:16:41 -0500 Subject: Check for a redirection after setting the headers. If there is a redirection the location header will be used to determine where to go. Signed-off-by: Thiago Macieira Signed-off-by: Peter Hartmann --- src/network/access/qnetworkaccesshttpbackend.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index b09e9a6..401dc71 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -888,8 +888,6 @@ bool QNetworkAccessHttpBackend::sendCacheContents(const QNetworkCacheMetaData &m if (status < 100) status = 200; // fake it - checkForRedirect(status); - setAttribute(QNetworkRequest::HttpStatusCodeAttribute, status); setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, attributes.value(QNetworkRequest::HttpReasonPhraseAttribute)); setAttribute(QNetworkRequest::SourceIsFromCacheAttribute, true); @@ -900,6 +898,8 @@ bool QNetworkAccessHttpBackend::sendCacheContents(const QNetworkCacheMetaData &m for ( ; it != end; ++it) setRawHeader(it->first, it->second); + checkForRedirect(status); + writeDownstreamData(contents); #if defined(QNETWORKACCESSHTTPBACKEND_DEBUG) qDebug() << "Successfully sent cache:" << url() << contents->size() << "bytes"; -- cgit v0.12 From 79f02e7dbd28f3a60deeb083afb3c74a14430a88 Mon Sep 17 00:00:00 2001 From: Benjamin C Meyer Date: Mon, 16 Mar 2009 14:05:22 -0400 Subject: When parsing a cookie string the ',' character is special because it is used in the date and to differentiate between multiple cookies. When there are multiple set-cookie headers rather then combining them with ', ' use '\n' like Firefox because we are 100% sure that we have multiple cookies and using , can result in cases where the , is interpreted as as part of the date such as the following set-cookie:a=b; expires=2009 mar 10 set-cookie:c=d Combined the old way they result in the second cookie being ignored a=b; expires=2009 mar 10, c=d Using '\n' moves our cookie parser closer to Firefox's algorithm which will result in more behavior and bug for bug compatibility. Attempting to be smarter about the , will result in incompatibility with Firefox's implementation (as my first attempt at fixing this bug resulted). Also when parsing multiple cookies when we have an error don't return an empty list of cookies, but return the list of cookies we were able to parse successfully so far. Signed-off-by: Thiago Macieira Signed-off-by: Peter Hartmann --- src/network/access/qnetworkaccesshttpbackend.cpp | 8 ++++++-- src/network/access/qnetworkcookie.cpp | 10 +++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index 401dc71..a52b5a0 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -769,8 +769,12 @@ void QNetworkAccessHttpBackend::replyHeaderChanged() for (; it != end; ++it) { QByteArray value = rawHeader(it->first); - if (!value.isEmpty()) - value += ", "; + if (!value.isEmpty()) { + if (it->first.toLower() == "set-cookie") + value += "\n"; + else + value += ", "; + } value += it->second; setRawHeader(it->first, value); } diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index 1235960..5c28ff3 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -543,11 +543,17 @@ QList QNetworkCookie::parseCookies(const QByteArray &cookieStrin while (position < length) { QNetworkCookie cookie; + // When there are multiple SetCookie headers they are join with a new line + // \n will always be the start of a new cookie + int endOfSetCookie = cookieString.indexOf('\n'); + if (endOfSetCookie == -1) + endOfSetCookie = length; + // The first part is always the "NAME=VALUE" part QPair field = nextField(cookieString, position); if (field.first.isEmpty() || field.second.isNull()) // parsing error - return QList(); + break; cookie.setName(field.first); cookie.setValue(field.second); @@ -664,6 +670,8 @@ QList QNetworkCookie::parseCookies(const QByteArray &cookieStrin } position = nextNonWhitespace(cookieString, position); + if (position > endOfSetCookie) + endOfCookie = true; } result += cookie; -- cgit v0.12 From b790584708a8090211c1897e85f8b3d6df7afa29 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 26 Mar 2009 12:59:56 +0100 Subject: Fix bug introduced by last patch. Make sure that we can handle two Set-Cookie headers. Signed-off-by: Peter Hartmann --- src/network/access/qnetworkcookie.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index 5c28ff3..a327bc0 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -559,7 +559,7 @@ QList QNetworkCookie::parseCookies(const QByteArray &cookieStrin position = nextNonWhitespace(cookieString, position); bool endOfCookie = false; - while (!endOfCookie && position < length) + while (!endOfCookie && position < endOfSetCookie) switch (cookieString.at(position++)) { case ',': // end of the cookie -- cgit v0.12 From 0fe33578f03a0966c42f9fc44d80a49495f87878 Mon Sep 17 00:00:00 2001 From: Benjamin C Meyer Date: Thu, 26 Feb 2009 12:21:37 -0500 Subject: Change cookie expiration reading to match the behavior of Firefox. Rather then only allowing the three date formats that are in the rfc allow a much wider set of date strings. Because many browsers support this many websites send dates strings that are not in the rfc format. See documentation in parseDateString for more details about the implementation. Signed-off-by: Thiago Macieira Signed-off-by: Peter Hartmann --- src/network/access/qnetworkcookie.cpp | 437 +++++++++++++++++++++++++++++----- 1 file changed, 384 insertions(+), 53 deletions(-) diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index a327bc0..b127f18 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -49,6 +49,7 @@ #include "QtCore/qlist.h" #include "QtCore/qlocale.h" #include "QtCore/qstring.h" +#include "QtCore/qstringlist.h" #include "QtCore/qurl.h" #include "private/qobject_p.h" @@ -513,6 +514,385 @@ QByteArray QNetworkCookie::toRawForm(RawForm form) const return result; } +static const char zones[] = + "pst\0" // -8 + "pdt\0" + "mst\0" // -7 + "mdt\0" + "cst\0" // -6 + "cdt\0" + "est\0" // -5 + "edt\0" + "ast\0" // -4 + "nst\0" // -3 + "gmt\0" // 0 + "utc\0" + "bst\0" + "met\0" // 1 + "eet\0" // 2 + "jst\0" // 9 + "\0"; +static int zoneOffsets[] = {-8, -8, -7, -7, -6, -6, -5, -5, -4, -3, 0, 0, 0, 1, 2, 9 }; + +static const char months[] = + "jan\0" + "feb\0" + "mar\0" + "apr\0" + "may\0" + "jun\0" + "jul\0" + "aug\0" + "sep\0" + "oct\0" + "nov\0" + "dec\0" + "\0"; + +static inline bool isNumber(char s) { return s >= '0' && s <= '9'; } +static inline bool isTerminator (char c) { return c == '\n' || c == '\r'; } +static inline bool isValueSeparator (char c) { return isTerminator(c) || c == ';'; } +static inline bool isWhitespace (char c) { return c == ' ' || c == '\t'; } + +static bool checkStaticArray(int &val, const QByteArray &dateString, int at, const char *array, size_t size) { + if (dateString[at] < 'a' || dateString[at] > 'z') + return false; + if (val == -1 && dateString.length() >= at + 3) { + int j = 0; + size_t i = 0; + while (i <= size) { + const char *str(array + i); + if (str[0] == dateString[at] + && str[1] == dateString[at + 1] + && str[2] == dateString[at + 2]) { + val = j; + return true; + } + i += strlen(str) + 1; + ++j; + } + } + return false; +} + +//#define PARSEDATESTRINGDEBUG + +#define ADAY 1 +#define AMONTH 2 +#define AYEAR 4 + +/* + Parse all the date formats that Firefox can. + + The official format is: + expires=ddd(d)?, dd-MMM-yyyy hh:mm:ss GMT + + But browsers have been supporting a very wide range of date + strings. To work on many sites we need to support more then + just the official date format. + + For reference see Firefox's PR_ParseTimeStringToExplodedTime in + prtime.c. The Firefox date parser is coded in a very complex way + and is slightly over ~700 lines long. While this implementation + will be slightly slower for the non standard dates it is smaller, + more readable, and maintainable. + + Or in their own words: + "} // else what the hell is this." +*/ +static QDateTime parseDateString(const QByteArray &dateString) +{ + QTime time; + // placeholders for values when we are not sure it is a year, month or day + int unknown[3] = {-1, -1, -1}; + int month = -1; + int day = -1; + int year = -1; + int zoneOffset = -1; + + // hour:minute:second.ms pm + QRegExp timeRx(QLatin1String("(\\d{1,2}):(\\d{1,2})(:(\\d{1,2})|)(\\.(\\d{1,3})|)((\\s{0,}(am|pm))|)")); + + int at = 0; + while (at < dateString.length()) { +#ifdef PARSEDATESTRINGDEBUG + qDebug() << dateString.mid(at); +#endif + bool isNum = isNumber(dateString[at]); + + // Month + if (!isNum + && checkStaticArray(month, dateString, at, months, sizeof(months)- 1)) { + ++month; +#ifdef PARSEDATESTRINGDEBUG + qDebug() << "Month:" << month; +#endif + at += 3; + continue; + } + // Zone + if (!isNum + && zoneOffset == -1 + && checkStaticArray(zoneOffset, dateString, at, zones, sizeof(zones)- 1)) { + int sign = (at >= 0 && dateString[at - 1] == '-') ? -1 : 1; + zoneOffset = sign * zoneOffsets[zoneOffset] * 60 * 60; +#ifdef PARSEDATESTRINGDEBUG + qDebug() << "Zone:" << month; +#endif + at += 3; + continue; + } + // Zone offset + if (!isNum + && (zoneOffset == -1 || zoneOffset == 0) // Can only go after gmt + && (dateString[at] == '+' || dateString[at] == '-') + && (at == 0 + || isWhitespace(dateString[at - 1]) + || dateString[at - 1] == ',' + || (dateString[at - 1] == 't'))) { + + int end = 1; + while (dateString[at + end] >= '0' && dateString[at + end] <= '9' + && end < 5) + ++end; + int minutes = 0; + int hours = 0; + switch (end - 1) { + case 4: + minutes = atoi(dateString.mid(at + 3, 2).constData()); + // fall through + case 2: + hours = atoi(dateString.mid(at + 1, 2).constData()); + break; + case 1: + hours = atoi(dateString.mid(at + 1, 1).constData()); + break; + default: + at += end; + continue; + } + if (end != 1) { + int sign = dateString[at] == '-' ? -1 : 1; + zoneOffset = sign * ((minutes * 60) + (hours * 60 * 60)); +#ifdef PARSEDATESTRINGDEBUG + qDebug() << "Zone offset:" << zoneOffset << hours << minutes; +#endif + at += end; + continue; + } + } + + // Time + if (isNum && time.isNull() + && dateString.length() >= at + 3 + && (dateString[at + 2] == ':' || dateString[at + 1] == ':')) { + // While the date can be found all over the string the format + // for the time is set and a nice regexp can be used. + int pos = timeRx.indexIn(QLatin1String(dateString), at); + if (pos != -1) { + QStringList list = timeRx.capturedTexts(); + int h = atoi(list.at(1).toLatin1().constData()); + int m = atoi(list.at(2).toLatin1().constData()); + int s = atoi(list.at(4).toLatin1().constData()); + int ms = atoi(list.at(6).toLatin1().constData()); + if (h < 12 && !list.at(9).isEmpty()) + if (list.at(9) == QLatin1String("pm")) + h += 12; + time = QTime(h, m, s, ms); +#ifdef PARSEDATESTRINGDEBUG + qDebug() << "Time:" << list << timeRx.matchedLength(); +#endif + at += timeRx.matchedLength(); + continue; + } + } + + // 4 digit Year + if (isNum + && year == -1 + && dateString.length() >= at + 3) { + if (isNumber(dateString[at + 1]) + && isNumber(dateString[at + 2]) + && isNumber(dateString[at + 3])) { + year = atoi(dateString.mid(at, 4).constData()); + at += 4; +#ifdef PARSEDATESTRINGDEBUG + qDebug() << "Year:" << year; +#endif + continue; + } + } + + // a one or two digit number + // Could be month, day or year + if (isNum) { + int length = 1; + if (dateString.length() >= at + 1 + && isNumber(dateString[at + 1])) + ++length; + int x = atoi(dateString.mid(at, length).constData()); + if (year == -1 && (x > 31 || x == 0)) { + year = x; + } else { + if (unknown[0] == -1) unknown[0] = x; + else if (unknown[1] == -1) unknown[1] = x; + else if (unknown[2] == -1) unknown[2] = x; + } + at += length; +#ifdef PARSEDATESTRINGDEBUG + qDebug() << "Saving" << x; +#endif + continue; + } + + // Unknown character, typically a weekday such as 'Mon' + ++at; + } + + // Once we are done parsing the string take the digits in unknown + // and determine which is the unknown year/month/day + + int couldBe[3] = { 0, 0, 0 }; + int unknownCount = 3; + for (int i = 0; i < unknownCount; ++i) { + if (unknown[i] == -1) { + couldBe[i] = ADAY | AYEAR | AMONTH; + unknownCount = i; + continue; + } + + if (unknown[i] >= 1) + couldBe[i] = ADAY; + + if (month == -1 && unknown[i] >= 1 && unknown[i] <= 12) + couldBe[i] |= AMONTH; + + if (year == -1) + couldBe[i] |= AYEAR; + } + + // For any possible day make sure one of the values that could be a month + // can contain that day. + // For any possible month make sure one of the values that can be a + // day that month can have. + // Example: 31 11 06 + // 31 can't be a day because 11 and 6 don't have 31 days + for (int i = 0; i < unknownCount; ++i) { + int currentValue = unknown[i]; + bool findMatchingMonth = couldBe[i] & ADAY && currentValue >= 29; + bool findMatchingDay = couldBe[i] & AMONTH; + if (!findMatchingMonth || !findMatchingDay) + continue; + for (int j = 0; j < 3; ++j) { + if (j == i) + continue; + for (int k = 0; k < 2; ++k) { + if (k == 0 && !(findMatchingMonth && (couldBe[j] & AMONTH))) + continue; + else if (k == 1 && !(findMatchingDay && (couldBe[j] & ADAY))) + continue; + int m = currentValue; + int d = unknown[j]; + if (k == 0) + qSwap(m, d); + if (m == -1) m = month; + bool found = true; + switch(m) { + case 2: + // When we get 29 and the year ends up having only 28 + // See date.isValid below + // Example: 29 23 Feb + if (d <= 29) + found = false; + break; + case 4: case 6: case 9: case 11: + if (d <= 30) + found = false; + break; + default: + if (d > 0 && d <= 31) + found = false; + } + if (k == 0) findMatchingMonth = found; + else if (k == 1) findMatchingDay = found; + } + } + if (findMatchingMonth) + couldBe[i] &= ~ADAY; + if (findMatchingDay) + couldBe[i] &= ~AMONTH; + } + + // First set the year/month/day that have been deduced + // and reduce the set as we go along to deduce more + for (int i = 0; i < unknownCount; ++i) { + int unset = 0; + for (int j = 0; j < 3; ++j) { + if (couldBe[j] == ADAY && day == -1) { + day = unknown[j]; + unset |= ADAY; + } else if (couldBe[j] == AMONTH && month == -1) { + month = unknown[j]; + unset |= AMONTH; + } else if (couldBe[j] == AYEAR && year == -1) { + year = unknown[j]; + unset |= AYEAR; + } else { + // common case + break; + } + couldBe[j] &= ~unset; + } + } + + // Now fallback to a standardized order to fill in the rest with + for (int i = 0; i < unknownCount; ++i) { + if (couldBe[i] & AMONTH && month == -1) month = unknown[i]; + else if (couldBe[i] & ADAY && day == -1) day = unknown[i]; + else if (couldBe[i] & AYEAR && year == -1) year = unknown[i]; + } +#ifdef PARSEDATESTRINGDEBUG + qDebug() << "Final set" << year << month << day; +#endif + + if (year == -1 || month == -1 || day == -1) { +#ifdef PARSEDATESTRINGDEBUG + qDebug() << "Parser failure" << year << month << day; +#endif + return QDateTime(); + } + + // Y2k behavior + int y2k = 0; + if (year < 70) + y2k = 2000; + else if (year < 100) + y2k = 1900; + + QDate date(year + y2k, month, day); + + // When we were given a bad cookie that when parsed + // set the day to 29 and the year to one that doesn't + // have the 29th of Feb rather then adding the extra + // complicated checking earlier just swap here. + // Example: 29 23 Feb + if (!date.isValid()) + date = QDate(day + y2k, month, year); + + QDateTime dateTime; + + if (zoneOffset == -1) { + dateTime = QDateTime(date, time); + dateTime = dateTime.toTimeSpec(Qt::UTC); + } else { + dateTime = QDateTime(date, time, Qt::UTC); + dateTime = dateTime.addSecs(zoneOffset); + } + if (!dateTime.isValid()) + return QDateTime(); + return dateTime; +} + /*! Parses the cookie string \a cookieString as received from a server response in the "Set-Cookie:" header. If there's a parsing error, @@ -572,64 +952,15 @@ QList QNetworkCookie::parseCookies(const QByteArray &cookieStrin field.first = field.first.toLower(); // everything but the NAME=VALUE is case-insensitive if (field.first == "expires") { - static const char dateFormats[] = - "d-MMM-yyyy hh:mm:ss\0" - "d MMM yyyy hh:mm:ss\0" - "d-MMM-yy hh:mm:ss\0" - "\0"; - - // expires is a special case because it contains a naked comma - // and naked spaces. The format is: - // expires=ddd(d)?, dd-MMM-yyyy hh:mm:ss GMT - // but we also accept standard HTTP dates - - // make sure we're at the comma - if (position >= length || cookieString.at(position) != ',') - // invalid cookie string - return QList(); - - ++position; + position -= field.second.length(); int end; for (end = position; end < length; ++end) - if (cookieString.at(end) == ',' || cookieString.at(end) == ';') + if (isValueSeparator(cookieString.at(end))) break; - QByteArray datestring = cookieString.mid(position, end - position).trimmed(); + QByteArray dateString = cookieString.mid(position, end - position).trimmed(); position = end; - if (datestring.endsWith(" GMT") || datestring.endsWith(" UTC")) - datestring.chop(4); - else if (datestring.endsWith(" +0000")) - datestring.chop(6); - - size_t i = 0; - int j = 0; - QLocale cLocale = QLocale::c(); - QDateTime dt; - do { - QLatin1String df(dateFormats + i); - i += strlen(dateFormats + i) + 1; - -#ifndef QT_NO_DATESTRING - dt = cLocale.toDateTime(QString::fromLatin1(datestring), df); - - // some cookies are set with a two-digit year - // (although this is not allowed); this is interpreted as a year - // in the 20th century by QDateTime. - // Work around this case here (assuming 00-69 is 21st century, - // 70-99 is 20th century) - QDate date = dt.date(); - if (j == 2 && date.year() >= 1900 && date.year() < 1970) - dt = dt.addYears(100); - if (date.year() >= 0 && date.year() < 100) - dt = dt.addYears(1900); -#endif - j++; - } while (!dt.isValid() && i <= sizeof dateFormats - 1); - if (!dt.isValid()) - // invalid cookie string - return QList(); - - dt.setTimeSpec(Qt::UTC); + QDateTime dt = parseDateString(dateString.toLower()); cookie.setExpirationDate(dt); } else if (field.first == "domain") { QByteArray rawDomain = field.second; -- cgit v0.12 From 83dc49feaf56bdf469388174972fa6fc815b844b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 26 Mar 2009 14:52:03 +0100 Subject: Fix a few issues introduced by Ben's last patch. Test if we're not past the end of the array before we attempt to read it. Dates without timezone information are taken to be UTC, so merge the code. If the date parsing failed, don't add a malformed cookie. Better to have no cookie than to have it for past its expiration date. Also update the autotests, since we now can cope with some of the invalid cookies seen on the net. Signed-off-by: Peter Hartmann --- src/network/access/qnetworkcookie.cpp | 39 +++++++++++++++--------- tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp | 11 +++---- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index b127f18..56cb539 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -549,17 +549,25 @@ static const char months[] = "dec\0" "\0"; -static inline bool isNumber(char s) { return s >= '0' && s <= '9'; } -static inline bool isTerminator (char c) { return c == '\n' || c == '\r'; } -static inline bool isValueSeparator (char c) { return isTerminator(c) || c == ';'; } -static inline bool isWhitespace (char c) { return c == ' ' || c == '\t'; } +static inline bool isNumber(char s) +{ return s >= '0' && s <= '9'; } -static bool checkStaticArray(int &val, const QByteArray &dateString, int at, const char *array, size_t size) { +static inline bool isTerminator(char c) +{ return c == '\n' || c == '\r'; } + +static inline bool isValueSeparator(char c) +{ return isTerminator(c) || c == ';'; } + +static inline bool isWhitespace(char c) +{ return c == ' ' || c == '\t'; } + +static bool checkStaticArray(int &val, const QByteArray &dateString, int at, const char *array, int size) +{ if (dateString[at] < 'a' || dateString[at] > 'z') return false; if (val == -1 && dateString.length() >= at + 3) { int j = 0; - size_t i = 0; + int i = 0; while (i <= size) { const char *str(array + i); if (str[0] == dateString[at] @@ -652,8 +660,7 @@ static QDateTime parseDateString(const QByteArray &dateString) || (dateString[at - 1] == 't'))) { int end = 1; - while (dateString[at + end] >= '0' && dateString[at + end] <= '9' - && end < 5) + while (end < 5 && dateString[at + end] >= '0' && dateString[at + end] <= '9') ++end; int minutes = 0; int hours = 0; @@ -879,13 +886,9 @@ static QDateTime parseDateString(const QByteArray &dateString) if (!date.isValid()) date = QDate(day + y2k, month, year); - QDateTime dateTime; + QDateTime dateTime(date, time, Qt::UTC); - if (zoneOffset == -1) { - dateTime = QDateTime(date, time); - dateTime = dateTime.toTimeSpec(Qt::UTC); - } else { - dateTime = QDateTime(date, time, Qt::UTC); + if (zoneOffset != -1) { dateTime = dateTime.addSecs(zoneOffset); } if (!dateTime.isValid()) @@ -961,6 +964,11 @@ QList QNetworkCookie::parseCookies(const QByteArray &cookieStrin QByteArray dateString = cookieString.mid(position, end - position).trimmed(); position = end; QDateTime dt = parseDateString(dateString.toLower()); + if (!dt.isValid()) { + cookie = QNetworkCookie(); + endOfCookie = true; + continue; + } cookie.setExpirationDate(dt); } else if (field.first == "domain") { QByteArray rawDomain = field.second; @@ -1005,7 +1013,8 @@ QList QNetworkCookie::parseCookies(const QByteArray &cookieStrin endOfCookie = true; } - result += cookie; + if (!cookie.name().isEmpty()) + result += cookie; } return result; diff --git a/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp b/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp index 9010db4..4da17d9 100644 --- a/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp +++ b/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp @@ -315,6 +315,9 @@ void tst_QNetworkCookie::parseSingleCookie_data() cookie.setExpirationDate(QDateTime(QDate(9999, 12, 31), QTime(23, 59, 59), Qt::UTC)); QTest::newRow("network2") << "__siteid=1; expires=Fri, 31-Dec-9999 23:59:59 GMT; path=/" << cookie; + cookie = QNetworkCookie("YM.LC", "v=2&m=9993_262838_159_1558_1063_0_5649_4012_3776161073,9426_260205_549_1295_1336_0_5141_4738_3922731647,6733_258196_952_1364_643_0_3560_-1_0,3677_237633_1294_1294_19267_0_3244_29483_4102206176,1315_235149_1693_1541_941_0_3224_1691_1861378060,1858_214311_2100_1298_19538_0_2873_30900_716411652,6258_212007_2506_1285_1017_0_2868_3606_4288540264,3743_207884_2895_1362_2759_0_2545_7114_3388520216,2654_205253_3257_1297_1332_0_2504_4682_3048534803,1891_184881_3660_1291_19079_0_978_29178_2592538685&f=1&n=20&s=date&o=down&e=1196548712&b=Inbox&u=removed"); + cookie.setPath("/"); + cookie.setDomain("mail.yahoo.com"); QTest::newRow("network3") << "YM.LC=v=2&m=9993_262838_159_1558_1063_0_5649_4012_3776161073,9426_260205_549_1295_1336_0_5141_4738_3922731647,6733_258196_952_1364_643_0_3560_-1_0,3677_237633_1294_1294_19267_0_3244_29483_4102206176,1315_235149_1693_1541_941_0_3224_1691_1861378060,1858_214311_2100_1298_19538_0_2873_30900_716411652,6258_212007_2506_1285_1017_0_2868_3606_4288540264,3743_207884_2895_1362_2759_0_2545_7114_3388520216,2654_205253_3257_1297_1332_0_2504_4682_3048534803,1891_184881_3660_1291_19079_0_978_29178_2592538685&f=1&n=20&s=date&o=down&e=1196548712&b=Inbox&u=removed; path=/; domain=mail.yahoo.com" << cookie; cookie = QNetworkCookie("__ac", "c2hhdXNtYW46U2FTYW80Wm8%3D"); @@ -330,9 +333,9 @@ void tst_QNetworkCookie::parseSingleCookie() QList result = QNetworkCookie::parseCookies(cookieString.toLatin1()); - QEXPECT_FAIL("network2", "QDateTime parsing problem: the date is beyond year 8000", Abort); - QEXPECT_FAIL("network3", "Cookie value contains commas, violating the HTTP spec", Abort); + //QEXPECT_FAIL("network2", "QDateTime parsing problem: the date is beyond year 8000", Abort); QCOMPARE(result.count(), 1); + QEXPECT_FAIL("network3", "Cookie value contains commas, violating the HTTP spec", Abort); QCOMPARE(result.at(0), expectedCookie); result = QNetworkCookie::parseCookies(result.at(0).toRawForm()); @@ -358,9 +361,7 @@ void tst_QNetworkCookie::parseMultipleCookies_data() // reason: malformed NAME=VALUE pair QTest::newRow("invalid-05") << "foo" << list; QTest::newRow("invalid-06") << "=b" << list; - QTest::newRow("invalid-08") << "a=b,foo" << list; QTest::newRow("invalid-09") << "foo,a=b" << list; - QTest::newRow("invalid-10") << "a=b,=b" << list; QTest::newRow("invalid-11") << ";path=/" << list; // reason: malformed expiration date string @@ -369,8 +370,6 @@ void tst_QNetworkCookie::parseMultipleCookies_data() QTest::newRow("invalid-14") << "a=b;expires=foobar, abc" << list; QTest::newRow("invalid-15") << "a=b;expires=foobar, dd-mmm-yyyy hh:mm:ss GMT; path=/" << list; QTest::newRow("invalid-16") << "a=b;expires=foobar, 32-Caz-1999 24:01:60 GMT; path=/" << list; - QTest::newRow("invalid-17") << "a=b,c=d;expires=" << list; - QTest::newRow("invalid-18") << "a=b, c=d; expires=foobar, 32-Caz-1999 24:01:60 GMT; path=/" << list; QNetworkCookie cookie; cookie.setName("a"); -- cgit v0.12 From 36b7256f87f97a84f1a1331c68d5ef7783aef9ab Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 26 Mar 2009 15:47:04 +0100 Subject: When doing date comparisons, force to the same timezone. It's the logical time that matters, not the exact date representation. Signed-off-by: Peter Hartmann --- src/network/access/qnetworkcookie.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index 56cb539..852fcd6 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -164,7 +164,7 @@ bool QNetworkCookie::operator==(const QNetworkCookie &other) const return true; return d->name == other.d->name && d->value == other.d->value && - d->expirationDate == other.d->expirationDate && + d->expirationDate.toUTC() == other.d->expirationDate.toUTC() && d->domain == other.d->domain && d->path == other.d->path && d->secure == other.d->secure && -- cgit v0.12 From fde8457213eaa3da881d1afa8f9f2294acdc4877 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 26 Mar 2009 15:47:59 +0100 Subject: Fix parsing of dates: if the month is followed by a dash, it's not the negative sign. I don't know why, but this only triggers for the month of October Signed-off-by: Peter Hartmann --- src/network/access/qnetworkcookie.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index 852fcd6..286c5f6 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -636,6 +636,8 @@ static QDateTime parseDateString(const QByteArray &dateString) qDebug() << "Month:" << month; #endif at += 3; + if (at < dateString.length() && dateString[at] == '-') + ++at; continue; } // Zone -- cgit v0.12 From 9cc1b5573affdfcf1862369afe387c8fdf8474e6 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 26 Mar 2009 15:48:18 +0100 Subject: Fix accesses past-the-end of the byte array Signed-off-by: Peter Hartmann --- src/network/access/qnetworkcookie.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index 286c5f6..4846618 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -662,7 +662,8 @@ static QDateTime parseDateString(const QByteArray &dateString) || (dateString[at - 1] == 't'))) { int end = 1; - while (end < 5 && dateString[at + end] >= '0' && dateString[at + end] <= '9') + while (end < 5 && dateString.length() > at+end + && dateString[at + end] >= '0' && dateString[at + end] <= '9') ++end; int minutes = 0; int hours = 0; @@ -736,7 +737,7 @@ static QDateTime parseDateString(const QByteArray &dateString) // Could be month, day or year if (isNum) { int length = 1; - if (dateString.length() >= at + 1 + if (dateString.length() > at + 1 && isNumber(dateString[at + 1])) ++length; int x = atoi(dateString.mid(at, length).constData()); -- cgit v0.12 From ece28c5e497c5a7ce1f7671094c5ff3e58d176c5 Mon Sep 17 00:00:00 2001 From: Benjamin C Meyer Date: Thu, 26 Mar 2009 15:53:09 +0100 Subject: Autotest: more date-time parsing tests for QNetworkCookie Signoff-by: Thiago Macieira Signed-off-by: Peter Hartmann --- tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp | 264 +++++++++++++++++++++++ 1 file changed, 264 insertions(+) diff --git a/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp b/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp index 4da17d9..2187b61 100644 --- a/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp +++ b/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp @@ -286,8 +286,263 @@ void tst_QNetworkCookie::parseSingleCookie_data() QTest::newRow("expiration3") << "a=b; expires=Wednesday, 09-Nov-1999 23:12:40 GMT " << cookie; QTest::newRow("expiration-utc") << "a=b;expires=Wednesday, 09-Nov-1999 23:12:40 UTC" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 4, 14), QTime(3, 20, 0, 0), Qt::UTC)); + QTest::newRow("time-0") << "a=b;expires=14 Apr 89 03:20" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 4, 14), QTime(3, 20, 12, 0), Qt::UTC)); + QTest::newRow("time-1") << "a=b;expires=14 Apr 89 03:20:12" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 4, 14), QTime(3, 20, 12, 88), Qt::UTC)); + QTest::newRow("time-2") << "a=b;expires=14 Apr 89 03:20:12.88" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 4, 14), QTime(3, 20, 12, 88), Qt::UTC)); + QTest::newRow("time-3") << "a=b;expires=14 Apr 89 03:20:12.88am" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 4, 14), QTime(15, 20, 12, 88), Qt::UTC)); + QTest::newRow("time-4") << "a=b;expires=14 Apr 89 03:20:12.88pm" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 4, 14), QTime(3, 20, 12, 88), Qt::UTC)); + QTest::newRow("time-5") << "a=b;expires=14 Apr 89 03:20:12.88 Am" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 4, 14), QTime(15, 20, 12, 88), Qt::UTC)); + QTest::newRow("time-6") << "a=b;expires=14 Apr 89 03:20:12.88 PM" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 4, 14), QTime(15, 20, 12, 88), Qt::UTC)); + QTest::newRow("time-7") << "a=b;expires=14 Apr 89 3:20:12.88 PM" << cookie; + + // normal months + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-1") << "a=b;expires=Jan 1 89 1:1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 2, 1), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-2") << "a=b;expires=Feb 1 89 1:1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 3, 1), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-3") << "a=b;expires=mar 1 89 1:1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 4, 1), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-4") << "a=b;expires=Apr 1 89 1:1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 5, 1), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-5") << "a=b;expires=May 1 89 1:1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 6, 1), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-6") << "a=b;expires=Jun 1 89 1:1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 7, 1), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-7") << "a=b;expires=Jul 1 89 1:1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 8, 1), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-8") << "a=b;expires=Aug 1 89 1:1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 9, 1), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-9") << "a=b;expires=Sep 1 89 1:1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 10, 1), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-10") << "a=b;expires=Oct 1 89 1:1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 11, 1), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-11") << "a=b;expires=Nov 1 89 1:1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 12, 1), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-12") << "a=b;expires=Dec 1 89 1:1" << cookie; + + // extra months + cookie.setExpirationDate(QDateTime(QDate(1989, 12, 1), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-13") << "a=b;expires=December 1 89 1:1" << cookie; + QTest::newRow("months-14") << "a=b;expires=1 89 1:1 Dec" << cookie; + //cookie.setExpirationDate(QDateTime()); + //QTest::newRow("months-15") << "a=b;expires=1 89 1:1 De" << cookie; + cookie.setExpirationDate(QDateTime(QDate(2024, 2, 29), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-16") << "a=b;expires=2024 29 Feb 1:1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(2024, 2, 29), QTime(1, 1), Qt::UTC)); + QTest::newRow("months-17") << "a=b;expires=Fri, 29-Feb-2024 01:01:00 GMT" << cookie; + QTest::newRow("months-18") << "a=b;expires=2024 29 Feb 1:1 GMT" << cookie; + + // normal offsets + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-0") << "a=b;expires=Jan 1 89 8:0 PST" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-1") << "a=b;expires=Jan 1 89 8:0 PDT" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-2") << "a=b;expires=Jan 1 89 7:0 MST" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-3") << "a=b;expires=Jan 1 89 7:0 MDT" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-4") << "a=b;expires=Jan 1 89 6:0 CST" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-5") << "a=b;expires=Jan 1 89 6:0 CDT" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-6") << "a=b;expires=Jan 1 89 5:0 EST" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-7") << "a=b;expires=Jan 1 89 5:0 EDT" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-8") << "a=b;expires=Jan 1 89 4:0 AST" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-9") << "a=b;expires=Jan 1 89 3:0 NST" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-10") << "a=b;expires=Jan 1 89 0:0 GMT" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-11") << "a=b;expires=Jan 1 89 0:0 BST" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 2), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-12") << "a=b;expires=Jan 1 89 23:0 MET" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 2), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-13") << "a=b;expires=Jan 1 89 22:0 EET" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 2), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-14") << "a=b;expires=Jan 1 89 15:0 JST" << cookie; + + // extra offsets + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 2), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-14") << "a=b;expires=Jan 1 89 15:0 JST+1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(1, 0), Qt::UTC)); + QTest::newRow("zoneoffset-15") << "a=b;expires=Jan 1 89 0:0 GMT+1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-15b") << "a=b;expires=Jan 1 89 1:0 GMT-1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(1, 0), Qt::UTC)); + QTest::newRow("zoneoffset-16") << "a=b;expires=Jan 1 89 0:0 GMT+01" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(1, 5), Qt::UTC)); + QTest::newRow("zoneoffset-17") << "a=b;expires=Jan 1 89 0:0 GMT+0105" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-18") << "a=b;expires=Jan 1 89 0:0 GMT+015" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-19") << "a=b;expires=Jan 1 89 0:0 GM" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-19b") << "a=b;expires=Jan 1 89 0:0 GMT" << cookie; + + // offsets from gmt + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(1, 0), Qt::UTC)); + QTest::newRow("zoneoffset-20") << "a=b;expires=Jan 1 89 0:0 +1" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(1, 0), Qt::UTC)); + QTest::newRow("zoneoffset-21") << "a=b;expires=Jan 1 89 0:0 +01" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(1, 1), Qt::UTC)); + QTest::newRow("zoneoffset-22") << "a=b;expires=Jan 1 89 0:0 +0101" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("zoneoffset-23") << "a=b;expires=Jan 1 89 1:0 -1" << cookie; + + // Y2k + cookie.setExpirationDate(QDateTime(QDate(2000, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("year-0") << "a=b;expires=Jan 1 00 0:0" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1970, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("year-1") << "a=b;expires=Jan 1 70 0:0" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1971, 1, 1), QTime(0, 0), Qt::UTC)); + QTest::newRow("year-2") << "a=b;expires=Jan 1 71 0:0" << cookie; + + // Day, month, year + cookie.setExpirationDate(QDateTime(QDate(2013, 1, 2), QTime(0, 0), Qt::UTC)); + QTest::newRow("date-0") << "a=b;expires=Jan 2 13 0:0" << cookie; + QTest::newRow("date-1") << "a=b;expires=1-2-13 0:0" << cookie; + QTest::newRow("date-2") << "a=b;expires=1/2/13 0:0" << cookie; + QTest::newRow("date-3") << "a=b;expires=Jan 2 13 0:0" << cookie; + QTest::newRow("date-4") << "a=b;expires=Jan 2, 13 0:0" << cookie; + QTest::newRow("date-5") << "a=b;expires=1-2-13 0:0" << cookie; + QTest::newRow("date-6") << "a=b;expires=1/2/13 0:0" << cookie; + + // Known Year, determine month and day + cookie.setExpirationDate(QDateTime(QDate(1995, 1, 13), QTime(0, 0), Qt::UTC)); + QTest::newRow("knownyear-0") << "a=b;expires=13/1/95 0:0" << cookie; + QTest::newRow("knownyear-1") << "a=b;expires=95/13/1 0:0" << cookie; + QTest::newRow("knownyear-2") << "a=b;expires=1995/1/13 0:0" << cookie; + QTest::newRow("knownyear-3") << "a=b;expires=1995/13/1 0:0" << cookie; + cookie.setExpirationDate(QDateTime(QDate(1995, 1, 2), QTime(0, 0), Qt::UTC)); + QTest::newRow("knownyear-4") << "a=b;expires=1/2/95 0:0" << cookie; + QTest::newRow("knownyear-5") << "a=b;expires=95/1/2 0:0" << cookie; + + // Known Year, Known day, determining month + cookie.setExpirationDate(QDateTime(QDate(1995, 1, 13), QTime(0, 0), Qt::UTC)); + QTest::newRow("knownYD-0") << "a=b;expires=13/1/95 0:0" << cookie; + QTest::newRow("knownYD-1") << "a=b;expires=1/13/95 0:0" << cookie; + QTest::newRow("knownYD-2") << "a=b;expires=95/13/1 0:0" << cookie; + QTest::newRow("knownYD-3") << "a=b;expires=95/1/13 0:0" << cookie; + + // Month comes before Year + cookie.setExpirationDate(QDateTime(QDate(2021, 03, 26), QTime(0, 0), Qt::UTC)); + QTest::newRow("month-0") << "a=b;expires=26/03/21 0:0" << cookie; + cookie.setExpirationDate(QDateTime(QDate(2015, 12, 30), QTime(16, 25, 0, 0), Qt::UTC)); + QTest::newRow("month-1") << "a=b;expires=wed 16:25pm December 2015 30" << cookie; + cookie.setExpirationDate(QDateTime(QDate(2031, 11, 11), QTime(16, 25, 0, 0), Qt::UTC)); + QTest::newRow("month-2") << "a=b;expires=16:25 11 31 11" << cookie; + + // The very ambiguous cases + // Matching Firefox's behavior of guessing month, day, year in those cases + cookie.setExpirationDate(QDateTime(QDate(2013, 10, 2), QTime(0, 0), Qt::UTC)); + QTest::newRow("ambiguousd-0") << "a=b;expires=10/2/13 0:0" << cookie; + cookie.setExpirationDate(QDateTime(QDate(2013, 2, 10), QTime(0, 0), Qt::UTC)); + QTest::newRow("ambiguousd-1") << "a=b;expires=2/10/13 0:0" << cookie; + cookie.setExpirationDate(QDateTime(QDate(2010, 2, 3), QTime(0, 0), Qt::UTC)); + QTest::newRow("ambiguousd-2") << "a=b;expires=2/3/10 0:0" << cookie; + + // FYI If you try these in Firefox it wont set a cookie for the following two string + // because 03 is turned into the year at which point it is expired + cookie.setExpirationDate(QDateTime(QDate(2003, 2, 10), QTime(0, 0), Qt::UTC)); + QTest::newRow("ambiguousd-3") << "a=b;expires=2/10/3 0:0" << cookie; + cookie.setExpirationDate(QDateTime(QDate(2003, 10, 2), QTime(0, 0), Qt::UTC)); + QTest::newRow("ambiguousd-4") << "a=b;expires=10/2/3 0:0" << cookie; + + // These are the cookies that firefox's source says it can parse + cookie.setExpirationDate(QDateTime(QDate(1989, 4, 14), QTime(3, 20, 0, 0), Qt::UTC)); + QTest::newRow("firefox-0") << "a=b;expires=14 Apr 89 03:20" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(1989, 4, 14), QTime(3, 20, 0, 0), Qt::UTC)); + QTest::newRow("firefox-1") << "a=b;expires=14 Apr 89 03:20 GMT" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(1989, 3, 17), QTime(4, 1, 33, 0), Qt::UTC)); + QTest::newRow("firefox-2") << "a=b;expires=Fri, 17 Mar 89 4:01:33" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(1989, 3, 17), QTime(4, 1, 0, 0), Qt::UTC)); + QTest::newRow("firefox-3") << "a=b;expires=Fri, 17 Mar 89 4:01 GMT" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 16), QTime(16-8, 12, 0, 0), Qt::UTC)); + QTest::newRow("firefox-4") << "a=b;expires=Mon Jan 16 16:12 PDT 1989" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(1989, 1, 16), QTime(17, 42, 0, 0), Qt::UTC)); + QTest::newRow("firefox-5") << "a=b;expires=Mon Jan 16 16:12 +0130 1989" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(1992, 5, 6), QTime(16-9, 41, 0, 0), Qt::UTC)); + QTest::newRow("firefox-6") << "a=b;expires=6 May 1992 16:41-JST (Wednesday)" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(1993, 8, 22), QTime(10, 59, 12, 82), Qt::UTC)); + QTest::newRow("firefox-7") << "a=b;expires=22-AUG-1993 10:59:12.82" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(1993, 8, 22), QTime(22, 59, 0, 0), Qt::UTC)); + QTest::newRow("firefox-8") << "a=b;expires=22-AUG-1993 10:59pm" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(1993, 8, 22), QTime(12, 59, 0, 0), Qt::UTC)); + QTest::newRow("firefox-9") << "a=b;expires=22-AUG-1993 12:59am" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(1993, 8, 22), QTime(12, 59, 0, 0), Qt::UTC)); + QTest::newRow("firefox-10") << "a=b;expires=22-AUG-1993 12:59 PM" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(1995, 8, 4), QTime(15, 54, 0, 0), Qt::UTC)); + QTest::newRow("firefox-11") << "a=b;expires=Friday, August 04, 1995 3:54 PM" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(1995, 6, 21), QTime(16, 24, 34, 0), Qt::UTC)); + QTest::newRow("firefox-12") << "a=b;expires=06/21/95 04:24:34 PM" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(1995, 6, 20), QTime(21, 7, 0, 0), Qt::UTC)); + QTest::newRow("firefox-13") << "a=b;expires=20/06/95 21:07" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(1995, 6, 8), QTime(19-5, 32, 48, 0), Qt::UTC)); + QTest::newRow("firefox-14") << "a=b;expires=95-06-08 19:32:48 EDT" << cookie; + + // Edge cases caught by fuzzing + // These are about the default cause creates dates that don't exits + cookie.setExpirationDate(QDateTime(QDate(2030, 2, 25), QTime(1, 1, 0, 0), Qt::UTC)); + QTest::newRow("fuzz-0") << "a=b; expires=30 -000002 1:1 25;" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(2031, 11, 20), QTime(1, 1, 0, 0), Qt::UTC)); + QTest::newRow("fuzz-1") << "a=b; expires=31 11 20 1:1;" << cookie; + + // April only has 30 days + cookie.setExpirationDate(QDateTime(QDate(2031, 4, 30), QTime(1, 1, 0, 0), Qt::UTC)); + QTest::newRow("fuzz-2") << "a=b; expires=31 30 4 1:1" << cookie; + + // 9 must be the month so 31 can't be the day + cookie.setExpirationDate(QDateTime(QDate(2031, 9, 21), QTime(1, 1, 0, 0), Qt::UTC)); + QTest::newRow("fuzz-3") << "a=b; expires=31 21 9 1:1" << cookie; + + // Year is known, then fallback to defaults of filling in month and day + cookie.setExpirationDate(QDateTime(QDate(2031, 11, 1), QTime(1, 1, 0, 0), Qt::UTC)); + QTest::newRow("fuzz-4") << "a=b; expires=31 11 01 1:1" << cookie; + + // 2 must be the month so 30 can't be the day + cookie.setExpirationDate(QDateTime(QDate(2030, 2, 20), QTime(1, 1, 0, 0), Qt::UTC)); + QTest::newRow("fuzz-5") << "a=b; expires=30 02 20 1:1" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(2021, 12, 22), QTime(1, 1, 0, 0), Qt::UTC)); + QTest::newRow("fuzz-6") << "a=b; expires=2021 12 22 1:1" << cookie; + + cookie.setExpirationDate(QDateTime(QDate(2029, 2, 23), QTime(1, 1, 0, 0), Qt::UTC)); + QTest::newRow("fuzz-7") << "a=b; expires=29 23 Feb 1:1" << cookie; + + // 11 and 6 don't have 31 days + cookie.setExpirationDate(QDateTime(QDate(2031, 11, 06), QTime(1, 1, 0, 0), Qt::UTC)); + QTest::newRow("fuzz-8") << "a=b; expires=31 11 06 1:1" << cookie; + // two-digit years: // from 70 until 99, we assume 20th century + cookie.setExpirationDate(QDateTime(QDate(1999, 11, 9), QTime(23, 12, 40), Qt::UTC)); QTest::newRow("expiration-2digit1") << "a=b; expires=Wednesday, 09-Nov-99 23:12:40 GMT " << cookie; cookie.setExpirationDate(QDateTime(QDate(1970, 1, 1), QTime(23, 12, 40), Qt::UTC)); QTest::newRow("expiration-2digit2") << "a=b; expires=Thursday, 01-Jan-70 23:12:40 GMT " << cookie; @@ -340,6 +595,15 @@ void tst_QNetworkCookie::parseSingleCookie() result = QNetworkCookie::parseCookies(result.at(0).toRawForm()); QCOMPARE(result.count(), 1); + + // Drop any millisecond information, if there's any + QDateTime dt = expectedCookie.expirationDate(); + if (dt.isValid()) { + QTime t = dt.time(); + dt.setTime(t.addMSecs(-t.msec())); + expectedCookie.setExpirationDate(dt); + } + QCOMPARE(result.at(0), expectedCookie); } -- cgit v0.12 From 37b61133eed38dbb8a7b87fce18b6ea016469fdc Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 26 Mar 2009 16:00:53 +0100 Subject: Fix parsing of multiple cookies that are separated by a newline Signed-off-by: Peter Hartmann --- src/network/access/qnetworkcookie.cpp | 2 +- tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index 4846618..fed0afc 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -931,7 +931,7 @@ QList QNetworkCookie::parseCookies(const QByteArray &cookieStrin // When there are multiple SetCookie headers they are join with a new line // \n will always be the start of a new cookie - int endOfSetCookie = cookieString.indexOf('\n'); + int endOfSetCookie = cookieString.indexOf('\n', position); if (endOfSetCookie == -1) endOfSetCookie = length; diff --git a/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp b/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp index 2187b61..36a4b45 100644 --- a/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp +++ b/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp @@ -680,6 +680,26 @@ void tst_QNetworkCookie::parseMultipleCookies_data() list << cookie; QTest::newRow("network1") << "id=51706646077999719 bb=\"K14144t\"_AAQ\"ototrK_A_ttot44AQ4KwoRQtoto| adv=; Domain=.bluestreak.com; expires=Tuesday 05-Dec-2017 09:11:07 GMT; path=/;" << list; + QNetworkCookie cookieA; + cookieA.setName("a"); + cookieA.setValue("b"); + + QNetworkCookie cookieB; + cookieB.setName("c"); + cookieB.setValue("d"); + + // NewLine + cookieA.setExpirationDate(QDateTime(QDate(2009, 3, 10), QTime(7, 0, 0, 0), Qt::UTC)); + cookieB.setExpirationDate(QDateTime(QDate(2009, 3, 20), QTime(7, 0, 0, 0), Qt::UTC)); + list = QList() << cookieA << cookieB; + QTest::newRow("real-0") << "a=b; expires=Tue Mar 10 07:00:00 2009 GMT\nc=d; expires=Fri Mar 20 07:00:00 2009 GMT" << list; + QTest::newRow("real-1") << "a=b; expires=Tue Mar 10 07:00:00 2009 GMT\n\nc=d; expires=Fri Mar 20 07:00:00 2009 GMT" << list; + QTest::newRow("real-2") << "a=b; expires=Mar 10 07:00:00 2009 GMT, Tue\nc=d; expires=Fri Mar 20 07:00:00 2009 GMT" << list; + + // Match firefox's behavior + cookieA.setPath("/foo"); + list = QList() << cookieA << cookieB; + QTest::newRow("real-3") << "a=b; expires=Mar 10 07:00:00 2009 GMT, Tue; path=/foo\nc=d; expires=Fri Mar 20 07:00:00 2009 GMT" << list; } void tst_QNetworkCookie::parseMultipleCookies() -- cgit v0.12 From 1e7d1500e9351d8fc0cd7d3bc017e974aa45b035 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 30 Mar 2009 08:58:40 -0700 Subject: Compile with QT_NO_DIRECTFB_WM s/QDirectFBSurface/QDirectFBScreen/g Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp index 00d1781..4ba1102 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbsurface.cpp @@ -154,7 +154,7 @@ void QDirectFBSurface::setGeometry(const QRect &rect, const QRegion &mask) description.width = rect.width(); description.height = rect.height(); QDirectFBScreen::initSurfaceDescriptionPixelFormat(&description, - QDirectFBSurface::instance()->pixelFormat()); + QDirectFBScreen::instance()->pixelFormat()); dfbSurface = QDirectFBScreen::instance()->createDFBSurface(&description, false); } else { Q_ASSERT(dfbSurface); -- cgit v0.12 From 9340b75300d90d055056cdd68d10725de7829bdd Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 30 Mar 2009 09:00:49 -0700 Subject: Compile with QT_NO_DIRECTFB_PREALLOCATED Use the right surface for locking/unlocking. Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 87a5910..3a6b3a2 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -161,13 +161,13 @@ IDirectFBSurface* QDirectFBScreen::createDFBSurface(const QImage &img, SurfaceCr if (surface) { char *mem; int bpl; - surface->Lock(dfbSurface, DSLF_WRITE, (void**)&mem, &bpl); + surface->Lock(surface, DSLF_WRITE, (void**)&mem, &bpl); const int h = img.height(); for (int i = 0; i < h; ++i) { memcpy(mem, img.scanLine(i), bpl); mem += bpl; } - surface->Unlock(ret); + surface->Unlock(surface); } #endif #ifndef QT_NO_DIRECTFB_PALETTE -- cgit v0.12 From b91da630b8b1d043bd8ebe52df6fd9c562564d89 Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Mon, 30 Mar 2009 18:08:37 +0200 Subject: Doc: Swapping \a with \c to fix a qdoc warning --- src/corelib/io/qtextstream.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp index 512332e..ed9d0aa 100644 --- a/src/corelib/io/qtextstream.cpp +++ b/src/corelib/io/qtextstream.cpp @@ -1370,7 +1370,7 @@ QTextStream::FieldAlignment QTextStream::fieldAlignment() const \snippet doc/src/snippets/code/src_corelib_io_qtextstream.cpp 5 - The string \a s contains: + The string \c s contains: \snippet doc/src/snippets/code/src_corelib_io_qtextstream.cpp 6 -- cgit v0.12 From e475c68f22732553caad350608f2539db7694979 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 30 Mar 2009 18:11:04 +0200 Subject: Doc: Added a code snippet to illustrate the opening of local files. Task-number: 223087 Reviewed-by: TrustMe --- doc/src/snippets/code/src_gui_util_qdesktopservices.cpp | 5 ++++- src/gui/util/qdesktopservices.cpp | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/doc/src/snippets/code/src_gui_util_qdesktopservices.cpp b/doc/src/snippets/code/src_gui_util_qdesktopservices.cpp index a9c630b..5001984 100644 --- a/doc/src/snippets/code/src_gui_util_qdesktopservices.cpp +++ b/doc/src/snippets/code/src_gui_util_qdesktopservices.cpp @@ -11,7 +11,10 @@ public slots: QDesktopServices::setUrlHandler("help", helpInstance, "showHelp"); //! [0] - //! [1] mailto:user@foo.com?subject=Test&body=Just a test //! [1] + +//! [2] +QDesktopServices::openUrl(QUrl("file:///C:/Documents and Settings/All Users/Desktop", QUrl::TolerantMode)); +//! [2] diff --git a/src/gui/util/qdesktopservices.cpp b/src/gui/util/qdesktopservices.cpp index 0fe1d69..84aa16e 100644 --- a/src/gui/util/qdesktopservices.cpp +++ b/src/gui/util/qdesktopservices.cpp @@ -157,6 +157,11 @@ void QOpenUrlHandlerRegistry::handlerDestroyed(QObject *handler) If the URL is a reference to a local file (i.e., the URL scheme is "file") then it will be opened with a suitable application instead of a Web browser. + The following example opens a file on the Windows file system residing on a path + that contains spaces: + + \snippet doc/src/snippets/code/src_gui_util_qdesktopservices.cpp 2 + If a \c mailto URL is specified, the user's e-mail client will be used to open a composer window containing the options specified in the URL, similar to the way \c mailto links are handled by a Web browser. -- cgit v0.12 From ca119ee4b440c1ebbd456417a60167e2998de4d9 Mon Sep 17 00:00:00 2001 From: Benjamin C Meyer Date: Mon, 30 Mar 2009 18:45:50 +0200 Subject: Fix the parsing of October dates. The code was looking for a 't' to detect GMT-nnnn. It should really be checking for 'gmt'. Signed-off-by: Thiago Macieira --- src/network/access/qnetworkcookie.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index fed0afc..b82d8f9 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -636,8 +636,6 @@ static QDateTime parseDateString(const QByteArray &dateString) qDebug() << "Month:" << month; #endif at += 3; - if (at < dateString.length() && dateString[at] == '-') - ++at; continue; } // Zone @@ -659,7 +657,10 @@ static QDateTime parseDateString(const QByteArray &dateString) && (at == 0 || isWhitespace(dateString[at - 1]) || dateString[at - 1] == ',' - || (dateString[at - 1] == 't'))) { + || (at >= 3 + && (dateString[at - 3] == 'g') + && (dateString[at - 2] == 'm') + && (dateString[at - 1] == 't')))) { int end = 1; while (end < 5 && dateString.length() > at+end -- cgit v0.12 From 1f695f65df9d78dc10c0277a9914c65902168c1c Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 30 Mar 2009 15:12:55 -0700 Subject: Take out todos that have been done Clipping for drawLines works fine. textureBrushes are now accelerated Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index da4f367..90fc446 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -380,7 +380,6 @@ void QDirectFBPaintEnginePrivate::setPen(const QPen &p) void QDirectFBPaintEnginePrivate::setBrush(const QBrush &b) { - // TODO: accelerate texture pattern brush = b; simpleBrush = (brush.style() == Qt::NoBrush) || (brush.style() == Qt::SolidPattern && !antialiased); @@ -509,8 +508,6 @@ void QDirectFBPaintEnginePrivate::drawLines(const QLine *lines, int n) const for (int i = 0; i < n; ++i) { const QLine l = transform.map(lines[i]); - // TODO: clip! - regions[i].x1 = l.x1(); regions[i].y1 = l.y1(); regions[i].x2 = l.x2(); @@ -526,8 +523,6 @@ void QDirectFBPaintEnginePrivate::drawLines(const QLineF *lines, int n) const for (int i = 0; i < n; ++i) { const QLine l = transform.map(lines[i]).toLine(); - // TODO: clip! - regions[i].x1 = l.x1(); regions[i].y1 = l.y1(); regions[i].x2 = l.x2(); -- cgit v0.12 From 8c21eabd758e7350b6736d968d4a30b03e75b2c3 Mon Sep 17 00:00:00 2001 From: Bill King Date: Tue, 31 Mar 2009 13:16:54 +1000 Subject: Fixes: QPSQL: datetime or time fields with negative time zone offsets not handled correctly Now also removes negative timestamps. Task-number: 249059 Reviewed-by: Justin McPherson --- src/sql/drivers/psql/qsql_psql.cpp | 6 +++-- tests/auto/qsqldatabase/tst_qsqldatabase.cpp | 40 +++++++++++++++++++++++++--- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp index e33dd95..afe45fc 100644 --- a/src/sql/drivers/psql/qsql_psql.cpp +++ b/src/sql/drivers/psql/qsql_psql.cpp @@ -351,8 +351,9 @@ QVariant QPSQLResult::data(int i) #ifndef QT_NO_DATESTRING if (str.isEmpty()) return QVariant(QTime()); - if (str.at(str.length() - 3) == QLatin1Char('+')) + if (str.at(str.length() - 3) == QLatin1Char('+') || str.at(str.length() - 3) == QLatin1Char('-')) // strip the timezone + // TODO: fix this when timestamp support comes into QDateTime return QVariant(QTime::fromString(str.left(str.length() - 3), Qt::ISODate)); return QVariant(QTime::fromString(str, Qt::ISODate)); #else @@ -365,7 +366,8 @@ QVariant QPSQLResult::data(int i) if (dtval.length() < 10) return QVariant(QDateTime()); // remove the timezone - if (dtval.at(dtval.length() - 3) == QLatin1Char('+')) + // TODO: fix this when timestamp support comes into QDateTime + if (dtval.at(dtval.length() - 3) == QLatin1Char('+') || dtval.at(dtval.length() - 3) == QLatin1Char('-')) dtval.chop(3); // milliseconds are sometimes returned with 2 digits only if (dtval.at(dtval.length() - 3).isPunct()) diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index 349db65..d8ad15a 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -148,8 +148,10 @@ private slots: void psql_schemas(); void psql_escapedIdentifiers_data(){ psql_schemas_data(); } void psql_escapedIdentifiers(); - void psql_escapeBytea_data() { generic_data(); } + void psql_escapeBytea_data() { psql_schemas_data(); } void psql_escapeBytea(); + void bug_249059_data() { psql_schemas_data(); } + void bug_249059(); void mysqlOdbc_unsignedIntegers_data() { generic_data(); } void mysqlOdbc_unsignedIntegers(); @@ -337,7 +339,8 @@ void tst_QSqlDatabase::dropTestTables(QSqlDatabase db) << qTableName("qtestBindBool") << qTableName("qtest_sqlguid") << qTableName("uint_table") - << qTableName("uint_test"); + << qTableName("uint_test") + << qTableName("bug_249059"); QSqlQuery q(0, db); if (db.driverName().startsWith("QPSQL")) @@ -1594,7 +1597,6 @@ void tst_QSqlDatabase::psql_escapeBytea() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - DBMS_SPECIFIC(db, "QPSQL"); const char dta[4] = {'\x71', '\x14', '\x32', '\x81'}; QByteArray ba(dta, 4); @@ -1621,6 +1623,38 @@ void tst_QSqlDatabase::psql_escapeBytea() QCOMPARE(i, 4); } +void tst_QSqlDatabase::bug_249059() +{ + QFETCH(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + QSqlQuery q(db); + QString tableName = qTableName("bug_249059"); + QVERIFY_SQL(q, exec(QString("CREATE TABLE %1 (dt timestamp, t time)").arg(tableName))); + + QSqlQuery iq(db); + QVERIFY_SQL(iq, prepare(QString("INSERT INTO %1 VALUES (?, ?)").arg(tableName))); + iq.bindValue(0, QVariant(QString("2001-09-09 04:05:06.789 -5:00"))); + iq.bindValue(1, QVariant(QString("04:05:06.789 -5:00"))); + QVERIFY_SQL(iq, exec()); + iq.bindValue(0, QVariant(QString("2001-09-09 04:05:06.789 +5:00"))); + iq.bindValue(1, QVariant(QString("04:05:06.789 +5:00"))); + QVERIFY_SQL(iq, exec()); + + QVERIFY_SQL(q, exec(QString("SELECT dt, t FROM %1").arg(tableName))); + QVERIFY_SQL(q, next()); + QDateTime dt1=q.value(0).toDateTime(); + QTime t1=q.value(1).toTime(); + QVERIFY_SQL(q, next()); + QDateTime dt2=q.value(0).toDateTime(); + QTime t2=q.value(1).toTime(); + + // These will fail when timezone support is added, when that's the case, set the second record to 14:05:06.789 and it should work correctly + QCOMPARE(dt1, dt2); + QCOMPARE(t1, t2); +} + // This test should be rewritten to work with Oracle as well - or the Oracle driver // should be fixed to make this test pass (handle overflows) void tst_QSqlDatabase::precisionPolicy() -- cgit v0.12 From 4f197396e028ca0537643f7ae69f6951c498d672 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 31 Mar 2009 10:41:53 +0200 Subject: Add missing copyright headers and the "we mean it" section. These were reported by mkdist Reviewed-by: TrustMe --- tools/configure/tools.cpp | 41 ++++++++++++++++++++++++++ tools/configure/tools.h | 41 ++++++++++++++++++++++++++ tools/designer/src/lib/shared/plugindialog_p.h | 11 +++++++ 3 files changed, 93 insertions(+) diff --git a/tools/configure/tools.cpp b/tools/configure/tools.cpp index ae1ecda..5d12ea5 100644 --- a/tools/configure/tools.cpp +++ b/tools/configure/tools.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 tools applications 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 "tools.h" #include diff --git a/tools/configure/tools.h b/tools/configure/tools.h index e95ff13..68a439a 100644 --- a/tools/configure/tools.h +++ b/tools/configure/tools.h @@ -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 tools applications 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 _TOOLS_H_ #define _TOOLS_H_ diff --git a/tools/designer/src/lib/shared/plugindialog_p.h b/tools/designer/src/lib/shared/plugindialog_p.h index d50a804..a2601d4 100644 --- a/tools/designer/src/lib/shared/plugindialog_p.h +++ b/tools/designer/src/lib/shared/plugindialog_p.h @@ -42,6 +42,17 @@ #ifndef PLUGINDIALOG_H #define PLUGINDIALOG_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 "ui_plugindialog.h" QT_BEGIN_NAMESPACE -- cgit v0.12 From a0601e169c114f66c5fb932a6cc8606a8151bebc Mon Sep 17 00:00:00 2001 From: jasplin Date: Tue, 31 Mar 2009 11:05:06 +0200 Subject: compile on Linux. Reviewed-by: Samuel --- src/gui/text/qfontengine_ft.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 45a25a4..cb0b436 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -1051,7 +1051,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, Glyph Q_ASSERT(antialias); uchar *convoluted = new uchar[bitmap.rows*bitmap.pitch]; bool useLegacyLcdFilter = false; -#if defined(FT_LCD_FILTER_H) +#if defined(FC_LCD_FILTER) && defined(FT_LCD_FILTER_H) useLegacyLcdFilter = (lcdFilterType == FT_LCD_FILTER_LEGACY); #endif uchar *buffer = bitmap.buffer; -- cgit v0.12 From 3d370dc92466b010bfe6cdd82411f7e3d13da7c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Tue, 31 Mar 2009 11:07:07 +0200 Subject: Fix text drawing and perspective transforms for the Windows, PDF and PostScript print engines. The PDF/PostScript does not support perspective transforms, so it has to be emulated through our draw_helper() fallback. PostScript doesn't support alpha blending, so all perspective drawing needs to be forced through the alpha print engine. Task-number: 249754 Reviewed-by: Samuel --- src/gui/painting/qpaintengine_alpha.cpp | 12 ++++++++++-- src/gui/painting/qpaintengine_alpha_p.h | 1 + src/gui/painting/qpdf.cpp | 5 +++++ src/gui/painting/qprintengine_win.cpp | 2 +- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/gui/painting/qpaintengine_alpha.cpp b/src/gui/painting/qpaintengine_alpha.cpp index e38f6a4..74cbebe 100644 --- a/src/gui/painting/qpaintengine_alpha.cpp +++ b/src/gui/painting/qpaintengine_alpha.cpp @@ -80,6 +80,7 @@ bool QAlphaPaintEngine::begin(QPaintDevice *pdev) d->m_advancedPen = false; d->m_advancedBrush = false; d->m_complexTransform = false; + d->m_emulateProjectiveTransforms = false; // clear alpha region d->m_alphargn = QRegion(); @@ -116,6 +117,9 @@ void QAlphaPaintEngine::updateState(const QPaintEngineState &state) if (flags & QPaintEngine::DirtyTransform) { d->m_transform = state.transform(); d->m_complexTransform = (d->m_transform.type() > QTransform::TxScale); + d->m_emulateProjectiveTransforms = !(d->m_savedcaps & QPaintEngine::PerspectiveTransform) + && !(d->m_savedcaps & QPaintEngine::AlphaBlend) + && (d->m_transform.type() >= QTransform::TxProject); } if (flags & QPaintEngine::DirtyPen) { d->m_pen = state.pen(); @@ -163,7 +167,9 @@ void QAlphaPaintEngine::drawPath(const QPainterPath &path) if (d->m_pass == 0) { d->m_continueCall = false; - if (d->m_hasalpha || d->m_advancedPen || d->m_advancedBrush) { + if (d->m_hasalpha || d->m_advancedPen || d->m_advancedBrush + || d->m_emulateProjectiveTransforms) + { d->addAlphaRect(tr); } if (d->m_picengine) @@ -187,7 +193,9 @@ void QAlphaPaintEngine::drawPolygon(const QPointF *points, int pointCount, Polyg if (d->m_pass == 0) { d->m_continueCall = false; - if (d->m_hasalpha || d->m_advancedPen || d->m_advancedBrush) { + if (d->m_hasalpha || d->m_advancedPen || d->m_advancedBrush + || d->m_emulateProjectiveTransforms) + { d->addAlphaRect(tr); } diff --git a/src/gui/painting/qpaintengine_alpha_p.h b/src/gui/painting/qpaintengine_alpha_p.h index f510c73..f7d7a34 100644 --- a/src/gui/painting/qpaintengine_alpha_p.h +++ b/src/gui/painting/qpaintengine_alpha_p.h @@ -113,6 +113,7 @@ public: bool m_advancedPen; bool m_advancedBrush; bool m_complexTransform; + bool m_emulateProjectiveTransforms; bool m_continueCall; QTransform m_transform; diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index b010209..55006f6 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -1106,6 +1106,11 @@ void QPdfBaseEngine::drawTextItem(const QPointF &p, const QTextItem &textItem) if (!d->hasPen || (d->clipEnabled && d->allClipped)) return; + if (d->stroker.matrix.type() >= QTransform::TxProject) { + QPaintEngine::drawTextItem(p, textItem); + return; + } + *d->currentPage << "q\n"; if(!d->simplePen) *d->currentPage << QPdf::generateMatrix(d->stroker.matrix); diff --git a/src/gui/painting/qprintengine_win.cpp b/src/gui/painting/qprintengine_win.cpp index d48b525..c8674b7 100644 --- a/src/gui/painting/qprintengine_win.cpp +++ b/src/gui/painting/qprintengine_win.cpp @@ -369,7 +369,7 @@ void QWin32PrintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem QRgb brushColor = state->pen().brush().color().rgb(); bool fallBack = state->pen().brush().style() != Qt::SolidPattern || qAlpha(brushColor) != 0xff - || QT_WA_INLINE(false, d->txop >= QTransform::TxScale) + || QT_WA_INLINE(d->txop >= QTransform::TxProject, d->txop >= QTransform::TxScale) || ti.fontEngine->type() != QFontEngine::Win; -- cgit v0.12 From b311ebf246a0af16f851dd16c92594c238a0048f Mon Sep 17 00:00:00 2001 From: kh Date: Tue, 31 Mar 2009 11:49:24 +0200 Subject: fixes search for non latin1 characters while parsing html files, we removed some entities the should have been converted to there native representation, thus we were not able to find them Task-number: 247732 Reviewed-by: hjk --- .../lib/qhelpsearchindexreader_clucene.cpp | 114 ++++-- .../lib/qhelpsearchindexreader_clucene_p.h | 15 +- .../lib/qhelpsearchindexwriter_clucene.cpp | 408 ++++++++++++++++++++- 3 files changed, 482 insertions(+), 55 deletions(-) diff --git a/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp b/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp index 82a3a17..a1ba001 100644 --- a/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp +++ b/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp @@ -83,9 +83,8 @@ void QHelpSearchIndexReader::cancelSearching() mutex.unlock(); } -void QHelpSearchIndexReader::search(const QString &collectionFile, - const QString &indexFilesFolder, - const QList &queryList) +void QHelpSearchIndexReader::search(const QString &collectionFile, const QString &indexFilesFolder, + const QList &queryList) { QMutexLocker lock(&mutex); @@ -147,17 +146,16 @@ void QHelpSearchIndexReader::run() try { #endif QCLuceneBooleanQuery booleanQuery; - if (!buildQuery(booleanQuery, queryList)) { + QCLuceneStandardAnalyzer analyzer; + if (!buildQuery(booleanQuery, queryList, analyzer)) { emit searchingFinished(0); return; } const QStringList attribList = engine.filterAttributes(engine.currentFilter()); if (!attribList.isEmpty()) { - QCLuceneStandardAnalyzer analyzer; QCLuceneQuery* query = QCLuceneQueryParser::parse(QLatin1String("+") - + attribList.join(QLatin1String(" +")), QLatin1String("attribute"), - analyzer); + + attribList.join(QLatin1String(" +")), QLatin1String("attribute"), analyzer); if (!query) { emit searchingFinished(0); @@ -168,10 +166,26 @@ void QHelpSearchIndexReader::run() QCLuceneIndexSearcher indexSearcher(indexPath); QCLuceneHits hits = indexSearcher.search(booleanQuery); - const QStringList namespaceList = engine.registeredDocumentations(); + + bool boost = true; + QCLuceneBooleanQuery tryHarderQuery; + if (hits.length() == 0) { + if (buildTryHarderQuery(tryHarderQuery, queryList, analyzer)) { + if (!attribList.isEmpty()) { + QCLuceneQuery* query = QCLuceneQueryParser::parse(QLatin1String("+") + + attribList.join(QLatin1String(" +")), QLatin1String("attribute"), + analyzer); + tryHarderQuery.add(query, true, true, false); + } + hits = indexSearcher.search(tryHarderQuery); + boost = (hits.length() == 0); + } + } QSet pathSet; QCLuceneDocument document; + const QStringList namespaceList = engine.registeredDocumentations(); + for (qint32 i = 0; i < hits.length(); i++) { document = hits.document(i); const QString path = document.get(QLatin1String("path")); @@ -192,8 +206,8 @@ void QHelpSearchIndexReader::run() } indexSearcher.close(); - int count = hitList.count(); - if (count > 0) + const int count = hitList.count(); + if ((count > 0) && boost) boostSearchHits(engine, hitList, queryList); emit searchingFinished(hitList.count()); @@ -206,11 +220,9 @@ void QHelpSearchIndexReader::run() } } -bool QHelpSearchIndexReader::defaultQuery(const QString &term, - QCLuceneBooleanQuery &booleanQuery) +bool QHelpSearchIndexReader::defaultQuery(const QString &term, QCLuceneBooleanQuery &booleanQuery, + QCLuceneStandardAnalyzer &analyzer) { - QCLuceneStandardAnalyzer analyzer; - const QLatin1String c("content"); const QLatin1String t("titleTokenized"); @@ -226,21 +238,23 @@ bool QHelpSearchIndexReader::defaultQuery(const QString &term, } bool QHelpSearchIndexReader::buildQuery(QCLuceneBooleanQuery &booleanQuery, - const QList &queryList) + const QList &queryList, QCLuceneStandardAnalyzer &analyzer) { foreach (const QHelpSearchQuery query, queryList) { switch (query.fieldName) { case QHelpSearchQuery::FUZZY: { const QLatin1String fuzzy("~"); - foreach (const QString term, query.wordList) { - if (term.isEmpty() || !defaultQuery(term.toLower() + fuzzy, booleanQuery)) + foreach (const QString &term, query.wordList) { + if (term.isEmpty() + || !defaultQuery(term.toLower() + fuzzy, booleanQuery, analyzer)) { return false; + } } } break; case QHelpSearchQuery::WITHOUT: { QStringList stopWords = QCLuceneStopAnalyzer().englishStopWords(); - foreach (const QString term, query.wordList) { + foreach (const QString &term, query.wordList) { if (stopWords.contains(term, Qt::CaseInsensitive)) continue; @@ -259,14 +273,14 @@ bool QHelpSearchIndexReader::buildQuery(QCLuceneBooleanQuery &booleanQuery, } break; case QHelpSearchQuery::PHRASE: { - const QString term = query.wordList.at(0).toLower(); + const QString &term = query.wordList.at(0).toLower(); if (term.contains(QLatin1Char(' '))) { QStringList termList = term.split(QLatin1String(" ")); QCLucenePhraseQuery *q = new QCLucenePhraseQuery(); QStringList stopWords = QCLuceneStopAnalyzer().englishStopWords(); - foreach (const QString t, termList) { - if (!stopWords.contains(t, Qt::CaseInsensitive)) - q->addTerm(QCLuceneTerm(QLatin1String("content"), t.toLower())); + foreach (const QString &term, termList) { + if (!stopWords.contains(term, Qt::CaseInsensitive)) + q->addTerm(QCLuceneTerm(QLatin1String("content"), term.toLower())); } booleanQuery.add(q, true, true, false); } else { @@ -286,7 +300,7 @@ bool QHelpSearchIndexReader::buildQuery(QCLuceneBooleanQuery &booleanQuery, case QHelpSearchQuery::ALL: { QStringList stopWords = QCLuceneStopAnalyzer().englishStopWords(); - foreach (const QString term, query.wordList) { + foreach (const QString &term, query.wordList) { if (stopWords.contains(term, Qt::CaseInsensitive)) continue; @@ -302,9 +316,8 @@ bool QHelpSearchIndexReader::buildQuery(QCLuceneBooleanQuery &booleanQuery, } break; case QHelpSearchQuery::DEFAULT: { - QCLuceneStandardAnalyzer analyzer; - foreach (const QString t, query.wordList) { - QCLuceneQuery *query = QCLuceneQueryParser::parse(t.toLower(), + foreach (const QString &term, query.wordList) { + QCLuceneQuery *query = QCLuceneQueryParser::parse(term.toLower(), QLatin1String("content"), analyzer); if (query) @@ -313,8 +326,8 @@ bool QHelpSearchIndexReader::buildQuery(QCLuceneBooleanQuery &booleanQuery, } break; case QHelpSearchQuery::ATLEAST: { - foreach (const QString term, query.wordList) { - if (term.isEmpty() || !defaultQuery(term.toLower(), booleanQuery)) + foreach (const QString &term, query.wordList) { + if (term.isEmpty() || !defaultQuery(term.toLower(), booleanQuery, analyzer)) return false; } } @@ -324,16 +337,38 @@ bool QHelpSearchIndexReader::buildQuery(QCLuceneBooleanQuery &booleanQuery, return true; } +bool QHelpSearchIndexReader::buildTryHarderQuery(QCLuceneBooleanQuery &booleanQuery, + const QList &queryList, QCLuceneStandardAnalyzer &analyzer) +{ + bool retVal = false; + foreach (const QHelpSearchQuery query, queryList) { + switch (query.fieldName) { + default: break; + case QHelpSearchQuery::DEFAULT: { + foreach (const QString &term, query.wordList) { + QCLuceneQuery *query = QCLuceneQueryParser::parse(term.toLower(), + QLatin1String("content"), analyzer); + + if (query) { + retVal = true; + booleanQuery.add(query, true, false, false); + } + } + } break; + } + } + return retVal; +} + void QHelpSearchIndexReader::boostSearchHits(const QHelpEngineCore &engine, - QList &hitList, - const QList &queryList) + QList &hitList, const QList &queryList) { foreach (const QHelpSearchQuery query, queryList) { if (query.fieldName != QHelpSearchQuery::DEFAULT) continue; QString joinedQuery = query.wordList.join(QLatin1String(" ")); - + QCLuceneStandardAnalyzer analyzer; QCLuceneQuery *parsedQuery = QCLuceneQueryParser::parse( joinedQuery, QLatin1String("content"), analyzer); @@ -351,8 +386,7 @@ void QHelpSearchIndexReader::boostSearchHits(const QHelpEngineCore &engine, QStringList searchTerms; while (index != -1) { nextIndex = joinedQuery.indexOf(QLatin1String("content:"), index + 1); - term = joinedQuery.mid(index + length, nextIndex - (length + index)) - .simplified(); + term = joinedQuery.mid(index + length, nextIndex - (length + index)).simplified(); if (term.startsWith(QLatin1String("\"")) && term.endsWith(QLatin1String("\""))) { searchTerms.append(term.remove(QLatin1String("\""))); @@ -370,17 +404,19 @@ void QHelpSearchIndexReader::boostSearchHits(const QHelpEngineCore &engine, QString data = QString::fromUtf8(engine.fileData(hit.first)); int counter = 0; - foreach (const QString& term, searchTerms) + foreach (const QString &term, searchTerms) counter += data.count(term, Qt::CaseInsensitive); hitMap.insertMulti(counter, hit); } QList boostedList; - QMap::const_iterator i; - for (i = hitMap.constEnd(), --i; i != hitMap.constBegin(); --i) - boostedList.append(i.value()); - boostedList += hitList.mid(count - 1, hitList.count()); - + QMap::const_iterator it = hitMap.constEnd(); + do { + --it; + boostedList.append(it.value()); + } while (it != hitMap.constBegin()); + boostedList += hitList.mid(count, hitList.count()); + hitList = boostedList; } } diff --git a/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h b/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h index 892c4e6..f7536e9 100644 --- a/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h +++ b/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h @@ -54,6 +54,8 @@ // #include "qhelpsearchengine.h" + +#include "fulltextsearch/qanalyzer_p.h" #include "fulltextsearch/qquery_p.h" #include @@ -93,12 +95,13 @@ signals: private: void run(); - bool defaultQuery(const QString &term, - QCLuceneBooleanQuery &booleanQuery); - bool buildQuery(QCLuceneBooleanQuery &booleanQuery, - const QList &queryList); - void boostSearchHits(const QHelpEngineCore &engine, - QList &hitList, + bool defaultQuery(const QString &term, QCLuceneBooleanQuery &booleanQuery, + QCLuceneStandardAnalyzer &analyzer); + bool buildQuery(QCLuceneBooleanQuery &booleanQuery, const QList &queryList, + QCLuceneStandardAnalyzer &analyzer); + bool buildTryHarderQuery(QCLuceneBooleanQuery &booleanQuery, + const QList &queryList, QCLuceneStandardAnalyzer &analyzer); + void boostSearchHits(const QHelpEngineCore &engine, QList &hitList, const QList &queryList); private: diff --git a/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp b/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp index e53bbae..195c490 100644 --- a/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp +++ b/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp @@ -59,16 +59,340 @@ #include #include +#include "private/qfunctions_p.h" + QT_BEGIN_NAMESPACE namespace qt { namespace fulltextsearch { namespace clucene { +// taken from qtexthtmlparser +static const struct QTextHtmlEntity +{ + const char *name; + quint16 code; +} entities[] = { + { "AElig", 0x00c6 }, + { "AMP", 38 }, + { "Aacute", 0x00c1 }, + { "Acirc", 0x00c2 }, + { "Agrave", 0x00c0 }, + { "Alpha", 0x0391 }, + { "Aring", 0x00c5 }, + { "Atilde", 0x00c3 }, + { "Auml", 0x00c4 }, + { "Beta", 0x0392 }, + { "Ccedil", 0x00c7 }, + { "Chi", 0x03a7 }, + { "Dagger", 0x2021 }, + { "Delta", 0x0394 }, + { "ETH", 0x00d0 }, + { "Eacute", 0x00c9 }, + { "Ecirc", 0x00ca }, + { "Egrave", 0x00c8 }, + { "Epsilon", 0x0395 }, + { "Eta", 0x0397 }, + { "Euml", 0x00cb }, + { "GT", 62 }, + { "Gamma", 0x0393 }, + { "Iacute", 0x00cd }, + { "Icirc", 0x00ce }, + { "Igrave", 0x00cc }, + { "Iota", 0x0399 }, + { "Iuml", 0x00cf }, + { "Kappa", 0x039a }, + { "LT", 60 }, + { "Lambda", 0x039b }, + { "Mu", 0x039c }, + { "Ntilde", 0x00d1 }, + { "Nu", 0x039d }, + { "OElig", 0x0152 }, + { "Oacute", 0x00d3 }, + { "Ocirc", 0x00d4 }, + { "Ograve", 0x00d2 }, + { "Omega", 0x03a9 }, + { "Omicron", 0x039f }, + { "Oslash", 0x00d8 }, + { "Otilde", 0x00d5 }, + { "Ouml", 0x00d6 }, + { "Phi", 0x03a6 }, + { "Pi", 0x03a0 }, + { "Prime", 0x2033 }, + { "Psi", 0x03a8 }, + { "QUOT", 34 }, + { "Rho", 0x03a1 }, + { "Scaron", 0x0160 }, + { "Sigma", 0x03a3 }, + { "THORN", 0x00de }, + { "Tau", 0x03a4 }, + { "Theta", 0x0398 }, + { "Uacute", 0x00da }, + { "Ucirc", 0x00db }, + { "Ugrave", 0x00d9 }, + { "Upsilon", 0x03a5 }, + { "Uuml", 0x00dc }, + { "Xi", 0x039e }, + { "Yacute", 0x00dd }, + { "Yuml", 0x0178 }, + { "Zeta", 0x0396 }, + { "aacute", 0x00e1 }, + { "acirc", 0x00e2 }, + { "acute", 0x00b4 }, + { "aelig", 0x00e6 }, + { "agrave", 0x00e0 }, + { "alefsym", 0x2135 }, + { "alpha", 0x03b1 }, + { "amp", 38 }, + { "and", 0x22a5 }, + { "ang", 0x2220 }, + { "apos", 0x0027 }, + { "aring", 0x00e5 }, + { "asymp", 0x2248 }, + { "atilde", 0x00e3 }, + { "auml", 0x00e4 }, + { "bdquo", 0x201e }, + { "beta", 0x03b2 }, + { "brvbar", 0x00a6 }, + { "bull", 0x2022 }, + { "cap", 0x2229 }, + { "ccedil", 0x00e7 }, + { "cedil", 0x00b8 }, + { "cent", 0x00a2 }, + { "chi", 0x03c7 }, + { "circ", 0x02c6 }, + { "clubs", 0x2663 }, + { "cong", 0x2245 }, + { "copy", 0x00a9 }, + { "crarr", 0x21b5 }, + { "cup", 0x222a }, + { "curren", 0x00a4 }, + { "dArr", 0x21d3 }, + { "dagger", 0x2020 }, + { "darr", 0x2193 }, + { "deg", 0x00b0 }, + { "delta", 0x03b4 }, + { "diams", 0x2666 }, + { "divide", 0x00f7 }, + { "eacute", 0x00e9 }, + { "ecirc", 0x00ea }, + { "egrave", 0x00e8 }, + { "empty", 0x2205 }, + { "emsp", 0x2003 }, + { "ensp", 0x2002 }, + { "epsilon", 0x03b5 }, + { "equiv", 0x2261 }, + { "eta", 0x03b7 }, + { "eth", 0x00f0 }, + { "euml", 0x00eb }, + { "euro", 0x20ac }, + { "exist", 0x2203 }, + { "fnof", 0x0192 }, + { "forall", 0x2200 }, + { "frac12", 0x00bd }, + { "frac14", 0x00bc }, + { "frac34", 0x00be }, + { "frasl", 0x2044 }, + { "gamma", 0x03b3 }, + { "ge", 0x2265 }, + { "gt", 62 }, + { "hArr", 0x21d4 }, + { "harr", 0x2194 }, + { "hearts", 0x2665 }, + { "hellip", 0x2026 }, + { "iacute", 0x00ed }, + { "icirc", 0x00ee }, + { "iexcl", 0x00a1 }, + { "igrave", 0x00ec }, + { "image", 0x2111 }, + { "infin", 0x221e }, + { "int", 0x222b }, + { "iota", 0x03b9 }, + { "iquest", 0x00bf }, + { "isin", 0x2208 }, + { "iuml", 0x00ef }, + { "kappa", 0x03ba }, + { "lArr", 0x21d0 }, + { "lambda", 0x03bb }, + { "lang", 0x2329 }, + { "laquo", 0x00ab }, + { "larr", 0x2190 }, + { "lceil", 0x2308 }, + { "ldquo", 0x201c }, + { "le", 0x2264 }, + { "lfloor", 0x230a }, + { "lowast", 0x2217 }, + { "loz", 0x25ca }, + { "lrm", 0x200e }, + { "lsaquo", 0x2039 }, + { "lsquo", 0x2018 }, + { "lt", 60 }, + { "macr", 0x00af }, + { "mdash", 0x2014 }, + { "micro", 0x00b5 }, + { "middot", 0x00b7 }, + { "minus", 0x2212 }, + { "mu", 0x03bc }, + { "nabla", 0x2207 }, + { "nbsp", 0x00a0 }, + { "ndash", 0x2013 }, + { "ne", 0x2260 }, + { "ni", 0x220b }, + { "not", 0x00ac }, + { "notin", 0x2209 }, + { "nsub", 0x2284 }, + { "ntilde", 0x00f1 }, + { "nu", 0x03bd }, + { "oacute", 0x00f3 }, + { "ocirc", 0x00f4 }, + { "oelig", 0x0153 }, + { "ograve", 0x00f2 }, + { "oline", 0x203e }, + { "omega", 0x03c9 }, + { "omicron", 0x03bf }, + { "oplus", 0x2295 }, + { "or", 0x22a6 }, + { "ordf", 0x00aa }, + { "ordm", 0x00ba }, + { "oslash", 0x00f8 }, + { "otilde", 0x00f5 }, + { "otimes", 0x2297 }, + { "ouml", 0x00f6 }, + { "para", 0x00b6 }, + { "part", 0x2202 }, + { "percnt", 0x0025 }, + { "permil", 0x2030 }, + { "perp", 0x22a5 }, + { "phi", 0x03c6 }, + { "pi", 0x03c0 }, + { "piv", 0x03d6 }, + { "plusmn", 0x00b1 }, + { "pound", 0x00a3 }, + { "prime", 0x2032 }, + { "prod", 0x220f }, + { "prop", 0x221d }, + { "psi", 0x03c8 }, + { "quot", 34 }, + { "rArr", 0x21d2 }, + { "radic", 0x221a }, + { "rang", 0x232a }, + { "raquo", 0x00bb }, + { "rarr", 0x2192 }, + { "rceil", 0x2309 }, + { "rdquo", 0x201d }, + { "real", 0x211c }, + { "reg", 0x00ae }, + { "rfloor", 0x230b }, + { "rho", 0x03c1 }, + { "rlm", 0x200f }, + { "rsaquo", 0x203a }, + { "rsquo", 0x2019 }, + { "sbquo", 0x201a }, + { "scaron", 0x0161 }, + { "sdot", 0x22c5 }, + { "sect", 0x00a7 }, + { "shy", 0x00ad }, + { "sigma", 0x03c3 }, + { "sigmaf", 0x03c2 }, + { "sim", 0x223c }, + { "spades", 0x2660 }, + { "sub", 0x2282 }, + { "sube", 0x2286 }, + { "sum", 0x2211 }, + { "sup", 0x2283 }, + { "sup1", 0x00b9 }, + { "sup2", 0x00b2 }, + { "sup3", 0x00b3 }, + { "supe", 0x2287 }, + { "szlig", 0x00df }, + { "tau", 0x03c4 }, + { "there4", 0x2234 }, + { "theta", 0x03b8 }, + { "thetasym", 0x03d1 }, + { "thinsp", 0x2009 }, + { "thorn", 0x00fe }, + { "tilde", 0x02dc }, + { "times", 0x00d7 }, + { "trade", 0x2122 }, + { "uArr", 0x21d1 }, + { "uacute", 0x00fa }, + { "uarr", 0x2191 }, + { "ucirc", 0x00fb }, + { "ugrave", 0x00f9 }, + { "uml", 0x00a8 }, + { "upsih", 0x03d2 }, + { "upsilon", 0x03c5 }, + { "uuml", 0x00fc }, + { "weierp", 0x2118 }, + { "xi", 0x03be }, + { "yacute", 0x00fd }, + { "yen", 0x00a5 }, + { "yuml", 0x00ff }, + { "zeta", 0x03b6 }, + { "zwj", 0x200d }, + { "zwnj", 0x200c } +}; + +Q_STATIC_GLOBAL_OPERATOR bool operator<(const QString &entityStr, const QTextHtmlEntity &entity) +{ + return entityStr < QLatin1String(entity.name); +} + +Q_STATIC_GLOBAL_OPERATOR bool operator<(const QTextHtmlEntity &entity, const QString &entityStr) +{ + return QLatin1String(entity.name) < entityStr; +} + +static QChar resolveEntity(const QString &entity) +{ + const QTextHtmlEntity *start = &entities[0]; + const QTextHtmlEntity *end = &entities[(sizeof(entities) / sizeof(entities[0]))]; + const QTextHtmlEntity *e = qBinaryFind(start, end, entity); + if (e == end) + return QChar(); + return e->code; +} + +static const uint latin1Extended[0xA0 - 0x80] = { + 0x20ac, // 0x80 + 0x0081, // 0x81 direct mapping + 0x201a, // 0x82 + 0x0192, // 0x83 + 0x201e, // 0x84 + 0x2026, // 0x85 + 0x2020, // 0x86 + 0x2021, // 0x87 + 0x02C6, // 0x88 + 0x2030, // 0x89 + 0x0160, // 0x8A + 0x2039, // 0x8B + 0x0152, // 0x8C + 0x008D, // 0x8D direct mapping + 0x017D, // 0x8E + 0x008F, // 0x8F directmapping + 0x0090, // 0x90 directmapping + 0x2018, // 0x91 + 0x2019, // 0x92 + 0x201C, // 0x93 + 0X201D, // 0x94 + 0x2022, // 0x95 + 0x2013, // 0x96 + 0x2014, // 0x97 + 0x02DC, // 0x98 + 0x2122, // 0x99 + 0x0161, // 0x9A + 0x203A, // 0x9B + 0x0153, // 0x9C + 0x009D, // 0x9D direct mapping + 0x017E, // 0x9E + 0x0178 // 0x9F +}; +// end taken from qtexthtmlparser + class DocumentHelper { public: - DocumentHelper(const QString& fileName, const QByteArray &data) + DocumentHelper(const QString &fileName, const QByteArray &data) : fileName(fileName) , data(readData(data)) {} ~DocumentHelper() {} @@ -131,8 +455,15 @@ private: while (j < length) { c = buf[j++]; if (c == QLatin1Char('<') || c == QLatin1Char('&')) { - if (count > 1) + if (count > 1 && c != QLatin1Char('&')) parsedContent.append(QLatin1Char(' ')); + else if (c == QLatin1Char('&')) { + // Note: this will modify the counter j, in case we sucessful parsed the entity + // we will have modified the counter to stay 1 before the closing ';', so + // the following if condition will be met with if (c == QLatin1Char(';')) + parsedContent.append(parseEntity(length, buf, j)); + } + count = 0; valid = false; continue; @@ -157,6 +488,63 @@ private: return parsedContent; } + // taken from qtexthtmlparser + // parses an entity after "&", and returns it + QString parseEntity(int len, const QChar *buf, int &pos) const + { + int recover = pos; + QString entity; + while (pos < len) { + QChar c = buf[pos++]; + if (c.isSpace() || pos - recover > 9) { + goto error; + } + if (c == QLatin1Char(';')) { + pos--; + break; + } + entity += c; + } + { + QChar resolved = resolveEntity(entity); + if (!resolved.isNull()) + return QString(resolved); + } + if (entity.length() > 1 && entity.at(0) == QLatin1Char('#')) { + entity.remove(0, 1); // removing leading # + + int base = 10; + bool ok = false; + + if (entity.at(0).toLower() == QLatin1Char('x')) { // hex entity? + entity.remove(0, 1); + base = 16; + } + + uint uc = entity.toUInt(&ok, base); + if (ok) { + if (uc >= 0x80 && uc < 0x80 + (sizeof(latin1Extended) / sizeof(latin1Extended[0]))) + uc = latin1Extended[uc - 0x80]; // windows latin 1 extended + QString str; + if (uc > 0xffff) { + // surrogate pair + uc -= 0x10000; + ushort high = uc/0x400 + 0xd800; + ushort low = uc%0x400 + 0xdc00; + str.append(QChar(high)); + str.append(QChar(low)); + } else { + str.append(QChar(uc)); + } + return str; + } + } + error: + pos = recover; + return QLatin1String(" "); + } + // end taken from qtexthtmlparser + private: QString fileName; QString data; @@ -239,7 +627,7 @@ void QHelpSearchIndexWriter::run() // old style qhc file < 4.4.2, need to convert... const QStringList indexedNamespaces = engine.customValue(oldKey). toString().split(QLatin1String("|"), QString::SkipEmptyParts); - foreach (const QString& nameSpace, indexedNamespaces) + foreach (const QString &nameSpace, indexedNamespaces) indexMap.insert(nameSpace, QDateTime()); engine.removeCustomValue(oldKey); } else { @@ -294,7 +682,7 @@ void QHelpSearchIndexWriter::run() } if (QCLuceneIndexReader::indexExists(indexPath) && !reindex) { - foreach(const QString& namespaceName, registeredDocs) { + foreach(const QString &namespaceName, registeredDocs) { mutexLocker.relock(); if (m_cancel) { emit indexingFinished(); @@ -342,7 +730,7 @@ void QHelpSearchIndexWriter::run() writer->setMaxFieldLength(QCLuceneIndexWriter::DEFAULT_MAX_FIELD_LENGTH); QStringList namespaces; - foreach(const QString& namespaceName, registeredDocs) { + foreach(const QString &namespaceName, registeredDocs) { mutexLocker.relock(); if (m_cancel) { writer->close(); @@ -367,7 +755,7 @@ void QHelpSearchIndexWriter::run() break; } else { bool bail = false; - foreach (const QStringList& attributes, attributeSets) { + foreach (const QStringList &attributes, attributeSets) { const QList docFiles = indexableFiles(&engine, namespaceName, attributes); if (!addDocuments(docFiles, engine, attributes, namespaceName, @@ -397,7 +785,7 @@ void QHelpSearchIndexWriter::run() mutexLocker.unlock(); QStringList indexedNamespaces = indexMap.keys(); - foreach(const QString& namespaceName, indexedNamespaces) { + foreach(const QString &namespaceName, indexedNamespaces) { mutexLocker.relock(); if (m_cancel) break; @@ -422,7 +810,7 @@ bool QHelpSearchIndexWriter::addDocuments(const QList docFiles, const QString attrList = attributes.join(QLatin1String(" ")); locker.unlock(); - foreach(const QUrl& url, docFiles) { + foreach(const QUrl &url, docFiles) { QCLuceneDocument document; DocumentHelper helper(url.toString(), engine.fileData(url)); if (helper.addFieldsToDocument(&document, namespaceName, attrList)) @@ -450,8 +838,8 @@ void QHelpSearchIndexWriter::removeDocuments(const QString &indexPath, reader.close(); } -bool QHelpSearchIndexWriter::writeIndexMap(QHelpEngineCore& engine, - const QMap& indexMap) +bool QHelpSearchIndexWriter::writeIndexMap(QHelpEngineCore &engine, + const QMap &indexMap) { QByteArray bArray; -- cgit v0.12 From 665c4c1e587daf3b2880f5f1802a0bb8a3f10e2b Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Tue, 31 Mar 2009 13:02:15 +0200 Subject: Doc - marking QPrintDialog::printer(), setPrinter() and addButton() as Unix only functions, part of Qt 3 Support. Task-number: 248752 and 245244 Reviewed-by: Simon Hausmann --- doc/src/qprintdialog.qdoc | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/doc/src/qprintdialog.qdoc b/doc/src/qprintdialog.qdoc index 6cac1c9..a4cd18b 100644 --- a/doc/src/qprintdialog.qdoc +++ b/doc/src/qprintdialog.qdoc @@ -39,26 +39,34 @@ ** ****************************************************************************/ +#ifdef QT3_SUPPORT /*! - \fn QPrinter *QPrintDialog::printer() const + \fn QPrinter *QPrintDialog::printer() const - Returns a pointer to the printer this dialog configures, or 0 if - this dialog does not operate on any printer. + Returns a pointer to the printer this dialog configures, or 0 if + this dialog does not operate on any printer. + + This function is available for Unix platforms only. */ /*! - \fn void QPrintDialog::setPrinter(QPrinter *printer, bool pickupSettings) + \fn void QPrintDialog::setPrinter(QPrinter *printer, bool pickupSettings) + + Sets this dialog to configure printer \a printer, or no printer if \a printer + is null. If \a pickupSettings is true, the dialog reads most of + its settings from \a printer. If \a pickupSettings is false (the + default) the dialog keeps its old settings. - Sets this dialog to configure printer \a printer, or no printer if \a printer - is null. If \a pickupSettings is true, the dialog reads most of - its settings from \a printer. If \a pickupSettings is false (the - default) the dialog keeps its old settings. + This function is available for Unix platforms only. */ /*! - \fn void QPrintDialog::addButton(QPushButton *button) + \fn void QPrintDialog::addButton(QPushButton *button) + + Adds the \a button to the layout of the print dialog. The added + buttons are arranged from the left to the right below the + last groupbox of the printdialog. - Adds the \a button to the layout of the print dialog. The added - buttons are arranged from the left to the right below the - last groupbox of the printdialog. + This function is available for Unix platforms only. */ +#endif -- cgit v0.12 From 6efb2e5836da7f83ec484bc93230649d027fb0c9 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Tue, 31 Mar 2009 13:56:03 +0200 Subject: Add Windows7 and Snow Leopard as values QSysInfo. It's likely these OS's will show up before we are done with 4.5, so it is worthwhile to have these values here, so that both we and other developers can do nice things with them. Reviewed-by: Prasanth Ullattil --- src/corelib/global/qglobal.cpp | 21 +++++++++++++++------ src/corelib/global/qglobal.h | 6 +++++- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 08ecf3c..68c213e 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -1054,6 +1054,7 @@ bool qSharedBuild() \value WV_XP Windows XP (operating system version 5.1) \value WV_2003 Windows Server 2003, Windows Server 2003 R2, Windows Home Server, Windows XP Professional x64 Edition (operating system version 5.2) \value WV_VISTA Windows Vista, Windows Server 2008 (operating system version 6.0) + \value WV_WINDOWS7 Windows 7 (operating system version 6.1) Alternatively, you may use the following macros which correspond directly to the Windows operating system version number: @@ -1062,6 +1063,7 @@ bool qSharedBuild() \value WV_5_1 Operating system version 5.1, corresponds to Windows XP \value WV_5_2 Operating system version 5.2, corresponds to Windows Server 2003, Windows Server 2003 R2, Windows Home Server, and Windows XP Professional x64 Edition \value WV_6_0 Operating system version 6.0, corresponds to Windows Vista and Windows Server 2008 + \value WV_6_1 Operating system version 6.1, corresponds to Windows 7 CE-based versions: @@ -1095,6 +1097,7 @@ bool qSharedBuild() \value MV_10_3 Mac OS X 10.3 \value MV_10_4 Mac OS X 10.4 \value MV_10_5 Mac OS X 10.5 + \value MV_10_6 Mac OS X 10.6 \value MV_Unknown An unknown and currently unsupported platform \value MV_CHEETAH Apple codename for MV_10_0 @@ -1103,6 +1106,7 @@ bool qSharedBuild() \value MV_PANTHER Apple codename for MV_10_3 \value MV_TIGER Apple codename for MV_10_4 \value MV_LEOPARD Apple codename for MV_10_5 + \value MV_SNOWLEOPARD Apple codename for MV_10_6 \sa WinVersion */ @@ -1631,16 +1635,19 @@ QSysInfo::WinVersion QSysInfo::windowsVersion() default: // VER_PLATFORM_WIN32_NT if (osver.dwMajorVersion < 5) { winver = QSysInfo::WV_NT; - } else if (osver.dwMajorVersion == 6) { - winver = QSysInfo::WV_VISTA; - } else if (osver.dwMinorVersion == 0) { + } else if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 0) { winver = QSysInfo::WV_2000; - } else if (osver.dwMinorVersion == 1) { + } else if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 1) { winver = QSysInfo::WV_XP; - } else if (osver.dwMinorVersion == 2) { + } else if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 2) { winver = QSysInfo::WV_2003; + } else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 0) { + winver = QSysInfo::WV_VISTA; + } else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 1) { + winver = QSysInfo::WV_WINDOWS7; } else { - qWarning("Qt: Untested Windows version detected!"); + qWarning("Qt: Untested Windows version %d.%d detected!", + osver.dwMajorVersion, osver.dwMinorVersion); winver = QSysInfo::WV_NT_based; } } @@ -1667,6 +1674,8 @@ QSysInfo::WinVersion QSysInfo::windowsVersion() winver = QSysInfo::WV_XP; else if (override == "VISTA") winver = QSysInfo::WV_VISTA; + else if (override == "WINDOWS7") + winver = QSysInfo::WV_WINDOWS7; } #endif diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 210f713..81af295 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1309,6 +1309,7 @@ public: WV_XP = 0x0030, WV_2003 = 0x0040, WV_VISTA = 0x0080, + WV_WINDOWS7 = 0x0090, WV_NT_based = 0x00f0, /* version numbers */ @@ -1317,6 +1318,7 @@ public: WV_5_1 = WV_XP, WV_5_2 = WV_2003, WV_6_0 = WV_VISTA, + WV_6_1 = WV_WINDOWS7, WV_CE = 0x0100, WV_CENET = 0x0200, @@ -1340,6 +1342,7 @@ public: MV_10_3 = 0x0005, MV_10_4 = 0x0006, MV_10_5 = 0x0007, + MV_10_6 = 0x0008, /* codenames */ MV_CHEETAH = MV_10_0, @@ -1347,7 +1350,8 @@ public: MV_JAGUAR = MV_10_2, MV_PANTHER = MV_10_3, MV_TIGER = MV_10_4, - MV_LEOPARD = MV_10_5 + MV_LEOPARD = MV_10_5, + MV_SNOWLEOPARD = MV_10_6 }; static const MacVersion MacintoshVersion; #endif -- cgit v0.12 From b620b46ec07879c1baa35d59f3baa00fde88a3b8 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Tue, 31 Mar 2009 14:13:12 +0200 Subject: Detailed description of QMetaType contradicts documentation of QMetaType::type() QMetaType::type() returns 0 for unknown types, not -1. Task-number: 248890 Reviewed By: Kavindra Devi Palaraja --- doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp b/doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp index 355a237..783852b 100644 --- a/doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp +++ b/doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp @@ -33,7 +33,7 @@ MyStruct s2 = var.value(); //! [3] int id = QMetaType::type("MyClass"); -if (id != -1) { +if (id == 0) { void *myClassPtr = QMetaType::construct(id); ... QMetaType::destroy(id, myClassPtr); -- cgit v0.12 From 9562f4a39ca9ca2c59bd621ac8e33af8b8006043 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Tue, 31 Mar 2009 14:42:45 +0200 Subject: Fix bug in QDirIterator that clear the cache of the fileinfo We basically store the currentFileInfo and use another one to continue moving into the dir. Task-number: 247645 Reviewed-by: Olivier --- src/corelib/io/qdiriterator.cpp | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index 46c7dd8..a2c5321 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -116,7 +116,9 @@ public: QAbstractFileEngine *engine; QStack fileEngineIterators; QString path; - QFileInfo fileInfo; + QFileInfo nextFileInfo; + //This fileinfo is the current that we will return from the public API + QFileInfo currentFileInfo; QString currentFilePath; QDirIterator::IteratorFlags iteratorFlags; QDir::Filters filters; @@ -140,8 +142,8 @@ QDirIteratorPrivate::QDirIteratorPrivate(const QString &path, const QStringList this->filters = filters; this->nameFilters = nameFilters; - fileInfo.setFile(path); - pushSubDirectory(fileInfo.isSymLink() ? fileInfo.canonicalFilePath() : path, + nextFileInfo.setFile(path); + pushSubDirectory(nextFileInfo.isSymLink() ? nextFileInfo.canonicalFilePath() : path, nameFilters, filters); } @@ -160,12 +162,12 @@ void QDirIteratorPrivate::pushSubDirectory(const QString &path, const QStringLis QDir::Filters filters) { if (iteratorFlags & QDirIterator::FollowSymlinks) { - if (fileInfo.filePath() != path) - fileInfo.setFile(path); - if (fileInfo.isSymLink()) { - visitedLinks << fileInfo.canonicalFilePath(); + if (nextFileInfo.filePath() != path) + nextFileInfo.setFile(path); + if (nextFileInfo.isSymLink()) { + visitedLinks << nextFileInfo.canonicalFilePath(); } else { - visitedLinks << fileInfo.absoluteFilePath(); + visitedLinks << nextFileInfo.absoluteFilePath(); } } @@ -213,15 +215,16 @@ void QDirIteratorPrivate::advance() while (it->hasNext()) { it->next(); if (matchesFilters(it)) { - fileInfo = it->currentFileInfo(); + currentFileInfo = nextFileInfo; + nextFileInfo = it->currentFileInfo(); // Signal that we want to follow this entry. - followNextDir = shouldFollowDirectory(fileInfo); - + followNextDir = shouldFollowDirectory(nextFileInfo); //We found a matching entry. return; } else if (iteratorFlags & QDirIterator::Subdirectories) { QFileInfo fileInfo = it->currentFileInfo(); + if (!shouldFollowDirectory(fileInfo)) continue; QString subDir = it->currentFilePath(); @@ -238,6 +241,7 @@ void QDirIteratorPrivate::advance() if (!foundDirectory) delete fileEngineIterators.pop(); } + currentFileInfo = nextFileInfo; done = true; } @@ -518,9 +522,7 @@ bool QDirIterator::hasNext() const */ QString QDirIterator::fileName() const { - if (d->fileInfo.path() != d->currentFilePath) - d->fileInfo.setFile(d->currentFilePath); - return d->fileInfo.fileName(); + return d->currentFileInfo.fileName(); } /*! @@ -543,9 +545,7 @@ QString QDirIterator::filePath() const */ QFileInfo QDirIterator::fileInfo() const { - if (d->fileInfo.filePath() != d->currentFilePath) - d->fileInfo.setFile(d->currentFilePath); - return d->fileInfo; + return d->currentFileInfo; } /*! -- cgit v0.12 From 2d13592054d1d6f049ecc1599913cb8c7541ef69 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Tue, 31 Mar 2009 15:19:07 +0200 Subject: QProcess::start() segfaults on empty program Handle cases where QProcess::start() and startDetached() are passed a null, empty, or "invalid" program string instead of crashing. Task-number: 247865 Reviewed-by: Andreas Aardal Hanssen --- src/corelib/io/qprocess.cpp | 9 +++++++++ tests/auto/qprocess/tst_qprocess.cpp | 26 ++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index a9d8ee2..f16f996 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -1601,6 +1601,13 @@ static QStringList parseCombinedArgString(const QString &program) void QProcess::start(const QString &program, OpenMode mode) { QStringList args = parseCombinedArgString(program); + if (args.isEmpty()) { + Q_D(QProcess); + d->processError = QProcess::FailedToStart; + setErrorString(tr("No program defined")); + emit error(d->processError); + return; + } QString prog = args.first(); args.removeFirst(); @@ -1769,6 +1776,8 @@ bool QProcess::startDetached(const QString &program, bool QProcess::startDetached(const QString &program) { QStringList args = parseCombinedArgString(program); + if (args.isEmpty()) + return false; QString prog = args.first(); args.removeFirst(); diff --git a/tests/auto/qprocess/tst_qprocess.cpp b/tests/auto/qprocess/tst_qprocess.cpp index f0dae5d..cb2b1bf 100644 --- a/tests/auto/qprocess/tst_qprocess.cpp +++ b/tests/auto/qprocess/tst_qprocess.cpp @@ -139,6 +139,8 @@ private slots: void switchReadChannels(); void setWorkingDirectory(); void startFinishStartFinish(); + void invalidProgramString_data(); + void invalidProgramString(); // keep these at the end, since they use lots of processes and sometimes // caused obscure failures to occur in tests that followed them (esp. on the Mac) @@ -2000,5 +2002,29 @@ void tst_QProcess::startFinishStartFinish() } } +//----------------------------------------------------------------------------- +void tst_QProcess::invalidProgramString_data() +{ + QTest::addColumn("programString"); + QTest::newRow("null string") << QString(); + QTest::newRow("empty string") << QString(""); + QTest::newRow("only blank string") << QString(" "); +} + +void tst_QProcess::invalidProgramString() +{ + QFETCH(QString, programString); + QProcess process; + + qRegisterMetaType("QProcess::ProcessError"); + QSignalSpy spy(&process, SIGNAL(error(QProcess::ProcessError))); + + process.start(programString); + QCOMPARE(process.error(), QProcess::FailedToStart); + QCOMPARE(spy.count(), 1); + + QVERIFY(!QProcess::startDetached(programString)); +} + QTEST_MAIN(tst_QProcess) #include "tst_qprocess.moc" -- cgit v0.12 From 0aaf811061f86c1b09670fff1e304d997bd34411 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Tue, 31 Mar 2009 16:34:00 +0200 Subject: Get the qt7 phonon plugin to minimally compile on 10.6 We need to protect some overridden type and that is done in qmacdefines_mac.h, so just include that. To top this off, a function has changed that was introduced in 10.5. In order to use it properly, we would need to do lots of version checking and shuffling between types and it seems like more trouble that it's worth at the moment. We may have to do that in the future, but we'll deal with that then. --- src/3rdparty/phonon/qt7/audionode.mm | 16 +++++++++------- src/3rdparty/phonon/qt7/backendinfo.mm | 1 + src/3rdparty/phonon/qt7/quicktimevideoplayer.h | 1 + 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/3rdparty/phonon/qt7/audionode.mm b/src/3rdparty/phonon/qt7/audionode.mm index cb9e82f..961230c 100644 --- a/src/3rdparty/phonon/qt7/audionode.mm +++ b/src/3rdparty/phonon/qt7/audionode.mm @@ -68,13 +68,15 @@ void AudioNode::createAndConnectAUNodes() << QString(!FindNextComponent(0, &description) ? "ERROR: COMPONENT NOT FOUND!" : "OK!")) OSStatus err = noErr; -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) - err = AUGraphAddNode(m_audioGraph->audioGraphRef(), &description, &m_auNode); - else -#endif - err = AUGraphNewNode(m_audioGraph->audioGraphRef(), &description, 0, 0, &m_auNode); - + + // The proper function to call here is AUGraphAddNode() but the type has + // changed between 10.5 and 10.6. it's still OK to call this function, but + // if we want to use the proper thing we need to move over to + // AudioComponentDescription everywhere, which is very similar to the + // ComponentDescription, but a different size. however, + // AudioComponentDescription only exists on 10.6+. More fun than we need to + // deal with at the moment, so we'll take the "deprecated" warning instead. + err = AUGraphNewNode(m_audioGraph->audioGraphRef(), &description, 0, 0, &m_auNode); BACKEND_ASSERT2(err != kAUGraphErr_OutputNodeErr, "A MediaObject can only be connected to one audio output device.", FATAL_ERROR) BACKEND_ASSERT2(err == noErr, "Could not create new AUNode.", FATAL_ERROR) } diff --git a/src/3rdparty/phonon/qt7/backendinfo.mm b/src/3rdparty/phonon/qt7/backendinfo.mm index e173f05..0d51db0 100644 --- a/src/3rdparty/phonon/qt7/backendinfo.mm +++ b/src/3rdparty/phonon/qt7/backendinfo.mm @@ -22,6 +22,7 @@ #include #include +#include #import #ifdef QUICKTIME_C_API_AVAILABLE diff --git a/src/3rdparty/phonon/qt7/quicktimevideoplayer.h b/src/3rdparty/phonon/qt7/quicktimevideoplayer.h index 0b3aec2..b80570a 100644 --- a/src/3rdparty/phonon/qt7/quicktimevideoplayer.h +++ b/src/3rdparty/phonon/qt7/quicktimevideoplayer.h @@ -20,6 +20,7 @@ #include "backendheader.h" +#include #import #import -- cgit v0.12 From 69c6f94c6cd6320a02ade785bb8ac5f02c1204de Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 31 Mar 2009 14:55:33 +0200 Subject: Doc: Removed a reference to a deprecated function. Reported by a former Doc Manager. Reviewed-by: TrustMe --- src/gui/dialogs/qcolordialog.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/dialogs/qcolordialog.cpp b/src/gui/dialogs/qcolordialog.cpp index b744dca..3aa04f6 100644 --- a/src/gui/dialogs/qcolordialog.cpp +++ b/src/gui/dialogs/qcolordialog.cpp @@ -1523,10 +1523,10 @@ static const Qt::WindowFlags DefaultWindowFlags = If you require a modeless dialog, use the QColorDialog constructor. \endomit - The static getColor() function shows the dialog, and allows the - user to specify a color. The getRgba() function does the same, but - also allows the user to specify a color with an alpha channel - (transparency) value. + The static getColor() function shows the dialog, and allows the user to + specify a color. This function can also be used to let users choose a + color with a level of transparency: pass the ShowAlphaChannel option as + an additional argument. The user can store customCount() different custom colors. The custom colors are shared by all color dialogs, and remembered -- cgit v0.12 From 1b9ed030accb14783ad269ced6897779022273ad Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 31 Mar 2009 16:53:36 +0200 Subject: Doc: Clarified that the main use case for QRegion is as a clipping primitive not as a rendering primitive. Task-number: 183493 Reviewed-by: TrustMe --- src/gui/painting/qregion.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp index 8169ef8..c88af7c 100644 --- a/src/gui/painting/qregion.cpp +++ b/src/gui/painting/qregion.cpp @@ -65,9 +65,17 @@ QT_BEGIN_NAMESPACE \ingroup shared QRegion is used with QPainter::setClipRegion() to limit the paint - area to what needs to be painted. There is also a - QWidget::repaint() function that takes a QRegion parameter. - QRegion is the best tool for reducing flicker. + area to what needs to be painted. There is also a QWidget::repaint() + function that takes a QRegion parameter. QRegion is the best tool for + minimizing the amount of screen area to be updated by a repaint. + + This class is not suitable for constructing shapes for rendering, especially + as outlines. Use QPainterPath to create paths and shapes for use with + QPainter. + + QRegion is an \l{implicitly shared} class. + + \section1 Creating and Using Regions A region can be created from a rectangle, an ellipse, a polygon or a bitmap. Complex regions may be created by combining simple @@ -84,8 +92,6 @@ QT_BEGIN_NAMESPACE Example of using complex regions: \snippet doc/src/snippets/code/src_gui_painting_qregion.cpp 0 - QRegion is an \l{implicitly shared} class. - \warning Due to window system limitations, the whole coordinate space for a region is limited to the points between -32767 and 32767 on Windows 95/98/ME. You can circumvent this limitation by using a QPainterPath. @@ -93,7 +99,7 @@ QT_BEGIN_NAMESPACE \section1 Additional License Information On Embedded Linux, Windows CE and X11 platforms, parts of this class rely on - code obtained under the following license: + code obtained under the following licenses: \legalese Copyright (c) 1987 X Consortium @@ -120,9 +126,7 @@ QT_BEGIN_NAMESPACE in this Software without prior written authorization from the X Consortium. \endlegalese - \raw HTML -
- \endraw + \br \legalese Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. -- cgit v0.12 From fb0c8a29f5ab04ac1a4697e2ae12eccea4dbca7e Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 31 Mar 2009 17:35:33 +0200 Subject: Doc: Noted the difference between the qLowerBound() functions. Task-number: 160621 Reviewed-by: TrustMe --- doc/src/qalgorithms.qdoc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/src/qalgorithms.qdoc b/doc/src/qalgorithms.qdoc index 459fb81..b33c250 100644 --- a/doc/src/qalgorithms.qdoc +++ b/doc/src/qalgorithms.qdoc @@ -490,7 +490,10 @@ of \a value in the variable passed as a reference in argument \a n. \overload - This is the same as qLowerBound(\a{container}.begin(), \a{container}.end(), value); + For read-only iteration over containers, this function is broadly equivalent to + qLowerBound(\a{container}.begin(), \a{container}.end(), value). However, since it + returns a const iterator, you cannot use it to modify the container; for example, + to insert items. */ /*! \fn RandomAccessIterator qUpperBound(RandomAccessIterator begin, RandomAccessIterator end, const T &value) -- cgit v0.12 From 9d4ddc4c1eb9c0aba31f99a0e8beb6f5a13188ca Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 31 Mar 2009 17:38:40 +0200 Subject: Doc: Made it clearer that QProcess::start() only starts a new process if one is not already running. Task-number: 231513 Reviewed-by: TrustMe --- src/corelib/io/qprocess.cpp | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index f16f996..a128482 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -1476,11 +1476,15 @@ QByteArray QProcess::readAllStandardError() } /*! - Starts the program \a program in a new process, passing the - command line arguments in \a arguments. The OpenMode is set to \a - mode. QProcess will immediately enter the Starting state. If the - process starts successfully, QProcess will emit started(); - otherwise, error() will be emitted. + Starts the program \a program in a new process, if one is not already + running, passing the command line arguments in \a arguments. The OpenMode + is set to \a mode. + + The QProcess object will immediately enter the Starting state. If the + process starts successfully, QProcess will emit started(); otherwise, + error() will be emitted. If the QProcess object is already running a + process, a warning may be printed at the console, and the existing + process will continue running. Note that arguments that contain spaces are not passed to the process as separate arguments. @@ -1577,10 +1581,10 @@ static QStringList parseCombinedArgString(const QString &program) /*! \overload - Starts the program \a program in a new process. \a program is a - single string of text containing both the program name and its - arguments. The arguments are separated by one or more - spaces. For example: + Starts the program \a program in a new process, if one is not already + running. \a program is a single string of text containing both the + program name and its arguments. The arguments are separated by one or + more spaces. For example: \snippet doc/src/snippets/code/src_corelib_io_qprocess.cpp 5 @@ -1589,6 +1593,9 @@ static QStringList parseCombinedArgString(const QString &program) \snippet doc/src/snippets/code/src_corelib_io_qprocess.cpp 6 + If the QProcess object is already running a process, a warning may be + printed at the console, and the existing process will continue running. + Note that, on Windows, quotes need to be both escaped and quoted. For example, the above code would be specified in the following way to ensure that \c{"My Documents"} is used as the argument to -- cgit v0.12 From 12849e1767f3f881c9060368c3a14fae6e5a9ef1 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Tue, 31 Mar 2009 00:26:10 -0700 Subject: Prevent crash on resizing The crash was caused by out-of-bounds reading on the raster engine's clipping structures since our size had changed size last lock. This code makes sure the clipData structures are atleast as tall as the current height of the paint device. Reviewed-by: Tom Cooksey --- .../gfxdrivers/directfb/qdirectfbpaintengine.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 90fc446..450c7f4 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -243,6 +243,7 @@ public: SurfaceCache *surfaceCache; QTransform transform; + int lastLockedHeight; private: // QRegion rectsToClippedRegion(const QRect *rects, int n) const; // QRegion rectsToClippedRegion(const QRectF *rects, int n) const; @@ -267,9 +268,9 @@ private: QDirectFBPaintEnginePrivate::QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p) : surface(0), antialiased(false), forceRasterPrimitives(false), simplePen(false), - simpleBrush(false), matrixRotShear(false), matrixScale(false), fbWidth(-1), fbHeight(-1), - opacity(255), drawFlags(0), blitFlags(0), duffFlags(0), dirtyFlags(false), dirtyClip(true), - dfbHandledClip(false), dfbDevice(0), q(p) + 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) { fb = QDirectFBScreen::instance()->dfb(); surfaceCache = new SurfaceCache; @@ -311,6 +312,8 @@ void QDirectFBPaintEnginePrivate::lock() // We will potentially get a new pointer to the buffer after a // lock so we need to call the base implementation of prepare so // it updates its rasterBuffer to point to the new buffer address. + lastLockedHeight = dfbDevice->height(); + Q_ASSERT(dfbDevice); prepare(dfbDevice); } @@ -330,6 +333,7 @@ void QDirectFBPaintEnginePrivate::setTransform(const QTransform &m) void QDirectFBPaintEnginePrivate::begin(QPaintDevice *device) { + lastLockedHeight = -1; if (device->devType() == QInternal::CustomRaster) dfbDevice = static_cast(device); else if (device->devType() == QInternal::Pixmap) { @@ -927,6 +931,9 @@ void QDirectFBPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) { Q_D(QDirectFBPaintEngine); d->setClipDirty(); + const QPoint bottom = d->transform.map(QPoint(0, path.controlPointRect().y2)); + if (bottom.y() >= d->lastLockedHeight) + d->lock(); QRasterPaintEngine::clip(path, op); } @@ -934,10 +941,15 @@ void QDirectFBPaintEngine::clip(const QRect &rect, Qt::ClipOperation op) { Q_D(QDirectFBPaintEngine); d->setClipDirty(); + if (!d->clip()->hasRectClip && d->clip()->enabled) { + const QPoint bottom = d->transform.map(QPoint(0, rect.bottom())); + if (bottom.y() >= d->lastLockedHeight) + d->lock(); + } + QRasterPaintEngine::clip(rect, op); } - void QDirectFBPaintEngine::drawRects(const QRect *rects, int rectCount) { Q_D(QDirectFBPaintEngine); -- cgit v0.12 From 810bbcd38e8f829ccc6702f5cdf2bb97bbca97cc Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 30 Mar 2009 21:51:33 -0700 Subject: No sense in detecting the format twice Use the format passed in to the function rather than detecting it again based on hasAlphaChannel(). Reviewed-by: Tom Cooksey --- src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 3a6b3a2..fd6f48a 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -249,14 +249,10 @@ IDirectFBSurface* QDirectFBScreen::createDFBSurface(const DFBSurfaceDescription } IDirectFBSurface *QDirectFBScreen::copyToDFBSurface(const QImage &img, - QImage::Format format, + QImage::Format pixmapFormat, SurfaceCreationOptions options) { QImage image = img; - const QImage::Format pixmapFormat = image.hasAlphaChannel() - ? QDirectFBScreen::alphaPixmapFormat() - : QDirectFBScreen::pixelFormat(); - if (QDirectFBScreen::getSurfacePixelFormat(image.format()) == DSPF_UNKNOWN #ifdef QT_NO_DIRECTFB_PREALLOCATED || image.format() != pixmapFormat @@ -266,7 +262,7 @@ IDirectFBSurface *QDirectFBScreen::copyToDFBSurface(const QImage &img, } - IDirectFBSurface *dfbSurface = createDFBSurface(img.size(), format, options); + IDirectFBSurface *dfbSurface = createDFBSurface(img.size(), pixmapFormat, options); if (!dfbSurface) { qWarning("QDirectFBPixmapData::fromImage() Couldn't create surface"); return 0; -- cgit v0.12 From c2417c61aeda9de8a8e4c876ea42d6076d4078b0 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Tue, 31 Mar 2009 10:27:59 -0700 Subject: Remove these convenience functions. They only make sense under the assumption that there most of the time is no transform. With Falcon this isn't really the case. Reviewed-by: Tom Cooksey --- .../gfxdrivers/directfb/qdirectfbpaintengine.cpp | 34 ++++++++-------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index 450c7f4..b8354d9 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -61,17 +61,6 @@ static inline uint ALPHA_MUL(uint x, uint a) return t; } -static inline QRect mapRect(const QTransform &transform, const QRect &rect) -{ - return (transform.isIdentity() ? rect : transform.mapRect(rect)); -} - -static inline QRect mapRect(const QTransform &transform, const QRectF &rect) -{ - return (transform.isIdentity() ? rect : transform.mapRect(rect)). - toRect(); -} - class SurfaceCache { public: @@ -542,7 +531,7 @@ QRegion QDirectFBPaintEnginePrivate::rectsToClippedRegion(const QRect *rects, QRegion region; for (int i = 0; i < n; ++i) { - const QRect r = ::mapRect(transform, rects[i]); + const QRect r = transform.mapRect(rects[i]); region += clip & r; } @@ -555,7 +544,7 @@ QRegion QDirectFBPaintEnginePrivate::rectsToClippedRegion(const QRectF *rects, QRegion region; for (int i = 0; i < n; ++i) { - const QRect r = ::mapRect(transform, rects[i]); + const QRect r = transform.mapRect(rects[i]).toRect(); region += clip & r; } @@ -584,7 +573,7 @@ void QDirectFBPaintEnginePrivate::fillRects(const QRect *rects, int n) const { QVarLengthArray dfbRects(n); for (int i = 0; i < n; ++i) { - const QRect r = ::mapRect(transform, rects[i]); + const QRect r = transform.mapRect(rects[i]); dfbRects[i].x = r.x(); dfbRects[i].y = r.y(); dfbRects[i].w = r.width(); @@ -597,7 +586,7 @@ void QDirectFBPaintEnginePrivate::fillRects(const QRectF *rects, int n) const { QVarLengthArray dfbRects(n); for (int i = 0; i < n; ++i) { - const QRect r = ::mapRect(transform, rects[i]); + const QRect r = transform.mapRect(rects[i]).toRect(); dfbRects[i].x = r.x(); dfbRects[i].y = r.y(); dfbRects[i].w = r.width(); @@ -609,7 +598,7 @@ void QDirectFBPaintEnginePrivate::fillRects(const QRectF *rects, int n) const void QDirectFBPaintEnginePrivate::drawRects(const QRect *rects, int n) const { for (int i = 0; i < n; ++i) { - const QRect r = ::mapRect(transform, rects[i]); + const QRect r = transform.mapRect(rects[i]); surface->DrawRectangle(surface, r.x(), r.y(), r.width() + 1, r.height() + 1); } @@ -618,7 +607,7 @@ void QDirectFBPaintEnginePrivate::drawRects(const QRect *rects, int n) const void QDirectFBPaintEnginePrivate::drawRects(const QRectF *rects, int n) const { for (int i = 0; i < n; ++i) { - const QRect r = ::mapRect(transform, rects[i]); + const QRect r = transform.mapRect(rects[i]).toRect(); surface->DrawRectangle(surface, r.x(), r.y(), r.width() + 1, r.height() + 1); } @@ -642,7 +631,7 @@ void QDirectFBPaintEnginePrivate::drawPixmap(const QRectF &dest, QDirectFBPixmapData *dfbData = static_cast(data); IDirectFBSurface *s = dfbData->directFBSurface(); const QRect sr = src.toRect(); - const QRect dr = ::mapRect(transform, dest); + const QRect dr = transform.mapRect(dest).toRect(); const DFBRectangle sRect = { sr.x(), sr.y(), sr.width(), sr.height() }; DFBResult result; @@ -674,6 +663,7 @@ void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, Q_ASSERT(data->classId() == QPixmapData::DirectFBClass); QDirectFBPixmapData *dfbData = static_cast(data); IDirectFBSurface *s = dfbData->directFBSurface(); + const QRect dr = transform.mapRect(dest).toRect(); const QRect dr = ::mapRect(transform, dest); DFBResult result = DFB_OK; @@ -696,7 +686,7 @@ void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, result = surface->BatchBlit(surface, s, rects.constData(), points.constData(), points.size()); } else { - const QRect sr = ::mapRect(transform, QRect(0, 0, pixmap.width(), pixmap.height())); + const QRect sr = transform.mapRect(QRect(0, 0, pixmap.width(), pixmap.height())); const int dx = sr.width(); const int dy = sr.height(); const DFBRectangle sRect = { 0, 0, dx, dy }; @@ -769,7 +759,7 @@ void QDirectFBPaintEnginePrivate::drawImage(const QRectF &dest, } const QRect sr = src.toRect(); - const QRect dr = ::mapRect(transform, 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); @@ -1197,7 +1187,7 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) d->unlock(); d->updateFlags(); d->setDFBColor(brush.color()); - const QRect r = ::mapRect(d->transform, rect); + const QRect r = d->transform.mapRect(rect).toRect(); d->surface->FillRectangle(d->surface, r.x(), r.y(), r.width(), r.height()); return; } @@ -1229,7 +1219,7 @@ void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QColor &color) d->unlock(); d->updateFlags(); d->setDFBColor(color); - const QRect r = ::mapRect(d->transform, rect); + const QRect r = d->transform.mapRect(rect).toRect(); d->surface->FillRectangle(d->surface, r.x(), r.y(), r.width(), r.height()); } -- cgit v0.12 From 4d878fe43bef5ff6387c3bb73587315efa21424d Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Tue, 31 Mar 2009 10:40:34 -0700 Subject: Compile I messed up the cherry-pick merge and left one of these in. Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp index b8354d9..3b6ea80 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpaintengine.cpp @@ -664,7 +664,6 @@ void QDirectFBPaintEnginePrivate::drawTiledPixmap(const QRectF &dest, QDirectFBPixmapData *dfbData = static_cast(data); IDirectFBSurface *s = dfbData->directFBSurface(); const QRect dr = transform.mapRect(dest).toRect(); - const QRect dr = ::mapRect(transform, dest); DFBResult result = DFB_OK; if (!matrixScale && dr == QRect(0, 0, fbWidth, fbHeight)) { -- cgit v0.12 From ac96e93728541897203a8d1bcbdf9e43c4af8758 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Tue, 31 Mar 2009 19:53:21 +0200 Subject: Doc: Fixed the screenshots and example description to match the code. Task-number: 242369 Reviewed-by: TrustMe --- doc/src/examples/extension.qdoc | 11 +++++------ doc/src/images/extension-example.png | Bin 7676 -> 9929 bytes doc/src/images/extension_more.png | Bin 9309 -> 13523 bytes 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/doc/src/examples/extension.qdoc b/doc/src/examples/extension.qdoc index 8a0ca3a..02e0698 100644 --- a/doc/src/examples/extension.qdoc +++ b/doc/src/examples/extension.qdoc @@ -80,9 +80,9 @@ user type a word to search for, we need several \l {QCheckBox}{QCheckBox}es to facilitate the search options, and we need three \l {QPushButton}{QPushButton}s: the \gui Find button to - start a search, the \gui More button to enable an advanced search, - and the \gui Close button to exit the application. Finally, we - need a QWidget representing the application's extension part. + start a search and the \gui More button to enable an advanced search. + Finally, we need a QWidget representing the application's extension + part. \section1 FindDialog Class Implementation @@ -128,8 +128,7 @@ the connection makes sure that the extension widget is shown depending on the state of \gui More button. - We also connect the \gui Close button to the QWidget::close() - slot, and we put the checkboxes associated with the advanced + We also put the check boxes associated with the advanced search options into a layout we install on the extension widget. \snippet examples/dialogs/extension/finddialog.cpp 4 @@ -137,7 +136,7 @@ Before we create the main layout, we create several child layouts for the widgets: First we allign the QLabel ans its buddy, the QLineEdit, using a QHBoxLayout. Then we vertically allign the - QLabel and QLineEdit with the checkboxes associated with the + QLabel and QLineEdit with the check boxes associated with the simple search, using a QVBoxLayout. We also create a QVBoxLayout for the buttons. In the end we lay out the two latter layouts and the extension widget using a QGridLayout. diff --git a/doc/src/images/extension-example.png b/doc/src/images/extension-example.png index dfaacc0..18fab52 100644 Binary files a/doc/src/images/extension-example.png and b/doc/src/images/extension-example.png differ diff --git a/doc/src/images/extension_more.png b/doc/src/images/extension_more.png index 2b06809..407af27 100644 Binary files a/doc/src/images/extension_more.png and b/doc/src/images/extension_more.png differ -- cgit v0.12 From ba8c15b71b006ddb5c74f0c97288d98541221328 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Tue, 31 Mar 2009 22:53:52 +0200 Subject: Subject: Compile fix on Windows Reviewed-by: Anders Bakken --- src/corelib/io/qdiriterator.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index a2c5321..b14f436 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -201,8 +201,8 @@ void QDirIteratorPrivate::advance() QString subDir = it->currentFilePath(); #ifdef Q_OS_WIN - if (fileInfo.isSymLink()) - subDir = fileInfo.canonicalFilePath(); + if (currentFileInfo.isSymLink()) + subDir = currentFileInfo.canonicalFilePath(); #endif pushSubDirectory(subDir, it->nameFilters(), it->filters()); } -- cgit v0.12 From 831d2742b7c41924f052acd81620e8bfc58afde7 Mon Sep 17 00:00:00 2001 From: Bill King Date: Wed, 1 Apr 2009 14:09:00 +1000 Subject: DB Autotest cleanup Make db autotest data set generation more consistent, slightly faster. Also, add ability to easily generate a set of a single databases entries worth of criteria to test. --- tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp | 20 ++- .../q3sqlselectcursor/tst_q3sqlselectcursor.cpp | 12 +- tests/auto/qsqldatabase/tst_qsqldatabase.cpp | 158 +++++-------------- tests/auto/qsqlquery/tst_qsqlquery.cpp | 95 +++--------- tests/auto/qsqlquerymodel/tst_qsqlquerymodel.cpp | 12 +- tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp | 167 +++++++++++---------- tests/auto/qsqlthread/tst_qsqlthread.cpp | 10 +- 7 files changed, 182 insertions(+), 292 deletions(-) diff --git a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp index c06485d..2d91186 100644 --- a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp +++ b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp @@ -89,7 +89,7 @@ private slots: void unicode(); void precision_data() { generic_data(); } void precision(); - void insertORA_data(); + void insertORA_data() { generic_data("QOCI"); } void insertORA(); void batchInsert_data() { generic_data(); } void batchInsert(); @@ -101,7 +101,7 @@ private slots: void insertFieldNameContainsWS(); // For task 117996 private: - void generic_data(); + void generic_data(const QString &engine=QString()); void createTestTables( QSqlDatabase db ); void dropTestTables( QSqlDatabase db ); void populateTestTables( QSqlDatabase db ); @@ -117,10 +117,14 @@ tst_Q3SqlCursor::~tst_Q3SqlCursor() { } -void tst_Q3SqlCursor::generic_data() +void tst_Q3SqlCursor::generic_data(const QString &engine) { - if ( dbs.fillTestTable() == 0 ) - QSKIP( "No database drivers are available in this Qt configuration", SkipAll ); + if ( dbs.fillTestTable(engine) == 0 ) { + if(engine.isEmpty()) + QSKIP( "No database drivers are available in this Qt configuration", SkipAll ); + else + QSKIP( (QString("No database drivers of type %1 are available in this Qt configuration").arg(engine)).toLocal8Bit(), SkipAll ); + } } void tst_Q3SqlCursor::createTestTables( QSqlDatabase db ) @@ -429,12 +433,6 @@ static QString dumpUtf8( const QString& str ) return res; } -void tst_Q3SqlCursor::insertORA_data() -{ - if ( dbs.fillTestTable( "QOCI" ) == 0 ) - QSKIP( "No Oracle database drivers are available in this Qt configuration", SkipAll ); -} - void tst_Q3SqlCursor::insertORA() { QFETCH( QString, dbName ); diff --git a/tests/auto/q3sqlselectcursor/tst_q3sqlselectcursor.cpp b/tests/auto/q3sqlselectcursor/tst_q3sqlselectcursor.cpp index a8c5940..9ab74f0 100644 --- a/tests/auto/q3sqlselectcursor/tst_q3sqlselectcursor.cpp +++ b/tests/auto/q3sqlselectcursor/tst_q3sqlselectcursor.cpp @@ -76,7 +76,7 @@ private slots: void _exec(); private: - void generic_data(); + void generic_data(const QString &engine=QString()); void createTestTables( QSqlDatabase db ); void dropTestTables( QSqlDatabase db ); void populateTestTables( QSqlDatabase db ); @@ -92,10 +92,14 @@ tst_Q3SqlSelectCursor::~tst_Q3SqlSelectCursor() { } -void tst_Q3SqlSelectCursor::generic_data() +void tst_Q3SqlSelectCursor::generic_data(const QString& engine) { - if ( dbs.fillTestTable() == 0 ) - QSKIP( "No database drivers are available in this Qt configuration", SkipAll ); + if ( dbs.fillTestTable(engine) == 0 ) { + if(engine.isEmpty()) + QSKIP( "No database drivers are available in this Qt configuration", SkipAll ); + else + QSKIP( (QString("No database drivers of type %1 are available in this Qt configuration").arg(engine)).toLocal8Bit(), SkipAll ); + } } void tst_Q3SqlSelectCursor::createTestTables( QSqlDatabase db ) diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index d8ad15a..e10a0ca 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -93,28 +93,28 @@ private slots: void addDatabase(); //database specific tests - void recordMySQL_data(); + void recordMySQL_data() { generic_data("QMYSQL"); } void recordMySQL(); - void recordPSQL_data(); + void recordPSQL_data() { generic_data("QPSQL"); } void recordPSQL(); - void recordOCI_data(); + void recordOCI_data() { generic_data("QOCI"); } void recordOCI(); - void recordTDS_data(); + void recordTDS_data() { generic_data("QTDS"); } void recordTDS(); - void recordDB2_data(); + void recordDB2_data() { generic_data("QDB2"); } void recordDB2(); - void recordSQLite_data(); + void recordSQLite_data() { generic_data("QSQLITE"); } void recordSQLite(); - void recordAccess_data(); + void recordAccess_data() { generic_data("QODBC"); } void recordAccess(); - void recordSQLServer_data(); + void recordSQLServer_data() { generic_data("QODBC"); } void recordSQLServer(); - void recordIBase_data(); + void recordIBase_data() {generic_data("QIBASE"); } void recordIBase(); - void eventNotificationIBase_data() { generic_data(); } + void eventNotificationIBase_data() { generic_data("QIBASE"); } void eventNotificationIBase(); - void eventNotificationPSQL_data() { generic_data(); } + void eventNotificationPSQL_data() { generic_data("QPSQL"); } void eventNotificationPSQL(); //database specific 64 bit integer test @@ -141,61 +141,61 @@ private slots: void precisionPolicy_data() { generic_data(); } void precisionPolicy(); - void db2_valueCacheUpdate_data() { generic_data(); } + void db2_valueCacheUpdate_data() { generic_data("QDB2"); } void db2_valueCacheUpdate(); - void psql_schemas_data(); + void psql_schemas_data() { generic_data("QPSQL"); } void psql_schemas(); - void psql_escapedIdentifiers_data(){ psql_schemas_data(); } + void psql_escapedIdentifiers_data() { generic_data("QPSQL"); } void psql_escapedIdentifiers(); - void psql_escapeBytea_data() { psql_schemas_data(); } + void psql_escapeBytea_data() { generic_data("QPSQL"); } void psql_escapeBytea(); - void bug_249059_data() { psql_schemas_data(); } + void bug_249059_data() { generic_data("QPSQL"); } void bug_249059(); void mysqlOdbc_unsignedIntegers_data() { generic_data(); } void mysqlOdbc_unsignedIntegers(); - void mysql_multiselect_data() { generic_data(); } + void mysql_multiselect_data() { generic_data("QMYSQL"); } void mysql_multiselect(); // For task 144331 void accessOdbc_strings_data() { generic_data(); } void accessOdbc_strings(); - void ibase_numericFields_data() { generic_data(); } + void ibase_numericFields_data() { generic_data("QIBASE"); } void ibase_numericFields(); // For task 125053 - void ibase_fetchBlobs_data() { generic_data(); } + void ibase_fetchBlobs_data() { generic_data("QIBASE"); } void ibase_fetchBlobs(); // For task 143471 - void ibase_useCustomCharset_data() { generic_data(); } + void ibase_useCustomCharset_data() { generic_data("QIBASE"); } void ibase_useCustomCharset(); // For task 134608 - void ibase_procWithoutReturnValues_data() { generic_data(); } // For task 165423 + void ibase_procWithoutReturnValues_data() { generic_data("QIBASE"); } // For task 165423 void ibase_procWithoutReturnValues(); - void ibase_procWithReturnValues_data() { generic_data(); } // For task 177530 + void ibase_procWithReturnValues_data() { generic_data("QIBASE"); } // For task 177530 void ibase_procWithReturnValues(); - void odbc_reopenDatabase_data() { generic_data(); } + void odbc_reopenDatabase_data() { generic_data("QODBC"); } void odbc_reopenDatabase(); - void odbc_uniqueidentifier_data() { generic_data(); } + void odbc_uniqueidentifier_data() { generic_data("QODBC"); } void odbc_uniqueidentifier(); // For task 141822 - void odbc_uintfield_data() { generic_data(); } + void odbc_uintfield_data() { generic_data("QODBC"); } void odbc_uintfield(); - void odbc_bindBoolean_data() { generic_data(); } + void odbc_bindBoolean_data() { generic_data("QODBC"); } void odbc_bindBoolean(); - void oci_serverDetach_data() { generic_data(); } + void oci_serverDetach_data() { generic_data("QOCI"); } void oci_serverDetach(); // For task 154518 - void oci_xmltypeSupport_data() { generic_data(); } + void oci_xmltypeSupport_data() { generic_data("QOCI"); } void oci_xmltypeSupport(); - void oci_fieldLength_data() { generic_data(); } + void oci_fieldLength_data() { generic_data("QOCI"); } void oci_fieldLength(); - void sqlite_bindAndFetchUInt_data() { generic_data(); } + void sqlite_bindAndFetchUInt_data() { generic_data("QSQLITE3"); } void sqlite_bindAndFetchUInt(); private: void createTestTables(QSqlDatabase db); void dropTestTables(QSqlDatabase db); void populateTestTables(QSqlDatabase db); - void generic_data(); + void generic_data(const QString &engine=QString()); #ifdef QT3_SUPPORT void testRecordInfo(const FieldDef fieldDefs[], const Q3SqlRecordInfo& inf); @@ -397,70 +397,14 @@ void tst_QSqlDatabase::cleanup() { } -void tst_QSqlDatabase::recordOCI_data() +void tst_QSqlDatabase::generic_data(const QString& engine) { - if (dbs.fillTestTable("QOCI") == 0) - QSKIP("No Oracle database drivers are available in this Qt configuration", SkipAll); -} - -void tst_QSqlDatabase::recordPSQL_data() -{ - if (dbs.fillTestTable("QPSQL") == 0) - QSKIP("No PostgreSQL database drivers are available in this Qt configuration", SkipAll); -} - -void tst_QSqlDatabase::recordMySQL_data() -{ - if (dbs.fillTestTable("QMYSQL") == 0) - QSKIP("No MySQL database drivers are available in this Qt configuration", SkipAll); -} - -void tst_QSqlDatabase::recordTDS_data() -{ - if (dbs.fillTestTable("QTDS") == 0) - QSKIP("No TDS database drivers are available in this Qt configuration", SkipAll); -} - -void tst_QSqlDatabase::recordDB2_data() -{ - if (dbs.fillTestTable("QDB2") == 0) - QSKIP("No DB2 database drivers are available in this Qt configuration", SkipAll); -} - -void tst_QSqlDatabase::recordSQLite_data() -{ - if (dbs.fillTestTable("QSQLITE") == 0) - QSKIP("No SQLite database drivers are available in this Qt configuration", SkipAll); -} - -void tst_QSqlDatabase::recordAccess_data() -{ - if (dbs.fillTestTable("QODBC") == 0) - QSKIP("No ODBC database drivers are available in this Qt configuration", SkipAll); -} - -void tst_QSqlDatabase::recordSQLServer_data() -{ - if (dbs.fillTestTable("QODBC") == 0) - QSKIP("No ODBC database drivers are available in this Qt configuration", SkipAll); -} - -void tst_QSqlDatabase::recordIBase_data() -{ - if (dbs.fillTestTable("QIBASE") == 0) - QSKIP("No Interbase database drivers are available in this Qt configuration", SkipAll); -} - -void tst_QSqlDatabase::psql_schemas_data() -{ - if (dbs.fillTestTable("QPSQL") == 0) - QSKIP("No Postgres database drivers are available in this Qt configuration", SkipAll); -} - -void tst_QSqlDatabase::generic_data() -{ - if (dbs.fillTestTable() == 0) - QSKIP("No database drivers are available in this Qt configuration", SkipAll); + if ( dbs.fillTestTable(engine) == 0 ) { + if(engine.isEmpty()) + QSKIP( "No database drivers are available in this Qt configuration", SkipAll ); + else + QSKIP( (QString("No database drivers of type %1 are available in this Qt configuration").arg(engine)).toLocal8Bit(), SkipAll ); + } } void tst_QSqlDatabase::addDatabase() @@ -888,7 +832,6 @@ void tst_QSqlDatabase::recordTDS() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - DBMS_SPECIFIC(db, "QTDS"); static const FieldDef fieldDefs[] = { FieldDef("tinyint", QVariant::Int, 255), @@ -937,7 +880,6 @@ void tst_QSqlDatabase::recordOCI() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - DBMS_SPECIFIC(db, "QOCI"); // runtime check for Oracle version since V8 doesn't support TIMESTAMPs if (tst_Databases::getOraVersion(db) >= 9) { @@ -1013,7 +955,6 @@ void tst_QSqlDatabase::recordPSQL() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - DBMS_SPECIFIC(db, "QPSQL"); FieldDef byteadef; if (db.driver()->hasFeature(QSqlDriver::BLOB)) @@ -1098,7 +1039,6 @@ void tst_QSqlDatabase::recordMySQL() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - DBMS_SPECIFIC(db, "QMYSQL"); FieldDef bin10, varbin10; int major = tst_Databases::getMySqlVersion( db ).section( QChar('.'), 0, 0 ).toInt(); @@ -1177,7 +1117,6 @@ void tst_QSqlDatabase::recordDB2() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - DBMS_SPECIFIC(db, "QDB2"); static const FieldDef fieldDefs[] = { FieldDef("char(20)", QVariant::String, QString("Blah1")), @@ -1223,7 +1162,6 @@ void tst_QSqlDatabase::recordIBase() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - DBMS_SPECIFIC(db, "QIBASE"); static const FieldDef fieldDefs[] = { FieldDef("char(20)", QVariant::String, QString("Blah1"), false), @@ -1254,7 +1192,6 @@ void tst_QSqlDatabase::recordSQLite() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - DBMS_SPECIFIC(db, "QSQLITE"); static const FieldDef fieldDefs[] = { // The affinity of these fields are TEXT so SQLite should give us strings, not ints or doubles. @@ -1801,7 +1738,6 @@ void tst_QSqlDatabase::ibase_numericFields() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - DBMS_SPECIFIC(db, "QIBASE"); QSqlQuery q(db); QString tableName = qTableName("numericfields"); @@ -1875,7 +1811,6 @@ void tst_QSqlDatabase::ibase_fetchBlobs() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - DBMS_SPECIFIC(db, "QIBASE"); QString tableName = qTableName("qtest_ibaseblobs"); QSqlQuery q(db); @@ -1908,7 +1843,6 @@ void tst_QSqlDatabase::ibase_procWithoutReturnValues() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - DBMS_SPECIFIC(db, "QIBASE"); QSqlQuery q(db); QString procName = qTableName("qtest_proc1"); @@ -1989,11 +1923,6 @@ void tst_QSqlDatabase::odbc_reopenDatabase() QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - if (!tst_Databases::isSqlServer(db)) { - QSKIP("SQL Server (ODBC) specific test", SkipSingle); - return; - } - QSqlQuery q(db); QVERIFY_SQL(q, exec("SELECT * from " + qTableName("qtest"))); QVERIFY_SQL(q, next()); @@ -2008,7 +1937,6 @@ void tst_QSqlDatabase::odbc_bindBoolean() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - DBMS_SPECIFIC(db, "QODBC"); QSqlQuery q(db); QVERIFY_SQL(q, exec("CREATE TABLE " + qTableName("qtestBindBool") + "(id int, boolvalue bit)")); @@ -2037,7 +1965,6 @@ void tst_QSqlDatabase::mysql_multiselect() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - DBMS_SPECIFIC(db, "QMYSQL"); QSqlQuery q(db); QVERIFY_SQL(q, exec("select version()")); @@ -2059,7 +1986,6 @@ void tst_QSqlDatabase::ibase_useCustomCharset() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - DBMS_SPECIFIC(db, "QIBASE"); QString nonlatin1string("��"); db.close(); @@ -2083,7 +2009,6 @@ void tst_QSqlDatabase::oci_serverDetach() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - DBMS_SPECIFIC(db, "QOCI"); for (int i = 0; i < 2; i++) { db.close(); @@ -2104,7 +2029,6 @@ void tst_QSqlDatabase::oci_xmltypeSupport() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - DBMS_SPECIFIC(db, "QOCI"); QString tableName = qTableName("qtest_xmltype"); QString xml("MY_TABLE"); @@ -2133,7 +2057,6 @@ void tst_QSqlDatabase::oci_fieldLength() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - DBMS_SPECIFIC(db, "QOCI"); QString tableName = qTableName("qtest"); QSqlQuery q(db); @@ -2198,7 +2121,6 @@ void tst_QSqlDatabase::odbc_uintfield() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - DBMS_SPECIFIC(db, "QODBC"); QString tableName = qTableName("uint_table"); unsigned int val = 4294967295U; @@ -2260,7 +2182,6 @@ void tst_QSqlDatabase::eventNotificationIBase() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - DBMS_SPECIFIC(db, "QIBASE"); QString procedureName = qTableName("posteventProc"); QSqlDriver *driver=db.driver(); @@ -2290,7 +2211,6 @@ void tst_QSqlDatabase::eventNotificationPSQL() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - DBMS_SPECIFIC(db, "QPSQL"); QSqlQuery query(db); QString procedureName = qTableName("posteventProc"); @@ -2311,7 +2231,6 @@ void tst_QSqlDatabase::sqlite_bindAndFetchUInt() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - DBMS_SPECIFIC(db, "QSQLITE3"); QSqlQuery q(db); QString tableName = qTableName("uint_test"); @@ -2333,7 +2252,6 @@ void tst_QSqlDatabase::db2_valueCacheUpdate() QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - DBMS_SPECIFIC(db, "QDB2"); QString tableName = qTableName("qtest"); QSqlQuery q(db); diff --git a/tests/auto/qsqlquery/tst_qsqlquery.cpp b/tests/auto/qsqlquery/tst_qsqlquery.cpp index 684d6ac..8d77589 100644 --- a/tests/auto/qsqlquery/tst_qsqlquery.cpp +++ b/tests/auto/qsqlquery/tst_qsqlquery.cpp @@ -93,7 +93,7 @@ private slots: void transaction(); void record_data() { generic_data(); } void record(); - void record_sqlite_data() { generic_data(); } + void record_sqlite_data() { generic_data("QSQLITE"); } void record_sqlite(); void finish_data() { generic_data(); } void finish(); @@ -107,13 +107,13 @@ private slots: void forwardOnly(); // bug specific tests - void bitField_data(); + void bitField_data() {generic_data("QTDS"); } void bitField(); - void nullBlob_data(); + void nullBlob_data() { generic_data("QOCI"); } void nullBlob(); void blob_data() { generic_data(); } void blob(); - void rawField_data(); + void rawField_data() { generic_data("QOCI"); } void rawField(); void precision_data() { generic_data(); } void precision(); @@ -129,19 +129,19 @@ private slots: void char1SelectUnicode(); void synonyms_data() { generic_data(); } void synonyms(); - void oraOutValues_data(); + void oraOutValues_data() { generic_data("QOCI"); } void oraOutValues(); - void mysqlOutValues_data(); + void mysqlOutValues_data() { generic_data("QMYSQL"); } void mysqlOutValues(); - void oraClob_data() { oraOutValues_data(); } + void oraClob_data() { generic_data("QOCI"); } void oraClob(); - void oraLong_data() { oraOutValues_data(); } + void oraLong_data() { generic_data("QOCI"); } void oraLong(); - void outValuesDB2_data(); + void outValuesDB2_data() { generic_data("QDB2"); } void outValuesDB2(); - void storedProceduresIBase_data(); + void storedProceduresIBase_data() {generic_data("QIBASE"); } void storedProceduresIBase(); - void oraRowId_data(); + void oraRowId_data() { generic_data("QOCI"); } void oraRowId(); void prepare_bind_exec_data() { generic_data(); } void prepare_bind_exec(); @@ -175,13 +175,13 @@ private slots: void emptyTableNavigate(); #ifdef NOT_READY_YET - void bug217003_data() { generic_data(); } - void bug217003(); + void task_217003_data() { generic_data(); } + void task_217003(); #endif private: // returns all database connections - void generic_data(); + void generic_data(const QString &engine=QString()); void dropTestTables( QSqlDatabase db ); void createTestTables( QSqlDatabase db ); void populateTestTables( QSqlDatabase db ); @@ -247,28 +247,14 @@ void tst_QSqlQuery::cleanup() } } -void tst_QSqlQuery::bitField_data() +void tst_QSqlQuery::generic_data(const QString& engine) { - if ( dbs.fillTestTable( "QTDS" ) == 0 ) - QSKIP( "No TDS database drivers are available in this Qt configuration", SkipAll ); -} - -void tst_QSqlQuery::nullBlob_data() -{ - if ( dbs.fillTestTable( "QOCI" ) == 0 ) - QSKIP( "No Oracle database drivers are available in this Qt configuration", SkipAll ); -} - -void tst_QSqlQuery::rawField_data() -{ - if ( dbs.fillTestTable( "QOCI" ) == 0 ) - QSKIP( "No Oracle database drivers are available in this Qt configuration", SkipAll ); -} - -void tst_QSqlQuery::generic_data() -{ - if ( dbs.fillTestTable() == 0 ) - QSKIP( "No database drivers are available in this Qt configuration", SkipAll ); + if ( dbs.fillTestTable(engine) == 0 ) { + if(engine.isEmpty()) + QSKIP( "No database drivers are available in this Qt configuration", SkipAll ); + else + QSKIP( (QString("No database drivers of type %1 are available in this Qt configuration").arg(engine)).toLocal8Bit(), SkipAll ); + } } void tst_QSqlQuery::dropTestTables( QSqlDatabase db ) @@ -421,12 +407,6 @@ void tst_QSqlQuery::char1SelectUnicode() QSKIP( "Database not unicode capable", SkipSingle ); } -void tst_QSqlQuery::oraRowId_data() -{ - if ( dbs.fillTestTable( "QOCI" ) == 0 ) - QSKIP( "No Oracle database drivers are available in this Qt configuration", SkipAll ); -} - void tst_QSqlQuery::oraRowId() { QFETCH( QString, dbName ); @@ -461,12 +441,6 @@ void tst_QSqlQuery::oraRowId() QCOMPARE( q.value( 0 ).toString(), QString( "b" ) ); } -void tst_QSqlQuery::mysqlOutValues_data() -{ - if ( dbs.fillTestTable( "QMYSQL" ) == 0 ) - QSKIP( "No MySQL database drivers are available in this Qt configuration", SkipAll ); -} - void tst_QSqlQuery::mysqlOutValues() { QFETCH( QString, dbName ); @@ -517,12 +491,6 @@ void tst_QSqlQuery::mysqlOutValues() QVERIFY_SQL( q, exec( "drop procedure " + qTableName( "qtestproc" ) ) ); } -void tst_QSqlQuery::oraOutValues_data() -{ - if ( dbs.fillTestTable( "QOCI" ) == 0 ) - QSKIP( "No Oracle database drivers are available in this Qt configuration", SkipAll ); -} - void tst_QSqlQuery::oraOutValues() { QFETCH( QString, dbName ); @@ -670,18 +638,11 @@ void tst_QSqlQuery::oraClob() QVERIFY( q.value( 1 ).toByteArray() == loong.toLatin1() ); } -void tst_QSqlQuery::storedProceduresIBase_data() -{ - if ( dbs.fillTestTable( "QIBASE" ) == 0 ) - QSKIP( "No Interbase database drivers are available in this Qt configuration", SkipAll ); -} - void tst_QSqlQuery::storedProceduresIBase() { QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); - DBMS_SPECIFIC( db, "QIBASE" ); QSqlQuery q( db ); q.exec( "drop procedure " + qTableName( "TESTPROC" ) ); @@ -713,12 +674,6 @@ void tst_QSqlQuery::storedProceduresIBase() q.exec( "drop procedure " + qTableName( "TestProc" ) ); } -void tst_QSqlQuery::outValuesDB2_data() -{ - if ( dbs.fillTestTable( "QDB2" ) == 0 ) - QSKIP( "No DB2 database drivers are available in this Qt configuration", SkipAll ); -} - void tst_QSqlQuery::outValuesDB2() { QFETCH( QString, dbName ); @@ -1355,7 +1310,6 @@ void tst_QSqlQuery::nullBlob() QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); - DBMS_SPECIFIC( db, "QOCI" ); QSqlQuery q( db ); QVERIFY_SQL( q, exec( "create table " + qTableName( "qtest_nullblob" ) + " (id int primary key, bb blob)" ) ); @@ -1385,7 +1339,6 @@ void tst_QSqlQuery::rawField() QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); - DBMS_SPECIFIC( db, "QOCI" ); QSqlQuery q( db ); q.setForwardOnly( true ); @@ -2103,7 +2056,6 @@ void tst_QSqlQuery::record_sqlite() QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); - DBMS_SPECIFIC( db, "QSQLITE" ); QSqlQuery q( db ); @@ -2131,7 +2083,6 @@ void tst_QSqlQuery::oraLong() QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); CHECK_DATABASE( db ); - DBMS_SPECIFIC( db, "QOCI" ); QSqlQuery q( db ); @@ -2158,7 +2109,7 @@ void tst_QSqlQuery::execErrorRecovery() QSqlQuery q( db ); - QVERIFY_SQL( q, exec( "create table " + qTableName( "qtest_exerr" ) + " (id int primary key)" ) ); + QVERIFY_SQL( q, exec( "create table " + qTableName( "qtest_exerr" ) + " (id int not null primary key)" ) ); QVERIFY_SQL( q, prepare( "insert into " + qTableName( "qtest_exerr" ) + " values (?)" ) ); q.addBindValue( 1 ); @@ -2698,7 +2649,7 @@ void tst_QSqlQuery::emptyTableNavigate() } #ifdef NOT_READY_YET -void tst_QSqlQuery::bug217003() +void tst_QSqlQuery::task_217003() { QFETCH( QString, dbName ); QSqlDatabase db = QSqlDatabase::database( dbName ); diff --git a/tests/auto/qsqlquerymodel/tst_qsqlquerymodel.cpp b/tests/auto/qsqlquerymodel/tst_qsqlquerymodel.cpp index 63202f8..88b5770 100644 --- a/tests/auto/qsqlquerymodel/tst_qsqlquerymodel.cpp +++ b/tests/auto/qsqlquerymodel/tst_qsqlquerymodel.cpp @@ -95,7 +95,7 @@ private slots: void setQueryWithNoRowsInResultSet(); private: - void generic_data(); + void generic_data(const QString &engine=QString()); void dropTestTables(QSqlDatabase db); void createTestTables(QSqlDatabase db); void populateTestTables(QSqlDatabase db); @@ -202,10 +202,14 @@ void tst_QSqlQueryModel::populateTestTables(QSqlDatabase db) tst_Databases::safeDropTables(db, QStringList() << qTableName("manytmp") << qTableName("test3tmp")); } -void tst_QSqlQueryModel::generic_data() +void tst_QSqlQueryModel::generic_data(const QString& engine) { - if (dbs.fillTestTable() == 0) - QSKIP("No database drivers are available in this Qt configuration", SkipAll); + if ( dbs.fillTestTable(engine) == 0 ) { + if(engine.isEmpty()) + QSKIP( "No database drivers are available in this Qt configuration", SkipAll ); + else + QSKIP( (QString("No database drivers of type %1 are available in this Qt configuration").arg(engine)).toLocal8Bit(), SkipAll ); + } } void tst_QSqlQueryModel::init() diff --git a/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp index 6015d1c..d4affe4 100644 --- a/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp +++ b/tests/auto/qsqltablemodel/tst_qsqltablemodel.cpp @@ -66,38 +66,59 @@ public: tst_Databases dbs; public slots: - void initTestCase_data(); void initTestCase(); void cleanupTestCase(); void init(); void cleanup(); private slots: + void select_data() { generic_data(); } void select(); + void submitAll_data() { generic_data(); } void submitAll(); - void setRecord_data(); + void setRecord_data() { generic_data(); } void setRecord(); + void insertRow_data() { generic_data(); } void insertRow(); + void insertRecord_data() { generic_data(); } void insertRecord(); + void insertMultiRecords_data() { generic_data(); } void insertMultiRecords(); + void removeRow_data() { generic_data(); } void removeRow(); + void removeRows_data() { generic_data(); } void removeRows(); + void removeInsertedRow_data() { generic_data(); } void removeInsertedRow(); + void setFilter_data() { generic_data(); } void setFilter(); + void setInvalidFilter_data() { generic_data(); } void setInvalidFilter(); + void emptyTable_data() { generic_data(); } void emptyTable(); + void tablesAndSchemas_data() { generic_data("QPSQL"); } void tablesAndSchemas(); + void whitespaceInIdentifiers_data() { generic_data(); } void whitespaceInIdentifiers(); + void primaryKeyOrder_data() { generic_data("QSQLITE"); } void primaryKeyOrder(); + void sqlite_bigTable_data() { generic_data("QSQLITE"); } void sqlite_bigTable(); // bug specific tests + void insertRecordBeforeSelect_data() { generic_data(); } void insertRecordBeforeSelect(); + void submitAllOnInvalidTable_data() { generic_data(); } void submitAllOnInvalidTable(); + void insertRecordsInLoop_data() { generic_data(); } void insertRecordsInLoop(); + void sqlite_attachedDatabase_data() { generic_data("QSQLITE"); } void sqlite_attachedDatabase(); // For task 130799 + +private: + void generic_data(const QString& engine=QString()); }; tst_QSqlTableModel::tst_QSqlTableModel() @@ -121,7 +142,8 @@ void tst_QSqlTableModel::dropTestTables() << qTableName("test2") << qTableName("test3") << qTableName("emptytable") - << qTableName("bigtable"); + << qTableName("bigtable") + << qTableName("foo"); if (testWhiteSpaceNames(db.driverName())) tableNames << qTableName("qtestw hitespace"); @@ -160,16 +182,16 @@ void tst_QSqlTableModel::repopulateTestTables() QSqlDatabase db = QSqlDatabase::database(dbs.dbNames.at(i)); QSqlQuery q(db); - QVERIFY_SQL( q, exec("delete from " + qTableName("test"))); + q.exec("delete from " + qTableName("test")); QVERIFY_SQL( q, exec("insert into " + qTableName("test") + " values(1, 'harry', 1)")); QVERIFY_SQL( q, exec("insert into " + qTableName("test") + " values(2, 'trond', 2)")); QVERIFY_SQL( q, exec("insert into " + qTableName("test") + " values(3, 'vohi', 3)")); - QVERIFY_SQL( q, exec("delete from " + qTableName("test2"))); + q.exec("delete from " + qTableName("test2")); QVERIFY_SQL( q, exec("insert into " + qTableName("test2") + " values(1, 'herr')")); QVERIFY_SQL( q, exec("insert into " + qTableName("test2") + " values(2, 'mister')")); - QVERIFY_SQL( q, exec("delete from " + qTableName("test3"))); + q.exec("delete from " + qTableName("test3")); QVERIFY_SQL( q, exec("insert into " + qTableName("test3") + " values(1, 'foo', 'bar')")); QVERIFY_SQL( q, exec("insert into " + qTableName("test3") + " values(2, 'baz', 'joe')")); } @@ -182,11 +204,13 @@ void tst_QSqlTableModel::recreateTestTables() repopulateTestTables(); } -void tst_QSqlTableModel::initTestCase_data() +void tst_QSqlTableModel::generic_data(const QString &engine) { - if (dbs.fillTestTable() == 0) { - qWarning("NO DATABASES"); - QSKIP("No database drivers are available in this Qt configuration", SkipAll); + if ( dbs.fillTestTable(engine) == 0 ) { + if(engine.isEmpty()) + QSKIP( "No database drivers are available in this Qt configuration", SkipAll ); + else + QSKIP( (QString("No database drivers of type %1 are available in this Qt configuration").arg(engine)).toLocal8Bit(), SkipAll ); } } @@ -212,7 +236,7 @@ void tst_QSqlTableModel::cleanup() void tst_QSqlTableModel::select() { - QFETCH_GLOBAL(QString, dbName); + QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); @@ -245,58 +269,51 @@ void tst_QSqlTableModel::select() QCOMPARE(model.data(model.index(3, 3)), QVariant()); } -void tst_QSqlTableModel::setRecord_data() -{ - QTest::addColumn("submitpolicy"); - QTest::newRow("OnFieldChange") << (uint)QSqlTableModel::OnFieldChange; - QTest::newRow("OnRowChange") << (uint)QSqlTableModel::OnRowChange; - QTest::newRow("OnManualSubmit") << (uint)QSqlTableModel::OnManualSubmit; -} - void tst_QSqlTableModel::setRecord() { - // This needs to be tested with ODBC, which requires a manual change to qsqldatabase\tst_databases.h - // to ensure an ODBC db is added - - QFETCH_GLOBAL(QString, dbName); - QFETCH(uint, submitpolicy); + QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - QSqlTableModel model(0, db); - model.setEditStrategy((QSqlTableModel::EditStrategy)submitpolicy); - model.setTable(qTableName("test3")); - model.setSort(0, Qt::AscendingOrder); - QVERIFY_SQL(model, select()); + QList policies = QList() << QSqlTableModel::OnFieldChange << QSqlTableModel::OnRowChange << QSqlTableModel::OnManualSubmit; + + foreach( QSqlTableModel::EditStrategy submitpolicy, policies) { + + QSqlTableModel model(0, db); + model.setEditStrategy((QSqlTableModel::EditStrategy)submitpolicy); + model.setTable(qTableName("test3")); + model.setSort(0, Qt::AscendingOrder); + QVERIFY_SQL(model, select()); - for (int i = 0; i < model.rowCount(); ++i) { - QSignalSpy spy(&model, SIGNAL(dataChanged(QModelIndex,QModelIndex))); - - QSqlRecord rec = model.record(i); - rec.setValue(1, rec.value(1).toString() + 'X'); - rec.setValue(2, rec.value(2).toString() + 'X'); - QVERIFY(model.setRecord(i, rec)); - - if ((QSqlTableModel::EditStrategy)submitpolicy == QSqlTableModel::OnManualSubmit) - QVERIFY(model.submitAll()); - else { - // dataChanged() is not emitted when submitAll() is called - QCOMPARE(spy.count(), 2); - QCOMPARE(spy.at(0).count(), 2); - QCOMPARE(qvariant_cast(spy.at(0).at(0)), model.index(i, 1)); - QCOMPARE(qvariant_cast(spy.at(0).at(1)), model.index(i, 1)); + for (int i = 0; i < model.rowCount(); ++i) { + QSignalSpy spy(&model, SIGNAL(dataChanged(QModelIndex,QModelIndex))); + + QSqlRecord rec = model.record(i); + rec.setValue(1, rec.value(1).toString() + 'X'); + rec.setValue(2, rec.value(2).toString() + 'X'); + QVERIFY(model.setRecord(i, rec)); + + if ((QSqlTableModel::EditStrategy)submitpolicy == QSqlTableModel::OnManualSubmit) + QVERIFY(model.submitAll()); + else { + // dataChanged() is not emitted when submitAll() is called + QCOMPARE(spy.count(), 2); + QCOMPARE(spy.at(0).count(), 2); + QCOMPARE(qvariant_cast(spy.at(0).at(0)), model.index(i, 1)); + QCOMPARE(qvariant_cast(spy.at(0).at(1)), model.index(i, 1)); + } } - } - 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")); + 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")); + } } void tst_QSqlTableModel::insertRow() { - QFETCH_GLOBAL(QString, dbName); + QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); @@ -321,7 +338,7 @@ void tst_QSqlTableModel::insertRow() void tst_QSqlTableModel::insertRecord() { - QFETCH_GLOBAL(QString, dbName); + QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); @@ -354,7 +371,7 @@ void tst_QSqlTableModel::insertRecord() void tst_QSqlTableModel::insertMultiRecords() { - QFETCH_GLOBAL(QString, dbName); + QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); @@ -403,7 +420,7 @@ void tst_QSqlTableModel::insertMultiRecords() void tst_QSqlTableModel::submitAll() { - QFETCH_GLOBAL(QString, dbName); + QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); @@ -438,7 +455,7 @@ void tst_QSqlTableModel::submitAll() void tst_QSqlTableModel::removeRow() { - QFETCH_GLOBAL(QString, dbName); + QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); @@ -484,7 +501,7 @@ void tst_QSqlTableModel::removeRow() void tst_QSqlTableModel::removeRows() { - QFETCH_GLOBAL(QString, dbName); + QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); @@ -533,7 +550,7 @@ void tst_QSqlTableModel::removeRows() void tst_QSqlTableModel::removeInsertedRow() { - QFETCH_GLOBAL(QString, dbName); + QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); @@ -565,7 +582,7 @@ void tst_QSqlTableModel::removeInsertedRow() void tst_QSqlTableModel::emptyTable() { - QFETCH_GLOBAL(QString, dbName); + QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); @@ -584,12 +601,10 @@ void tst_QSqlTableModel::emptyTable() void tst_QSqlTableModel::tablesAndSchemas() { - QFETCH_GLOBAL(QString, dbName); + QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - DBMS_SPECIFIC(db, "QPSQL"); - QSqlQuery q(db); q.exec("DROP SCHEMA " + qTableName("testschema") + " CASCADE"); QVERIFY_SQL( q, exec("create schema " + qTableName("testschema"))); @@ -607,7 +622,7 @@ void tst_QSqlTableModel::tablesAndSchemas() void tst_QSqlTableModel::whitespaceInIdentifiers() { - QFETCH_GLOBAL(QString, dbName); + QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); @@ -623,16 +638,16 @@ void tst_QSqlTableModel::whitespaceInIdentifiers() void tst_QSqlTableModel::primaryKeyOrder() { - QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "primaryKeyOrderTest"); - db.setDatabaseName(":memory:"); - QVERIFY_SQL(db, open()); + QFETCH(QString, dbName); + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); QSqlQuery q(db); - QVERIFY_SQL( q, exec("create table foo(a varchar(20), id int primary key, b varchar(20))")); + QVERIFY_SQL( q, exec("create table "+qTableName("foo")+"(a varchar(20), id int not null primary key, b varchar(20))")); QSqlTableModel model(0, db); - model.setTable("foo"); + model.setTable(qTableName("foo")); QSqlIndex pk = model.primaryKey(); QCOMPARE(pk.count(), 1); @@ -652,7 +667,7 @@ void tst_QSqlTableModel::primaryKeyOrder() void tst_QSqlTableModel::setInvalidFilter() { - QFETCH_GLOBAL(QString, dbName); + QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); @@ -671,7 +686,7 @@ void tst_QSqlTableModel::setInvalidFilter() void tst_QSqlTableModel::setFilter() { - QFETCH_GLOBAL(QString, dbName); + QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); @@ -724,12 +739,10 @@ void tst_QSqlTableModel::setFilter() void tst_QSqlTableModel::sqlite_bigTable() { - QFETCH_GLOBAL(QString, dbName); + QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - DBMS_SPECIFIC(db, "QSQLITE"); - bool hasTransactions = db.driver()->hasFeature(QSqlDriver::Transactions); if (hasTransactions) QVERIFY(db.transaction()); QSqlQuery q(db); @@ -763,7 +776,7 @@ void tst_QSqlTableModel::sqlite_bigTable() // had first been called. void tst_QSqlTableModel::insertRecordBeforeSelect() { - QFETCH_GLOBAL(QString, dbName); + QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); @@ -796,7 +809,7 @@ void tst_QSqlTableModel::insertRecordBeforeSelect() // are inserted and submitted on a non-existing table. void tst_QSqlTableModel::submitAllOnInvalidTable() { - QFETCH_GLOBAL(QString, dbName); + QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); @@ -828,7 +841,7 @@ void tst_QSqlTableModel::submitAllOnInvalidTable() // For task 147575: the rowsRemoved signal emitted from the model was lying void tst_QSqlTableModel::insertRecordsInLoop() { - QFETCH_GLOBAL(QString, dbName); + QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); @@ -866,12 +879,10 @@ void tst_QSqlTableModel::insertRecordsInLoop() void tst_QSqlTableModel::sqlite_attachedDatabase() { - QFETCH_GLOBAL(QString, dbName); + QFETCH(QString, dbName); QSqlDatabase db = QSqlDatabase::database(dbName); CHECK_DATABASE(db); - DBMS_SPECIFIC(db, "QSQLITE"); - QSqlDatabase attachedDb = QSqlDatabase::cloneDatabase(db, db.driverName() + QLatin1String("attached")); attachedDb.setDatabaseName(db.databaseName()+QLatin1String("attached.dat")); QVERIFY_SQL(attachedDb, open()); diff --git a/tests/auto/qsqlthread/tst_qsqlthread.cpp b/tests/auto/qsqlthread/tst_qsqlthread.cpp index 94e0f98..d871be4 100644 --- a/tests/auto/qsqlthread/tst_qsqlthread.cpp +++ b/tests/auto/qsqlthread/tst_qsqlthread.cpp @@ -286,10 +286,14 @@ tst_QSqlThread::~tst_QSqlThread() { } -void tst_QSqlThread::generic_data() +void tst_QSqlThread::generic_data(const QString& engine) { - if (dbs.fillTestTable() == 0) - QSKIP("No database drivers are available in this Qt configuration", SkipAll); + if ( dbs.fillTestTable(engine) == 0 ) { + if(engine.isEmpty()) + QSKIP( "No database drivers are available in this Qt configuration", SkipAll ); + else + QSKIP( (QString("No database drivers of type %1 are available in this Qt configuration").arg(engine)).toLocal8Bit(), SkipAll ); + } } void tst_QSqlThread::dropTestTables() -- cgit v0.12 From 4edf0c16170f0f727536c6eaefca92b40d03f835 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 1 Apr 2009 10:30:43 +0200 Subject: Subject: A couple of minor doc fixes Reviewed-by: Morten Engvoldsen --- doc/src/platform-notes.qdoc | 1 - src/gui/painting/qprinter.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/src/platform-notes.qdoc b/doc/src/platform-notes.qdoc index d5eee27..6532d1e 100644 --- a/doc/src/platform-notes.qdoc +++ b/doc/src/platform-notes.qdoc @@ -493,7 +493,6 @@ \row \row \o aCC series 3 \o \o \o \o \bold{X} \o \bold{X} \row \o aCC series 6 \o \bold{X} \o \bold{X} \o \bold{X} \o \bold{X} \o \bold{X} - \row \o MIPSpro 7.4.2m \o{5,1} \e{Unsupported - see the Unsupported Platforms table} \row \o xlC 6 \o \o \o \o \bold{X} \o \bold{X} \row \o \l{Known Issues in %VERSION%}{Intel CC 10 (see note)} \o \bold{X} \o \bold{X} \o \bold{X} \o \bold{X} \o \bold{X} diff --git a/src/gui/painting/qprinter.cpp b/src/gui/painting/qprinter.cpp index 413f4a1..6c309c7 100644 --- a/src/gui/painting/qprinter.cpp +++ b/src/gui/painting/qprinter.cpp @@ -849,7 +849,7 @@ void QPrinter::setPrinterName(const QString &name) Returns true if the printer currently selected is a valid printer in the system, or a pure PDF/PostScript printer; otherwise returns false. - To detect other failures check the output of QPainter::begin() or QPainter::nextPage(). + To detect other failures check the output of QPainter::begin() or QPrinter::newPage(). \snippet doc/src/snippets/printing-qprinter/errors.cpp 0 -- cgit v0.12 From 21b8f37ba1c29450d46abe3d86f6215d42e5f232 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 1 Apr 2009 11:32:41 +0200 Subject: Subject: Mention setProxy() should be called before setHost() in the doc Reviewed-by: Kavindra Devi Palaraja --- src/network/access/qhttp.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/network/access/qhttp.cpp b/src/network/access/qhttp.cpp index 0141ae2..96ccc91 100644 --- a/src/network/access/qhttp.cpp +++ b/src/network/access/qhttp.cpp @@ -2120,6 +2120,10 @@ int QHttp::setUser(const QString &userName, const QString &password) Web proxy cache server (from \l http://www.squid.org/). For transparent proxying, such as SOCKS5, use QNetworkProxy instead. + \note setProxy() has to be called before setHost() for it to take effect. + If setProxy() is called after setHost(), then it will not apply until after + setHost() is called again. + \sa QFtp::setProxy() */ int QHttp::setProxy(const QString &host, int port, @@ -2139,7 +2143,7 @@ int QHttp::setProxy(const QString &host, int port, is QNetworkProxy::HttpCachingProxy, QHttp will behave like the previous function. - Note: for compatibility with Qt 4.3, if the proxy type is + \note for compatibility with Qt 4.3, if the proxy type is QNetworkProxy::HttpProxy and the request type is unencrypted (that is, ConnectionModeHttp), QHttp will treat the proxy as a caching proxy. -- cgit v0.12 From 665d338817900f3474d41359df39285515921f34 Mon Sep 17 00:00:00 2001 From: Morten Engvoldsen Date: Thu, 26 Mar 2009 16:03:44 +0100 Subject: Subject: added options to CONFIG in qmake Details: added some non documented options for COFIG in the qmake manual Fields Reviewed-by: Geir Vattekar Reviewed-by: Marius Storm-Olsen Task-number: 248432 --- doc/src/qmake-manual.qdoc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/doc/src/qmake-manual.qdoc b/doc/src/qmake-manual.qdoc index 30da8c6..27cfa0b 100644 --- a/doc/src/qmake-manual.qdoc +++ b/doc/src/qmake-manual.qdoc @@ -367,15 +367,20 @@ \row \o debug \o The project is to be built in debug mode. \row \o debug_and_release \o The project is built in \e both debug and release modes. + \row \o debug_and_release_target \o The project is built in \e both debug + and release modes. TARGET is built into \e both the debug and release directories. \row \o build_all \o If \c debug_and_release is specified, the project is built in both debug and release modes by default. + \row \o autogen_precompile_source \o Automatically generates a \c .cpp file that includes + the precompiled header file specified in the .pro file. \row \o ordered \o When using the \c subdirs template, this option specifies that the directories listed should be processed in the order in which they are given. \row \o warn_on \o The compiler should output as many warnings as possible. This is ignored if \c warn_off is specified. \row \o warn_off \o The compiler should output as few warnings as possible. - \endtable + \row \o copy_dir_files \o Enables the install rule to also copy directories, not just files. + \endtable The \c debug_and_release option is special in that it enables \e both debug and release versions of a project to be built. In such a case, the Makefile that -- cgit v0.12 From 914c2c25d0a60bc5c9d14f405a49b08a162c8908 Mon Sep 17 00:00:00 2001 From: Morten Engvoldsen Date: Fri, 27 Mar 2009 14:17:51 +0100 Subject: Subject: Replaced comment with a better one. Details: Replaced the comment for QButton::setDown(bool). It was kind of narrow. Reviewed-by: Geir Vattekar --- doc/src/porting4-removedvirtual.qdocinc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/porting4-removedvirtual.qdocinc b/doc/src/porting4-removedvirtual.qdocinc index 3eedad2..1af4fa6 100644 --- a/doc/src/porting4-removedvirtual.qdocinc +++ b/doc/src/porting4-removedvirtual.qdocinc @@ -22,7 +22,7 @@ \row \o void QButton::drawButtonLabel(QPainter *) \o Use Q3Button instead or reimplement QButton::paintEvent(). \row \o void QButton::setAccel(const QKeySequence &) \o Setter. \row \o void QButton::setAutoRepeat(bool) \o Setter. -\row \o void QButton::setDown(bool) \o Setter. +\row \o void QButton::setDown(bool) \o Use Q3Button instead or reimplement or port to the new QPushButton API. \row \o void QButton::setPixmap(const QPixmap &) \o Setter. \row \o void QButton::setState(ToggleState) \o Setter. \row \o void QButton::setText(const QString &) \o Use the QAbstractButton::setText() setter function. -- cgit v0.12 From 14d9633f576429b29257ed43143abc6de3918e5d Mon Sep 17 00:00:00 2001 From: Morten Engvoldsen Date: Mon, 30 Mar 2009 13:48:46 +0200 Subject: Adding note to the qFuzzyCompare doc Adding note about how comparing using 0.0 will fail, and an example on how to do it. Reviewed-by: David Boddie Reviewed-by: Geir Vattekar --- doc/src/snippets/code/src_corelib_global_qglobal.cpp | 8 ++++++++ src/corelib/global/qglobal.cpp | 7 ++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/doc/src/snippets/code/src_corelib_global_qglobal.cpp b/doc/src/snippets/code/src_corelib_global_qglobal.cpp index 72663e9..287181a 100644 --- a/doc/src/snippets/code/src_corelib_global_qglobal.cpp +++ b/doc/src/snippets/code/src_corelib_global_qglobal.cpp @@ -456,3 +456,11 @@ class MyClass : public QObject //! [45] QWidget w = QWidget(); //! [45] + +//! [46] + // Instead of comparing with 0.0 + qFuzzyCompare(0.0,1.0e-200); // This will return false + // Compare adding 1 to both values will fix the problem + qFuzzyCompare(1 + 0.0, 1 + 1.0e-200); // This will return true +//! [46] + diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 68c213e..69d0a53 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -2942,7 +2942,12 @@ bool QInternal::callFunction(InternalFunction func, void **args) Compares the floating point value \a p1 and \a p2 and returns \c true if they are considered equal, otherwise \c false. - + + Note that comparing values where either \a p1 or \a p2 is 0.0 will not work. + The solution to this is to compare against values greater than or equal to 1.0 + + \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 46 + The two numbers are compared in a relative way, where the exactness is stronger the smaller the numbers are. */ -- cgit v0.12 From 84741443a8f7971e6b715f15f71f7a1a8ef05353 Mon Sep 17 00:00:00 2001 From: Morten Engvoldsen Date: Mon, 30 Mar 2009 15:10:05 +0200 Subject: Changes: Clearifying docs on qInstallMsgHandler Details: Added comment about QT_NO_WARNING_OUTPUT and/or QT_NO_DEBUG_OUTPUT on http://doc.trolltech.com/4.5/qtglobal.html#qInstallMsgHandler Review-by: Geir Vattekar --- src/corelib/global/qglobal.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 69d0a53..1645279 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -1934,9 +1934,11 @@ QString qt_error_string(int errorCode) The message handler is a function that prints out debug messages, warnings, critical and fatal error messages. The Qt library (debug - version) contains hundreds of warning messages that are printed + mode) contains hundreds of warning messages that are printed when internal errors (usually invalid function arguments) - occur. If you implement your own message handler, you get total + occur. Qt built in release mode also contains such warnings unless + QT_NO_WARNING_OUTPUT and/or QT_NO_DEBUG_OUTPUT have been set during + compilation. If you implement your own message handler, you get total control of these messages. The default message handler prints the message to the standard -- cgit v0.12 From 9969f5383711454389435370ae71b6f19d3b2255 Mon Sep 17 00:00:00 2001 From: Morten Engvoldsen Date: Wed, 1 Apr 2009 10:45:59 +0200 Subject: Subject: Added platform spec. note about type convertion Details: Added a note to the description about using POSIX functions for converting between data types such as floats and strings Task-number: 244600 Reviewed-by: Denis Dzyubenko Reviewed-by: Geir Vattekar --- src/corelib/kernel/qcoreapplication.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index b3f9f1a..a23b2dd 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -377,6 +377,14 @@ QString qAppName() QLibrary) can be retrieved with libraryPaths() and manipulated by setLibraryPaths(), addLibraryPath(), and removeLibraryPath(). + On Unix/Linux Qt is configured to use the system local settings by + default. This can cause a conflict when using POSIX functions, for + instance, when converting between data types such as floats and + strings, since the notation may differ between locales. To get + around this problem call the POSIX function setlocale(LC_NUMERIC,"C") + right after initializing QApplication or QCoreApplication to reset + the locale that is used for number formatting to "C"-locale. + \sa QApplication, QAbstractEventDispatcher, QEventLoop, {Semaphores Example}, {Wait Conditions Example} */ -- cgit v0.12 From e58807c2d750f41cbe88d49baa5ab42d0f61f5e7 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 31 Mar 2009 15:23:53 +0200 Subject: one more bogus trolltech => qtsoftware rename --- tools/linguist/linguist/phrase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/linguist/linguist/phrase.cpp b/tools/linguist/linguist/phrase.cpp index 563c72d..300f6e8 100644 --- a/tools/linguist/linguist/phrase.cpp +++ b/tools/linguist/linguist/phrase.cpp @@ -243,7 +243,7 @@ bool PhraseBook::load(const QString &fileName, bool *langGuessed) // don't click on these! reader.setFeature(QLatin1String("http://xml.org/sax/features/namespaces"), false); reader.setFeature(QLatin1String("http://xml.org/sax/features/namespace-prefixes"), true); - reader.setFeature(QLatin1String("http://qtsoftware.com/xml/features/report-whitespace" + reader.setFeature(QLatin1String("http://trolltech.com/xml/features/report-whitespace" "-only-CharData"), false); QphHandler *hand = new QphHandler(this); reader.setContentHandler(hand); -- cgit v0.12 From a5386aa328260157368877b44f2d8d40871f02cf Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 31 Mar 2009 16:11:54 +0200 Subject: do not crash upon dnd-ing text into non-focused lineedit Task-number: 249519 --- tools/linguist/linguist/messageeditor.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/linguist/linguist/messageeditor.cpp b/tools/linguist/linguist/messageeditor.cpp index 16908bf..dc8b8e4 100644 --- a/tools/linguist/linguist/messageeditor.cpp +++ b/tools/linguist/linguist/messageeditor.cpp @@ -786,6 +786,7 @@ void MessageEditor::selectAll() void MessageEditor::emitTranslationChanged() { + static_cast(sender())->getEditor()->setFocus(); // DND proofness updateBeginFromSource(); updateUndoRedo(); emit translationChanged(translations(m_currentModel)); @@ -793,6 +794,7 @@ void MessageEditor::emitTranslationChanged() void MessageEditor::emitTranslatorCommentChanged() { + static_cast(sender())->getEditor()->setFocus(); // DND proofness updateUndoRedo(); emit translatorCommentChanged(m_editors[m_currentModel].transCommentText->getTranslation()); } -- cgit v0.12 From eeb83668baf0f396f60882976437299746372217 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 31 Mar 2009 16:50:43 +0200 Subject: normalize file names makes tool tips less ugly Task-number: 246114 --- tools/linguist/linguist/formpreviewview.cpp | 2 +- tools/linguist/linguist/mainwindow.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/linguist/linguist/formpreviewview.cpp b/tools/linguist/linguist/formpreviewview.cpp index 990414b..184f01b 100644 --- a/tools/linguist/linguist/formpreviewview.cpp +++ b/tools/linguist/linguist/formpreviewview.cpp @@ -473,7 +473,7 @@ void FormPreviewView::setSourceContext(int model, MessageItem *messageItem) } QDir dir = QFileInfo(m_dataModel->srcFileName(model)).dir(); - QString fileName = dir.absoluteFilePath(messageItem->fileName()); + QString fileName = QDir::cleanPath(dir.absoluteFilePath(messageItem->fileName())); if (m_lastFormName != fileName) { delete m_form; m_form = 0; diff --git a/tools/linguist/linguist/mainwindow.cpp b/tools/linguist/linguist/mainwindow.cpp index 6ee0dd8..84200d4 100644 --- a/tools/linguist/linguist/mainwindow.cpp +++ b/tools/linguist/linguist/mainwindow.cpp @@ -1535,7 +1535,7 @@ void MainWindow::selectedMessageChanged(const QModelIndex &sortedIndex, const QM } else { m_sourceAndFormView->setCurrentWidget(m_sourceCodeView); QDir dir = QFileInfo(m_dataModel->srcFileName(model)).dir(); - QString fileName = dir.absoluteFilePath(m->fileName()); + QString fileName = QDir::cleanPath(dir.absoluteFilePath(m->fileName())); m_sourceCodeView->setSourceContext(fileName, m->lineNumber()); } m_errorsView->setEnabled(true); -- cgit v0.12 From 5ec8a27470d4004a60a2d9fc6bd757bbebae1fd7 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Wed, 1 Apr 2009 12:21:50 +0200 Subject: QComboBox with Qt::NoFocus triggers a crash. The showPopup() from a combobox triggers a crash. This happens only for a combobox which dosen't accept focus and it has been recreated. This is due to some invalid widget pointer stored in the input context. Task-number: 249576 Reviewed-by: ddenis --- src/gui/kernel/qapplication.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index c4224ed..09f0f91 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -2055,9 +2055,13 @@ void QApplicationPrivate::setFocusWidget(QWidget *focus, Qt::FocusReason reason) QWidget *prev = focus_widget; focus_widget = focus; - if (prev && reason != Qt::PopupFocusReason && reason != Qt::MenuBarFocusReason && - prev->testAttribute(Qt::WA_InputMethodEnabled)) { - QInputContext *qic = prev->inputContext(); + if (prev && ((reason != Qt::PopupFocusReason && reason != Qt::MenuBarFocusReason + && prev->testAttribute(Qt::WA_InputMethodEnabled)) + // Do reset the input context, in case the new focus widget won't accept keyboard input + // or it is not created fully yet. + || (focus_widget && (!focus_widget->testAttribute(Qt::WA_InputMethodEnabled) + || !focus_widget->testAttribute(Qt::WA_WState_Created))))) { + QInputContext *qic = prev->inputContext(); if(qic) { qic->reset(); qic->setFocusWidget(0); -- cgit v0.12 From 7ff89f9ee6d7c11a42300299cb699185dc020379 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Wed, 1 Apr 2009 11:21:45 +0200 Subject: QNetworkInterface: fix listing of all interfaces Before, we returned 0 for many interfaces because we picked up the IPv6 address regardless whether it was 0 or not. Reviewed-by: Prasanth Ullattil Task-number: 249312 --- src/network/kernel/qnetworkinterface_win.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/network/kernel/qnetworkinterface_win.cpp b/src/network/kernel/qnetworkinterface_win.cpp index 9540c18..de97629 100644 --- a/src/network/kernel/qnetworkinterface_win.cpp +++ b/src/network/kernel/qnetworkinterface_win.cpp @@ -173,14 +173,14 @@ static QList interfaceListingWinXP() interfaces << iface; iface->index = 0; - if (ptr->Length >= offsetof(IP_ADAPTER_ADDRESSES, Ipv6IfIndex)) + if (ptr->Length >= offsetof(IP_ADAPTER_ADDRESSES, Ipv6IfIndex) && ptr->Ipv6IfIndex != 0) iface->index = ptr->Ipv6IfIndex; else if (ptr->IfIndex != 0) iface->index = ptr->IfIndex; iface->flags = QNetworkInterface::CanBroadcast; - if (ptr->OperStatus == IfOperStatusUp) - iface->flags |= QNetworkInterface::IsUp | QNetworkInterface::IsRunning; + if (ptr->OperStatus == IfOperStatusUp) + iface->flags |= QNetworkInterface::IsUp | QNetworkInterface::IsRunning; if ((ptr->Flags & IP_ADAPTER_NO_MULTICAST) == 0) iface->flags |= QNetworkInterface::CanMulticast; -- cgit v0.12 From 8006e8bcb427a3949b6b4eec80b65bb58b5fdb8a Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Wed, 1 Apr 2009 13:24:19 +0200 Subject: QTextStream autotest: do not test against "imap.troll.no" ... but test against the test server. Reviewed-by: ogoffart --- tests/auto/qtextstream/tst_qtextstream.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/auto/qtextstream/tst_qtextstream.cpp b/tests/auto/qtextstream/tst_qtextstream.cpp index a60433a..5a6cce8 100644 --- a/tests/auto/qtextstream/tst_qtextstream.cpp +++ b/tests/auto/qtextstream/tst_qtextstream.cpp @@ -60,6 +60,8 @@ #include #include +#include "../network-settings.h" + static const char *TestFileName = "testfile"; Q_DECLARE_METATYPE(qlonglong) @@ -1229,7 +1231,7 @@ void tst_QTextStream::stillOpenWhenAtEnd() QSKIP("Qt/CE: Cannot test network on emulator", SkipAll); #endif QTcpSocket socket; - socket.connectToHost("imap.troll.no", 143); + socket.connectToHost(QtNetworkSettings::serverName(), 143); QVERIFY(socket.waitForReadyRead(5000)); QTextStream stream2(&socket); -- cgit v0.12 From 363636a3aa8abce0344388c0357a237e0d23baa3 Mon Sep 17 00:00:00 2001 From: kh Date: Wed, 1 Apr 2009 13:34:48 +0200 Subject: strip fragment and other parts from url in case of pdf Task-number: part of 238496 Reviewed-by: hjk --- tools/assistant/tools/assistant/helpviewer.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/tools/assistant/tools/assistant/helpviewer.cpp b/tools/assistant/tools/assistant/helpviewer.cpp index 9817f23..6b049e8 100644 --- a/tools/assistant/tools/assistant/helpviewer.cpp +++ b/tools/assistant/tools/assistant/helpviewer.cpp @@ -201,10 +201,14 @@ bool HelpPage::acceptNavigationRequest(QWebFrame *, { const QUrl &url = request.url(); if (isLocalUrl(url)) { - if (url.path().endsWith(QLatin1String("pdf"))) { - QString fileName = url.toString(); - fileName = QDir::tempPath() + QDir::separator() + fileName.right - (fileName.length() - fileName.lastIndexOf(QChar('/'))); + const QString& path = url.path(); + if (path.endsWith(QLatin1String(".pdf"))) { + const int lastDash = path.lastIndexOf(QChar('/')); + QString fileName = QDir::tempPath() + QDir::separator(); + if (lastDash < 0) + fileName += path; + else + fileName += path.mid(lastDash + 1, path.length()); QFile tmpFile(QDir::cleanPath(fileName)); if (tmpFile.open(QIODevice::ReadWrite)) { @@ -396,15 +400,19 @@ void HelpViewer::zoomOut(int range) bool HelpViewer::launchedWithExternalApp(const QUrl &url) { - bool isPdf = url.path().endsWith(QLatin1String("pdf")); + bool isPdf = url.path().endsWith(QLatin1String(".pdf")); if (url.scheme() == QLatin1String("http") || url.scheme() == QLatin1String("ftp") || url.scheme() == QLatin1String("mailto") || isPdf) { bool launched = false; if (isPdf && url.scheme() == QLatin1String("qthelp")) { - QString fileName = url.toString(); - fileName = QDir::tempPath() + QDir::separator() + fileName.right - (fileName.length() - fileName.lastIndexOf(QLatin1Char('/'))); + const QString& path = url.path(); + const int lastDash = path.lastIndexOf(QChar('/')); + QString fileName = QDir::tempPath() + QDir::separator(); + if (lastDash < 0) + fileName += path; + else + fileName += path.mid(lastDash + 1, path.length()); QFile tmpFile(QDir::cleanPath(fileName)); if (tmpFile.open(QIODevice::ReadWrite)) { -- cgit v0.12 From f6830ef93552005b5dc9fee2d9649f9915842615 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 1 Apr 2009 15:06:01 +0200 Subject: Subject: Fix typo in CompositionMode section Reviewed-by: TrustMe --- 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 e2d9b32..fe6cc69 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -1293,7 +1293,7 @@ void QPainterPrivate::updateState(QPainterState *newState) destination. Note that composition transformation operates pixelwise. For that - reason, there is a difference between using the grahic primitive + reason, there is a difference between using the graphic primitive itself and its bounding rectangle: The bounding rect contains pixels with alpha == 0 (i.e the pixels surrounding the primitive). These pixels will overwrite the other image's pixels, -- cgit v0.12 From b224b6006e823435297c2f0b82c835f5987f9b10 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Tue, 31 Mar 2009 13:40:34 +0200 Subject: Input Method cannot be enabled in License Wizard and Class Wizard Input methods didn't work properly wor widgets inside QWizardPage because the widget got focus before it was shown and input context wasn't initialized properly. The fix is to postpone qinputcontext->setFocusWidget call until the widget is created (input context will be initialized in the QWidget::create_sys function). Task-number: 244604 Reviewed-by: Prasanth Ullattil --- src/gui/inputmethod/qximinputcontext_x11.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/inputmethod/qximinputcontext_x11.cpp b/src/gui/inputmethod/qximinputcontext_x11.cpp index 1c8560f..c320fb4 100644 --- a/src/gui/inputmethod/qximinputcontext_x11.cpp +++ b/src/gui/inputmethod/qximinputcontext_x11.cpp @@ -437,7 +437,8 @@ void QXIMInputContext::create_xim() // reinitialize input context after the input method // server (like SCIM) has been launched without // requiring the user to manually switch focus. - if (focusWidget->testAttribute(Qt::WA_InputMethodEnabled)) + if (focusWidget->testAttribute(Qt::WA_InputMethodEnabled) + && focusWidget->testAttribute(Qt::WA_WState_Created)) setFocusWidget(focusWidget); } // following code fragment is not required for immodule -- cgit v0.12 From ebd82c4fb5d7e9b417baca199b6f9e6893318536 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 1 Apr 2009 11:04:29 +0200 Subject: Removed obsolete internal function that focuses input context. Reviewed-by: TrustMe --- src/gui/kernel/qwidget.cpp | 22 ---------------------- src/gui/kernel/qwidget_p.h | 2 -- src/gui/kernel/qwidget_x11.cpp | 1 - 3 files changed, 25 deletions(-) diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 09162ee..fd3d304 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -235,28 +235,6 @@ QWindowSurface *QWidgetPrivate::createDefaultWindowSurface() /*! \internal - This is an internal function, you should never call this. - - This function is called to focus associated input context. The - code intends to eliminate duplicate focus for the context even if - the context is shared between widgets - - \sa QInputContext::setFocus() - */ -void QWidgetPrivate::focusInputContext() -{ -#ifndef QT_NO_IM - Q_Q(QWidget); - QInputContext *qic = q->inputContext(); - if (qic) { - if(qic->focusWidget() != q) - qic->setFocusWidget(q); - } -#endif // QT_NO_IM -} - -/*! - \internal */ void QWidgetPrivate::scrollChildren(int dx, int dy) { diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index f254c4a..9e93f66 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -354,8 +354,6 @@ public: void setWindowIcon_sys(bool forceReset = false); void setWindowOpacity_sys(qreal opacity); - void focusInputContext(); - void adjustQuitOnCloseAttribute(); #if defined(Q_WS_X11) diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp index a12b50c..e71bc2f 100644 --- a/src/gui/kernel/qwidget_x11.cpp +++ b/src/gui/kernel/qwidget_x11.cpp @@ -1516,7 +1516,6 @@ void QWidget::activateWindow() X11->userTime = X11->time; qt_net_update_user_time(tlw, X11->userTime); XSetInputFocus(X11->display, tlw->internalWinId(), XRevertToParent, X11->time); - d->focusInputContext(); } } -- cgit v0.12 From aaf765dfb797da6b72807fad61fd2a1d19187c0c Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 1 Apr 2009 11:19:26 +0200 Subject: Marked QWidget::resetInputContext() function as obsolete. Fixed the behavior of the function that was broken by me some time ago. But anyway this function is for convenience only since QInputContext that operates on the widget is available to the user directly. Reviewed-by: Prasanth Ullattil --- src/gui/kernel/qwidget.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index fd3d304..f92d660 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -308,20 +308,24 @@ void QWidget::setInputContext(QInputContext *context) /*! + \obsolete + This function can be called on the widget that currently has focus to reset the input method operating on it. - \sa QInputContext, QInputContext::reset() + This function is providing for convenience, instead you should use + \l{QInputContext::}{reset()} on the input context that was + returned by inputContext(). + + \sa QInputContext, inputContext(), QInputContext::reset() */ void QWidget::resetInputContext() { if (!hasFocus()) return; #ifndef QT_NO_IM - if (!d_func()->ic) - return; QInputContext *qic = this->inputContext(); - if( qic ) + if(qic) qic->reset(); #endif // QT_NO_IM } -- cgit v0.12 From 1df41e19604d8c8945ad8e55e36016e480446576 Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Wed, 1 Apr 2009 16:04:58 +0200 Subject: Doc - clarified that QMessageBox's predefined icons are not defined in QMessageBox, but provided by the style. Task-number: 249946 Reviewed-by: TrustMe --- src/gui/dialogs/qmessagebox.cpp | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/gui/dialogs/qmessagebox.cpp b/src/gui/dialogs/qmessagebox.cpp index f343405..1967837 100644 --- a/src/gui/dialogs/qmessagebox.cpp +++ b/src/gui/dialogs/qmessagebox.cpp @@ -532,11 +532,11 @@ void QMessageBoxPrivate::_q_buttonClicked(QAbstractButton *button) \section2 Severity Levels and the Icon and Pixmap Properties - QMessageBox supports four predefined message severity levels, or - message types, which really only differ in the predefined icon - they each show. Specify one of the four predefined message types - by setting the \l{QMessageBox::icon} {icon} property to one of the - \l{QMessageBox::Icon} {predefined Icons}. The following rules are + QMessageBox supports four predefined message severity levels, or message + types, which really only differ in the predefined icon they each show. + Specify one of the four predefined message types by setting the + \l{QMessageBox::icon}{icon} property to one of the + \l{QMessageBox::Icon}{predefined icons}. The following rules are guidelines: \table @@ -558,17 +558,17 @@ void QMessageBoxPrivate::_q_buttonClicked(QAbstractButton *button) \o For reporting critical errors. \endtable - The default value is \l{QMessageBox::NoIcon} {No Icon}. The - message boxes are otherwise the same for all cases. When using a - standard icon, use the one recommended in the table, or use the - one recommended by the style guidelines for your platform. If none - of the standard icons is right for your message box, you can use a - custom icon by setting the \l{QMessageBox::iconPixmap} {icon - pixmap} property instead of setting the \l{QMessageBox::icon} - {icon} property. - - In summary, to set an icon, use \e{either} setIcon() for one of - the standard icons, \e{or} setIconPixmap() for a custom icon. + \l{QMessageBox::Icon}{Predefined icons} are not defined by QMessageBox, but + provided by the style. The default value is \l{QMessageBox::NoIcon} + {No Icon}. The message boxes are otherwise the same for all cases. When + using a standard icon, use the one recommended in the table, or use the + one recommended by the style guidelines for your platform. If none of the + standard icons is right for your message box, you can use a custom icon by + setting the \l{QMessageBox::iconPixmap}{icon pixmap} property instead of + setting the \l{QMessageBox::icon}{icon} property. + + In summary, to set an icon, use \e{either} setIcon() for one of the + standard icons, \e{or} setIconPixmap() for a custom icon. \section1 The Static Functions API -- cgit v0.12 From 6eac95b553f4a2958c2c58127441f2705b05b0a3 Mon Sep 17 00:00:00 2001 From: kh Date: Wed, 1 Apr 2009 16:17:18 +0200 Subject: don't open the TopicChooser if no link is avaliable Task-number: none Reviewed-by: hjk --- tools/assistant/tools/assistant/indexwindow.cpp | 56 ++++++++++--------------- tools/assistant/tools/assistant/indexwindow.h | 2 + 2 files changed, 23 insertions(+), 35 deletions(-) diff --git a/tools/assistant/tools/assistant/indexwindow.cpp b/tools/assistant/tools/assistant/indexwindow.cpp index e7575fa..4bd6f4f 100644 --- a/tools/assistant/tools/assistant/indexwindow.cpp +++ b/tools/assistant/tools/assistant/indexwindow.cpp @@ -122,10 +122,9 @@ bool IndexWindow::eventFilter(QObject *obj, QEvent *e) m_indexWidget->setCurrentIndex(idx); break; case Qt::Key_Escape: - emit escapePressed(); + emit escapePressed(); break; - default: - ; + default: ; // stop complaining } } else if (obj == m_indexWidget && e->type() == QEvent::ContextMenu) { QContextMenuEvent *ctxtEvent = static_cast(e); @@ -140,44 +139,15 @@ bool IndexWindow::eventFilter(QObject *obj, QEvent *e) if (curTab == action) m_indexWidget->activateCurrentItem(); else if (newTab == action) { - QHelpIndexModel *model = - qobject_cast(m_indexWidget->model()); - QString keyword = model->data(idx, Qt::DisplayRole).toString(); - if (model) { - QMap links = model->linksForKeyword(keyword); - if (links.count() == 1) { - CentralWidget::instance()-> - setSourceInNewTab(links.constBegin().value()); - } else { - TopicChooser tc(this, keyword, links); - if (tc.exec() == QDialog::Accepted) { - CentralWidget::instance()->setSourceInNewTab(tc.link()); - } - } - } + open(m_indexWidget, idx); } } } else if (m_indexWidget && obj == m_indexWidget->viewport() && e->type() == QEvent::MouseButtonRelease) { QMouseEvent *mouseEvent = static_cast(e); QModelIndex idx = m_indexWidget->indexAt(mouseEvent->pos()); - if (idx.isValid() && mouseEvent->button()==Qt::MidButton) { - QHelpIndexModel *model = - qobject_cast(m_indexWidget->model()); - QString keyword = model->data(idx, Qt::DisplayRole).toString(); - if (model) { - QMap links = model->linksForKeyword(keyword); - if (links.count() > 1) { - TopicChooser tc(this, keyword, links); - if (tc.exec() == QDialog::Accepted) { - CentralWidget::instance()->setSourceInNewTab(tc.link()); - } - } else if (links.count() == 1) { - CentralWidget::instance()-> - setSourceInNewTab(links.constBegin().value()); - } - } - } + if (idx.isValid() && mouseEvent->button()==Qt::MidButton) + open(m_indexWidget, idx); } #ifdef Q_OS_MAC else if (obj == m_indexWidget && e->type() == QEvent::KeyPress) { @@ -213,4 +183,20 @@ void IndexWindow::focusInEvent(QFocusEvent *e) } } +void IndexWindow::open(QHelpIndexWidget* indexWidget, const QModelIndex &index) +{ + QHelpIndexModel *model = qobject_cast(indexWidget->model()); + if (model) { + QString keyword = model->data(index, Qt::DisplayRole).toString(); + QMap links = model->linksForKeyword(keyword); + if (links.count() > 1) { + TopicChooser tc(this, keyword, links); + if (tc.exec() == QDialog::Accepted) + CentralWidget::instance()->setSourceInNewTab(tc.link()); + } else if (links.count() == 1) { + CentralWidget::instance()->setSourceInNewTab(links.constBegin().value()); + } + } +} + QT_END_NAMESPACE diff --git a/tools/assistant/tools/assistant/indexwindow.h b/tools/assistant/tools/assistant/indexwindow.h index f1f57f9..14ed83c 100644 --- a/tools/assistant/tools/assistant/indexwindow.h +++ b/tools/assistant/tools/assistant/indexwindow.h @@ -50,6 +50,7 @@ QT_BEGIN_NAMESPACE class QHelpIndexWidget; class QHelpEngine; +class QModelIndex; class IndexWindow : public QWidget { @@ -79,6 +80,7 @@ private slots: private: bool eventFilter(QObject *obj, QEvent *e); void focusInEvent(QFocusEvent *e); + void open(QHelpIndexWidget *indexWidget, const QModelIndex &index); QLineEdit *m_searchLineEdit; QHelpIndexWidget *m_indexWidget; -- cgit v0.12 From ef46fa38e50b807c6122dc37d84d2944069ef3ea Mon Sep 17 00:00:00 2001 From: kh Date: Wed, 1 Apr 2009 16:18:12 +0200 Subject: don't invoke the current item without selection Task-number: none Reviewed-by: hjk --- tools/assistant/tools/assistant/contentwindow.cpp | 41 +++++++++++++---------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/tools/assistant/tools/assistant/contentwindow.cpp b/tools/assistant/tools/assistant/contentwindow.cpp index ef272e8..24e7ca9 100644 --- a/tools/assistant/tools/assistant/contentwindow.cpp +++ b/tools/assistant/tools/assistant/contentwindow.cpp @@ -118,19 +118,24 @@ void ContentWindow::keyPressEvent(QKeyEvent *e) bool ContentWindow::eventFilter(QObject *o, QEvent *e) { - if (m_contentWidget && o == m_contentWidget->viewport() && e->type() - == QEvent::MouseButtonRelease) { + if (m_contentWidget && o == m_contentWidget->viewport() + && e->type() == QEvent::MouseButtonRelease) { QMouseEvent *me = static_cast(e); - if (m_contentWidget->indexAt(me->pos()).isValid() - && me->button() == Qt::LeftButton) { - itemClicked(m_contentWidget->currentIndex()); - } else if (m_contentWidget->indexAt(me->pos()).isValid() - && me->button() == Qt::MidButton) { - QHelpContentModel *contentModel = - qobject_cast(m_contentWidget->model()); - QHelpContentItem *itm = - contentModel->contentItemAt(m_contentWidget->currentIndex()); - CentralWidget::instance()->setSourceInNewTab(itm->url()); + QModelIndex index = m_contentWidget->indexAt(me->pos()); + QItemSelectionModel *sm = m_contentWidget->selectionModel(); + + if (index.isValid() && (sm && sm->isSelected(index))) { + if (me->button() == Qt::LeftButton) { + itemClicked(index); + } else if (me->button() == Qt::MidButton) { + QHelpContentModel *contentModel = + qobject_cast(m_contentWidget->model()); + if (contentModel) { + QHelpContentItem *itm = contentModel->contentItemAt(index); + if (itm) + CentralWidget::instance()->setSourceInNewTab(itm->url()); + } + } } } return QWidget::eventFilter(o, e); @@ -160,14 +165,14 @@ void ContentWindow::showContextMenu(const QPoint &pos) void ContentWindow::itemClicked(const QModelIndex &index) { - if (!index.isValid()) - return; QHelpContentModel *contentModel = qobject_cast(m_contentWidget->model()); - QHelpContentItem *itm = - contentModel->contentItemAt(index); - if (itm) - emit linkActivated(itm->url()); + + if (contentModel) { + QHelpContentItem *itm = contentModel->contentItemAt(index); + if (itm) + emit linkActivated(itm->url()); + } } QT_END_NAMESPACE -- cgit v0.12