diff options
Diffstat (limited to 'src')
63 files changed, 578 insertions, 406 deletions
diff --git a/src/corelib/animation/qpropertyanimation.cpp b/src/corelib/animation/qpropertyanimation.cpp index a68301c..7526a81 100644 --- a/src/corelib/animation/qpropertyanimation.cpp +++ b/src/corelib/animation/qpropertyanimation.cpp @@ -43,6 +43,7 @@ \class QPropertyAnimation \brief The QPropertyAnimation class animates Qt properties \since 4.6 + \mainclass \ingroup animation QPropertyAnimation interpolates over \l{Qt's Property System}{Qt diff --git a/src/corelib/codecs/qfontlaocodec.cpp b/src/corelib/codecs/qfontlaocodec.cpp index 85017e0..6dd87de 100644 --- a/src/corelib/codecs/qfontlaocodec.cpp +++ b/src/corelib/codecs/qfontlaocodec.cpp @@ -97,8 +97,7 @@ QString QFontLaoCodec::convertToUnicode(const char *, int, ConverterState *) con QByteArray QFontLaoCodec::convertFromUnicode(const QChar *uc, int len, ConverterState *) const { - QByteArray rstring; - rstring.resize(len); + QByteArray rstring(len, Qt::Uninitialized); uchar *rdata = (uchar *) rstring.data(); const QChar *sdata = uc; int i = 0; diff --git a/src/corelib/codecs/qiconvcodec.cpp b/src/corelib/codecs/qiconvcodec.cpp index 6b9c77b..1bf76ea 100644 --- a/src/corelib/codecs/qiconvcodec.cpp +++ b/src/corelib/codecs/qiconvcodec.cpp @@ -225,11 +225,10 @@ QString QIconvCodec::convertToUnicode(const char* chars, int len, ConverterState char *inBytes = const_cast<char *>(chars); #endif - QByteArray in; if (remainingCount) { // we have to prepend the remaining bytes from the previous conversion inBytesLeft += remainingCount; - in.resize(inBytesLeft); + QByteArray in(inBytesLeft, Qt::Uninitialized); inBytes = in.data(); memcpy(in.data(), remainingBuffer, remainingCount); @@ -238,9 +237,8 @@ QString QIconvCodec::convertToUnicode(const char* chars, int len, ConverterState remainingCount = 0; } - QByteArray ba; size_t outBytesLeft = len * 2 + 2; - ba.resize(outBytesLeft); + QByteArray ba(outBytesLeft, Qt::Uninitialized); char *outBytes = ba.data(); do { size_t ret = iconv(state->cd, &inBytes, &inBytesLeft, &outBytes, &outBytesLeft); @@ -328,8 +326,7 @@ QByteArray QIconvCodec::convertFromUnicode(const QChar *uc, int len, ConverterSt state = new IconvState(QIconvCodec::createIconv_t(0, UTF16)); if (state->cd != reinterpret_cast<iconv_t>(-1)) { size_t outBytesLeft = len + 3; // +3 for the BOM - QByteArray ba; - ba.resize(outBytesLeft); + QByteArray ba(outBytesLeft, Qt::Uninitialized); outBytes = ba.data(); #if !defined(NO_BOM) @@ -358,18 +355,16 @@ QByteArray QIconvCodec::convertFromUnicode(const QChar *uc, int len, ConverterSt } size_t outBytesLeft = len; - QByteArray ba; - ba.resize(outBytesLeft); + QByteArray ba(outBytesLeft, Qt::Uninitialized); outBytes = ba.data(); // now feed iconv() the real data inBytes = const_cast<char *>(reinterpret_cast<const char *>(uc)); inBytesLeft = len * sizeof(QChar); - QByteArray in; if (convState && convState->remainingChars) { // we have one surrogate char to be prepended - in.resize(sizeof(QChar) + len); + QByteArray in(sizeof(QChar) + len, Qt::Uninitialized); inBytes = in.data(); QChar remaining = convState->state_data[0]; diff --git a/src/corelib/codecs/qisciicodec.cpp b/src/corelib/codecs/qisciicodec.cpp index a33fd0d..c054313 100644 --- a/src/corelib/codecs/qisciicodec.cpp +++ b/src/corelib/codecs/qisciicodec.cpp @@ -187,8 +187,7 @@ QByteArray QIsciiCodec::convertFromUnicode(const QChar *uc, int len, ConverterSt } int invalid = 0; - QByteArray result; - result.resize(2*len); //worst case + QByteArray result(2 * len, Qt::Uninitialized); //worst case uchar *ch = reinterpret_cast<uchar *>(result.data()); @@ -250,8 +249,7 @@ QString QIsciiCodec::convertToUnicode(const char* chars, int len, ConverterState halant = state->state_data[0]; } - QString result; - result.resize(len); + QString result(len, Qt::Uninitialized); QChar *uc = result.data(); const int base = codecs[idx].base; diff --git a/src/corelib/codecs/qlatincodec.cpp b/src/corelib/codecs/qlatincodec.cpp index 176ae97..9113555 100644 --- a/src/corelib/codecs/qlatincodec.cpp +++ b/src/corelib/codecs/qlatincodec.cpp @@ -62,8 +62,7 @@ QString QLatin1Codec::convertToUnicode(const char *chars, int len, ConverterStat QByteArray QLatin1Codec::convertFromUnicode(const QChar *ch, int len, ConverterState *state) const { const char replacement = (state && state->flags & ConvertInvalidToNull) ? 0 : '?'; - QByteArray r; - r.resize(len); + QByteArray r(len, Qt::Uninitialized); char *d = r.data(); int invalid = 0; for (int i = 0; i < len; ++i) { @@ -151,8 +150,7 @@ QString QLatin15Codec::convertToUnicode(const char* chars, int len, ConverterSta QByteArray QLatin15Codec::convertFromUnicode(const QChar *in, int length, ConverterState *state) const { const char replacement = (state && state->flags & ConvertInvalidToNull) ? 0 : '?'; - QByteArray r; - r.resize(length); + QByteArray r(length, Qt::Uninitialized); char *d = r.data(); int invalid = 0; for (int i = 0; i < length; ++i) { diff --git a/src/corelib/codecs/qsimplecodec.cpp b/src/corelib/codecs/qsimplecodec.cpp index 7a62d4e..0d14f67 100644 --- a/src/corelib/codecs/qsimplecodec.cpp +++ b/src/corelib/codecs/qsimplecodec.cpp @@ -653,8 +653,7 @@ QString QSimpleTextCodec::convertToUnicode(const char* chars, int len, Converter const unsigned char * c = (const unsigned char *)chars; - QString r; - r.resize(len); + QString r(len, Qt::Uninitialized); QChar* uc = r.data(); for (int i = 0; i < len; i++) { @@ -677,8 +676,7 @@ QByteArray QSimpleTextCodec::convertFromUnicode(const QChar *in, int length, Con delete tmp; } - QByteArray r; - r.resize(length); + QByteArray r(length, Qt::Uninitialized); int i = length; int u; const QChar* ucp = in; diff --git a/src/corelib/codecs/qtsciicodec.cpp b/src/corelib/codecs/qtsciicodec.cpp index 7f660bf..c24d32d 100644 --- a/src/corelib/codecs/qtsciicodec.cpp +++ b/src/corelib/codecs/qtsciicodec.cpp @@ -82,8 +82,7 @@ QByteArray QTsciiCodec::convertFromUnicode(const QChar *uc, int len, ConverterSt } int invalid = 0; - QByteArray rstr; - rstr.resize(len); + QByteArray rstr(len, Qt::Uninitialized); uchar* cursor = (uchar*)rstr.data(); for (int i = 0; i < len; i++) { QChar ch = uc[i]; diff --git a/src/corelib/codecs/qutfcodec.cpp b/src/corelib/codecs/qutfcodec.cpp index 12575f9..abae6f7 100644 --- a/src/corelib/codecs/qutfcodec.cpp +++ b/src/corelib/codecs/qutfcodec.cpp @@ -351,8 +351,7 @@ QString QUtf16Codec::convertToUnicode(const char *chars, int len, ConverterState if (headerdone && endian == Detect) endian = (QSysInfo::ByteOrder == QSysInfo::BigEndian) ? BE : LE; - QString result; - result.resize(len); // worst case + QString result(len, Qt::Uninitialized); // worst case QChar *qch = (QChar *)result.unicode(); while (len--) { if (half) { @@ -472,8 +471,7 @@ QByteArray QUtf32Codec::convertFromUnicode(const QChar *uc, int len, ConverterSt endian = (QSysInfo::ByteOrder == QSysInfo::BigEndian) ? BE : LE; } - QByteArray d; - d.resize(length); + QByteArray d(length, Qt::Uninitialized); char *data = d.data(); if (!state || !(state->flags & IgnoreHeader)) { if (endian == BE) { diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index fe11fab..2e2a09d 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1546,6 +1546,10 @@ public: TitleBarArea // For move }; + enum Initialization { + Uninitialized + }; + enum TouchPointState { TouchPointPressed = 0x01, TouchPointMoved = 0x02, diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 0c45776..5d3386e 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -1304,6 +1304,21 @@ QByteArray::QByteArray(int size, char ch) } /*! + \internal + + Constructs a byte array of size \a size with uninitialized contents. +*/ + +QByteArray::QByteArray(int size, Qt::Initialization) +{ + d = static_cast<Data *>(qMalloc(sizeof(Data)+size)); + d->ref = 1; + d->alloc = d->size = size; + d->data = d->array; + d->array[size] = '\0'; +} + +/*! Sets the size of the byte array to \a size bytes. If \a size is greater than the current size, the byte array is @@ -2977,8 +2992,7 @@ QByteArray QByteArray::simplified() const { if (d->size == 0) return *this; - QByteArray result; - result.resize(d->size); + QByteArray result(d->size, Qt::Uninitialized); const char *from = d->data; const char *fromend = from + d->size; int outc=0; @@ -3429,8 +3443,7 @@ QByteArray QByteArray::toBase64() const const char padchar = '='; int padlen = 0; - QByteArray tmp; - tmp.resize(((d->size * 4) / 3) + 3); + QByteArray tmp((d->size * 4) / 3 + 3, Qt::Uninitialized); int i = 0; char *out = tmp.data(); @@ -3768,8 +3781,7 @@ QByteArray QByteArray::fromBase64(const QByteArray &base64) { unsigned int buf = 0; int nbits = 0; - QByteArray tmp; - tmp.resize((base64.size() * 3) / 4); + QByteArray tmp((base64.size() * 3) / 4, Qt::Uninitialized); int offset = 0; for (int i = 0; i < base64.size(); ++i) { @@ -3817,8 +3829,7 @@ QByteArray QByteArray::fromBase64(const QByteArray &base64) */ QByteArray QByteArray::fromHex(const QByteArray &hexEncoded) { - QByteArray res; - res.resize((hexEncoded.size() + 1)/ 2); + QByteArray res((hexEncoded.size() + 1)/ 2, Qt::Uninitialized); uchar *result = (uchar *)res.data() + res.size(); bool odd_digit = true; @@ -3855,8 +3866,7 @@ QByteArray QByteArray::fromHex(const QByteArray &hexEncoded) */ QByteArray QByteArray::toHex() const { - QByteArray hex; - hex.resize(d->size*2); + QByteArray hex(d->size * 2, Qt::Uninitialized); char *hexData = hex.data(); const uchar *data = (const uchar *)d->data; for (int i = 0; i < d->size; ++i) { diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h index 5cd4d63..e494ac1 100644 --- a/src/corelib/tools/qbytearray.h +++ b/src/corelib/tools/qbytearray.h @@ -42,8 +42,8 @@ #ifndef QBYTEARRAY_H #define QBYTEARRAY_H -#include <QtCore/qglobal.h> #include <QtCore/qatomic.h> +#include <QtCore/qnamespace.h> #include <string.h> #include <stdarg.h> @@ -127,6 +127,7 @@ public: QByteArray(const char *); QByteArray(const char *, int size); QByteArray(int size, char c); + QByteArray(int size, Qt::Initialization); inline QByteArray(const QByteArray &); inline ~QByteArray(); diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 52fb8a2..cbdd32c 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -185,8 +185,7 @@ static QString languageToCode(QLocale::Language language) const unsigned char *c = language_code_list + 3*(uint(language)); - QString code; - code.resize(c[2] == 0 ? 2 : 3); + QString code(c[2] == 0 ? 2 : 3, Qt::Uninitialized); code[0] = ushort(c[0]); code[1] = ushort(c[1]); @@ -201,8 +200,7 @@ static QString countryToCode(QLocale::Country country) if (country == QLocale::AnyCountry) return QString(); - QString code; - code.resize(2); + QString code(2, Qt::Uninitialized); const unsigned char *c = country_code_list + 2*(uint(country)); code[0] = ushort(c[0]); code[1] = ushort(c[1]); diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 3b70f44..3ff263d 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -1012,14 +1012,13 @@ QString::QString(int size, QChar ch) } } -/*! - Constructs a string of the given \a size without initializing the - characters. This is only used in \c QStringBuilder::toString(). +/*! \fn QString::QString(int size, Qt::Initialization) + \internal - \internal + Constructs a string of the given \a size without initializing the + characters. This is only used in \c QStringBuilder::toString(). */ - -QString::QString(int size, Uninitialized) +QString::QString(int size, Qt::Initialization) { d = (Data*) qMalloc(sizeof(Data)+size*sizeof(QChar)); d->ref = 1; @@ -3849,8 +3848,7 @@ QString QString::fromUtf8(const char *str, int size) if (size < 0) size = qstrlen(str); - QString result; - result.resize(size); // worst case + QString result(size, Qt::Uninitialized); // worst case ushort *qch = result.d->data; uint uc = 0; uint min_uc = 0; @@ -3965,8 +3963,7 @@ QString QString::fromUcs4(const uint *unicode, int size) ++size; } - QString s; - s.resize(size*2); // worst case + QString s(size * 2, Qt::Uninitialized); // worst case ushort *uc = s.d->data; for (int i = 0; i < size; ++i) { uint u = unicode[i]; @@ -4029,8 +4026,7 @@ QString QString::simplified() const { if (d->size == 0) return *this; - QString result; - result.resize(d->size); + QString result(d->size, Qt::Uninitialized); const QChar *from = (const QChar*) d->data; const QChar *fromend = (const QChar*) from+d->size; int outc=0; @@ -4882,8 +4878,7 @@ QString QString::toLower() const c = QChar::surrogateToUcs4(*(p - 1), c); const QUnicodeTables::Properties *prop = qGetProp(c); if (prop->lowerCaseDiff || prop->lowerCaseSpecial) { - QString s; - s.resize(d->size); + QString s(d->size, Qt::Uninitialized); memcpy(s.d->data, d->data, (p - d->data)*sizeof(ushort)); ushort *pp = s.d->data + (p - d->data); while (p < e) { @@ -4974,8 +4969,7 @@ QString QString::toUpper() const c = QChar::surrogateToUcs4(*(p - 1), c); const QUnicodeTables::Properties *prop = qGetProp(c); if (prop->upperCaseDiff || prop->upperCaseSpecial) { - QString s; - s.resize(d->size); + QString s(d->size, Qt::Uninitialized); memcpy(s.d->data, d->data, (p - d->data)*sizeof(ushort)); ushort *pp = s.d->data + (p - d->data); while (p < e) { @@ -6272,8 +6266,7 @@ static QString replaceArgEscapes(const QString &s, const ArgEscapeData &d, int f + d.locale_occurrences *qMax(abs_field_width, larg.length()); - QString result; - result.resize(result_len); + QString result(result_len, Qt::Uninitialized); QChar *result_buff = (QChar*) result.unicode(); QChar *rc = result_buff; diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 4b2ceb7..6bb0d8e 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -579,8 +579,7 @@ public: bool isSimpleText() const { if (!d->clean) updateProperties(); return d->simpletext; } bool isRightToLeft() const { if (!d->clean) updateProperties(); return d->righttoleft; } - struct Uninitialized {}; - QString(int size, Uninitialized); + QString(int size, Qt::Initialization); private: #if defined(QT_NO_CAST_FROM_ASCII) && !defined(Q_NO_DECLARED_NOT_DEFINED) diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h index 19f14b4..852c072 100644 --- a/src/corelib/tools/qstringbuilder.h +++ b/src/corelib/tools/qstringbuilder.h @@ -80,7 +80,7 @@ public: operator QString() const { QString s(QConcatenable< QStringBuilder<A, B> >::size(*this), - QString::Uninitialized()); + Qt::Uninitialized); QChar *d = s.data(); QConcatenable< QStringBuilder<A, B> >::appendTo(*this, d); diff --git a/src/gui/dialogs/qfontdialog.cpp b/src/gui/dialogs/qfontdialog.cpp index 582ba9b..e258cb5 100644 --- a/src/gui/dialogs/qfontdialog.cpp +++ b/src/gui/dialogs/qfontdialog.cpp @@ -501,8 +501,6 @@ void QFontDialogPrivate::updateFamilies() { Q_Q(QFontDialog); - familyList->blockSignals(true); - enum match_t { MATCH_NONE = 0, MATCH_LAST_RESORT = 1, MATCH_APP = 2, MATCH_FAMILY = 3 }; QStringList familyNames = fdb.families(writingSystem); @@ -556,7 +554,6 @@ void QFontDialogPrivate::updateFamilies() && familyList->hasFocus()) familyEdit->selectAll(); - familyList->blockSignals(false); updateStyles(); } @@ -567,9 +564,6 @@ void QFontDialogPrivate::updateFamilies() void QFontDialogPrivate::updateStyles() { Q_Q(QFontDialog); - - styleList->blockSignals(true); - QStringList styles = fdb.styles(familyList->currentText()); styleList->model()->setStringList(styles); @@ -613,8 +607,6 @@ void QFontDialogPrivate::updateStyles() smoothScalable = fdb.isSmoothlyScalable(familyList->currentText(), styleList->currentText()); } - styleList->blockSignals(false); - updateSizes(); } @@ -628,8 +620,6 @@ void QFontDialogPrivate::updateSizes() { Q_Q(QFontDialog); - sizeList->blockSignals(true); - if (!familyList->currentText().isEmpty()) { QList<int> sizes = fdb.pointSizes(familyList->currentText(), styleList->currentText()); @@ -659,7 +649,6 @@ void QFontDialogPrivate::updateSizes() sizeEdit->clear(); } - sizeList->blockSignals(false); _q_updateSample(); } diff --git a/src/gui/dialogs/qinputdialog.cpp b/src/gui/dialogs/qinputdialog.cpp index 8c0c2c7..e2c5742 100644 --- a/src/gui/dialogs/qinputdialog.cpp +++ b/src/gui/dialogs/qinputdialog.cpp @@ -1128,8 +1128,8 @@ void QInputDialog::done(int result) is \a parent. The dialog will be modal and uses the specified widget \a flags. - This function returns the text which has been entered in the line - edit. It will not return an empty string. + If the dialog is accepted, this function returns the text in the dialog's + line edit. If the dialog is rejected, a null QString is returned. Use this static function like this: @@ -1158,7 +1158,7 @@ QString QInputDialog::getText(QWidget *parent, const QString &title, const QStri if (ret) { return dialog.textValue(); } else { - return text; + return QString(); } } diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 1c062cc..e8ed97f 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -800,7 +800,7 @@ QPointF QGraphicsItemPrivate::genericMapFromScene(const QPointF &pos, void QGraphicsItemPrivate::combineTransformToParent(QTransform *x, const QTransform *viewTransform) const { // COMBINE - if (itemIsUntransformable() && viewTransform) { + if (viewTransform && itemIsUntransformable()) { *x = q_ptr->deviceTransform(*viewTransform); } else { if (transformData) @@ -822,7 +822,7 @@ void QGraphicsItemPrivate::combineTransformToParent(QTransform *x, const QTransf void QGraphicsItemPrivate::combineTransformFromParent(QTransform *x, const QTransform *viewTransform) const { // COMBINE - if (itemIsUntransformable() && viewTransform) { + if (viewTransform && itemIsUntransformable()) { *x = q_ptr->deviceTransform(*viewTransform); } else { x->translate(pos.x(), pos.y()); @@ -992,7 +992,8 @@ void QGraphicsItemPrivate::childrenBoundingRectHelper(QTransform *x, QRectF *rec bool hasPos = !childd->pos.isNull(); if (hasPos || childd->transformData) { // COMBINE - QTransform matrix = childd->transformToParent() * *x; + QTransform matrix = childd->transformToParent(); + matrix *= *x; *rect |= matrix.mapRect(child->boundingRect()); if (!childd->children.isEmpty()) childd->childrenBoundingRectHelper(&matrix, rect); @@ -3238,8 +3239,7 @@ QTransform QGraphicsItem::deviceTransform(const QTransform &viewportTransform) c QPointF mappedPoint = (untransformedAncestor->sceneTransform() * viewportTransform).map(QPointF(0, 0)); // COMBINE - QTransform matrix; - matrix.translate(mappedPoint.x(), mappedPoint.y()); + QTransform matrix = QTransform::fromTranslate(mappedPoint.x(), mappedPoint.y()); if (untransformedAncestor->d_ptr->transformData) matrix = untransformedAncestor->d_ptr->transformData->computedFullTransform(&matrix); @@ -3337,9 +3337,8 @@ QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) co bool cousins = other != commonAncestor && this != commonAncestor; if (cousins) { bool good = false; - QTransform thisToScene; - QTransform otherToScene; - thisToScene = itemTransform(commonAncestor, &good); + QTransform thisToScene = itemTransform(commonAncestor, &good); + QTransform otherToScene(Qt::Uninitialized); if (good) otherToScene = other->itemTransform(commonAncestor, &good); if (!good) { @@ -4184,8 +4183,7 @@ QRegion QGraphicsItem::boundingRegion(const QTransform &itemToDeviceTransform) c p.end(); // Transform QRegion back to device space - QTransform unscale; - unscale.scale(1 / granularity, 1 / granularity); + QTransform unscale = QTransform::fromScale(1 / granularity, 1 / granularity); QRegion r; QBitmap colorMask = QBitmap::fromImage(mask.createMaskFromColor(0)); foreach (const QRect &rect, QRegion( colorMask ).rects()) { diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 7428d79..6998429 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1428,6 +1428,63 @@ QGraphicsWidget *QGraphicsScenePrivate::windowForItem(const QGraphicsItem *item) return 0; } +QList<QGraphicsItem *> QGraphicsScenePrivate::topLevelItemsInStackingOrder(const QTransform *const viewTransform, + QRegion *exposedRegion) +{ + if (indexMethod == QGraphicsScene::NoIndex || !exposedRegion) { + if (needSortTopLevelItems) { + needSortTopLevelItems = false; + qStableSort(topLevelItems.begin(), topLevelItems.end(), qt_notclosestLeaf); + } + return topLevelItems; + } + + const QRectF exposedRect = exposedRegion->boundingRect().adjusted(-1, -1, 1, 1); + QRectF sceneRect; + QTransform invertedViewTransform(Qt::Uninitialized); + if (!viewTransform) { + sceneRect = exposedRect; + } else { + invertedViewTransform = viewTransform->inverted(); + sceneRect = invertedViewTransform.mapRect(exposedRect); + } + if (!largestUntransformableItem.isEmpty()) { + // ### Nuke this when we move the indexing code into a separate + // class. All the largestUntransformableItem code should then go + // away, and the estimate function should return untransformable + // items as well. + QRectF untr = largestUntransformableItem; + QRectF ltri = !viewTransform ? untr : invertedViewTransform.mapRect(untr); + ltri.adjust(-untr.width(), -untr.height(), untr.width(), untr.height()); + sceneRect.adjust(-ltri.width(), -ltri.height(), ltri.width(), ltri.height()); + } + + QList<QGraphicsItem *> tmp = estimateItemsInRect(sceneRect); + for (int i = 0; i < tmp.size(); ++i) + tmp.at(i)->topLevelItem()->d_ptr->itemDiscovered = 1; + + // Sort if the toplevel list is unsorted. + if (needSortTopLevelItems) { + needSortTopLevelItems = false; + qStableSort(topLevelItems.begin(), topLevelItems.end(), qt_notclosestLeaf); + } + + QList<QGraphicsItem *> tli; + for (int i = 0; i < topLevelItems.size(); ++i) { + // ### Investigate smarter ways. Looping through all top level + // items is not optimal. If the BSP tree is to have maximum + // effect, it should be possible to sort the subset of items + // quickly. We must use this approach for now, as it's the only + // current way to keep the stable sorting order (insertion order). + QGraphicsItem *item = topLevelItems.at(i); + if (item->d_ptr->itemDiscovered) { + item->d_ptr->itemDiscovered = 0; + tli << item; + } + } + return tli; +} + void QGraphicsScenePrivate::recursive_items_helper(QGraphicsItem *item, QRectF rect, QList<QGraphicsItem *> *items, const QTransform &parentTransform, @@ -5169,165 +5226,118 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte } void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *painter, - const QTransform &viewTransform, + const QTransform *const viewTransform, QRegion *exposedRegion, QWidget *widget, - QList<QGraphicsItem *> *topLevelItems, qreal parentOpacity) { - // Calculate opacity. - qreal opacity; - bool invisibleButChildIgnoresParentOpacity = false; - if (item) { - if (!item->d_ptr->visible) - return; - opacity = item->d_ptr->combineOpacityFromParent(parentOpacity); - if (opacity == 0.0 && !(item->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) { - invisibleButChildIgnoresParentOpacity = !item->d_ptr->childrenCombineOpacity(); - if (!invisibleButChildIgnoresParentOpacity) - return; - } - } else { - opacity = parentOpacity; - } - - // Item is invisible. - bool hasContents = item && !(item->d_ptr->flags & QGraphicsItem::ItemHasNoContents); - bool invisible = !hasContents || invisibleButChildIgnoresParentOpacity; - - // Calculate the full transform for this item. - bool wasDirtyParentSceneTransform = false; - bool dontDrawItem = true; - QTransform transform; - if (item) { - if (item->d_ptr->itemIsUntransformable()) { - transform = item->deviceTransform(viewTransform); - } else { - if (item->d_ptr->dirtySceneTransform) { - item->d_ptr->sceneTransform = item->d_ptr->parent ? item->d_ptr->parent->d_ptr->sceneTransform - : QTransform(); - item->d_ptr->combineTransformFromParent(&item->d_ptr->sceneTransform); - item->d_ptr->dirtySceneTransform = 0; - wasDirtyParentSceneTransform = true; - } - transform = item->d_ptr->sceneTransform; - transform *= viewTransform; - } - - if (!invisible) { - QRectF brect = item->boundingRect(); - // ### This does not take the clip into account. - _q_adjustRect(&brect); - QRect viewBoundingRect = transform.mapRect(brect).toRect(); - item->d_ptr->paintedViewBoundingRects.insert(widget, viewBoundingRect); - viewBoundingRect.adjust(-1, -1, 1, 1); - if (exposedRegion) - dontDrawItem = !exposedRegion->intersects(viewBoundingRect); - else - dontDrawItem = viewBoundingRect.isEmpty(); - } - } + Q_ASSERT(item); - // Find and sort children. - QList<QGraphicsItem *> tmp; - QList<QGraphicsItem *> *children = 0; - if (item) { - children = &item->d_ptr->children; - } else if (topLevelItems) { - children = topLevelItems; - } else if (indexMethod == QGraphicsScene::NoIndex || !exposedRegion) { - children = &this->topLevelItems; - } else { - QRectF sceneRect = viewTransform.inverted().mapRect(QRectF(exposedRegion->boundingRect().adjusted(-1, -1, 1, 1))); - if (!largestUntransformableItem.isEmpty()) { - // ### Nuke this when we move the indexing code into a separate - // class. All the largestUntransformableItem code should then go - // away, and the estimate function should return untransformable - // items as well. - QRectF untr = largestUntransformableItem; - QRectF ltri = viewTransform.inverted().mapRect(untr); - ltri.adjust(-untr.width(), -untr.height(), untr.width(), untr.height()); - sceneRect.adjust(-ltri.width(), -ltri.height(), ltri.width(), ltri.height()); - } - tmp = estimateItemsInRect(sceneRect); + if (!item->d_ptr->visible) + return; - QList<QGraphicsItem *> tli; - for (int i = 0; i < tmp.size(); ++i) - tmp.at(i)->topLevelItem()->d_ptr->itemDiscovered = 1; + const bool itemHasContents = !(item->d_ptr->flags & QGraphicsItem::ItemHasNoContents); + const bool itemHasChildren = !item->d_ptr->children.isEmpty(); + if (!itemHasContents && !itemHasChildren) + return; // Item has neither contents nor children!(?) - // Sort if the toplevel list is unsorted. - if (needSortTopLevelItems) { - needSortTopLevelItems = false; - qStableSort(this->topLevelItems.begin(), - this->topLevelItems.end(), qt_notclosestLeaf); - } + const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity); + const bool itemIsFullyTransparent = (opacity < 0.0001); + if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity())) + return; - for (int i = 0; i < this->topLevelItems.size(); ++i) { - // ### Investigate smarter ways. Looping through all top level - // items is not optimal. If the BSP tree is to have maximum - // effect, it should be possible to sort the subset of items - // quickly. We must use this approach for now, as it's the only - // current way to keep the stable sorting order (insertion order). - QGraphicsItem *item = this->topLevelItems.at(i); - if (item->d_ptr->itemDiscovered) { - item->d_ptr->itemDiscovered = 0; - tli << item; + QTransform transform(Qt::Uninitialized); + QTransform *transformPtr = 0; +#define ENSURE_TRANSFORM_PTR \ + if (!transformPtr) { \ + Q_ASSERT(!itemIsUntransformable); \ + if (viewTransform) { \ + transform = item->d_ptr->sceneTransform; \ + transform *= *viewTransform; \ + transformPtr = &transform; \ + } else { \ + transformPtr = &item->d_ptr->sceneTransform; \ + } \ + } + + // Update the item's scene transform if the item is transformable; + // otherwise calculate the full transform, + bool wasDirtyParentSceneTransform = false; + const bool itemIsUntransformable = item->d_ptr->itemIsUntransformable(); + if (itemIsUntransformable) { + transform = item->deviceTransform(viewTransform ? *viewTransform : QTransform()); + transformPtr = &transform; + } else if (item->d_ptr->dirtySceneTransform) { + item->d_ptr->sceneTransform = item->d_ptr->parent ? item->d_ptr->parent->d_ptr->sceneTransform + : QTransform(); + item->d_ptr->combineTransformFromParent(&item->d_ptr->sceneTransform); + item->d_ptr->dirtySceneTransform = 0; + wasDirtyParentSceneTransform = true; + } + + const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape); + bool drawItem = itemHasContents && !itemIsFullyTransparent; + if (drawItem) { + const QRectF brect = adjustedItemBoundingRect(item); + ENSURE_TRANSFORM_PTR + QRect viewBoundingRect = transformPtr->mapRect(brect).toRect(); + item->d_ptr->paintedViewBoundingRects.insert(widget, viewBoundingRect); + viewBoundingRect.adjust(-1, -1, 1, 1); + drawItem = exposedRegion ? exposedRegion->intersects(viewBoundingRect) : !viewBoundingRect.isEmpty(); + if (!drawItem) { + if (!itemHasChildren) + return; + if (itemClipsChildrenToShape) { + if (wasDirtyParentSceneTransform) + item->d_ptr->invalidateChildrenSceneTransform(); + return; } } + } // else we know for sure this item has children we must process. - tmp = tli; - children = &tmp; - } - - bool childClip = (item && (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape)); - bool dontDrawChildren = item && hasContents && dontDrawItem && childClip; - childClip &= !dontDrawChildren && !children->isEmpty(); - if (item && invisible) - dontDrawItem = true; - - // Clip children. - if (childClip) { - painter->save(); - painter->setWorldTransform(transform); - painter->setClipPath(item->shape(), Qt::IntersectClip); - } - - if (!dontDrawChildren) { - if (item && item->d_ptr->needSortChildren) { + int i = 0; + if (itemHasChildren) { + if (item->d_ptr->needSortChildren) { item->d_ptr->needSortChildren = 0; - qStableSort(children->begin(), children->end(), qt_notclosestLeaf); - } else if (!item && needSortTopLevelItems && children != &tmp) { - needSortTopLevelItems = false; - qStableSort(children->begin(), children->end(), qt_notclosestLeaf); + qStableSort(item->d_ptr->children.begin(), item->d_ptr->children.end(), qt_notclosestLeaf); } - } - // Draw children behind - int i = 0; - if (!dontDrawChildren) { - // ### Don't visit children that don't ignore parent opacity if this - // item is invisible. - for (i = 0; i < children->size(); ++i) { - QGraphicsItem *child = children->at(i); + if (itemClipsChildrenToShape) { + painter->save(); + ENSURE_TRANSFORM_PTR + painter->setWorldTransform(*transformPtr); + painter->setClipPath(item->shape(), Qt::IntersectClip); + } + + // Draw children behind + for (i = 0; i < item->d_ptr->children.size(); ++i) { + QGraphicsItem *child = item->d_ptr->children.at(i); if (wasDirtyParentSceneTransform) child->d_ptr->dirtySceneTransform = 1; if (!(child->d_ptr->flags & QGraphicsItem::ItemStacksBehindParent)) break; - drawSubtreeRecursive(child, painter, viewTransform, exposedRegion, widget, - 0, opacity); + if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity)) + continue; + drawSubtreeRecursive(child, painter, viewTransform, exposedRegion, widget, opacity); } } // Draw item - if (!dontDrawItem) { - item->d_ptr->initStyleOption(&styleOptionTmp, transform, exposedRegion ? *exposedRegion : QRegion(), exposedRegion == 0); - - bool clipsToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsToShape); - bool savePainter = clipsToShape || painterStateProtection; + if (drawItem) { + Q_ASSERT(!itemIsFullyTransparent); + Q_ASSERT(itemHasContents); + item->d_ptr->initStyleOption(&styleOptionTmp, transform, exposedRegion + ? *exposedRegion : QRegion(), exposedRegion == 0); + + const bool itemClipsToShape = item->d_ptr->flags & QGraphicsItem::ItemClipsToShape; + const bool savePainter = itemClipsToShape || painterStateProtection; if (savePainter) painter->save(); - if (!childClip) - painter->setWorldTransform(transform); - if (clipsToShape) + + if (!itemHasChildren || !itemClipsChildrenToShape) { + ENSURE_TRANSFORM_PTR + painter->setWorldTransform(*transformPtr); + } + if (itemClipsToShape) painter->setClipPath(item->shape(), Qt::IntersectClip); painter->setOpacity(opacity); @@ -5341,22 +5351,19 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter * } // Draw children in front - if (!dontDrawChildren) { - // ### Don't visit children that don't ignore parent opacity if this - // item is invisible. - for (; i < children->size(); ++i) { - QGraphicsItem *child = children->at(i); + if (itemHasChildren) { + for (; i < item->d_ptr->children.size(); ++i) { + QGraphicsItem *child = item->d_ptr->children.at(i); if (wasDirtyParentSceneTransform) child->d_ptr->dirtySceneTransform = 1; - drawSubtreeRecursive(child, painter, viewTransform, exposedRegion, - widget, 0, opacity); + if (itemIsFullyTransparent && !(child->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity)) + continue; + drawSubtreeRecursive(child, painter, viewTransform, exposedRegion, widget, opacity); } - } else if (wasDirtyParentSceneTransform) { - item->d_ptr->invalidateChildrenSceneTransform(); } // Restore child clip - if (childClip) + if (itemHasChildren && itemClipsChildrenToShape) painter->restore(); } @@ -5649,7 +5656,7 @@ void QGraphicsScene::drawItems(QPainter *painter, if (!item->d_ptr->itemDiscovered) { topLevelItems << item; item->d_ptr->itemDiscovered = 1; - d->drawSubtreeRecursive(item, painter, viewTransform, expose, widget); + d->drawSubtreeRecursive(item, painter, &viewTransform, expose, widget); } } diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 983486f..ebc854f 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -211,6 +211,7 @@ public: void mousePressEventHandler(QGraphicsSceneMouseEvent *mouseEvent); QGraphicsWidget *windowForItem(const QGraphicsItem *item) const; + QList<QGraphicsItem *> topLevelItemsInStackingOrder(const QTransform *const, QRegion *); void recursive_items_helper(QGraphicsItem *item, QRectF rect, QList<QGraphicsItem *> *items, const QTransform &parentTransform, const QTransform &viewTransform, Qt::ItemSelectionMode mode, Qt::SortOrder order, qreal parentOpacity = 1.0) const; @@ -264,10 +265,18 @@ public: void drawItemHelper(QGraphicsItem *item, QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget, bool painterStateProtection); - - void drawSubtreeRecursive(QGraphicsItem *item, QPainter *painter, const QTransform &viewTransform, - QRegion *exposedRegion, QWidget *widget, - QList<QGraphicsItem *> *topLevelItems = 0, qreal parentOpacity = qreal(1.0)); + + inline void drawItems(QPainter *painter, const QTransform *const viewTransform, + QRegion *exposedRegion, QWidget *widget) + { + const QList<QGraphicsItem *> tli = topLevelItemsInStackingOrder(viewTransform, exposedRegion); + for (int i = 0; i < tli.size(); ++i) + drawSubtreeRecursive(tli.at(i), painter, viewTransform, exposedRegion, widget); + return; + } + + void drawSubtreeRecursive(QGraphicsItem *item, QPainter *painter, const QTransform *const, + QRegion *exposedRegion, QWidget *widget, qreal parentOpacity = qreal(1.0)); void markDirty(QGraphicsItem *item, const QRectF &rect = QRectF(), bool invalidateChildren = false, bool maybeDirtyClipPath = false, bool force = false, bool ignoreOpacity = false, bool removingItemFromScene = false); diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 6ac2914..ee45690 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -1965,8 +1965,7 @@ void QGraphicsView::render(QPainter *painter, const QRectF &target, const QRect itemList.clear(); // Setup painter matrix. - QTransform moveMatrix; - moveMatrix.translate(-d->horizontalScroll(), -d->verticalScroll()); + QTransform moveMatrix = QTransform::fromTranslate(-d->horizontalScroll(), -d->verticalScroll()); QTransform painterMatrix = d->matrix * moveMatrix; painterMatrix *= QTransform() .translate(targetRect.left(), targetRect.top()) @@ -2317,9 +2316,9 @@ QPolygonF QGraphicsView::mapToScene(const QPolygon &polygon) const QPainterPath QGraphicsView::mapToScene(const QPainterPath &path) const { Q_D(const QGraphicsView); - QTransform moveMatrix; - moveMatrix.translate(d->horizontalScroll(), d->verticalScroll()); - return (moveMatrix * d->matrix.inverted()).map(path); + QTransform matrix = QTransform::fromTranslate(d->horizontalScroll(), d->verticalScroll()); + matrix *= d->matrix.inverted(); + return matrix.map(path); } /*! @@ -2413,9 +2412,9 @@ QPolygon QGraphicsView::mapFromScene(const QPolygonF &polygon) const QPainterPath QGraphicsView::mapFromScene(const QPainterPath &path) const { Q_D(const QGraphicsView); - QTransform moveMatrix; - moveMatrix.translate(-d->horizontalScroll(), -d->verticalScroll()); - return (d->matrix * moveMatrix).map(path); + QTransform matrix = d->matrix; + matrix *= QTransform::fromTranslate(-d->horizontalScroll(), -d->verticalScroll()); + return matrix.map(path); } /*! @@ -3360,8 +3359,8 @@ void QGraphicsView::paintEvent(QPaintEvent *event) // Items if (!(d->optimizationFlags & IndirectPainting)) { - d->scene->d_func()->drawSubtreeRecursive(0, &painter, viewTransform, &d->exposedRegion, - viewport(), 0); + d->scene->d_func()->drawItems(&painter, viewTransformed ? &viewTransform : 0, + &d->exposedRegion, viewport()); } else { // Find all exposed items bool allItems = false; @@ -3614,8 +3613,7 @@ QTransform QGraphicsView::transform() const QTransform QGraphicsView::viewportTransform() const { Q_D(const QGraphicsView); - QTransform moveMatrix; - moveMatrix.translate(-d->horizontalScroll(), -d->verticalScroll()); + QTransform moveMatrix = QTransform::fromTranslate(-d->horizontalScroll(), -d->verticalScroll()); return d->identityMatrix ? moveMatrix : d->matrix * moveMatrix; } diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index ca2b782..fa1ce29 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -3951,10 +3951,8 @@ QImage QImage::scaled(const QSize& s, Qt::AspectRatioMode aspectMode, Qt::Transf if (newSize == size()) return copy(); - QImage img; - QTransform wm; - wm.scale((qreal)newSize.width() / width(), (qreal)newSize.height() / height()); - img = transformed(wm, mode); + QTransform wm = QTransform::fromScale((qreal)newSize.width() / width(), (qreal)newSize.height() / height()); + QImage img = transformed(wm, mode); return img; } @@ -3981,9 +3979,8 @@ QImage QImage::scaledToWidth(int w, Qt::TransformationMode mode) const if (w <= 0) return QImage(); - QTransform wm; qreal factor = (qreal) w / width(); - wm.scale(factor, factor); + QTransform wm = QTransform::fromScale(factor, factor); return transformed(wm, mode); } @@ -4010,9 +4007,8 @@ QImage QImage::scaledToHeight(int h, Qt::TransformationMode mode) const if (h <= 0) return QImage(); - QTransform wm; qreal factor = (qreal) h / height(); - wm.scale(factor, factor); + QTransform wm = QTransform::fromScale(factor, factor); return transformed(wm, mode); } diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 56c3a29..61be832 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -1446,10 +1446,9 @@ QPixmap QPixmap::scaled(const QSize& s, Qt::AspectRatioMode aspectMode, Qt::Tran if (newSize == size()) return *this; - QPixmap pix; - QTransform wm; - wm.scale((qreal)newSize.width() / width(), (qreal)newSize.height() / height()); - pix = transformed(wm, mode); + QTransform wm = QTransform::fromScale((qreal)newSize.width() / width(), + (qreal)newSize.height() / height()); + QPixmap pix = transformed(wm, mode); return pix; } @@ -1476,9 +1475,8 @@ QPixmap QPixmap::scaledToWidth(int w, Qt::TransformationMode mode) const if (w <= 0) return QPixmap(); - QTransform wm; qreal factor = (qreal) w / width(); - wm.scale(factor, factor); + QTransform wm = QTransform::fromScale(factor, factor); return transformed(wm, mode); } @@ -1505,9 +1503,8 @@ QPixmap QPixmap::scaledToHeight(int h, Qt::TransformationMode mode) const if (h <= 0) return QPixmap(); - QTransform wm; qreal factor = (qreal) h / height(); - wm.scale(factor, factor); + QTransform wm = QTransform::fromScale(factor, factor); return transformed(wm, mode); } diff --git a/src/gui/itemviews/qitemeditorfactory.cpp b/src/gui/itemviews/qitemeditorfactory.cpp index c576e40..480a472 100644 --- a/src/gui/itemviews/qitemeditorfactory.cpp +++ b/src/gui/itemviews/qitemeditorfactory.cpp @@ -158,6 +158,10 @@ QByteArray QItemEditorFactory::valuePropertyName(QVariant::Type type) const */ QItemEditorFactory::~QItemEditorFactory() { + //we make sure we delete all the QItemEditorCreatorBase + //this has to be done only once, hence the QSet + QSet<QItemEditorCreatorBase*> set = creatorMap.values().toSet(); + qDeleteAll(set); } /*! @@ -170,8 +174,16 @@ QItemEditorFactory::~QItemEditorFactory() */ void QItemEditorFactory::registerEditor(QVariant::Type type, QItemEditorCreatorBase *creator) { - delete creatorMap.value(type, 0); - creatorMap[type] = creator; + QHash<QVariant::Type, QItemEditorCreatorBase *>::iterator it = creatorMap.find(type); + if (it != creatorMap.end()) { + QItemEditorCreatorBase *oldCreator = it.value(); + Q_ASSERT(oldCreator); + creatorMap.erase(it); + if (!creatorMap.values().contains(oldCreator)) + delete oldCreator; // if it is no more in use we can delete it + } + + creatorMap[type] = creator; } class QDefaultItemEditorFactory : public QItemEditorFactory diff --git a/src/gui/painting/qmatrix.cpp b/src/gui/painting/qmatrix.cpp index 7c50b80..221267f 100644 --- a/src/gui/painting/qmatrix.cpp +++ b/src/gui/painting/qmatrix.cpp @@ -197,6 +197,10 @@ QT_BEGIN_NAMESPACE /***************************************************************************** QMatrix member functions *****************************************************************************/ +/*! + \fn QMatrix::QMatrix(Qt::Initialization) + \internal +*/ /*! Constructs an identity matrix. diff --git a/src/gui/painting/qmatrix.h b/src/gui/painting/qmatrix.h index e28c950..aa4177c 100644 --- a/src/gui/painting/qmatrix.h +++ b/src/gui/painting/qmatrix.h @@ -61,6 +61,7 @@ class QVariant; class Q_GUI_EXPORT QMatrix // 2D transform matrix { public: + inline explicit QMatrix(Qt::Initialization) {} QMatrix(); QMatrix(qreal m11, qreal m12, qreal m21, qreal m22, qreal dx, qreal dy); diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp index 8e8485d..4fb1832 100644 --- a/src/gui/painting/qpaintengine.cpp +++ b/src/gui/painting/qpaintengine.cpp @@ -1008,8 +1008,7 @@ void QPaintEnginePrivate::drawBoxTextItem(const QPointF &p, const QTextItemInt & const int size = qRound(ti.fontEngine->ascent()); QVarLengthArray<QFixedPoint> positions; QVarLengthArray<glyph_t> glyphs; - QTransform matrix; - matrix.translate(p.x(), p.y() - size); + QTransform matrix = QTransform::fromTranslate(p.x(), p.y() - size); ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); if (glyphs.size() == 0) return; diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 1d3e38e..78515ac 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -3996,7 +3996,7 @@ void QRasterPaintEnginePrivate::initializeRasterizer(QSpanData *data) const QClipData *c = clip(); if (c) { const QRect r(QPoint(c->xmin, c->ymin), - QPoint(c->xmax, c->ymax)); + QSize(c->xmax - c->xmin, c->ymax - c->ymin)); clipRect = clipRect.intersected(r); blend = data->blend; } else { diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 5ebca47..a4db284 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -848,8 +848,7 @@ void QPaintEngineEx::drawImage(const QPointF &pos, const QImage &image) void QPaintEngineEx::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s) { QBrush brush(state()->pen.color(), pixmap); - QTransform xform; - xform.translate(r.x() - s.x(), r.y() - s.y()); + QTransform xform = QTransform::fromTranslate(r.x() - s.x(), r.y() - s.y()); brush.setTransform(xform); qreal pts[] = { r.x(), r.y(), diff --git a/src/gui/painting/qpathclipper.cpp b/src/gui/painting/qpathclipper.cpp index 9625b28..053955c 100644 --- a/src/gui/painting/qpathclipper.cpp +++ b/src/gui/painting/qpathclipper.cpp @@ -45,9 +45,6 @@ #include <private/qdatabuffer_p.h> #include <qmath.h> -#include <QImage> -#include <QPainter> - /** The algorithm is as follows: @@ -68,6 +65,20 @@ QT_BEGIN_NAMESPACE +static inline bool fuzzyIsNull(qreal d) +{ + if (sizeof(qreal) == sizeof(double)) + return qAbs(d) <= 1e-12; + else + return qAbs(d) <= 1e-5f; +} + +static inline bool comparePoints(const QPointF &a, const QPointF &b) +{ + return fuzzyIsNull(a.x() - b.x()) + && fuzzyIsNull(a.y() - b.y()); +} + //#define QDEBUG_CLIPPER static qreal dot(const QPointF &a, const QPointF &b) { @@ -105,8 +116,10 @@ private: bool QIntersectionFinder::beziersIntersect(const QBezier &one, const QBezier &two) const { - return (one.pt1() == two.pt1() && one.pt2() == two.pt2() && one.pt3() == two.pt3() && one.pt4() == two.pt4()) - || (one.pt1() == two.pt4() && one.pt2() == two.pt3() && one.pt3() == two.pt2() && one.pt4() == two.pt1()) + return (comparePoints(one.pt1(), two.pt1()) && comparePoints(one.pt2(), two.pt2()) + && comparePoints(one.pt3(), two.pt3()) && comparePoints(one.pt4(), two.pt4())) + || (comparePoints(one.pt1(), two.pt4()) && comparePoints(one.pt2(), two.pt3()) + && comparePoints(one.pt3(), two.pt2()) && comparePoints(one.pt4(), two.pt1())) || QBezier::findIntersections(one, two, 0); } @@ -118,17 +131,17 @@ bool QIntersectionFinder::linesIntersect(const QLineF &a, const QLineF &b) const const QPointF q1 = b.p1(); const QPointF q2 = b.p2(); - if (p1 == p2 || q1 == q2) + if (comparePoints(p1, p2) || comparePoints(q1, q2)) return false; - const bool p1_equals_q1 = (p1 == q1); - const bool p2_equals_q2 = (p2 == q2); + const bool p1_equals_q1 = comparePoints(p1, q1); + const bool p2_equals_q2 = comparePoints(p2, q2); if (p1_equals_q1 && p2_equals_q2) return true; - const bool p1_equals_q2 = (p1 == q2); - const bool p2_equals_q1 = (p2 == q1); + const bool p1_equals_q2 = comparePoints(p1, q2); + const bool p2_equals_q1 = comparePoints(p2, q1); if (p1_equals_q2 && p2_equals_q1) return true; @@ -184,8 +197,10 @@ bool QIntersectionFinder::linesIntersect(const QLineF &a, const QLineF &b) const void QIntersectionFinder::intersectBeziers(const QBezier &one, const QBezier &two, QVector<QPair<qreal, qreal> > &t, QDataBuffer<QIntersection> &intersections) { - if ((one.pt1() == two.pt1() && one.pt2() == two.pt2() && one.pt3() == two.pt3() && one.pt4() == two.pt4()) - || (one.pt1() == two.pt4() && one.pt2() == two.pt3() && one.pt3() == two.pt2() && one.pt4() == two.pt1())) { + if ((comparePoints(one.pt1(), two.pt1()) && comparePoints(one.pt2(), two.pt2()) + && comparePoints(one.pt3(), two.pt3()) && comparePoints(one.pt4(), two.pt4())) + || (comparePoints(one.pt1(), two.pt4()) && comparePoints(one.pt2(), two.pt3()) + && comparePoints(one.pt3(), two.pt2()) && comparePoints(one.pt4(), two.pt1()))) { return; } @@ -230,17 +245,17 @@ void QIntersectionFinder::intersectLines(const QLineF &a, const QLineF &b, QData const QPointF q1 = b.p1(); const QPointF q2 = b.p2(); - if (p1 == p2 || q1 == q2) + if (comparePoints(p1, p2) || comparePoints(q1, q2)) return; - const bool p1_equals_q1 = (p1 == q1); - const bool p2_equals_q2 = (p2 == q2); + const bool p1_equals_q1 = comparePoints(p1, q1); + const bool p2_equals_q2 = comparePoints(p2, q2); if (p1_equals_q1 && p2_equals_q2) return; - const bool p1_equals_q2 = (p1 == q2); - const bool p2_equals_q1 = (p2 == q1); + const bool p1_equals_q2 = comparePoints(p1, q2); + const bool p2_equals_q1 = comparePoints(p2, q1); if (p1_equals_q2 && p2_equals_q1) return; @@ -624,11 +639,11 @@ public: const qreal pivot = pivotComponents[depth & 1]; const qreal value = pointComponents[depth & 1]; - if (qFuzzyCompare(pivot, value)) { + if (fuzzyIsNull(pivot - value)) { const qreal pivot2 = pivotComponents[(depth + 1) & 1]; const qreal value2 = pointComponents[(depth + 1) & 1]; - if (qFuzzyCompare(pivot2, value2)) { + if (fuzzyIsNull(pivot2 - value2)) { if (node.id < 0) node.id = m_tree->nextId(); @@ -802,15 +817,15 @@ QWingedEdge::TraversalStatus QWingedEdge::next(const QWingedEdge::TraversalStatu static bool isLine(const QBezier &bezier) { - const bool equal_1_2 = bezier.pt1() == bezier.pt2(); - const bool equal_2_3 = bezier.pt2() == bezier.pt3(); - const bool equal_3_4 = bezier.pt3() == bezier.pt4(); + const bool equal_1_2 = comparePoints(bezier.pt1(), bezier.pt2()); + const bool equal_2_3 = comparePoints(bezier.pt2(), bezier.pt3()); + const bool equal_3_4 = comparePoints(bezier.pt3(), bezier.pt4()); // point? if (equal_1_2 && equal_2_3 && equal_3_4) return true; - if (bezier.pt1() == bezier.pt4()) + if (comparePoints(bezier.pt1(), bezier.pt4())) return equal_1_2 || equal_3_4; return (equal_1_2 && equal_3_4) || (equal_1_2 && equal_2_3) || (equal_2_3 && equal_3_4); @@ -844,14 +859,14 @@ void QPathSegments::addPath(const QPainterPath &path) else currentPoint = path.elementAt(i); - if (i > 0 && m_points.at(lastMoveTo) == currentPoint) + if (i > 0 && comparePoints(m_points.at(lastMoveTo), currentPoint)) current = lastMoveTo; else m_points << currentPoint; switch (path.elementAt(i).type) { case QPainterPath::MoveToElement: - if (hasMoveTo && last != lastMoveTo && m_points.at(last) != m_points.at(lastMoveTo)) + if (hasMoveTo && last != lastMoveTo && !comparePoints(m_points.at(last), m_points.at(lastMoveTo))) m_segments << Segment(m_pathId, last, lastMoveTo); hasMoveTo = true; last = lastMoveTo = current; @@ -879,7 +894,7 @@ void QPathSegments::addPath(const QPainterPath &path) } } - if (hasMoveTo && last != lastMoveTo && m_points.at(last) != m_points.at(lastMoveTo)) + if (hasMoveTo && last != lastMoveTo && !comparePoints(m_points.at(last), m_points.at(lastMoveTo))) m_segments << Segment(m_pathId, last, lastMoveTo); for (int i = firstSegment; i < m_segments.size(); ++i) { @@ -1357,7 +1372,7 @@ void QWingedEdge::addBezierEdge(const QBezier *bezier, const QPointF &a, const Q if (qFuzzyCompare(alphaA, alphaB)) return; - if (a == b) { + if (comparePoints(a, b)) { int v = insert(a); addBezierEdge(bezier, v, v, alphaA, alphaB, path); diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index c3452e1..664751a 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -1929,8 +1929,7 @@ void QPdfBaseEnginePrivate::drawTextItem(const QPointF &p, const QTextItemInt &t QVarLengthArray<glyph_t> glyphs; QVarLengthArray<QFixedPoint> positions; - QTransform m; - m.translate(p.x(), p.y()); + QTransform m = QTransform::fromTranslate(p.x(), p.y()); ti.fontEngine->getGlyphPositions(ti.glyphs, m, ti.flags, glyphs, positions); if (glyphs.size() == 0) diff --git a/src/gui/painting/qprintengine_win.cpp b/src/gui/painting/qprintengine_win.cpp index 179927f..72faf7c 100644 --- a/src/gui/painting/qprintengine_win.cpp +++ b/src/gui/painting/qprintengine_win.cpp @@ -663,8 +663,7 @@ void QWin32PrintEngine::drawPixmap(const QRectF &targetRect, qreal scaleX = 1.0f; qreal scaleY = 1.0f; - QTransform scaleMatrix; - scaleMatrix.scale(r.width() / pixmap.width(), r.height() / pixmap.height()); + QTransform scaleMatrix = QTransform::fromScale(r.width() / pixmap.width(), r.height() / pixmap.height()); QTransform adapted = QPixmap::trueMatrix(d->painterMatrix * scaleMatrix, pixmap.width(), pixmap.height()); @@ -1875,8 +1874,7 @@ static void draw_text_item_win(const QPointF &_pos, const QTextItemInt &ti, HDC QVarLengthArray<QFixedPoint> positions; QVarLengthArray<glyph_t> _glyphs; - QTransform matrix; - matrix.translate(baseline_pos.x(), baseline_pos.y()); + QTransform matrix = QTransform::fromTranslate(baseline_pos.x(), baseline_pos.y()); ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, _glyphs, positions); if (_glyphs.size() == 0) { diff --git a/src/gui/painting/qrasterizer.cpp b/src/gui/painting/qrasterizer.cpp index 629b38e..58e4b4e 100644 --- a/src/gui/painting/qrasterizer.cpp +++ b/src/gui/painting/qrasterizer.cpp @@ -703,7 +703,7 @@ static inline qreal qRoundF(qreal v) void QRasterizer::rasterizeLine(const QPointF &a, const QPointF &b, qreal width, bool squareCap) { - if (a == b || width == 0) + if (a == b || width == 0 || d->clipRect.isEmpty()) return; QPointF pa = a; diff --git a/src/gui/painting/qstroker_p.h b/src/gui/painting/qstroker_p.h index f94c353..30c22b2 100644 --- a/src/gui/painting/qstroker_p.h +++ b/src/gui/painting/qstroker_p.h @@ -179,7 +179,7 @@ private: }; -class QStroker : public QStrokerOps +class Q_GUI_EXPORT QStroker : public QStrokerOps { public: diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp index 5b1ae07..f0b2351 100644 --- a/src/gui/painting/qtransform.cpp +++ b/src/gui/painting/qtransform.cpp @@ -232,6 +232,11 @@ QT_BEGIN_NAMESPACE */ /*! + \fn QTransform::QTransform(Qt::Initialization) + \internal +*/ + +/*! Constructs an identity matrix. All elements are set to zero except \c m11 and \c m22 (specifying diff --git a/src/gui/painting/qtransform.h b/src/gui/painting/qtransform.h index bb04f7b..291d35c 100644 --- a/src/gui/painting/qtransform.h +++ b/src/gui/painting/qtransform.h @@ -71,6 +71,7 @@ public: TxProject = 0x10 }; + inline explicit QTransform(Qt::Initialization) : affine(Qt::Uninitialized) {} QTransform(); QTransform(qreal h11, qreal h12, qreal h13, qreal h21, qreal h22, qreal h23, diff --git a/src/gui/styles/qcleanlooksstyle.cpp b/src/gui/styles/qcleanlooksstyle.cpp index 902ffdd..3855ba7 100644 --- a/src/gui/styles/qcleanlooksstyle.cpp +++ b/src/gui/styles/qcleanlooksstyle.cpp @@ -1738,8 +1738,7 @@ void QCleanlooksStyle::drawControl(ControlElement element, const QStyleOption *o // same rendering code for both orientations. if (vertical) { rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height - QTransform m; - m.translate(rect.height()-1, -1.0); + QTransform m = QTransform::fromTranslate(rect.height()-1, -1.0); m.rotate(90.0); painter->setTransform(m, true); } diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp index 682e00b..c5c6973 100644 --- a/src/gui/styles/qcommonstyle.cpp +++ b/src/gui/styles/qcommonstyle.cpp @@ -1963,8 +1963,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, newRot = -90; } tr.setRect(0, 0, tr.height(), tr.width()); - QTransform m; - m.translate(newX, newY); + QTransform m = QTransform::fromTranslate(newX, newY); m.rotate(newRot); p->setTransform(m, true); } diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index a4a468d..8499811 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -2848,8 +2848,7 @@ void QGtkStyle::drawControl(ControlElement element, if (vertical) { rect.translate(xt, -yt * 2); rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // Flip width and height - QTransform m; - m.translate(rect.height(), 0); + QTransform m = QTransform::fromTranslate(rect.height(), 0); m.rotate(90.0); painter->setTransform(m); } diff --git a/src/gui/styles/qplastiquestyle.cpp b/src/gui/styles/qplastiquestyle.cpp index 3935dc1..12aa679 100644 --- a/src/gui/styles/qplastiquestyle.cpp +++ b/src/gui/styles/qplastiquestyle.cpp @@ -2642,8 +2642,7 @@ void QPlastiqueStyle::drawControl(ControlElement element, const QStyleOption *op // same rendering code for both orientations. if (vertical) { rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height - QTransform m; - m.translate(rect.height()-1, 0); + QTransform m = QTransform::fromTranslate(rect.height()-1, 0); m.rotate(90.0); painter->setTransform(m, true); } diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 25bdfd2..05b3695 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -422,8 +422,7 @@ void QFontEngine::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyphs, QVarLengthArray<QFixedPoint> positions; QVarLengthArray<glyph_t> positioned_glyphs; - QTransform matrix; - matrix.translate(x, y); + QTransform matrix = QTransform::fromTranslate(x, y); getGlyphPositions(glyphs, matrix, flags, positioned_glyphs, positions); addGlyphsToPath(positioned_glyphs.data(), positions.data(), positioned_glyphs.size(), path, flags); } @@ -1151,8 +1150,7 @@ void QFontEngineBox::addOutlineToPath(qreal x, qreal y, const QGlyphLayout &glyp QVarLengthArray<QFixedPoint> positions; QVarLengthArray<glyph_t> positioned_glyphs; - QTransform matrix; - matrix.translate(x, y - _size); + QTransform matrix = QTransform::fromTranslate(x, y - _size); getGlyphPositions(glyphs, matrix, flags, positioned_glyphs, positions); QSize s(_size - 3, _size - 3); @@ -1180,8 +1178,7 @@ void QFontEngineBox::draw(QPaintEngine *p, qreal x, qreal y, const QTextItemInt QVarLengthArray<QFixedPoint> positions; QVarLengthArray<glyph_t> glyphs; - QTransform matrix; - matrix.translate(x, y - _size); + QTransform matrix = QTransform::fromTranslate(x, y - _size); ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); if (glyphs.size() == 0) return; diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index 6bbf4e8..fc55a2c 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -1826,7 +1826,7 @@ void QMenu::popup(const QPoint &p, QAction *atAction) if (d->scroll && d->scroll->scrollFlags != QMenuPrivate::QMenuScroller::ScrollNone && !style()->styleHint(QStyle::SH_Menu_FillScreenWithScroll, 0, this)) { int below_height = above_height + d->scroll->scrollOffset; - for(int i2 = i; i2 < (int)d->actionList.count(); i2++) + for(int i2 = i; i2 < d->actionList.count(); i2++) below_height += d->actionRects.value(d->actionList.at(i2)).height(); size.setHeight(below_height); } @@ -2263,7 +2263,7 @@ void QMenu::mouseReleaseEvent(QMouseEvent *e) break; } } - if (e->button() == Qt::LeftButton || (e->button() == Qt::RightButton && isContextMenu)) + if (e->button() || isContextMenu) #endif d->activateAction(action, QAction::Trigger); } @@ -2746,7 +2746,7 @@ void QMenu::mouseMoveEvent(QMouseEvent *e) if (d->hasHadMouse && !rect().contains(e->pos())) d->setCurrentAction(0); return; - } else if(e->buttons() & (Qt::LeftButton | Qt::RightButton)) { + } else if(e->buttons()) { d->mouseDown = this; } if (d->sloppyRegion.contains(e->pos())) { diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index d1978e3..4977b31 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -1029,15 +1029,14 @@ void QPlainTextEditPrivate::ensureViewportLayouted() \section1 Using QPlainTextEdit as a Display Widget - The text is set or replaced using setPlainText() which deletes any - existing text and replaces it with the text passed in the - setPlainText() call. + The text is set or replaced using setPlainText() which deletes the + existing text and replaces it with the text passed to setPlainText(). - Text itself can be inserted using the QTextCursor class or using - the convenience functins insertPlainText(), appendPlainText() or + Text can be inserted using the QTextCursor class or using the + convenience functions insertPlainText(), appendPlainText() or paste(). - By default the text edit wraps words at whitespace to fit within + By default, the text edit wraps words at whitespace to fit within the text edit widget. The setLineWrapMode() function is used to specify the kind of line wrap you want, \l WidgetWidth or \l NoWrap if you don't want any wrapping. If you use word wrap to @@ -1725,8 +1724,7 @@ static void fillBackground(QPainter *p, const QRectF &rect, QBrush brush, QRectF p->save(); if (brush.style() >= Qt::LinearGradientPattern && brush.style() <= Qt::ConicalGradientPattern) { if (!gradientRect.isNull()) { - QTransform m; - m.translate(gradientRect.left(), gradientRect.top()); + QTransform m = QTransform::fromTranslate(gradientRect.left(), gradientRect.top()); m.scale(gradientRect.width(), gradientRect.height()); brush.setTransform(m); const_cast<QGradient *>(brush.gradient())->setCoordinateMode(QGradient::LogicalMode); diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index cfce735..f0c694d 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -1020,7 +1020,8 @@ void QHttpNetworkConnectionPrivate::removeReply(QHttpNetworkReply *reply) for (int i = 0; i < channelCount; ++i) { if (channels[i].reply == reply) { channels[i].reply = 0; - closeChannel(i); + if (reply->d_func()->connectionCloseEnabled()) + closeChannel(i); QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection); return; } diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index ed2f220..907aaef 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -112,8 +112,6 @@ static void ensureInitialized() are supplied that take a request and optional data, and each return a QNetworkReply object. The returned object is used to obtain any data returned in response to the corresponding request. - the reply to is where most of the signals as well - as the downloaded data are posted. A simple download off the network could be accomplished with: \snippet doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp 0 @@ -122,7 +120,8 @@ static void ensureInitialized() takes is the QNetworkReply object containing the downloaded data as well as meta-data (headers, etc.). - \note The slot is responsible for deleting the object at that point. + \note After the request has finished, it is the responsibility of the user + to delete the QNetworkReply object at an appropriate time. A more involved example, assuming the manager is already existent, can be: diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 75d8a56..6ff0c53 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1063,8 +1063,7 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(const QPointF &p, const QTextIte QVarLengthArray<QFixedPoint> positions; QVarLengthArray<glyph_t> glyphs; - QTransform matrix; - matrix.translate(p.x(), p.y()); + QTransform matrix = QTransform::fromTranslate(p.x(), p.y()); ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); QFontEngineGlyphCache::Type glyphType = ti.fontEngine->glyphFormat >= 0 diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index b594f5b..e173a8d 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -4206,8 +4206,7 @@ void QOpenGLPaintEnginePrivate::drawImageAsPath(const QRectF &r, const QImage &i qreal scaleX = r.width() / sr.width(); qreal scaleY = r.height() / sr.height(); - QTransform brush_matrix; - brush_matrix.translate(r.left(), r.top()); + QTransform brush_matrix = QTransform::fromTranslate(r.left(), r.top()); brush_matrix.scale(scaleX, scaleY); brush_matrix.translate(-sr.left(), -sr.top()); @@ -4228,8 +4227,7 @@ void QOpenGLPaintEnginePrivate::drawTiledImageAsPath(const QRectF &r, const QIma QBrush old_brush = cbrush; QPointF old_brush_origin = brush_origin; - QTransform brush_matrix; - brush_matrix.translate(r.left(), r.top()); + QTransform brush_matrix = QTransform::fromTranslate(r.left(), r.top()); brush_matrix.scale(sx, sy); cbrush = QBrush(img); @@ -4871,8 +4869,7 @@ void QOpenGLPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte // add the glyphs used to the glyph texture cache QVarLengthArray<QFixedPoint> positions; QVarLengthArray<glyph_t> glyphs; - QTransform matrix; - matrix.translate(qRound(p.x()), qRound(p.y())); + QTransform matrix = QTransform::fromTranslate(qRound(p.x()), qRound(p.y())); ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); // make sure the glyphs we want to draw are in the cache diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index 1c86466..9dc7818 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -237,6 +237,7 @@ void QDirectFBPixmapData::copy(const QPixmapData *data, const QRect &rect) w = rect.width(); h = rect.height(); d = otherData->d; + is_null = (w <= 0 || h <= 0); DFBResult result = dfbSurface->Blit(dfbSurface, src, &blitRect, 0, 0); #if (Q_DIRECTFB_VERSION >= 0x010000) dfbSurface->ReleaseSource(dfbSurface); @@ -330,6 +331,8 @@ QPixmap QDirectFBPixmapData::transformed(const QTransform &transform, data->dfbSurface->StretchBlit(data->dfbSurface, dfbSurface, 0, &destRect); data->w = size.width(); data->h = size.height(); + data->is_null = (data->w <= 0 || data->h <= 0); + #if (Q_DIRECTFB_VERSION >= 0x010000) data->dfbSurface->ReleaseSource(data->dfbSurface); #endif diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h index ad6c38e..e81aef4 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h @@ -60,22 +60,23 @@ public: ~QDirectFBPixmapData(); // Re-implemented from QPixmapData: - void resize(int width, int height); - void fromImage(const QImage &image, Qt::ImageConversionFlags flags); - void copy(const QPixmapData *data, const QRect &rect); - void fill(const QColor &color); - inline bool hasAlphaChannel() const { return alpha; } - QPixmap transformed(const QTransform &matrix, - Qt::TransformationMode mode) const; - QImage toImage() const; - QPaintEngine* paintEngine() const; + virtual void resize(int width, int height); + virtual void fromImage(const QImage &image, Qt::ImageConversionFlags flags); + virtual void copy(const QPixmapData *data, const QRect &rect); + virtual void fill(const QColor &color); + virtual QPixmap transformed(const QTransform &matrix, + Qt::TransformationMode mode) const; + virtual QImage toImage() const; + virtual QPaintEngine *paintEngine() const; virtual QImage *buffer(); + virtual int metric(QPaintDevice::PaintDeviceMetric m) const {return QDirectFBPaintDevice::metric(m);} + QImage *buffer(uint lockFlags); // Pure virtual in QPixmapData, so re-implement here and delegate to QDirectFBPaintDevice - int metric(QPaintDevice::PaintDeviceMetric m) const {return QDirectFBPaintDevice::metric(m);} inline QImage::Format pixelFormat() const { return format; } static bool hasAlphaChannel(const QImage &img); + inline bool hasAlphaChannel() const { return alpha; } private: void invalidate(); QDirectFBPaintEngine *engine; diff --git a/src/sql/drivers/db2/qsql_db2.cpp b/src/sql/drivers/db2/qsql_db2.cpp index b6ca82d..1a82377 100644 --- a/src/sql/drivers/db2/qsql_db2.cpp +++ b/src/sql/drivers/db2/qsql_db2.cpp @@ -1043,26 +1043,22 @@ QVariant QDB2Result::data(int field) case QVariant::Double: { QString value=qGetStringData(d->hStmt, field, info.length() + 1, isNull); - bool ok=false; - switch(d->precisionPolicy) { + switch(numericalPrecisionPolicy()) { case QSql::LowPrecisionInt32: - v = new QVariant(value.toInt(&ok)); + v = new QVariant(qGetIntData(d->hStmt, field, isNull)); break; case QSql::LowPrecisionInt64: - v = new QVariant(value.toLongLong(&ok)); + v = new QVariant(qGetBigIntData(d->hStmt, field, isNull)); break; case QSql::LowPrecisionDouble: - v = new QVariant(value.toDouble(&ok)); + v = new QVariant(qGetDoubleData(d->hStmt, field, isNull)); break; case QSql::HighPrecision: default: // length + 1 for the comma - v = new QVariant(value); - ok = true; + v = new QVariant(qGetStringData(d->hStmt, field, info.length() + 1, isNull)); break; } - if(!ok) - v = new QVariant(); break; } case QVariant::String: @@ -1146,6 +1142,10 @@ void QDB2Result::virtual_hook(int id, void *data) Q_ASSERT(data); *static_cast<bool*>(data) = nextResult(); break; + case QSqlResult::DetachFromResultSet: + if (d->hStmt) + SQLCloseCursor(d->hStmt); + break; default: QSqlResult::virtual_hook(id, data); } @@ -1177,7 +1177,7 @@ QDB2Driver::~QDB2Driver() delete d; } -bool QDB2Driver::open(const QString& db, const QString& user, const QString& password, const QString&, int, +bool QDB2Driver::open(const QString& db, const QString& user, const QString& password, const QString& host, int port, const QString& connOpts) { if (isOpen()) @@ -1200,6 +1200,8 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas setOpenError(true); return false; } + + QString protocol; // Set connection attributes const QStringList opts(connOpts.split(QLatin1Char(';'), QString::SkipEmptyParts)); for (int i = 0; i < opts.count(); ++i) { @@ -1230,7 +1232,10 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas } else if (opt == QLatin1String("SQL_ATTR_LOGIN_TIMEOUT")) { v = val.toUInt(); r = SQLSetConnectAttr(d->hDbc, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER) v, 0); - } else { + } else if (opt.compare(QLatin1String("PROTOCOL"), Qt::CaseInsensitive) == 0) { + protocol = tmp; + } + else { qWarning("QDB2Driver::open: Unknown connection attribute '%s'", tmp.toLocal8Bit().constData()); } @@ -1239,9 +1244,18 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas "Unable to set connection attribute '%1'").arg(opt), d); } + if (protocol.isEmpty()) + protocol = QLatin1String("PROTOCOL=TCPIP"); + + if (port < 0 ) + port = 50000; + QString connQStr; - connQStr = QLatin1String("DSN=") + db + QLatin1String(";UID=") + user + QLatin1String(";PWD=") - + password; + connQStr = protocol + QLatin1String(";DATABASE=") + db + QLatin1String(";HOSTNAME=") + host + + QLatin1String(";PORT=") + QString::number(port) + QLatin1String(";UID=") + user + + QLatin1String(";PWD=") + password; + + SQLTCHAR connOut[SQL_MAX_OPTION_STRING_LENGTH]; SQLSMALLINT cb; @@ -1260,7 +1274,7 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas return false; } - d->user = user.toUpper(); + d->user = user; setOpen(true); setOpenError(false); return true; @@ -1305,10 +1319,25 @@ QSqlRecord QDB2Driver::record(const QString& tableName) const SQLHANDLE hStmt; QString catalog, schema, table; - qSplitTableQualifier(tableName.toUpper(), &catalog, &schema, &table); + qSplitTableQualifier(tableName, &catalog, &schema, &table); if (schema.isEmpty()) schema = d->user; + if (isIdentifierEscaped(catalog, QSqlDriver::TableName)) + catalog = stripDelimiters(catalog, QSqlDriver::TableName); + else + catalog = catalog.toUpper(); + + if (isIdentifierEscaped(schema, QSqlDriver::TableName)) + schema = stripDelimiters(schema, QSqlDriver::TableName); + else + schema = schema.toUpper(); + + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + else + table = table.toUpper(); + SQLRETURN r = SQLAllocHandle(SQL_HANDLE_STMT, d->hDbc, &hStmt); @@ -1322,6 +1351,9 @@ QSqlRecord QDB2Driver::record(const QString& tableName) const (SQLPOINTER) SQL_CURSOR_FORWARD_ONLY, SQL_IS_UINTEGER); + + //Aside: szSchemaName and szTableName parameters of SQLColumns + //are case sensitive search patterns, so no escaping is used. r = SQLColumns(hStmt, NULL, 0, @@ -1402,7 +1434,13 @@ QStringList QDB2Driver::tables(QSql::TableType type) const bool isNull; QString fieldVal = qGetStringData(hStmt, 2, -1, isNull); QString userVal = qGetStringData(hStmt, 1, -1, isNull); - if (userVal != d->user) + QString user = d->user; + if ( isIdentifierEscaped(user, QSqlDriver::TableName)) + user = stripDelimiters(user, QSqlDriver::TableName); + else + user = user.toUpper(); + + if (userVal != user) fieldVal = userVal + QLatin1Char('.') + fieldVal; tl.append(fieldVal); r = SQLFetchScroll(hStmt, @@ -1433,7 +1471,23 @@ QSqlIndex QDB2Driver::primaryIndex(const QString& tablename) const return index; } QString catalog, schema, table; - qSplitTableQualifier(tablename.toUpper(), &catalog, &schema, &table); + qSplitTableQualifier(tablename, &catalog, &schema, &table); + + if (isIdentifierEscaped(catalog, QSqlDriver::TableName)) + catalog = stripDelimiters(catalog, QSqlDriver::TableName); + else + catalog = catalog.toUpper(); + + if (isIdentifierEscaped(schema, QSqlDriver::TableName)) + schema = stripDelimiters(schema, QSqlDriver::TableName); + else + schema = schema.toUpper(); + + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + else + table = table.toUpper(); + r = SQLSetStmtAttr(hStmt, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER)SQL_CURSOR_FORWARD_ONLY, @@ -1477,7 +1531,6 @@ bool QDB2Driver::hasFeature(DriverFeature f) const case BatchOperations: case LastInsertId: case SimpleLocking: - case LowPrecisionNumbers: case EventNotifications: return false; case BLOB: @@ -1485,6 +1538,8 @@ bool QDB2Driver::hasFeature(DriverFeature f) const case MultipleResultSets: case PreparedQueries: case PositionalPlaceholders: + case LowPrecisionNumbers: + case FinishQuery: return true; case Unicode: // this is the query that shows the codepage for the types: diff --git a/src/sql/drivers/ibase/qsql_ibase.cpp b/src/sql/drivers/ibase/qsql_ibase.cpp index 0698f26..d714327 100644 --- a/src/sql/drivers/ibase/qsql_ibase.cpp +++ b/src/sql/drivers/ibase/qsql_ibase.cpp @@ -1103,6 +1103,19 @@ bool QIBaseResult::gotoNext(QSqlCachedResult::ValueCache& row, int rowIdx) // null value QVariant v; v.convert(qIBaseTypeName2(d->sqlda->sqlvar[i].sqltype, d->sqlda->sqlvar[i].sqlscale < 0)); + if(v.type() == QVariant::Double) { + switch(numericalPrecisionPolicy()) { + case QSql::LowPrecisionInt32: + v.convert(QVariant::Int); + break; + case QSql::LowPrecisionInt64: + v.convert(QVariant::LongLong); + break; + case QSql::HighPrecision: + v.convert(QVariant::String); + break; + } + } row[idx] = v; continue; } @@ -1168,6 +1181,27 @@ bool QIBaseResult::gotoNext(QSqlCachedResult::ValueCache& row, int rowIdx) row[idx] = QVariant(); break; } + if (d->sqlda->sqlvar[i].sqlscale < 0) { + QVariant v = row[idx]; + switch(numericalPrecisionPolicy()) { + case QSql::LowPrecisionInt32: + if(v.convert(QVariant::Int)) + row[idx]=v; + break; + case QSql::LowPrecisionInt64: + if(v.convert(QVariant::LongLong)) + row[idx]=v; + break; + case QSql::LowPrecisionDouble: + if(v.convert(QVariant::Double)) + row[idx]=v; + break; + case QSql::HighPrecision: + if(v.convert(QVariant::String)) + row[idx]=v; + break; + } + } } return true; @@ -1339,7 +1373,6 @@ bool QIBaseDriver::hasFeature(DriverFeature f) const case LastInsertId: case BatchOperations: case SimpleLocking: - case LowPrecisionNumbers: case FinishQuery: case MultipleResultSets: return false; @@ -1349,6 +1382,7 @@ bool QIBaseDriver::hasFeature(DriverFeature f) const case Unicode: case BLOB: case EventNotifications: + case LowPrecisionNumbers: return true; } return false; @@ -1558,12 +1592,16 @@ QSqlRecord QIBaseDriver::record(const QString& tablename) const QSqlQuery q(createResult()); q.setForwardOnly(true); - + QString table = tablename; + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + else + table = table.toUpper(); q.exec(QLatin1String("SELECT a.RDB$FIELD_NAME, b.RDB$FIELD_TYPE, b.RDB$FIELD_LENGTH, " "b.RDB$FIELD_SCALE, b.RDB$FIELD_PRECISION, a.RDB$NULL_FLAG " "FROM RDB$RELATION_FIELDS a, RDB$FIELDS b " "WHERE b.RDB$FIELD_NAME = a.RDB$FIELD_SOURCE " - "AND a.RDB$RELATION_NAME = '") + tablename.toUpper() + QLatin1String("' " + "AND a.RDB$RELATION_NAME = '") + table + QLatin1String("' " "ORDER BY a.RDB$FIELD_POSITION")); while (q.next()) { @@ -1591,12 +1629,18 @@ QSqlIndex QIBaseDriver::primaryIndex(const QString &table) const if (!isOpen()) return index; + QString tablename = table; + if (isIdentifierEscaped(tablename, QSqlDriver::TableName)) + tablename = stripDelimiters(tablename, QSqlDriver::TableName); + else + tablename = tablename.toUpper(); + QSqlQuery q(createResult()); q.setForwardOnly(true); q.exec(QLatin1String("SELECT a.RDB$INDEX_NAME, b.RDB$FIELD_NAME, d.RDB$FIELD_TYPE, d.RDB$FIELD_SCALE " "FROM RDB$RELATION_CONSTRAINTS a, RDB$INDEX_SEGMENTS b, RDB$RELATION_FIELDS c, RDB$FIELDS d " "WHERE a.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' " - "AND a.RDB$RELATION_NAME = '") + table.toUpper() + + "AND a.RDB$RELATION_NAME = '") + tablename + QLatin1String(" 'AND a.RDB$INDEX_NAME = b.RDB$INDEX_NAME " "AND c.RDB$RELATION_NAME = a.RDB$RELATION_NAME " "AND c.RDB$FIELD_NAME = b.RDB$FIELD_NAME " diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp index 46726a5..bfd65fc 100644 --- a/src/sql/drivers/mysql/qsql_mysql.cpp +++ b/src/sql/drivers/mysql/qsql_mysql.cpp @@ -254,6 +254,9 @@ static QVariant::Type qDecodeMYSQLType(int mysqltype, uint flags) case FIELD_TYPE_FLOAT : case FIELD_TYPE_DOUBLE : case FIELD_TYPE_DECIMAL : +#if defined(FIELD_TYPE_NEWDECIMAL) + case FIELD_TYPE_NEWDECIMAL: +#endif type = QVariant::Double; break; case FIELD_TYPE_DATE : diff --git a/src/sql/drivers/oci/qsql_oci.cpp b/src/sql/drivers/oci/qsql_oci.cpp index ca4b286..d5fb10f 100644 --- a/src/sql/drivers/oci/qsql_oci.cpp +++ b/src/sql/drivers/oci/qsql_oci.cpp @@ -1899,7 +1899,7 @@ void QOCIResult::virtual_hook(int id, void *data) QOCICols::execBatch(d, boundValues(), *reinterpret_cast<bool *>(data)); break; default: - QSqlResult::virtual_hook(id, data); + QSqlCachedResult::virtual_hook(id, data); } } diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp index 164e82c..3658ff3 100644 --- a/src/sql/drivers/odbc/qsql_odbc.cpp +++ b/src/sql/drivers/odbc/qsql_odbc.cpp @@ -598,6 +598,7 @@ QChar QODBCDriverPrivate::quoteChar() const return quote; } + bool QODBCDriverPrivate::setConnectionOptions(const QString& connOpts) { // Set any connection attributes diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp index db09e93..1ab8214 100644 --- a/src/sql/drivers/psql/qsql_psql.cpp +++ b/src/sql/drivers/psql/qsql_psql.cpp @@ -891,6 +891,16 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const QString schema; qSplitTableName(tbl, schema); + if (isIdentifierEscaped(tbl, QSqlDriver::TableName)) + tbl = stripDelimiters(tbl, QSqlDriver::TableName); + else + tbl = tbl.toLower(); + + if (isIdentifierEscaped(schema, QSqlDriver::TableName)) + schema = stripDelimiters(schema, QSqlDriver::TableName); + else + schema = schema.toLower(); + switch(d->pro) { case QPSQLDriver::Version6: stmt = QLatin1String("select pg_att1.attname, int(pg_att1.atttypid), pg_cl.relname " @@ -923,7 +933,7 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const "FROM pg_attribute, pg_class " "WHERE %1 pg_class.oid IN " "(SELECT indexrelid FROM pg_index WHERE indisprimary = true AND indrelid IN " - " (SELECT oid FROM pg_class WHERE lower(relname) = '%2')) " + " (SELECT oid FROM pg_class WHERE relname = '%2')) " "AND pg_attribute.attrelid = pg_class.oid " "AND pg_attribute.attisdropped = false " "ORDER BY pg_attribute.attnum"); @@ -931,11 +941,11 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const stmt = stmt.arg(QLatin1String("pg_table_is_visible(pg_class.oid) AND")); else stmt = stmt.arg(QString::fromLatin1("pg_class.relnamespace = (select oid from " - "pg_namespace where pg_namespace.nspname = '%1') AND ").arg(schema.toLower())); + "pg_namespace where pg_namespace.nspname = '%1') AND ").arg(schema)); break; } - i.exec(stmt.arg(tbl.toLower())); + i.exec(stmt.arg(tbl)); while (i.isActive() && i.next()) { QSqlField f(i.value(0).toString(), qDecodePSQLType(i.value(1).toInt())); idx.append(f); @@ -954,6 +964,16 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const QString schema; qSplitTableName(tbl, schema); + if (isIdentifierEscaped(tbl, QSqlDriver::TableName)) + tbl = stripDelimiters(tbl, QSqlDriver::TableName); + else + tbl = tbl.toLower(); + + if (isIdentifierEscaped(schema, QSqlDriver::TableName)) + schema = stripDelimiters(schema, QSqlDriver::TableName); + else + schema = schema.toLower(); + QString stmt; switch(d->pro) { case QPSQLDriver::Version6: @@ -998,7 +1018,7 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const "left join pg_attrdef on (pg_attrdef.adrelid = " "pg_attribute.attrelid and pg_attrdef.adnum = pg_attribute.attnum) " "where %1 " - "and lower(pg_class.relname) = '%2' " + "and pg_class.relname = '%2' " "and pg_attribute.attnum > 0 " "and pg_attribute.attrelid = pg_class.oid " "and pg_attribute.attisdropped = false " @@ -1007,12 +1027,12 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const stmt = stmt.arg(QLatin1String("pg_table_is_visible(pg_class.oid)")); else stmt = stmt.arg(QString::fromLatin1("pg_class.relnamespace = (select oid from " - "pg_namespace where pg_namespace.nspname = '%1')").arg(schema.toLower())); + "pg_namespace where pg_namespace.nspname = '%1')").arg(schema)); break; } QSqlQuery query(createResult()); - query.exec(stmt.arg(tbl.toLower())); + query.exec(stmt.arg(tbl)); if (d->pro >= QPSQLDriver::Version71) { while (query.next()) { int len = query.value(3).toInt(); diff --git a/src/sql/drivers/sqlite/qsql_sqlite.cpp b/src/sql/drivers/sqlite/qsql_sqlite.cpp index 1a05873..8e1091b 100644 --- a/src/sql/drivers/sqlite/qsql_sqlite.cpp +++ b/src/sql/drivers/sqlite/qsql_sqlite.cpp @@ -289,7 +289,7 @@ void QSQLiteResult::virtual_hook(int id, void *data) sqlite3_reset(d->stmt); break; default: - QSqlResult::virtual_hook(id, data); + QSqlCachedResult::virtual_hook(id, data); } } @@ -656,9 +656,13 @@ QSqlIndex QSQLiteDriver::primaryIndex(const QString &tblname) const if (!isOpen()) return QSqlIndex(); + QString table = tblname; + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + QSqlQuery q(createResult()); q.setForwardOnly(true); - return qGetTableInfo(q, tblname, true); + return qGetTableInfo(q, table, true); } QSqlRecord QSQLiteDriver::record(const QString &tbl) const @@ -666,9 +670,13 @@ QSqlRecord QSQLiteDriver::record(const QString &tbl) const if (!isOpen()) return QSqlRecord(); + QString table = tbl; + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + QSqlQuery q(createResult()); q.setForwardOnly(true); - return qGetTableInfo(q, tbl); + return qGetTableInfo(q, table); } QVariant QSQLiteDriver::handle() const @@ -676,10 +684,10 @@ QVariant QSQLiteDriver::handle() const return qVariantFromValue(d->access); } -QString QSQLiteDriver::escapeIdentifier(const QString &identifier, IdentifierType /*type*/) const +QString QSQLiteDriver::escapeIdentifier(const QString &identifier, IdentifierType type) const { QString res = identifier; - if(!identifier.isEmpty() && identifier.left(1) != QString(QLatin1Char('"')) && identifier.right(1) != QString(QLatin1Char('"')) ) { + if(!identifier.isEmpty() && !isIdentifierEscaped(identifier, type) ) { res.replace(QLatin1Char('"'), QLatin1String("\"\"")); res.prepend(QLatin1Char('"')).append(QLatin1Char('"')); res.replace(QLatin1Char('.'), QLatin1String("\".\"")); diff --git a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp index 790c1ef..1989c45 100644 --- a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp +++ b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp @@ -260,7 +260,7 @@ void QSQLite2Result::virtual_hook(int id, void *data) d->finalize(); break; default: - QSqlResult::virtual_hook(id, data); + QSqlCachedResult::virtual_hook(id, data); } } diff --git a/src/sql/drivers/tds/qsql_tds.cpp b/src/sql/drivers/tds/qsql_tds.cpp index 5ddc4e4..e100863 100644 --- a/src/sql/drivers/tds/qsql_tds.cpp +++ b/src/sql/drivers/tds/qsql_tds.cpp @@ -293,6 +293,8 @@ QTDSResult::QTDSResult(const QTDSDriver* db) // insert d in error handler dict errs()->insert(d->dbproc, d); + dbcmd(d->dbproc, "set quoted_identifier on"); + dbsqlexec(d->dbproc); } QTDSResult::~QTDSResult() @@ -367,7 +369,7 @@ bool QTDSResult::gotoNext(QSqlCachedResult::ValueCache &values, int index) if (qIsNull(d->buffer.at(i * 2 + 1))) values[idx] = QVariant(QVariant::String); else - values[idx] = QString::fromLocal8Bit((const char*)d->buffer.at(i * 2)); + values[idx] = QString::fromLocal8Bit((const char*)d->buffer.at(i * 2)).trimmed(); break; case QVariant::ByteArray: { if (qIsNull(d->buffer.at(i * 2 + 1))) @@ -698,9 +700,14 @@ QSqlRecord QTDSDriver::record(const QString& tablename) const return info; QSqlQuery t(createResult()); t.setForwardOnly(true); + + QString table = tablename; + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + QString stmt (QLatin1String("select name, type, length, prec from syscolumns " "where id = (select id from sysobjects where name = '%1')")); - t.exec(stmt.arg(tablename)); + t.exec(stmt.arg(table)); while (t.next()) { QSqlField f(t.value(0).toString().simplified(), qDecodeTDSType(t.value(1).toInt())); f.setLength(t.value(2).toInt()); @@ -770,13 +777,17 @@ QSqlIndex QTDSDriver::primaryIndex(const QString& tablename) const { QSqlRecord rec = record(tablename); - QSqlIndex idx(tablename); - if ((!isOpen()) || (tablename.isEmpty())) + QString table = tablename; + if (isIdentifierEscaped(table, QSqlDriver::TableName)) + table = stripDelimiters(table, QSqlDriver::TableName); + + QSqlIndex idx(table); + if ((!isOpen()) || (table.isEmpty())) return QSqlIndex(); QSqlQuery t(createResult()); t.setForwardOnly(true); - t.exec(QString::fromLatin1("sp_helpindex '%1'").arg(tablename)); + t.exec(QString::fromLatin1("sp_helpindex '%1'").arg(table)); if (t.next()) { QStringList fNames = t.value(2).toString().simplified().split(QLatin1Char(',')); QRegExp regx(QLatin1String("\\s*(\\S+)(?:\\s+(DESC|desc))?\\s*")); diff --git a/src/sql/kernel/qsqlcachedresult.cpp b/src/sql/kernel/qsqlcachedresult.cpp index 3cace06..ca51dc0 100644 --- a/src/sql/kernel/qsqlcachedresult.cpp +++ b/src/sql/kernel/qsqlcachedresult.cpp @@ -294,4 +294,17 @@ QSqlCachedResult::ValueCache &QSqlCachedResult::cache() return d->cache; } +void QSqlCachedResult::virtual_hook(int id, void *data) +{ + switch (id) { + case QSqlResult::DetachFromResultSet: + case QSqlResult::SetNumericalPrecision: + cleanup(); + break; + default: + QSqlResult::virtual_hook(id, data); + } +} + + QT_END_NAMESPACE diff --git a/src/sql/kernel/qsqlcachedresult_p.h b/src/sql/kernel/qsqlcachedresult_p.h index d19435c..a384b2e 100644 --- a/src/sql/kernel/qsqlcachedresult_p.h +++ b/src/sql/kernel/qsqlcachedresult_p.h @@ -89,6 +89,7 @@ protected: int colCount() const; ValueCache &cache(); + void virtual_hook(int id, void *data); private: bool cacheNext(); QSqlCachedResultPrivate *d; diff --git a/src/sql/kernel/qsqlresult.cpp b/src/sql/kernel/qsqlresult.cpp index 1c1595d..93c9d9f 100644 --- a/src/sql/kernel/qsqlresult.cpp +++ b/src/sql/kernel/qsqlresult.cpp @@ -905,7 +905,6 @@ QVariant QSqlResult::lastInsertId() const */ void QSqlResult::virtual_hook(int, void *) { - Q_ASSERT(false); } /*! \internal @@ -971,6 +970,7 @@ void QSqlResult::detachFromResultSet() void QSqlResult::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy policy) { d->precisionPolicy = policy; + virtual_hook(SetNumericalPrecision, &policy); } /*! \internal diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp index 1acc846..156af26 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -98,7 +98,10 @@ bool QSqlTableModelPrivate::setRecord(int row, const QSqlRecord &record) int QSqlTableModelPrivate::nameToIndex(const QString &name) const { - return rec.indexOf(name); + QString fieldname = name; + if (db.driver()->isIdentifierEscaped(fieldname, QSqlDriver::FieldName)) + fieldname = db.driver()->stripDelimiters(fieldname, QSqlDriver::FieldName); + return rec.indexOf(fieldname); } void QSqlTableModelPrivate::initRecordAndPrimaryIndex() @@ -367,10 +370,7 @@ void QSqlTableModel::setTable(const QString &tableName) { Q_D(QSqlTableModel); clear(); - if(d->db.tables().contains(tableName.toUpper())) - d->tableName = tableName.toUpper(); - else - d->tableName = tableName; + d->tableName = tableName; d->initRecordAndPrimaryIndex(); d->initColOffsets(d->rec.count()); @@ -976,7 +976,9 @@ QString QSqlTableModel::orderByClause() const if (!f.isValid()) return s; - QString table = d->db.driver()->escapeIdentifier(d->tableName, QSqlDriver::TableName); + QString table = d->tableName; + //we can safely escape the field because it would have been obtained from the database + //and have the correct case QString field = d->db.driver()->escapeIdentifier(f.name(), QSqlDriver::FieldName); s.append(QLatin1String("ORDER BY ")).append(table).append(QLatin1Char('.')).append(field); s += d->sortOrder == Qt::AscendingOrder ? QLatin1String(" ASC") : QLatin1String(" DESC"); @@ -1317,8 +1319,12 @@ bool QSqlTableModel::setRecord(int row, const QSqlRecord &record) mrow.rec = d->rec; mrow.primaryValues = d->primaryValues(indexInQuery(createIndex(row, 0)).row()); } + QString fieldName; for (int i = 0; i < record.count(); ++i) { - int idx = mrow.rec.indexOf(record.fieldName(i)); + fieldName = record.fieldName(i); + if (d->db.driver()->isIdentifierEscaped(fieldName, QSqlDriver::FieldName)) + fieldName = d->db.driver()->stripDelimiters(fieldName, QSqlDriver::FieldName); + int idx = mrow.rec.indexOf(fieldName); if (idx == -1) isOk = false; else diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index 44477e5..e2c1312 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -3378,6 +3378,7 @@ void QSvgHandler::init() { m_doc = 0; m_style = 0; + m_animEnd = 0; m_defaultCoords = LT_PX; m_defaultPen = QPen(Qt::black, 1, Qt::NoPen, Qt::FlatCap, Qt::SvgMiterJoin); m_defaultPen.setMiterLimit(4); |