summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/src/frameworks-technologies/activeqt.qdoc17
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp114
-rw-r--r--src/gui/graphicsview/qgraphicsitem.h7
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h67
-rw-r--r--src/gui/graphicsview/qgraphicswidget.cpp14
-rw-r--r--src/gui/graphicsview/qgraphicswidget_p.cpp51
-rw-r--r--src/gui/graphicsview/qgraphicswidget_p.h9
-rw-r--r--src/multimedia/audio/qaudioinput_mac_p.cpp4
-rw-r--r--src/sql/drivers/odbc/qsql_odbc.cpp157
-rw-r--r--tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp178
-rw-r--r--tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp44
-rw-r--r--tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp34
-rw-r--r--tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp28
-rw-r--r--tests/auto/qsqlquery/tst_qsqlquery.cpp9
14 files changed, 592 insertions, 141 deletions
diff --git a/doc/src/frameworks-technologies/activeqt.qdoc b/doc/src/frameworks-technologies/activeqt.qdoc
index 67b9bb3..5e8473f 100644
--- a/doc/src/frameworks-technologies/activeqt.qdoc
+++ b/doc/src/frameworks-technologies/activeqt.qdoc
@@ -57,6 +57,7 @@
\brief An overview of Qt's ActiveX and COM integration on Windows.
\ingroup platform-specific
+ \ingroup frameworks-technologies
\keyword ActiveQt
Qt's ActiveX and COM support allows Qt for Windows developers to:
@@ -69,19 +70,23 @@
controls.
\endlist
- The ActiveQt framework consists of two modules:
+ The ActiveQt framework consists of two frameworks:
\list
- \o The \l QAxContainer module is a static
- library implementing QObject and QWidget subclasses, QAxObject and
- QAxWidget, that act as containers for COM objects and ActiveX
- controls.
- \o The \l QAxServer module is a static library that implements
+ \o The \l{Using ActiveX controls and COM objects in Qt}{QAxContainer}
+ module is a static library implementing QObject and QWidget subclasses,
+ QAxObject and QAxWidget, that act as containers for COM objects and
+ ActiveX controls.
+ \o The \l{Building ActiveX servers and controls with Qt}{QAxServer}
+ module is a static library that implements
functionality for in-process and executable COM servers. This
module provides the QAxAggregated, QAxBindable and QAxFactory
classes.
\endlist
+ A set of \l{Tools for ActiveQt}{tools} is provided to simplify the
+ developing and building of Qt projects that use ActiveX.
+
To build the static libraries, change into the \c activeqt directory
(usually \c QTDIR/src/activeqt), and run \c qmake and your make
tool in both the \c container and the \c control subdirectory.
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index f3c90ca..f110a5c 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -1130,6 +1130,9 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const Q
}
}
+ // Resolve depth.
+ invalidateDepthRecursively();
+
if ((parent = newParent)) {
if (parent->d_func()->scene && parent->d_func()->scene != scene) {
// Move this item to its new parent's scene
@@ -1180,8 +1183,6 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const Q
}
}
- // Resolve depth.
- invalidateDepthRecursively();
dirtySceneTransform = 1;
// Restore the sub focus chain.
@@ -2176,8 +2177,12 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo
QGraphicsItemCache *c = (QGraphicsItemCache *)qVariantValue<void *>(extra(ExtraCacheData));
if (c)
c->purge();
- if (scene)
+ if (scene) {
+#ifndef QT_NO_GRAPHICSEFFECT
+ invalidateParentGraphicsEffectsRecursively();
+#endif //QT_NO_GRAPHICSEFFECT
scene->d_func()->markDirty(q_ptr, QRectF(), /*invalidateChildren=*/false, /*force=*/true);
+ }
}
// Certain properties are dropped as an item becomes invisible.
@@ -5219,6 +5224,8 @@ void QGraphicsItemPrivate::addChild(QGraphicsItem *child)
needSortChildren = 1; // ### maybe 0
child->d_ptr->siblingIndex = children.size();
children.append(child);
+ if (isObject)
+ emit static_cast<QGraphicsObject *>(q_ptr)->childrenChanged();
}
/*!
@@ -5241,6 +5248,8 @@ void QGraphicsItemPrivate::removeChild(QGraphicsItem *child)
// the child is not guaranteed to be at the index after the list is sorted.
// (see ensureSortedChildren()).
child->d_ptr->siblingIndex = -1;
+ if (isObject)
+ emit static_cast<QGraphicsObject *>(q_ptr)->childrenChanged();
}
/*!
@@ -7448,6 +7457,88 @@ void QGraphicsObject::ungrabGesture(Qt::GestureType gesture)
}
}
+void QGraphicsItemPrivate::append(QDeclarativeListProperty<QGraphicsObject> *list, QGraphicsObject *item)
+{
+ QGraphicsItemPrivate::get(item)->setParentItemHelper(static_cast<QGraphicsObject *>(list->object), /*newParentVariant=*/0, /*thisPointerVariant=*/0);
+}
+
+/*!
+ Returns a list of this item's children.
+
+ The items are sorted by stacking order. This takes into account both the
+ items' insertion order and their Z-values.
+
+*/
+QDeclarativeListProperty<QGraphicsObject> QGraphicsItemPrivate::childrenList()
+{
+ Q_Q(QGraphicsItem);
+ if (isObject) {
+ QGraphicsObject *that = static_cast<QGraphicsObject *>(q);
+ return QDeclarativeListProperty<QGraphicsObject>(that, &children, QGraphicsItemPrivate::append);
+ } else {
+ //QGraphicsItem is not supported for this property
+ return QDeclarativeListProperty<QGraphicsObject>();
+ }
+}
+
+/*!
+ \internal
+ Returns the width of the item
+ Reimplemented by QGraphicsWidget
+*/
+qreal QGraphicsItemPrivate::width() const
+{
+ return 0;
+}
+
+/*!
+ \internal
+ Set the width of the item
+ Reimplemented by QGraphicsWidget
+*/
+void QGraphicsItemPrivate::setWidth(qreal w)
+{
+ Q_UNUSED(w);
+}
+
+/*!
+ \internal
+ Reset the width of the item
+ Reimplemented by QGraphicsWidget
+*/
+void QGraphicsItemPrivate::resetWidth()
+{
+}
+
+/*!
+ \internal
+ Returns the height of the item
+ Reimplemented by QGraphicsWidget
+*/
+qreal QGraphicsItemPrivate::height() const
+{
+ return 0;
+}
+
+/*!
+ \internal
+ Set the height of the item
+ Reimplemented by QGraphicsWidget
+*/
+void QGraphicsItemPrivate::setHeight(qreal h)
+{
+ Q_UNUSED(h);
+}
+
+/*!
+ \internal
+ Reset the height of the item
+ Reimplemented by QGraphicsWidget
+*/
+void QGraphicsItemPrivate::resetHeight()
+{
+}
+
/*!
\property QGraphicsObject::parent
\brief the parent of the item
@@ -7634,6 +7725,23 @@ void QGraphicsObject::ungrabGesture(Qt::GestureType gesture)
\sa scale, rotation, QGraphicsItem::transformOriginPoint()
*/
+/*!
+ \fn void QGraphicsObject::widthChanged()
+ \internal
+*/
+
+/*!
+ \fn void QGraphicsObject::heightChanged()
+ \internal
+*/
+
+/*!
+
+ \fn QGraphicsObject::childrenChanged()
+
+ This signal gets emitted whenever the children list changes
+ \internal
+*/
/*!
\class QAbstractGraphicsShapeItem
diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h
index d72833b..5023f60 100644
--- a/src/gui/graphicsview/qgraphicsitem.h
+++ b/src/gui/graphicsview/qgraphicsitem.h
@@ -547,6 +547,10 @@ class Q_GUI_EXPORT QGraphicsObject : public QObject, public QGraphicsItem
Q_PROPERTY(qreal rotation READ rotation WRITE setRotation NOTIFY rotationChanged)
Q_PROPERTY(qreal scale READ scale WRITE setScale NOTIFY scaleChanged)
Q_PROPERTY(QPointF transformOriginPoint READ transformOriginPoint WRITE setTransformOriginPoint)
+ Q_PRIVATE_PROPERTY(QGraphicsItem::d_func(), QDeclarativeListProperty<QGraphicsObject> children READ childrenList DESIGNABLE false NOTIFY childrenChanged)
+ Q_PRIVATE_PROPERTY(QGraphicsItem::d_func(), qreal width READ width WRITE setWidth NOTIFY widthChanged RESET resetWidth FINAL)
+ Q_PRIVATE_PROPERTY(QGraphicsItem::d_func(), qreal height READ height WRITE setHeight NOTIFY heightChanged RESET resetHeight FINAL)
+ Q_CLASSINFO("DefaultProperty", "children")
Q_INTERFACES(QGraphicsItem)
public:
QGraphicsObject(QGraphicsItem *parent = 0);
@@ -571,6 +575,9 @@ Q_SIGNALS:
void zChanged();
void rotationChanged();
void scaleChanged();
+ void childrenChanged();
+ void widthChanged();
+ void heightChanged();
protected:
QGraphicsObject(QGraphicsItemPrivate &dd, QGraphicsItem *parent, QGraphicsScene *scene);
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index ea04e0b..669ae1b 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -71,6 +71,62 @@ QT_BEGIN_NAMESPACE
class QGraphicsItemPrivate;
+#ifndef QDECLARATIVELISTPROPERTY
+#define QDECLARATIVELISTPROPERTY
+template<typename T>
+struct QDeclarativeListProperty {
+ typedef void (*AppendFunction)(QDeclarativeListProperty<T> *, T*);
+ typedef int (*CountFunction)(QDeclarativeListProperty<T> *);
+ typedef T *(*AtFunction)(QDeclarativeListProperty<T> *, int);
+ typedef void (*ClearFunction)(QDeclarativeListProperty<T> *);
+
+ QDeclarativeListProperty()
+ : object(0), data(0), append(0), count(0), at(0), clear(0), dummy1(0), dummy2(0) {}
+ QDeclarativeListProperty(QObject *o, QList<T *> &list)
+ : object(o), data(&list), append(qlist_append), count(qlist_count), at(qlist_at),
+ clear(qlist_clear), dummy1(0), dummy2(0) {}
+ QDeclarativeListProperty(QObject *o, void *d, AppendFunction a, CountFunction c = 0, AtFunction t = 0,
+ ClearFunction r = 0)
+ : object(o), data(d), append(a), count(c), at(t), clear(r), dummy1(0), dummy2(0) {}
+
+ bool operator==(const QDeclarativeListProperty &o) const {
+ return object == o.object &&
+ data == o.data &&
+ append == o.append &&
+ count == o.count &&
+ at == o.at &&
+ clear == o.clear;
+ }
+
+ QObject *object;
+ void *data;
+
+ AppendFunction append;
+
+ CountFunction count;
+ AtFunction at;
+
+ ClearFunction clear;
+
+ void *dummy1;
+ void *dummy2;
+
+private:
+ static void qlist_append(QDeclarativeListProperty *p, T *v) {
+ ((QList<T *> *)p->data)->append(v);
+ }
+ static int qlist_count(QDeclarativeListProperty *p) {
+ return ((QList<T *> *)p->data)->count();
+ }
+ static T *qlist_at(QDeclarativeListProperty *p, int idx) {
+ return ((QList<T *> *)p->data)->at(idx);
+ }
+ static void qlist_clear(QDeclarativeListProperty *p) {
+ return ((QList<T *> *)p->data)->clear();
+ }
+};
+#endif
+
class QGraphicsItemCache
{
public:
@@ -237,6 +293,7 @@ public:
void resolveDepth();
void addChild(QGraphicsItem *child);
void removeChild(QGraphicsItem *child);
+ QDeclarativeListProperty<QGraphicsObject> childrenList();
void setParentItemHelper(QGraphicsItem *parent, const QVariant *newParentVariant,
const QVariant *thisPointerVariant);
void childrenBoundingRectHelper(QTransform *x, QRectF *rect);
@@ -423,11 +480,21 @@ public:
inline QTransform transformToParent() const;
inline void ensureSortedChildren();
+ static void append(QDeclarativeListProperty<QGraphicsObject> *list, QGraphicsObject *item);
static inline bool insertionOrder(QGraphicsItem *a, QGraphicsItem *b);
void ensureSequentialSiblingIndex();
inline void sendScenePosChange();
virtual void siblingOrderChange();
+ // Private Properties
+ virtual qreal width() const;
+ virtual void setWidth(qreal);
+ virtual void resetWidth();
+
+ virtual qreal height() const;
+ virtual void setHeight(qreal);
+ virtual void resetHeight();
+
QRectF childrenBoundingRect;
QRectF needsRepaint;
QMap<QWidget *, QRect> paintedViewBoundingRects;
diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp
index f42fe4f..a091347 100644
--- a/src/gui/graphicsview/qgraphicswidget.cpp
+++ b/src/gui/graphicsview/qgraphicswidget.cpp
@@ -324,6 +324,14 @@ void QGraphicsWidget::resize(const QSizeF &size)
*/
/*!
+
+ \fn QGraphicsWidget::geometryChanged()
+
+ This signal gets emitted whenever the geometry of the item changes
+ \internal
+*/
+
+/*!
\property QGraphicsWidget::geometry
\brief the geometry of the widget
@@ -391,6 +399,10 @@ void QGraphicsWidget::setGeometry(const QRectF &rect)
QGraphicsSceneResizeEvent re;
re.setOldSize(oldSize);
re.setNewSize(newGeom.size());
+ if (oldSize.width() != newGeom.size().width())
+ emit widthChanged();
+ if (oldSize.height() != newGeom.size().height())
+ emit heightChanged();
QApplication::sendEvent(this, &re);
}
}
@@ -2322,5 +2334,7 @@ void QGraphicsWidget::dumpFocusChain()
#endif
QT_END_NAMESPACE
+
+#include "moc_qgraphicswidget.cpp"
#endif //QT_NO_GRAPHICSVIEW
diff --git a/src/gui/graphicsview/qgraphicswidget_p.cpp b/src/gui/graphicsview/qgraphicswidget_p.cpp
index 1835c74..6e397b6 100644
--- a/src/gui/graphicsview/qgraphicswidget_p.cpp
+++ b/src/gui/graphicsview/qgraphicswidget_p.cpp
@@ -44,6 +44,7 @@
#ifndef QT_NO_GRAPHICSVIEW
#include <QtCore/qdebug.h>
+#include <QtCore/qnumeric.h>
#include "qgraphicswidget_p.h"
#include "qgraphicslayout.h"
#include "qgraphicsscene_p.h"
@@ -825,6 +826,56 @@ void QGraphicsWidgetPrivate::setLayout_helper(QGraphicsLayout *l)
}
}
+qreal QGraphicsWidgetPrivate::width() const
+{
+ Q_Q(const QGraphicsWidget);
+ return q->geometry().width();
+}
+
+void QGraphicsWidgetPrivate::setWidth(qreal w)
+{
+ if (qIsNaN(w))
+ return;
+ Q_Q(QGraphicsWidget);
+ if (q->geometry().width() == w)
+ return;
+
+ QRectF oldGeom = q->geometry();
+
+ q->setGeometry(QRectF(q->x(), q->y(), w, height()));
+}
+
+void QGraphicsWidgetPrivate::resetWidth()
+{
+ Q_Q(QGraphicsWidget);
+ q->setGeometry(QRectF(q->x(), q->y(), 0, height()));
+}
+
+qreal QGraphicsWidgetPrivate::height() const
+{
+ Q_Q(const QGraphicsWidget);
+ return q->geometry().height();
+}
+
+void QGraphicsWidgetPrivate::setHeight(qreal h)
+{
+ if (qIsNaN(h))
+ return;
+ Q_Q(QGraphicsWidget);
+ if (q->geometry().height() == h)
+ return;
+
+ QRectF oldGeom = q->geometry();
+
+ q->setGeometry(QRectF(q->x(), q->y(), width(), h));
+}
+
+void QGraphicsWidgetPrivate::resetHeight()
+{
+ Q_Q(QGraphicsWidget);
+ q->setGeometry(QRectF(q->x(), q->y(), width(), 0));
+}
+
QT_END_NAMESPACE
#endif //QT_NO_GRAPHICSVIEW
diff --git a/src/gui/graphicsview/qgraphicswidget_p.h b/src/gui/graphicsview/qgraphicswidget_p.h
index 2c5b3bf..f34a755 100644
--- a/src/gui/graphicsview/qgraphicswidget_p.h
+++ b/src/gui/graphicsview/qgraphicswidget_p.h
@@ -130,6 +130,15 @@ public:
void windowFrameHoverLeaveEvent(QGraphicsSceneHoverEvent *event);
bool hasDecoration() const;
+ // Private Properties
+ qreal width() const;
+ void setWidth(qreal);
+ void resetWidth();
+
+ qreal height() const;
+ void setHeight(qreal);
+ void resetHeight();
+
// State
inline int attributeToBitIndex(Qt::WidgetAttribute att) const
{
diff --git a/src/multimedia/audio/qaudioinput_mac_p.cpp b/src/multimedia/audio/qaudioinput_mac_p.cpp
index 4b37b18..cb65f6e 100644
--- a/src/multimedia/audio/qaudioinput_mac_p.cpp
+++ b/src/multimedia/audio/qaudioinput_mac_p.cpp
@@ -670,8 +670,8 @@ bool QAudioInputPrivate::open()
}
// Allocate buffer
- periodSizeBytes = (numberOfFrames * streamFormat.mSampleRate / deviceFormat.mSampleRate) *
- streamFormat.mBytesPerFrame;
+ periodSizeBytes = numberOfFrames * streamFormat.mBytesPerFrame;
+
if (internalBufferSize < periodSizeBytes * 2)
internalBufferSize = periodSizeBytes * 2;
else
diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp
index e75c19d..f41a914 100644
--- a/src/sql/drivers/odbc/qsql_odbc.cpp
+++ b/src/sql/drivers/odbc/qsql_odbc.cpp
@@ -131,11 +131,10 @@ class QODBCDriverPrivate
public:
enum DefaultCase{Lower, Mixed, Upper, Sensitive};
QODBCDriverPrivate()
- : hEnv(0), hDbc(0), useSchema(false), disconnectCount(0), isMySqlServer(false),
- isMSSqlServer(false), hasSQLFetchScroll(true), hasMultiResultSets(false),
- isQuoteInitialized(false), quote(QLatin1Char('"'))
+ : hEnv(0), hDbc(0), unicode(false), useSchema(false), disconnectCount(0), isMySqlServer(false),
+ isMSSqlServer(false), isFreeTDSDriver(false), hasSQLFetchScroll(true),
+ hasMultiResultSets(false), isQuoteInitialized(false), quote(QLatin1Char('"'))
{
- unicode = false;
}
SQLHANDLE hEnv;
@@ -146,6 +145,7 @@ public:
int disconnectCount;
bool isMySqlServer;
bool isMSSqlServer;
+ bool isFreeTDSDriver;
bool hasSQLFetchScroll;
bool hasMultiResultSets;
@@ -172,7 +172,10 @@ public:
QODBCPrivate(QODBCDriverPrivate *dpp)
: hStmt(0), useSchema(false), hasSQLFetchScroll(true), driverPrivate(dpp), userForwardOnly(false)
{
- unicode = false;
+ unicode = dpp->unicode;
+ useSchema = dpp->useSchema;
+ disconnectCount = dpp->disconnectCount;
+ hasSQLFetchScroll = dpp->hasSQLFetchScroll;
}
inline void clearValues()
@@ -349,7 +352,9 @@ static QVariant::Type qDecodeODBCType(SQLSMALLINT sqltype, const T* p, bool isSi
#endif
case SQL_CHAR:
case SQL_VARCHAR:
+#if (ODBCVER >= 0x0350)
case SQL_GUID:
+#endif
case SQL_LONGVARCHAR:
type = QVariant::String;
break;
@@ -374,44 +379,88 @@ static QString qGetStringData(SQLHANDLE hStmt, int column, int colSize, bool uni
} else {
colSize++; // make sure there is room for more than the 0 termination
}
- r = SQLGetData(hStmt,
- column+1,
- SQL_C_TCHAR,
- NULL,
- 0,
- &lengthIndicator);
- if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && lengthIndicator > 0)
- colSize = lengthIndicator/sizeof(SQLTCHAR) + 1;
- QVarLengthArray<SQLTCHAR> buf(colSize);
- while (true) {
+ if(unicode) {
r = SQLGetData(hStmt,
column+1,
SQL_C_TCHAR,
- (SQLPOINTER)buf.data(),
- colSize*sizeof(SQLTCHAR),
+ NULL,
+ 0,
&lengthIndicator);
- if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) {
- if (lengthIndicator == SQL_NULL_DATA || lengthIndicator == SQL_NO_TOTAL) {
+ if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && lengthIndicator > 0)
+ colSize = lengthIndicator/sizeof(SQLTCHAR) + 1;
+ QVarLengthArray<SQLTCHAR> buf(colSize);
+ memset(buf.data(), 0, colSize*sizeof(SQLTCHAR));
+ while (true) {
+ r = SQLGetData(hStmt,
+ column+1,
+ SQL_C_TCHAR,
+ (SQLPOINTER)buf.data(),
+ colSize*sizeof(SQLTCHAR),
+ &lengthIndicator);
+ if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) {
+ if (lengthIndicator == SQL_NULL_DATA || lengthIndicator == SQL_NO_TOTAL) {
+ fieldVal.clear();
+ break;
+ }
+ // if SQL_SUCCESS_WITH_INFO is returned, indicating that
+ // more data can be fetched, the length indicator does NOT
+ // contain the number of bytes returned - it contains the
+ // total number of bytes that CAN be fetched
+ // colSize-1: remove 0 termination when there is more data to fetch
+ int rSize = (r == SQL_SUCCESS_WITH_INFO) ? colSize : lengthIndicator/sizeof(SQLTCHAR);
+ fieldVal += fromSQLTCHAR(buf, rSize);
+ if (lengthIndicator < (unsigned int)colSize*sizeof(SQLTCHAR)) {
+ // workaround for Drivermanagers that don't return SQL_NO_DATA
+ break;
+ }
+ } else if (r == SQL_NO_DATA) {
+ break;
+ } else {
+ qWarning() << "qGetStringData: Error while fetching data (" << qWarnODBCHandle(SQL_HANDLE_STMT, hStmt) << ')';
fieldVal.clear();
break;
}
- // if SQL_SUCCESS_WITH_INFO is returned, indicating that
- // more data can be fetched, the length indicator does NOT
- // contain the number of bytes returned - it contains the
- // total number of bytes that CAN be fetched
- // colSize-1: remove 0 termination when there is more data to fetch
- int rSize = (r == SQL_SUCCESS_WITH_INFO) ? colSize : lengthIndicator/sizeof(SQLTCHAR);
- fieldVal += fromSQLTCHAR(buf, rSize);
- if (lengthIndicator < (unsigned int)colSize*sizeof(SQLTCHAR)) {
- // workaround for Drivermanagers that don't return SQL_NO_DATA
+ }
+ } else {
+ r = SQLGetData(hStmt,
+ column+1,
+ SQL_C_CHAR,
+ NULL,
+ 0,
+ &lengthIndicator);
+ if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && lengthIndicator > 0)
+ colSize = lengthIndicator + 1;
+ QVarLengthArray<SQLCHAR> buf(colSize);
+ while (true) {
+ r = SQLGetData(hStmt,
+ column+1,
+ SQL_C_CHAR,
+ (SQLPOINTER)buf.data(),
+ colSize,
+ &lengthIndicator);
+ if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) {
+ if (lengthIndicator == SQL_NULL_DATA || lengthIndicator == SQL_NO_TOTAL) {
+ fieldVal.clear();
+ break;
+ }
+ // if SQL_SUCCESS_WITH_INFO is returned, indicating that
+ // more data can be fetched, the length indicator does NOT
+ // contain the number of bytes returned - it contains the
+ // total number of bytes that CAN be fetched
+ // colSize-1: remove 0 termination when there is more data to fetch
+ int rSize = (r == SQL_SUCCESS_WITH_INFO) ? colSize : lengthIndicator;
+ fieldVal += QString::fromUtf8((const char *)buf.constData(), rSize);
+ if (lengthIndicator < (unsigned int)colSize) {
+ // workaround for Drivermanagers that don't return SQL_NO_DATA
+ break;
+ }
+ } else if (r == SQL_NO_DATA) {
+ break;
+ } else {
+ qWarning() << "qGetStringData: Error while fetching data (" << qWarnODBCHandle(SQL_HANDLE_STMT, hStmt) << ')';
+ fieldVal.clear();
break;
}
- } else if (r == SQL_NO_DATA) {
- break;
- } else {
- qWarning() << "qGetStringData: Error while fetching data (" << qWarnODBCHandle(SQL_HANDLE_STMT, hStmt) << ')';
- fieldVal.clear();
- break;
}
}
return fieldVal;
@@ -866,10 +915,6 @@ QODBCResult::QODBCResult(const QODBCDriver * db, QODBCDriverPrivate* p)
: QSqlResult(db)
{
d = new QODBCPrivate(p);
- d->unicode = p->unicode;
- d->useSchema = p->useSchema;
- d->disconnectCount = p->disconnectCount;
- d->hasSQLFetchScroll = p->hasSQLFetchScroll;
}
QODBCResult::~QODBCResult()
@@ -1846,6 +1891,7 @@ bool QODBCDriver::open(const QString & db,
SQLSMALLINT cb;
QVarLengthArray<SQLTCHAR> connOut(1024);
+ memset(connOut.data(), 0, connOut.size() * sizeof(SQLTCHAR));
r = SQLDriverConnect(d->hDbc,
NULL,
#ifdef UNICODE
@@ -1943,6 +1989,7 @@ void QODBCDriverPrivate::checkUnicode()
NULL);
if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (fFunc & SQL_CVT_WCHAR)) {
unicode = true;
+ return;
}
r = SQLGetInfo(hDbc,
@@ -1952,6 +1999,7 @@ void QODBCDriverPrivate::checkUnicode()
NULL);
if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (fFunc & SQL_CVT_WVARCHAR)) {
unicode = true;
+ return;
}
r = SQLGetInfo(hDbc,
@@ -1961,7 +2009,25 @@ void QODBCDriverPrivate::checkUnicode()
NULL);
if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && (fFunc & SQL_CVT_WLONGVARCHAR)) {
unicode = true;
+ return;
+ }
+ SQLHANDLE hStmt;
+ r = SQLAllocHandle(SQL_HANDLE_STMT,
+ hDbc,
+ &hStmt);
+
+ r = SQLExecDirect(hStmt, toSQLTCHAR(QLatin1String("select 'test'")).data(), SQL_NTS);
+ if(r == SQL_SUCCESS) {
+ r = SQLFetch(hStmt);
+ if(r == SQL_SUCCESS) {
+ QVarLengthArray<SQLWCHAR> buffer(10);
+ r = SQLGetData(hStmt, 1, SQL_C_WCHAR, buffer.data(), buffer.size() * sizeof(SQLWCHAR), NULL);
+ if(r == SQL_SUCCESS && fromSQLTCHAR(buffer) == QLatin1String("test")) {
+ unicode = true;
+ }
+ }
}
+ r = SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
}
bool QODBCDriverPrivate::checkDriver() const
@@ -2053,6 +2119,21 @@ void QODBCDriverPrivate::checkSqlServer()
isMySqlServer = serverType.contains(QLatin1String("mysql"), Qt::CaseInsensitive);
isMSSqlServer = serverType.contains(QLatin1String("Microsoft SQL Server"), Qt::CaseInsensitive);
}
+ r = SQLGetInfo(hDbc,
+ SQL_DRIVER_NAME,
+ serverString.data(),
+ serverString.size() * sizeof(SQLTCHAR),
+ &t);
+ if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) {
+ QString serverType;
+#ifdef UNICODE
+ serverType = fromSQLTCHAR(serverString, t/sizeof(SQLTCHAR));
+#else
+ serverType = QString::fromUtf8((const char *)serverString.constData(), t);
+#endif
+ isFreeTDSDriver = serverType.contains(QLatin1String("tdsodbc"), Qt::CaseInsensitive);
+ unicode = isFreeTDSDriver == false;
+ }
}
void QODBCDriverPrivate::checkHasSQLFetchScroll()
diff --git a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp
index f837564..f3c2c09 100644
--- a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp
+++ b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp
@@ -44,7 +44,7 @@
#include <q3sqlcursor.h>
#include <qsqlfield.h>
#include <qsqldriver.h>
-
+#include <QSet>
#include "../qsqldatabase/tst_databases.h"
@@ -122,7 +122,7 @@ void tst_Q3SqlCursor::generic_data(const QString &engine)
{
if ( dbs.fillTestTable(engine) == 0 ) {
if(engine.isEmpty())
- QSKIP( "No database drivers are available in this Qt configuration", SkipAll );
+ 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 );
}
@@ -131,7 +131,7 @@ void tst_Q3SqlCursor::generic_data(const QString &engine)
void tst_Q3SqlCursor::createTestTables( QSqlDatabase db )
{
if ( !db.isValid() )
- return;
+ return;
QSqlQuery q( db );
if (tst_Databases::isSqlServer(db)) {
@@ -143,20 +143,20 @@ void tst_Q3SqlCursor::createTestTables( QSqlDatabase db )
// please never ever change this table; otherwise fix all tests ;)
if ( tst_Databases::isMSAccess( db ) ) {
- QVERIFY_SQL(q, exec( "create table " + qtest + " ( id int not null, t_varchar varchar(40) not null,"
- "t_char char(40), t_numeric number, primary key (id, t_varchar) )" ));
+ QVERIFY_SQL(q, exec( "create table " + qtest + " ( id int not null, t_varchar varchar(40) not null,"
+ "t_char char(40), t_numeric number, primary key (id, t_varchar) )" ));
} else {
- QVERIFY_SQL(q, exec( "create table " + qtest + " ( id int not null, t_varchar varchar(40) not null,"
- "t_char char(40), t_numeric numeric(6, 3), primary key (id, t_varchar) )" ));
+ QVERIFY_SQL(q, exec( "create table " + qtest + " ( id int not null, t_varchar varchar(40) not null,"
+ "t_char char(40), t_numeric numeric(6, 3), primary key (id, t_varchar) )" ));
}
if ( tst_Databases::isSqlServer( db ) ) {
- //workaround for SQL SERVER since he can store unicode only in nvarchar fields
- QVERIFY_SQL(q, exec("create table " + qTableName("qtest_unicode", __FILE__) + " (id int not null, "
- "t_varchar nvarchar(80) not null, t_char nchar(80) )" ));
+ //workaround for SQL SERVER since he can store unicode only in nvarchar fields
+ QVERIFY_SQL(q, exec("create table " + qTableName("qtest_unicode", __FILE__) + " (id int not null, "
+ "t_varchar nvarchar(80) not null, t_char nchar(80) )" ));
} else {
- QVERIFY_SQL(q, exec("create table " + qTableName("qtest_unicode", __FILE__) + " (id int not null, "
- "t_varchar varchar(100) not null," "t_char char(100))" ));
+ QVERIFY_SQL(q, exec("create table " + qTableName("qtest_unicode", __FILE__) + " (id int not null, "
+ "t_varchar varchar(100) not null," "t_char char(100))" ));
}
if (tst_Databases::isMSAccess(db)) {
@@ -169,7 +169,7 @@ void tst_Q3SqlCursor::createTestTables( QSqlDatabase db )
void tst_Q3SqlCursor::dropTestTables( QSqlDatabase db )
{
if ( !db.isValid() )
- return;
+ return;
QStringList tableNames;
tableNames << qtest
<< qTableName( "qtest_unicode", __FILE__ )
@@ -183,7 +183,7 @@ void tst_Q3SqlCursor::dropTestTables( QSqlDatabase db )
void tst_Q3SqlCursor::populateTestTables( QSqlDatabase db )
{
if (!db.isValid())
- return;
+ return;
QSqlQuery q( db );
q.exec( "delete from " + qtest ); //not fatal
@@ -200,21 +200,21 @@ void tst_Q3SqlCursor::initTestCase()
dbs.open();
for ( QStringList::ConstIterator it = dbs.dbNames.begin(); it != dbs.dbNames.end(); ++it ) {
- QSqlDatabase db = QSqlDatabase::database( (*it) );
- CHECK_DATABASE( db );
+ QSqlDatabase db = QSqlDatabase::database( (*it) );
+ CHECK_DATABASE( db );
- dropTestTables( db ); //in case of leftovers
- createTestTables( db );
- populateTestTables( db );
+ dropTestTables( db ); //in case of leftovers
+ createTestTables( db );
+ populateTestTables( db );
}
}
void tst_Q3SqlCursor::cleanupTestCase()
{
for ( QStringList::ConstIterator it = dbs.dbNames.begin(); it != dbs.dbNames.end(); ++it ) {
- QSqlDatabase db = QSqlDatabase::database( (*it) );
- CHECK_DATABASE( db );
- dropTestTables( db );
+ QSqlDatabase db = QSqlDatabase::database( (*it) );
+ CHECK_DATABASE( db );
+ dropTestTables( db );
}
dbs.close();
@@ -230,9 +230,9 @@ void tst_Q3SqlCursor::cleanup()
QSqlDatabase db = QSqlDatabase::database( dbName );
CHECK_DATABASE( db );
if ( QTest::currentTestFailed() ) {
- //since Oracle ODBC totally craps out on error, we init again
- db.close();
- db.open();
+ //since Oracle ODBC totally craps out on error, we init again
+ db.close();
+ db.open();
}
}
@@ -244,10 +244,10 @@ void tst_Q3SqlCursor::copyConstructor()
Q3SqlCursor cur2;
{
- Q3SqlCursor cur( qtest, true, db );
- QVERIFY_SQL(cur, select( cur.index( QString("id") ) ));
- cur2 = Q3SqlCursor( cur );
- // let "cur" run out of scope...
+ Q3SqlCursor cur( qtest, true, db );
+ QVERIFY_SQL(cur, select( cur.index( QString("id") ) ));
+ cur2 = Q3SqlCursor( cur );
+ // let "cur" run out of scope...
}
QSqlRecord* rec = cur2.primeUpdate();
@@ -256,8 +256,8 @@ void tst_Q3SqlCursor::copyConstructor()
int i = 0;
while ( cur2.next() ) {
- QVERIFY( cur2.value("id").toInt() == i );
- i++;
+ QVERIFY( cur2.value("id").toInt() == i );
+ i++;
}
}
@@ -271,8 +271,8 @@ void tst_Q3SqlCursor::value()
QVERIFY_SQL(cur, select( cur.index( QString("id") ) ));
int i = 0;
while ( cur.next() ) {
- QCOMPARE(cur.value("id").toInt(), i);
- i++;
+ QCOMPARE(cur.value("id").toInt(), i);
+ i++;
}
}
@@ -285,11 +285,11 @@ void tst_Q3SqlCursor::primaryIndex()
Q3SqlCursor cur( qtest, true, db );
QSqlIndex index = cur.primaryIndex();
if ( tst_Databases::isMSAccess( db ) ) {
- QCOMPARE( index.fieldName(1).upper(), QString( "ID" ) );
- QCOMPARE( index.fieldName(0).upper(), QString( "T_VARCHAR" ) );
+ QCOMPARE( index.fieldName(1).upper(), QString( "ID" ) );
+ QCOMPARE( index.fieldName(0).upper(), QString( "T_VARCHAR" ) );
} else {
- QCOMPARE( index.fieldName(0).upper(), QString( "ID" ) );
- QCOMPARE( index.fieldName(1).upper(), QString( "T_VARCHAR" ) );
+ QCOMPARE( index.fieldName(0).upper(), QString( "ID" ) );
+ QCOMPARE( index.fieldName(1).upper(), QString( "T_VARCHAR" ) );
}
QVERIFY(!index.isDescending(0));
QVERIFY(!index.isDescending(1));
@@ -308,10 +308,10 @@ void tst_Q3SqlCursor::insert()
// check that primeInsert returns a valid QSqlRecord
QCOMPARE( (int)irec->count(), 4 );
if ( ( irec->field( 0 ).type() != QVariant::Int ) &&
- ( irec->field( 0 ).type() != QVariant::String ) &&
+ ( irec->field( 0 ).type() != QVariant::String ) &&
( irec->field( 0 ).type() != QVariant::Double ) ) {
- QFAIL( QString( "Wrong datatype %1 for field 'ID'"
- " (expected Int or String)" ).arg( QVariant::typeToName( irec->field( 0 ).type() ) ) );
+ QFAIL( QString( "Wrong datatype %1 for field 'ID'"
+ " (expected Int or String)" ).arg( QVariant::typeToName( irec->field( 0 ).type() ) ) );
}
QCOMPARE( QVariant::typeToName( irec->field( 1 ).type() ), QVariant::typeToName( QVariant::String ) );
QCOMPARE( QVariant::typeToName( irec->field( 2 ).type() ), QVariant::typeToName( QVariant::String ) );
@@ -327,7 +327,9 @@ void tst_Q3SqlCursor::insert()
irec->setValue( "t_char", "SomeChar" );
irec->setValue( "t_numeric", 400.400 );
- QCOMPARE( cur.insert(), 1 );
+ QSet<int> validReturns(QSet<int>() << -1 << 1);
+
+ QVERIFY( validReturns.contains(cur.insert()) );
// restore old test-tables
populateTestTables( db );
@@ -338,6 +340,7 @@ void tst_Q3SqlCursor::insertSpecial()
QFETCH( QString, dbName );
QSqlDatabase db = QSqlDatabase::database( dbName );
CHECK_DATABASE( db );
+ QSet<int> validReturns(QSet<int>() << -1 << 1);
Q3SqlCursor cur( qtest, true, db );
QSqlRecord* irec = cur.primeInsert();
@@ -355,25 +358,25 @@ void tst_Q3SqlCursor::insertSpecial()
// INSERT the strings
QStringList::Iterator it;
for ( it = strings.begin(); it != strings.end(); ++it ) {
- QSqlRecord* irec = cur.primeInsert();
- QVERIFY( irec != 0 );
- irec->setValue( "id", i );
- irec->setValue( "t_varchar", (*it) );
- irec->setValue( "t_char", (*it) );
- irec->setValue( "t_numeric", (double)i );
- ++i;
- QCOMPARE( cur.insert(), 1 );
+ QSqlRecord* irec = cur.primeInsert();
+ QVERIFY( irec != 0 );
+ irec->setValue( "id", i );
+ irec->setValue( "t_varchar", (*it) );
+ irec->setValue( "t_char", (*it) );
+ irec->setValue( "t_numeric", (double)i );
+ ++i;
+ QVERIFY( validReturns.contains(cur.insert()) );
}
QVERIFY( cur.select( "id >= 800 and id < 900" ) );
int i2 = 800;
while( cur.next() ) {
- QCOMPARE( cur.value( "id" ).toInt(), i2 );
- QCOMPARE( cur.value( "t_varchar" ).toString().stripWhiteSpace(), strings.at( i2 - 800 ) );
- QCOMPARE( cur.value( "t_char" ).toString().stripWhiteSpace(), strings.at( i2 - 800 ) );
- QCOMPARE( cur.value( "t_numeric" ).toDouble(), (double)i2 );
- ++i2;
+ QCOMPARE( cur.value( "id" ).toInt(), i2 );
+ QCOMPARE( cur.value( "t_varchar" ).toString().stripWhiteSpace(), strings.at( i2 - 800 ) );
+ QCOMPARE( cur.value( "t_char" ).toString().stripWhiteSpace(), strings.at( i2 - 800 ) );
+ QCOMPARE( cur.value( "t_numeric" ).toDouble(), (double)i2 );
+ ++i2;
}
QCOMPARE( i, i2 );
@@ -385,6 +388,7 @@ void tst_Q3SqlCursor::batchInsert()
QFETCH( QString, dbName );
QSqlDatabase db = QSqlDatabase::database( dbName );
CHECK_DATABASE( db );
+ QSet<int> validReturns(QSet<int>() << -1 << 1);
QSqlQuery q( db );
q.exec( "delete from " + qtest );
@@ -393,16 +397,16 @@ void tst_Q3SqlCursor::batchInsert()
int i = 0;
for ( ; i < 100; ++i ) {
- QSqlRecord* irec = cur.primeInsert();
- Q_ASSERT( irec );
- irec->setValue( "id", i );
- irec->setValue( "t_varchar", "blah" );
- irec->setValue( "t_char", "blah" );
- irec->setValue( "t_numeric", 1.1 );
- if ( db.driverName().startsWith( "QSQLITE" ) ) {
- QVERIFY( cur.insert( true ) );
- } else {
- QCOMPARE( cur.insert( true ), 1 );
+ QSqlRecord* irec = cur.primeInsert();
+ Q_ASSERT( irec );
+ irec->setValue( "id", i );
+ irec->setValue( "t_varchar", "blah" );
+ irec->setValue( "t_char", "blah" );
+ irec->setValue( "t_numeric", 1.1 );
+ if ( db.driverName().startsWith( "QSQLITE" ) ) {
+ QVERIFY( cur.insert( true ) );
+ } else {
+ QVERIFY( validReturns.contains(cur.insert( true )) );
}
}
@@ -413,18 +417,18 @@ void tst_Q3SqlCursor::batchInsert()
irec->setValue( "t_varchar", "blah" );
irec->setValue( "t_char", "blah" );
irec->setValue( "t_numeric", 1.1 );
- if ( db.driverName().startsWith( "QSQLITE" ) ) {
- QVERIFY( cur.insert( false ) );
- } else {
- QCOMPARE( cur.insert( false ), 1 );
+ if ( db.driverName().startsWith( "QSQLITE" ) ) {
+ QVERIFY( cur.insert( false ) );
+ } else {
+ QVERIFY( validReturns.contains(cur.insert( false )) );
}
}
i = 0;
QVERIFY_SQL(q, exec( "select * from " + qtest + " order by id" ));
while ( q.next() ) {
- QCOMPARE( q.value( 0 ).toInt(), i );
- i++;
+ QCOMPARE( q.value( 0 ).toInt(), i );
+ i++;
}
QCOMPARE( i, 200 );
@@ -436,7 +440,7 @@ static QString dumpUtf8( const QString& str )
{
QString res;
for ( int i = 0; i < (int)str.length(); ++i ) {
- res += "0x" + QString::number( str[ i ].unicode(), 16 ) + ' ';
+ res += "0x" + QString::number( str[ i ].unicode(), 16 ) + ' ';
}
return res;
}
@@ -448,7 +452,7 @@ void tst_Q3SqlCursor::insertORA()
CHECK_DATABASE( db );
if (tst_Databases::getOraVersion(db) < 9)
- QSKIP("Need Oracle >= 9", SkipSingle);
+ QSKIP("Need Oracle >= 9", SkipSingle);
/****** CHARSET TEST ******/
@@ -466,8 +470,8 @@ void tst_Q3SqlCursor::insertORA()
QVERIFY_SQL(cur, select());
QVERIFY( cur.next() );
if ( cur.value( "t_char" ).toString() != val1 )
- qDebug( QString( "Wrong value for t_char: expected '%1', got '%2'" ).arg( val1 ).arg(
- cur.value( "t_char" ).toString() ) );
+ qDebug( QString( "Wrong value for t_char: expected '%1', got '%2'" ).arg( val1 ).arg(
+ cur.value( "t_char" ).toString() ) );
static const unsigned short utf8arr[] = { 0xd792,0xd79c,0xd792,0xd79c,0xd799,0x00 };
static const QString utf8str = QString::fromUcs2( utf8arr );
@@ -524,7 +528,7 @@ void tst_Q3SqlCursor::unicode()
static const QString utf8str = QString::fromUtf8( "ὕαλον ϕαγεῖν δύναμαι· τοῦτο οὔ με βλάπτει." );
if ( !db.driver()->hasFeature( QSqlDriver::Unicode ) ) {
- QSKIP( "DBMS not Unicode capable", SkipSingle );
+ QSKIP( "DBMS not Unicode capable", SkipSingle );
}
// ascii in the data storage, can't transliterate properly. invalid test.
if(db.driverName().startsWith("QIBASE") && (db.databaseName() == "silence.nokia.troll.no:c:\\ibase\\testdb_ascii" || db.databaseName() == "/opt/interbase/qttest.gdb"))
@@ -640,11 +644,11 @@ void tst_Q3SqlCursor::select()
QSqlIndex idx = cur4.primaryIndex( false );
QCOMPARE( (int)idx.count(), 2 );
if ( tst_Databases::isMSAccess( db ) ) {
- QCOMPARE( idx.field( 1 ).name().upper(), QString("ID") );
- QCOMPARE( idx.field( 0 ).name().upper(), QString("T_VARCHAR") );
+ QCOMPARE( idx.field( 1 ).name().upper(), QString("ID") );
+ QCOMPARE( idx.field( 0 ).name().upper(), QString("T_VARCHAR") );
} else {
- QCOMPARE( idx.field( 0 ).name().upper(), QString("ID") );
- QCOMPARE( idx.field( 1 ).name().upper(), QString("T_VARCHAR") );
+ QCOMPARE( idx.field( 0 ).name().upper(), QString("ID") );
+ QCOMPARE( idx.field( 1 ).name().upper(), QString("T_VARCHAR") );
}
#ifdef QT_DEBUG
@@ -688,17 +692,18 @@ void tst_Q3SqlCursor::updateNoPK()
QFETCH( QString, dbName );
QSqlDatabase db = QSqlDatabase::database( dbName );
CHECK_DATABASE( db );
-
+ QSet<int> validReturns(QSet<int>() << -1 << 1);
+
QSqlQuery q(db);
QVERIFY_SQL(q, exec("create table " + qTableName( "qtestPK", __FILE__ ) + " (id int, name varchar(20), num numeric)"));
-
+
Q3SqlCursor cur(qTableName("qtestPK", __FILE__), true, db);
QSqlRecord* rec = cur.primeInsert();
Q_ASSERT(rec);
rec->setNull(0);
rec->setNull(1);
rec->setNull(2);
- QVERIFY_SQL(cur, insert() == 1);
+ QVERIFY(validReturns.contains(cur.insert()));
if (!db.driver()->hasFeature(QSqlDriver::PreparedQueries)) {
// Only QPSQL, QMYSQL, QODBC and QOCI drivers currently use escape identifiers for column names
@@ -713,8 +718,8 @@ void tst_Q3SqlCursor::updateNoPK()
+ " values (NULL,NULL,NULL)");
QCOMPARE(cur.lastQuery(), query);
} else {
- QCOMPARE(cur.lastQuery(), QString::fromLatin1("insert into " + qTableName("qtestPK", __FILE__) +
- " (\"id\",\"name\",\"num\") values (NULL,NULL,NULL)"));
+ QCOMPARE(cur.lastQuery(), QString::fromLatin1("insert into " + qTableName("qtestPK", __FILE__) +
+ " (\"id\",\"name\",\"num\") values (NULL,NULL,NULL)"));
}
}
@@ -733,7 +738,7 @@ void tst_Q3SqlCursor::updateNoPK()
qTableName("qtestPK", __FILE__) + ".num IS NULL";
if (!db.driver()->hasFeature(QSqlDriver::PreparedQueries)) {
if (!db.driverName().startsWith("QSQLITE")) {
- QCOMPARE(cur.lastQuery(), expect);
+ QCOMPARE(cur.lastQuery(), expect);
}
}
QVERIFY(cur.select(cur.index(QString("id"))));
@@ -750,6 +755,7 @@ void tst_Q3SqlCursor::insertFieldNameContainsWS() {
QFETCH( QString, dbName );
QSqlDatabase db = QSqlDatabase::database( dbName );
CHECK_DATABASE( db );
+ QSet<int> validReturns(QSet<int>() << -1 << 1);
// The bugfix (and this test) depends on QSqlDriver::escapeIdentifier(...)
// to be implemented, which is currently only the case for the
@@ -778,7 +784,7 @@ void tst_Q3SqlCursor::insertFieldNameContainsWS() {
r->setValue("firsT NaMe", "Kong");
r->setValue("lastNaMe", "Harald");
- QVERIFY(cur.insert() == 1);
+ QVERIFY(validReturns.contains(cur.insert()));
cur.select();
cur.next();
diff --git a/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp b/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp
index 1007d61..49b840f 100644
--- a/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp
+++ b/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp
@@ -46,6 +46,7 @@
#include <QtGui/qgraphicsview.h>
#include <QtGui/qgraphicsscene.h>
#include <QtGui/qgraphicsitem.h>
+#include <QtGui/qgraphicswidget.h>
#include <QtGui/qstyleoption.h>
#include "../../shared/util.h"
@@ -73,6 +74,7 @@ private slots:
void deviceCoordinateTranslateCaching();
void inheritOpacity();
void dropShadowClipping();
+ void childrenVisibilityShouldInvalidateCache();
};
void tst_QGraphicsEffect::initTestCase()
@@ -510,6 +512,7 @@ void tst_QGraphicsEffect::drawPixmapItem()
QGraphicsView view(&scene);
view.show();
QTest::qWaitForWindowShown(&view);
+ QTRY_VERIFY(effect->repaints >= 1);
item->rotate(180);
QTest::qWait(50);
@@ -613,6 +616,47 @@ void tst_QGraphicsEffect::dropShadowClipping()
QCOMPARE(img.pixel(x, y), img.pixel(x, y-1));
}
+class MyGraphicsItem : public QGraphicsWidget
+{
+public:
+ MyGraphicsItem(QGraphicsItem *parent = 0) :
+ QGraphicsWidget(parent), nbPaint(0)
+ {}
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+ {
+ nbPaint++;
+ QGraphicsWidget::paint(painter, option, widget);
+ }
+ int nbPaint;
+};
+
+void tst_QGraphicsEffect::childrenVisibilityShouldInvalidateCache()
+{
+ QGraphicsScene scene;
+ MyGraphicsItem parent;
+ parent.resize(200, 200);
+ QGraphicsWidget child(&parent);
+ child.resize(200, 200);
+ child.setVisible(false);
+ scene.addItem(&parent);
+ QGraphicsView view(&scene);
+ view.show();
+ QApplication::setActiveWindow(&view);
+ QTest::qWaitForWindowShown(&view);
+ QTRY_COMPARE(parent.nbPaint, 1);
+ //we set an effect on the parent
+ parent.setGraphicsEffect(new QGraphicsDropShadowEffect(&parent));
+ //flush the events
+ QApplication::processEvents();
+ //new effect applied->repaint
+ QCOMPARE(parent.nbPaint, 2);
+ child.setVisible(true);
+ //flush the events
+ QApplication::processEvents();
+ //a new child appears we need to redraw the effect.
+ QCOMPARE(parent.nbPaint, 3);
+}
+
QTEST_MAIN(tst_QGraphicsEffect)
#include "tst_qgraphicseffect.moc"
diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
index 4d9f23f..75fb337 100644
--- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
+++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
@@ -439,6 +439,7 @@ private slots:
void QTBUG_7714_fullUpdateDiscardingOpacityUpdate2();
void QT_2653_fullUpdateDiscardingOpacityUpdate();
void QT_2649_focusScope();
+ void sortItemsWhileAdding();
private:
QList<QGraphicsItem *> paintedItems;
@@ -10070,5 +10071,38 @@ void tst_QGraphicsItem::QT_2649_focusScope()
delete scene;
}
+class MyGraphicsItemWithItemChange : public QGraphicsWidget
+{
+public:
+ MyGraphicsItemWithItemChange(QGraphicsItem *parent = 0) : QGraphicsWidget(parent)
+ {}
+
+ QVariant itemChange(GraphicsItemChange change, const QVariant &value)
+ {
+ if (change == QGraphicsItem::ItemSceneHasChanged) {
+ foreach (QGraphicsView *view, scene()->views()) {
+ //We trigger a sort of unindexed items in the BSP
+ view->sceneRect();
+ }
+ }
+ return QGraphicsWidget::itemChange(change, value);
+ }
+};
+
+void tst_QGraphicsItem::sortItemsWhileAdding()
+{
+ QGraphicsScene scene;
+ QGraphicsView view(&scene);
+ QGraphicsWidget grandGrandParent;
+ grandGrandParent.resize(200, 200);
+ scene.addItem(&grandGrandParent);
+ QGraphicsWidget grandParent;
+ grandParent.resize(200, 200);
+ QGraphicsWidget parent(&grandParent);
+ parent.resize(200, 200);
+ MyGraphicsItemWithItemChange item(&parent);
+ grandParent.setParentItem(&grandGrandParent);
+}
+
QTEST_MAIN(tst_QGraphicsItem)
#include "tst_qgraphicsitem.moc"
diff --git a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp
index 0d1ad9e..5a3a54c 100644
--- a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp
+++ b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp
@@ -111,6 +111,8 @@ private slots:
void fontPropagationSceneChange();
void geometry_data();
void geometry();
+ void width();
+ void height();
void getContentsMargins_data();
void getContentsMargins();
void initStyleOption_data();
@@ -775,6 +777,32 @@ void tst_QGraphicsWidget::geometry()
QCOMPARE(widget.geometry(), QRectF(pos, size));
}
+void tst_QGraphicsWidget::width()
+{
+ QGraphicsWidget w;
+ QCOMPARE(w.property("width").toReal(), qreal(0));
+ QSignalSpy spy(&w, SIGNAL(widthChanged()));
+ w.setProperty("width", qreal(50));
+ QCOMPARE(w.property("width").toReal(), qreal(50));
+ QCOMPARE(spy.count(), 1);
+ //calling old school setGeometry should work too
+ w.setGeometry(0, 0, 200, 200);
+ QCOMPARE(spy.count(), 2);
+}
+
+void tst_QGraphicsWidget::height()
+{
+ QGraphicsWidget w;
+ QCOMPARE(w.property("height").toReal(), qreal(0));
+ QSignalSpy spy(&w, SIGNAL(heightChanged()));
+ w.setProperty("height", qreal(50));
+ QCOMPARE(w.property("height").toReal(), qreal(50));
+ QCOMPARE(spy.count(), 1);
+ //calling old school setGeometry should work too
+ w.setGeometry(0, 0, 200, 200);
+ QCOMPARE(spy.count(), 2);
+}
+
void tst_QGraphicsWidget::getContentsMargins_data()
{
QTest::addColumn<qreal>("left");
diff --git a/tests/auto/qsqlquery/tst_qsqlquery.cpp b/tests/auto/qsqlquery/tst_qsqlquery.cpp
index b9ab73f..db3a929 100644
--- a/tests/auto/qsqlquery/tst_qsqlquery.cpp
+++ b/tests/auto/qsqlquery/tst_qsqlquery.cpp
@@ -1137,17 +1137,14 @@ void tst_QSqlQuery::last()
QVERIFY( q.last() );
- if ( !tst_Databases::isMSAccess( db ) )
- // Access doesn't return the correct position
- QCOMPARE( q.at(), ( i-1 ) );
+ QSet<int> validReturns(QSet<int>() << -1 << i-1);
+ QVERIFY( validReturns.contains(q.at()) );
QSqlQuery q2( "select * from " + qtest, db );
QVERIFY( q2.last() );
- if ( !tst_Databases::isMSAccess( db ) )
- // Access doesn't return the correct position
- QCOMPARE( q.at(), ( i-1 ) );
+ QVERIFY( validReturns.contains(q.at()) );
}
void tst_QSqlQuery::seek()