summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/phonon/phonon/mediasource.cpp2
-rw-r--r--src/3rdparty/sqlite.pri4
-rw-r--r--src/corelib/global/qnamespace.qdoc5
-rw-r--r--src/corelib/io/qiodevice_p.h2
-rw-r--r--src/corelib/io/qprocess.cpp4
-rw-r--r--src/corelib/kernel/qabstractitemmodel.cpp16
-rw-r--r--src/corelib/kernel/qeventdispatcher_symbian.cpp36
-rw-r--r--src/corelib/tools/qstring.cpp2
-rw-r--r--src/declarative/graphicsitems/qdeclarativegridview.cpp5
-rw-r--r--src/declarative/graphicsitems/qdeclarativeimage.cpp59
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitem.cpp97
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitem_p.h20
-rw-r--r--src/declarative/graphicsitems/qdeclarativelistview.cpp16
-rw-r--r--src/declarative/graphicsitems/qdeclarativeloader.cpp7
-rw-r--r--src/declarative/graphicsitems/qdeclarativemousearea.cpp10
-rw-r--r--src/declarative/graphicsitems/qdeclarativetext.cpp20
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextedit.cpp5
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput.cpp4
-rw-r--r--src/declarative/qml/qdeclarativebinding.cpp145
-rw-r--r--src/declarative/qml/qdeclarativebinding_p_p.h28
-rw-r--r--src/declarative/qml/qdeclarativecontext_p.h1
-rw-r--r--src/declarative/qml/qdeclarativeengine.cpp12
-rw-r--r--src/declarative/qml/qdeclarativeengine_p.h1
-rw-r--r--src/declarative/qml/qdeclarativeexpression.cpp478
-rw-r--r--src/declarative/qml/qdeclarativeexpression_p.h83
-rw-r--r--src/declarative/qml/qdeclarativeimageprovider.cpp16
-rw-r--r--src/declarative/qml/qdeclarativelist.cpp2
-rw-r--r--src/declarative/util/qdeclarativestateoperations.cpp2
-rw-r--r--src/declarative/util/qdeclarativexmllistmodel.cpp19
-rw-r--r--src/gui/dialogs/qwizard_win.cpp42
-rw-r--r--src/gui/dialogs/qwizard_win_p.h21
-rw-r--r--src/gui/graphicsview/qgraphicsgridlayout.cpp7
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp9
-rw-r--r--src/gui/graphicsview/qgraphicslinearlayout.cpp7
-rw-r--r--src/gui/graphicsview/qgraphicswidget_p.cpp4
-rw-r--r--src/gui/itemviews/qabstractitemview.cpp2
-rw-r--r--src/gui/itemviews/qfileiconprovider.cpp71
-rw-r--r--src/gui/kernel/qapplication.cpp2
-rw-r--r--src/gui/kernel/qapplication.h3
-rw-r--r--src/gui/kernel/qapplication_win.cpp2
-rw-r--r--src/gui/kernel/qcocoasharedwindowmethods_mac_p.h4
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm38
-rw-r--r--src/gui/kernel/qcocoaview_mac_p.h1
-rw-r--r--src/gui/kernel/qgesture.cpp29
-rw-r--r--src/gui/kernel/qgesture.h3
-rw-r--r--src/gui/kernel/qgesture_p.h1
-rw-r--r--src/gui/kernel/qgesturemanager.cpp4
-rw-r--r--src/gui/kernel/qguifunctions_wince.cpp28
-rw-r--r--src/gui/kernel/qstandardgestures.cpp7
-rw-r--r--src/gui/kernel/qwidget.cpp4
-rw-r--r--src/gui/kernel/qwidget_mac.mm7
-rw-r--r--src/gui/kernel/qwidget_win.cpp1
-rw-r--r--src/gui/kernel/qwidget_wince.cpp1
-rw-r--r--src/gui/styles/qstyle.cpp4
-rw-r--r--src/gui/styles/qstyle.h2
-rw-r--r--src/gui/styles/qstyleoption.cpp6
-rw-r--r--src/gui/styles/qstyleoption.h2
-rw-r--r--src/gui/text/qtextcursor.cpp6
-rw-r--r--src/gui/text/qtextoption.cpp7
-rw-r--r--src/gui/text/qtexttable.cpp28
-rw-r--r--src/gui/util/qcompleter.cpp4
-rw-r--r--src/imports/particles/qdeclarativeparticles.cpp21
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp9
-rw-r--r--src/network/access/qnetworkaccesshttpbackend.cpp8
-rw-r--r--src/network/access/qnetworkrequest.cpp8
-rw-r--r--src/network/access/qnetworkrequest.h2
-rw-r--r--src/network/kernel/qauthenticator.cpp408
-rw-r--r--src/network/kernel/qauthenticator.h5
-rw-r--r--src/network/kernel/qauthenticator_p.h6
-rw-r--r--src/network/kernel/qhostaddress.cpp12
-rw-r--r--src/network/socket/qtcpserver.cpp2
-rw-r--r--src/network/ssl/qsslsocket.cpp4
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp89
-rw-r--r--src/network/ssl/qsslsocket_openssl_p.h1
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp2
-rw-r--r--src/opengl/qgl.cpp14
-rw-r--r--src/plugins/sqldrivers/db2/db2.pro10
-rw-r--r--src/plugins/sqldrivers/ibase/ibase.pro14
-rw-r--r--src/plugins/sqldrivers/mysql/mysql.pro23
-rw-r--r--src/plugins/sqldrivers/oci/oci.pro13
-rw-r--r--src/plugins/sqldrivers/odbc/odbc.pro19
-rw-r--r--src/plugins/sqldrivers/psql/psql.pro18
-rw-r--r--src/plugins/sqldrivers/sqlite/sqlite.pro17
-rw-r--r--src/plugins/sqldrivers/sqlite2/sqlite2.pro9
-rw-r--r--src/plugins/sqldrivers/tds/tds.pro15
-rw-r--r--src/s60installs/bwins/QtDeclarativeu.def1
-rw-r--r--src/s60installs/eabi/QtDeclarativeu.def1
-rw-r--r--src/script/api/qscriptvalue.cpp6
-rw-r--r--src/sql/drivers/db2/qsql_db2.pri8
-rw-r--r--src/sql/drivers/drivers.pri130
-rw-r--r--src/sql/drivers/ibase/qsql_ibase.pri11
-rw-r--r--src/sql/drivers/mysql/qsql_mysql.pri16
-rw-r--r--src/sql/drivers/oci/qsql_oci.cpp2
-rw-r--r--src/sql/drivers/oci/qsql_oci.pri9
-rw-r--r--src/sql/drivers/odbc/qsql_odbc.pri13
-rw-r--r--src/sql/drivers/psql/qsql_psql.pri13
-rw-r--r--src/sql/drivers/sqlite/qsql_sqlite.pri9
-rw-r--r--src/sql/drivers/sqlite2/qsql_sqlite2.pri4
-rw-r--r--src/sql/drivers/tds/qsql_tds.pri10
99 files changed, 1528 insertions, 892 deletions
diff --git a/src/3rdparty/phonon/phonon/mediasource.cpp b/src/3rdparty/phonon/phonon/mediasource.cpp
index be22dc3..11d2428 100644
--- a/src/3rdparty/phonon/phonon/mediasource.cpp
+++ b/src/3rdparty/phonon/phonon/mediasource.cpp
@@ -50,7 +50,7 @@ MediaSource::MediaSource(const QString &filename)
const QFileInfo fileInfo(filename);
if (fileInfo.exists()) {
bool localFs = QAbstractFileEngine::LocalDiskFlag & QFSFileEngine(filename).fileFlags(QAbstractFileEngine::LocalDiskFlag);
- if (localFs) {
+ if (localFs && !filename.startsWith(QLatin1String(":/")) && !filename.startsWith(QLatin1String("qrc://"))) {
d->url = QUrl::fromLocalFile(fileInfo.absoluteFilePath());
} else {
#ifndef QT_NO_PHONON_ABSTRACTMEDIASTREAM
diff --git a/src/3rdparty/sqlite.pri b/src/3rdparty/sqlite.pri
new file mode 100644
index 0000000..575412d
--- /dev/null
+++ b/src/3rdparty/sqlite.pri
@@ -0,0 +1,4 @@
+CONFIG(release, debug|release):DEFINES *= NDEBUG
+DEFINES += SQLITE_OMIT_LOAD_EXTENSION SQLITE_OMIT_COMPLETE
+INCLUDEPATH += $$PWD/sqlite
+SOURCES += $$PWD/sqlite/sqlite3.c
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index ed2ae6e..5cd7f0e 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -470,6 +470,7 @@
\value TextIncludeTrailingSpaces Same as IncludeTrailingSpaces
\value TextJustificationForced Ensures that text lines are justified.
+ \omitvalue TextBypassShaping
\omitvalue BreakAnywhere
\omitvalue DontClip
\omitvalue DontPrint
@@ -1730,7 +1731,7 @@
\value Key_MediaLast
\value Key_unknown
- \value Key_Call A key to answer or initiate a call (see \l Key_ToggleCallHangup for a key to toggle current call state)
+ \value Key_Call A key to answer or initiate a call (see Qt::Key_ToggleCallHangup for a key to toggle current call state)
\value Key_Camera A key to activate the camera shutter
\value Key_CameraFocus A key to focus the camera
\value Key_Context1
@@ -1738,7 +1739,7 @@
\value Key_Context3
\value Key_Context4
\value Key_Flip
- \value Key_Hangup A key to end an ongoing call (see \l Key_ToggleCallHangup for a key to toggle current call state)
+ \value Key_Hangup A key to end an ongoing call (see Qt::Key_ToggleCallHangup for a key to toggle current call state)
\value Key_No
\value Key_Select
\value Key_Yes
diff --git a/src/corelib/io/qiodevice_p.h b/src/corelib/io/qiodevice_p.h
index 4a25562..1dd51ea 100644
--- a/src/corelib/io/qiodevice_p.h
+++ b/src/corelib/io/qiodevice_p.h
@@ -155,10 +155,10 @@ public:
if ((first - buf) < size) {
// underflow, the existing valid data needs to move to the end of the (potentially bigger) buffer
makeSpace(len + size, freeSpaceAtStart);
- memcpy(first - size, block, size);
}
first -= size;
len += size;
+ memcpy(first, block, size);
}
private:
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index 9bc4063..739ac4d 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -1399,10 +1399,10 @@ QString QProcess::nativeArguments() const
\since 4.7
\overload
- Sets additional native command line arguments for the program.
+ Sets additional native command line \a arguments for the program.
On operating systems where the system API for passing command line
- arguments to a subprocess natively uses a single string, one can
+ \a arguments to a subprocess natively uses a single string, one can
conceive command lines which cannot be passed via QProcess's portable
list-based API. In such cases this function must be used to set a
string which is \e appended to the string composed from the usual
diff --git a/src/corelib/kernel/qabstractitemmodel.cpp b/src/corelib/kernel/qabstractitemmodel.cpp
index 8415259..e3fce18 100644
--- a/src/corelib/kernel/qabstractitemmodel.cpp
+++ b/src/corelib/kernel/qabstractitemmodel.cpp
@@ -1197,7 +1197,7 @@ void QAbstractItemModelPrivate::columnsRemoved(const QModelIndex &parent,
\l{QAbstractItemModel::}{endInsertRows()} must be called.
\sa {Model Classes}, {Model Subclassing Reference}, QModelIndex,
- QAbstractItemView, {Using Drag and Drop with Item Views},
+ QAbstractItemView, {Using drag & drop with item views},
{Simple DOM Model Example}, {Simple Tree Model Example},
{Editable Tree Model Example}, {Fetch More Example}
*/
@@ -1761,7 +1761,7 @@ QMimeData *QAbstractItemModel::mimeData(const QModelIndexList &indexes) const
where to place the data. This can occur in a tree when data is dropped on
a parent. Models will usually append the data to the parent in this case.
- \sa supportedDropActions(), {Using Drag and Drop with Item Views}
+ \sa supportedDropActions(), {Using drag & drop with item views}
*/
bool QAbstractItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
int row, int column, const QModelIndex &parent)
@@ -1798,8 +1798,8 @@ bool QAbstractItemModel::dropMimeData(const QMimeData *data, Qt::DropAction acti
reimplement the dropMimeData() function to handle the additional
operations.
- \sa dropMimeData(), Qt::DropActions, {Using Drag and Drop with Item
- Views}
+ \sa dropMimeData(), Qt::DropActions, {Using drag & drop with item
+ views}
*/
Qt::DropActions QAbstractItemModel::supportedDropActions() const
{
@@ -1815,7 +1815,7 @@ Qt::DropActions QAbstractItemModel::supportedDropActions() const
supportedDragActions() is used by QAbstractItemView::startDrag() as the
default values when a drag occurs.
- \sa Qt::DropActions, {Using Drag and Drop with Item Views}
+ \sa Qt::DropActions, {Using drag & drop with item views}
*/
Qt::DropActions QAbstractItemModel::supportedDragActions() const
{
@@ -1831,7 +1831,7 @@ Qt::DropActions QAbstractItemModel::supportedDragActions() const
Sets the supported drag \a actions for the items in the model.
- \sa supportedDragActions(), {Using Drag and Drop with Item Views}
+ \sa supportedDragActions(), {Using drag & drop with item views}
*/
void QAbstractItemModel::setSupportedDragActions(Qt::DropActions actions)
{
@@ -2547,7 +2547,7 @@ bool QAbstractItemModelPrivate::allowMove(const QModelIndex &srcParent, int star
For example, as shown in the diagram, we move three rows from
row 2 to 4 in the source, so \a sourceFirst is 2 and \a sourceLast is 4.
- We move those items to above row 2 in the destination, so \a destinationRow is 2.
+ We move those items to above row 2 in the destination, so \a destinationChild is 2.
\snippet doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp 6
@@ -2558,7 +2558,7 @@ bool QAbstractItemModelPrivate::allowMove(const QModelIndex &srcParent, int star
\o To append rows to another parent, move them to after the last row.
For example, as shown in the diagram, we move three rows to a
- collection of 6 existing rows (ending in row 5), so \a destinationStart is 6:
+ collection of 6 existing rows (ending in row 5), so \a destinationChild is 6:
\snippet doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp 7
diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp
index e86efb2..2a52044 100644
--- a/src/corelib/kernel/qeventdispatcher_symbian.cpp
+++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp
@@ -47,8 +47,6 @@
#include <unistd.h>
#include <errno.h>
-#include <net/if.h>
-
QT_BEGIN_NAMESPACE
#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
@@ -100,16 +98,19 @@ static inline int qt_socket_select(int nfds, fd_set *readfds, fd_set *writefds,
class QSelectMutexGrabber
{
public:
- QSelectMutexGrabber(int fd, QMutex *mutex)
+ QSelectMutexGrabber(int writeFd, int readFd, QMutex *mutex)
: m_mutex(mutex)
{
if (m_mutex->tryLock())
return;
char dummy = 0;
- qt_pipe_write(fd, &dummy, 1);
+ qt_pipe_write(writeFd, &dummy, 1);
m_mutex->lock();
+
+ char buffer;
+ while (::read(readFd, &buffer, 1) > 0) {}
}
~QSelectMutexGrabber()
@@ -403,10 +404,6 @@ void QSelectThread::run()
ret = qt_socket_select(maxfd, &readfds, &writefds, &exceptionfds, 0);
savedSelectErrno = errno;
- char buffer;
-
- while (::read(m_pipeEnds[0], &buffer, 1) > 0) {}
-
if(ret == 0) {
// do nothing
} else if (ret < 0) {
@@ -481,7 +478,8 @@ void QSelectThread::run()
updateActivatedNotifiers(QSocketNotifier::Write, &writefds);
}
- m_waitCond.wait(&m_mutex);
+ if (FD_ISSET(m_pipeEnds[0], &readfds))
+ m_waitCond.wait(&m_mutex);
}
m_mutex.unlock();
@@ -495,7 +493,9 @@ void QSelectThread::requestSocketEvents ( QSocketNotifier *notifier, TRequestSta
start();
}
- QSelectMutexGrabber lock(m_pipeEnds[1], &m_mutex);
+ Q_ASSERT(QThread::currentThread() == this->thread());
+
+ QSelectMutexGrabber lock(m_pipeEnds[1], m_pipeEnds[0], &m_mutex);
Q_ASSERT(!m_AOStatuses.contains(notifier));
@@ -506,7 +506,9 @@ void QSelectThread::requestSocketEvents ( QSocketNotifier *notifier, TRequestSta
void QSelectThread::cancelSocketEvents ( QSocketNotifier *notifier )
{
- QSelectMutexGrabber lock(m_pipeEnds[1], &m_mutex);
+ Q_ASSERT(QThread::currentThread() == this->thread());
+
+ QSelectMutexGrabber lock(m_pipeEnds[1], m_pipeEnds[0], &m_mutex);
m_AOStatuses.remove(notifier);
@@ -515,7 +517,9 @@ void QSelectThread::cancelSocketEvents ( QSocketNotifier *notifier )
void QSelectThread::restart()
{
- QSelectMutexGrabber lock(m_pipeEnds[1], &m_mutex);
+ Q_ASSERT(QThread::currentThread() == this->thread());
+
+ QSelectMutexGrabber lock(m_pipeEnds[1], m_pipeEnds[0], &m_mutex);
m_waitCond.wakeAll();
}
@@ -571,17 +575,13 @@ void QSelectThread::updateActivatedNotifiers(QSocketNotifier::Type type, fd_set
* check if socket is in exception set
* then signal RequestComplete for it
*/
- qWarning("exception on %d [will do setdefaultif(0) - hack]", i.key()->socket());
+ qWarning("exception on %d [will close the socket handle - hack]", i.key()->socket());
// quick fix; there is a bug
// when doing read on socket
// errors not preoperly mapped
// after offline-ing the device
// on some devices we do get exception
- // close all exiting sockets
- // and reset default IAP
- if(::setdefaultif(0) != KErrNone) // well we can't do much about it
- qWarning("setdefaultif(0) failed");
-
+ ::close(i.key()->socket());
toRemove.append(i.key());
TRequestStatus *status = i.value();
QEventDispatcherSymbian::RequestComplete(d->threadData->symbian_thread_handle, status, KErrNone);
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 57f79a0..b2cf49b 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -6954,7 +6954,7 @@ bool QString::isRightToLeft() const
/*! \fn bool QString::isRightToLeft() const
- \internal
+ Returns true if the string is read right to left.
*/
diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp
index dce6f0e..14a4f08 100644
--- a/src/declarative/graphicsitems/qdeclarativegridview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp
@@ -2438,8 +2438,11 @@ void QDeclarativeGridView::itemsRemoved(int modelIndex, int count)
if (removedVisible && d->visibleItems.isEmpty()) {
d->timeline.clear();
d->setPosition(0);
- if (d->itemCount == 0)
+ if (d->itemCount == 0) {
+ d->updateHeader();
+ d->updateFooter();
update();
+ }
}
emit countChanged();
diff --git a/src/declarative/graphicsitems/qdeclarativeimage.cpp b/src/declarative/graphicsitems/qdeclarativeimage.cpp
index 34d33f5..90738c8 100644
--- a/src/declarative/graphicsitems/qdeclarativeimage.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeimage.cpp
@@ -324,17 +324,34 @@ qreal QDeclarativeImage::paintedHeight() const
/*!
\qmlproperty QSize Image::sourceSize
- This property holds the size of the loaded image, in pixels.
+ This property holds the actual width and height of the loaded image.
- This is used to control the storage used by a loaded image. Unlike
- the width and height properties, which scale the painting of the image, this property
- affects the number of pixels stored.
+ Unlike the \l {Item::}{width} and \l {Item::}{height} properties, which scale
+ the painting of the image, this property sets the actual number of pixels
+ stored for the loaded image so that large images do not use more
+ memory than necessary. For example, this ensures the image is memory is no
+ larger than 1024x1024 pixels, regardless of the Image's \l {Item::}{width} and
+ \l {Item::}{height} values:
+
+ \code
+ Rectangle {
+ width: ...
+ height: ...
+
+ Image {
+ anchors.fill: parent
+ source: "reallyBigImage.jpg"
+ sourceSize.width: 1024
+ sourceSize.height: 1024
+ }
+ }
+ \endcode
If the image's actual size is larger than the sourceSize, the image is scaled down.
If only one dimension of the size is set to greater than 0, the
other dimension is set in proportion to preserve the source image's aspect ratio.
(The \l fillMode is independent of this.)
-
+
If the source is an instrinsically scalable image (eg. SVG), this property
determines the size of the loaded image regardless of intrinsic size.
Avoid changing this property dynamically; rendering an SVG is \e slow compared
@@ -344,34 +361,8 @@ qreal QDeclarativeImage::paintedHeight() const
be no greater than this property specifies. For some formats (currently only JPEG),
the whole image will never actually be loaded into memory.
- \note \e{Changing this property dynamically will lead to the image source being reloaded,
- potentially even from the network if it is not in the disk cache.}
-
- Here is an example that ensures the size of the image in memory is
- no larger than 1024x1024 pixels, regardless of the size of the Image element.
-
- \code
- Image {
- anchors.fill: parent
- source: "images/reallyBigImage.jpg"
- sourceSize.width: 1024
- sourceSize.height: 1024
- }
- \endcode
-
- The example below ensures the memory used by the image is no more than necessary
- to display the image at the size of the Image element.
- Of course if the Image element is resized a costly reload will be required, so
- use this technique \e only when the Image size is fixed.
-
- \code
- Image {
- anchors.fill: parent
- source: "images/reallyBigImage.jpg"
- sourceSize.width: width
- sourceSize.height: height
- }
- \endcode
+ \note \e {Changing this property dynamically causes the image source to be reloaded,
+ potentially even from the network, if it is not in the disk cache.}
*/
void QDeclarativeImage::updatePaintedGeometry()
@@ -415,6 +406,8 @@ void QDeclarativeImage::geometryChanged(const QRectF &newGeometry, const QRectF
Image can handle any image format supported by Qt, loaded from any URL scheme supported by Qt.
The URL may be absolute, or relative to the URL of the component.
+
+ \sa QDeclarativeImageProvider
*/
/*!
diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp
index f5ea537..b9498f1 100644
--- a/src/declarative/graphicsitems/qdeclarativeitem.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp
@@ -1388,26 +1388,6 @@ QDeclarativeKeysAttached *QDeclarativeKeysAttached::qmlAttachedProperties(QObjec
*/
/*!
- \property QDeclarativeItem::baseline
- \internal
-*/
-
-/*!
- \property QDeclarativeItem::focus
- \internal
-*/
-
-/*!
- \property QDeclarativeItem::wantsFocus
- \internal
-*/
-
-/*!
- \property QDeclarativeItem::transformOrigin
- \internal
-*/
-
-/*!
\fn void QDeclarativeItem::childrenRectChanged(const QRectF &)
\internal
*/
@@ -1609,7 +1589,7 @@ QDeclarativeItem *QDeclarativeItem::parentItem() const
bool QDeclarativeItem::isComponentComplete() const
{
Q_D(const QDeclarativeItem);
- return d->_componentComplete;
+ return d->componentComplete;
}
void QDeclarativeItemPrivate::data_append(QDeclarativeListProperty<QObject> *prop, QObject *o)
@@ -1750,7 +1730,7 @@ QRectF QDeclarativeItem::childrenRect()
Q_D(QDeclarativeItem);
if (!d->_contents) {
d->_contents = new QDeclarativeContents(this);
- if (d->_componentComplete)
+ if (d->componentComplete)
d->_contents->complete();
}
return d->_contents->rectF();
@@ -1970,6 +1950,9 @@ QVariant QDeclarativeItem::inputMethodQuery(Qt::InputMethodQuery query) const
return v;
}
+/*!
+ \internal
+ */
void QDeclarativeItem::keyPressPreHandler(QKeyEvent *event)
{
Q_D(QDeclarativeItem);
@@ -1980,6 +1963,9 @@ void QDeclarativeItem::keyPressPreHandler(QKeyEvent *event)
d->doneEventPreHandler = true;
}
+/*!
+ \internal
+ */
void QDeclarativeItem::keyReleasePreHandler(QKeyEvent *event)
{
Q_D(QDeclarativeItem);
@@ -1990,6 +1976,9 @@ void QDeclarativeItem::keyReleasePreHandler(QKeyEvent *event)
d->doneEventPreHandler = true;
}
+/*!
+ \internal
+ */
void QDeclarativeItem::inputMethodPreHandler(QInputMethodEvent *event)
{
Q_D(QDeclarativeItem);
@@ -2000,7 +1989,6 @@ void QDeclarativeItem::inputMethodPreHandler(QInputMethodEvent *event)
d->doneEventPreHandler = true;
}
-
/*!
\internal
*/
@@ -2097,7 +2085,7 @@ QDeclarativeAnchorLine QDeclarativeItemPrivate::baseline() const
relationship with other items.
Margins apply to top, bottom, left, right, and fill anchors.
- The margins property can be used to set all of the various margins at once, to the same value.
+ The \c anchors.margins property can be used to set all of the various margins at once, to the same value.
Offsets apply for horizontal center, vertical center, and baseline anchors.
@@ -2132,10 +2120,12 @@ QDeclarativeAnchorLine QDeclarativeItemPrivate::baseline() const
\endqml
\endtable
- anchors.fill provides a convenient way for one item to have the
+ \c anchors.fill provides a convenient way for one item to have the
same geometry as another item, and is equivalent to connecting all
four directional anchors.
+ To clear an anchor value, set it to \c undefined.
+
\note You can only anchor an item to siblings or a parent.
For more information see \l {anchor-layout}{Anchor Layouts}.
@@ -2154,19 +2144,19 @@ QDeclarativeAnchorLine QDeclarativeItemPrivate::baseline() const
qreal QDeclarativeItem::baselineOffset() const
{
Q_D(const QDeclarativeItem);
- if (!d->_baselineOffset.isValid()) {
+ if (!d->baselineOffset.isValid()) {
return 0.0;
} else
- return d->_baselineOffset;
+ return d->baselineOffset;
}
void QDeclarativeItem::setBaselineOffset(qreal offset)
{
Q_D(QDeclarativeItem);
- if (offset == d->_baselineOffset)
+ if (offset == d->baselineOffset)
return;
- d->_baselineOffset = offset;
+ d->baselineOffset = offset;
for(int ii = 0; ii < d->changeListeners.count(); ++ii) {
const QDeclarativeItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
@@ -2295,7 +2285,7 @@ void QDeclarativeItem::setBaselineOffset(qreal offset)
bool QDeclarativeItem::keepMouseGrab() const
{
Q_D(const QDeclarativeItem);
- return d->_keepMouse;
+ return d->keepMouse;
}
/*!
@@ -2319,7 +2309,7 @@ bool QDeclarativeItem::keepMouseGrab() const
void QDeclarativeItem::setKeepMouseGrab(bool keep)
{
Q_D(QDeclarativeItem);
- d->_keepMouse = keep;
+ d->keepMouse = keep;
}
/*!
@@ -2416,6 +2406,8 @@ QDeclarativeItem *QDeclarativeItem::childAt(qreal x, qreal y) const
void QDeclarativeItemPrivate::focusChanged(bool flag)
{
Q_Q(QDeclarativeItem);
+ if (!(flags & QGraphicsItem::ItemIsFocusScope) && parent)
+ emit q->wantsFocusChanged(flag); //see also QDeclarativeItemPrivate::subFocusItemChange()
emit q->focusChanged(flag);
}
@@ -2499,7 +2491,7 @@ QDeclarativeListProperty<QDeclarativeTransition> QDeclarativeItemPrivate::transi
\qmlproperty bool Item::clip
This property holds whether clipping is enabled.
- if clipping is enabled, an item will clip its own painting, as well
+ If clipping is enabled, an item will clip its own painting, as well
as the painting of its children, to its bounding rectangle.
Non-rectangular clipping regions are not supported for performance reasons.
@@ -2539,11 +2531,6 @@ QDeclarativeListProperty<QDeclarativeTransition> QDeclarativeItemPrivate::transi
\sa {qmlstates}{States}
*/
-/*!
- \property QDeclarativeItem::state
- \internal
-*/
-
/*! \internal */
QString QDeclarativeItemPrivate::state() const
{
@@ -2566,11 +2553,6 @@ void QDeclarativeItemPrivate::setState(const QString &state)
For more information see \l Transform.
*/
-/*!
- \property QDeclarativeItem::transform
- \internal
-*/
-
/*! \internal */
QDeclarativeListProperty<QGraphicsTransform> QDeclarativeItem::transform()
{
@@ -2590,7 +2572,7 @@ QDeclarativeListProperty<QGraphicsTransform> QDeclarativeItem::transform()
void QDeclarativeItem::classBegin()
{
Q_D(QDeclarativeItem);
- d->_componentComplete = false;
+ d->componentComplete = false;
if (d->_stateGroup)
d->_stateGroup->classBegin();
if (d->_anchors)
@@ -2608,7 +2590,7 @@ void QDeclarativeItem::classBegin()
void QDeclarativeItem::componentComplete()
{
Q_D(QDeclarativeItem);
- d->_componentComplete = true;
+ d->componentComplete = true;
if (d->_stateGroup)
d->_stateGroup->componentComplete();
if (d->_anchors) {
@@ -2626,7 +2608,7 @@ QDeclarativeStateGroup *QDeclarativeItemPrivate::_states()
Q_Q(QDeclarativeItem);
if (!_stateGroup) {
_stateGroup = new QDeclarativeStateGroup;
- if (!_componentComplete)
+ if (!componentComplete)
_stateGroup->classBegin();
QObject::connect(_stateGroup, SIGNAL(stateChanged(QString)),
q, SIGNAL(stateChanged(QString)));
@@ -2859,6 +2841,26 @@ void QDeclarativeItem::setSmooth(bool smooth)
}
/*!
+ \property QDeclarativeItem::focus
+ \internal
+*/
+
+/*!
+ \property QDeclarativeItem::transform
+ \internal
+*/
+
+/*!
+ \property QDeclarativeItem::transformOrigin
+ \internal
+*/
+
+/*!
+ \property QDeclarativeItem::wantsFocus
+ \internal
+*/
+
+/*!
\internal
Return the width of the item
*/
@@ -3107,7 +3109,10 @@ void QDeclarativeItem::setSize(const QSizeF &size)
/*! \internal */
bool QDeclarativeItem::wantsFocus() const
{
- return focusItem() != 0;
+ Q_D(const QDeclarativeItem);
+ return focusItem() == this ||
+ (d->flags & QGraphicsItem::ItemIsFocusScope && focusItem() != 0) ||
+ (!parentItem() && focusItem() != 0);
}
/*!
diff --git a/src/declarative/graphicsitems/qdeclarativeitem_p.h b/src/declarative/graphicsitems/qdeclarativeitem_p.h
index fb416c2..bc5d809 100644
--- a/src/declarative/graphicsitems/qdeclarativeitem_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeitem_p.h
@@ -120,11 +120,11 @@ class Q_DECLARATIVE_EXPORT QDeclarativeItemPrivate : public QGraphicsItemPrivate
public:
QDeclarativeItemPrivate()
: _anchors(0), _contents(0),
- _baselineOffset(0),
+ baselineOffset(0),
_anchorLines(0),
_stateGroup(0), origin(QDeclarativeItem::Center),
widthValid(false), heightValid(false),
- _componentComplete(true), _keepMouse(false),
+ componentComplete(true), keepMouse(false),
smooth(false), transformOriginDirty(true), doneEventPreHandler(false), keyHandler(0),
mWidth(0), mHeight(0), implicitWidth(0), implicitHeight(0)
{
@@ -144,12 +144,10 @@ public:
QDeclarative_setParent_noEvent(q, parent);
q->setParentItem(parent);
}
- _baselineOffset.invalidate();
+ baselineOffset.invalidate();
mouseSetsFocus = false;
}
- QString _id;
-
// Private Properties
qreal width() const;
void setWidth(qreal);
@@ -203,7 +201,7 @@ public:
if (!_anchors) {
Q_Q(QDeclarativeItem);
_anchors = new QDeclarativeAnchors(q);
- if (!_componentComplete)
+ if (!componentComplete)
_anchors->classBegin();
}
return _anchors;
@@ -211,7 +209,7 @@ public:
QDeclarativeAnchors *_anchors;
QDeclarativeContents *_contents;
- QDeclarativeNullableValue<qreal> _baselineOffset;
+ QDeclarativeNullableValue<qreal> baselineOffset;
struct AnchorLines {
AnchorLines(QGraphicsObject *);
@@ -260,8 +258,8 @@ public:
QDeclarativeItem::TransformOrigin origin:4;
bool widthValid:1;
bool heightValid:1;
- bool _componentComplete:1;
- bool _keepMouse:1;
+ bool componentComplete:1;
+ bool keepMouse:1;
bool smooth:1;
bool transformOriginDirty : 1;
bool doneEventPreHandler : 1;
@@ -286,7 +284,9 @@ public:
// Reimplemented from QGraphicsItemPrivate
virtual void subFocusItemChange()
{
- emit q_func()->wantsFocusChanged(subFocusItem != 0);
+ if (flags & QGraphicsItem::ItemIsFocusScope || !parent)
+ emit q_func()->wantsFocusChanged(subFocusItem != 0);
+ //see also QDeclarativeItemPrivate::focusChanged
}
// Reimplemented from QGraphicsItemPrivate
diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp
index 91e9995..fa422fd 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp
@@ -494,7 +494,7 @@ public:
QSmoothedAnimation *highlightSizeAnimator;
QDeclarativeViewSection *sectionCriteria;
QString currentSection;
- static const int sectionCacheSize = 3;
+ static const int sectionCacheSize = 4;
QDeclarativeItem *sectionCache[sectionCacheSize];
qreal spacing;
qreal highlightMoveSpeed;
@@ -1029,6 +1029,11 @@ void QDeclarativeListViewPrivate::updateCurrent(int modelIndex)
}
currentItem->item->setFocus(true);
currentItem->attached->setIsCurrentItem(true);
+ // Avoid showing section delegate twice. We still need the section heading so that
+ // currentItem positioning works correctly.
+ // This is slightly sub-optimal, but section heading caching minimizes the impact.
+ if (currentItem->section)
+ currentItem->section->setVisible(false);
}
updateHighlight();
emit q->currentIndexChanged();
@@ -1072,7 +1077,7 @@ void QDeclarativeListViewPrivate::updateFooter()
}
if (footer) {
if (visibleItems.count()) {
- qreal endPos = endPosition();
+ qreal endPos = endPosition() + 1;
if (lastVisibleIndex() == model->count()-1) {
footer->setPosition(endPos);
} else {
@@ -1727,7 +1732,7 @@ void QDeclarativeListView::setHighlight(QDeclarativeComponent *highlight)
highlight is not moved by the view, and any movement must be implemented
by the highlight.
- Here is a highlight with its motion defined by a \l {SpringAniamtion} item:
+ Here is a highlight with its motion defined by a \l {SpringAnimation} item:
\snippet doc/src/snippets/declarative/listview/listview.qml highlightFollowsCurrentItem
@@ -2888,8 +2893,11 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count)
d->visiblePos = d->header ? d->header->size() : 0;
d->timeline.clear();
d->setPosition(0);
- if (d->itemCount == 0)
+ if (d->itemCount == 0) {
+ d->updateHeader();
+ d->updateFooter();
update();
+ }
}
emit countChanged();
diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp
index e745ca6..cc7f8e5 100644
--- a/src/declarative/graphicsitems/qdeclarativeloader.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp
@@ -118,9 +118,9 @@ void QDeclarativeLoaderPrivate::initResize()
be instantiated may be specified directly by the \l sourceComponent
property, or loaded from a URL via the \l source property.
- Loader can be used to delay the creation of a component until it is required.
- For example, this loads "Page1.qml" as a component into the Loader element
- when the \l MouseArea is clicked:
+ Loader can be used to delay the creation of a component until it
+ is required. For example, this loads "Page1.qml" as a component
+ into the Loader element, when the \l MouseArea is clicked:
\code
import Qt 4.7
@@ -165,7 +165,6 @@ void QDeclarativeLoaderPrivate::initResize()
/*!
\internal
\class QDeclarativeLoader
- \qmlclass Loader
*/
/*!
diff --git a/src/declarative/graphicsitems/qdeclarativemousearea.cpp b/src/declarative/graphicsitems/qdeclarativemousearea.cpp
index 7b65ca7..b7b0c9e 100644
--- a/src/declarative/graphicsitems/qdeclarativemousearea.cpp
+++ b/src/declarative/graphicsitems/qdeclarativemousearea.cpp
@@ -767,10 +767,16 @@ QDeclarativeDrag *QDeclarativeMouseArea::drag()
\i \c drag.minimum and \c drag.maximum limit how far the target can be dragged along the corresponding axes.
\endlist
- The following example displays an image that can be dragged along the X-axis. The opacity
- of the image is reduced when it is dragged to the right.
+ The following example displays a \l Rectangle that can be dragged along the X-axis. The opacity
+ of the rectangle is reduced when it is dragged to the right.
\snippet doc/src/snippets/declarative/mousearea.qml drag
+
+ \note Items cannot be dragged if they are anchored for the requested
+ \c drag.axis. For example, if \c anchors.left or \c anchors.right was set
+ for \c rect in the above example, it cannot be dragged along the X-axis.
+ This can be avoided by settng the anchor value to \c undefined in
+ an \l onPressed handler.
*/
QT_END_NAMESPACE
diff --git a/src/declarative/graphicsitems/qdeclarativetext.cpp b/src/declarative/graphicsitems/qdeclarativetext.cpp
index 9a281e5..ba4fa21 100644
--- a/src/declarative/graphicsitems/qdeclarativetext.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetext.cpp
@@ -1127,6 +1127,15 @@ int QDeclarativeText::resourcesLoading() const
return d->doc ? d->doc->resourcesLoading() : 0;
}
+/*!
+ \qmlproperty bool Text::clip
+ This property holds whether the text is clipped.
+
+ Note that if the text does not fit in the bounding rectangle it will be abruptly chopped.
+
+ If you want to display potentially long text in a limited space, you probably want to use \c elide instead.
+*/
+
void QDeclarativeText::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *)
{
Q_D(QDeclarativeText);
@@ -1146,13 +1155,10 @@ void QDeclarativeText::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWid
bool needClip = clip() && (d->imgCache.width() > width() ||
d->imgCache.height() > height());
- if (needClip) {
- p->save();
- p->setClipRect(boundingRect(), Qt::IntersectClip);
- }
- p->drawPixmap(br.x(), br.y(), d->imgCache);
if (needClip)
- p->restore();
+ p->drawPixmap(0, 0, width(), height(), d->imgCache, -br.x(), -br.y(), width(), height());
+ else
+ p->drawPixmap(br.x(), br.y(), d->imgCache);
if (d->smooth) {
p->setRenderHint(QPainter::Antialiasing, oldAA);
@@ -1166,7 +1172,7 @@ void QDeclarativeText::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWid
if (needClip) {
p->save();
- p->setClipRect(boundingRect(), Qt::IntersectClip);
+ p->setClipRect(0, 0, width(), height(), Qt::IntersectClip);
}
if (d->richText) {
QAbstractTextDocumentLayout::PaintContext context;
diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
index f3eef23..d13e139 100644
--- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
@@ -202,8 +202,9 @@ QString QDeclarativeTextEdit::text() const
Sets the font size in pixels.
- Using this function makes the font device dependent.
- Use \l font.pointSize to set the size of the font in a device independent manner.
+ Using this function makes the font device dependent. Use
+ \l{TextEdit::font.pointSize} to set the size of the font in a
+ device independent manner.
*/
/*!
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
index f6af1f4..2a5d73d 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
@@ -275,6 +275,8 @@ void QDeclarativeTextInput::setSelectionColor(const QColor &color)
QPalette p = d->control->palette();
p.setColor(QPalette::Highlight, d->selectionColor);
d->control->setPalette(p);
+ clearCache();
+ update();
emit selectionColorChanged(color);
}
@@ -299,6 +301,8 @@ void QDeclarativeTextInput::setSelectedTextColor(const QColor &color)
QPalette p = d->control->palette();
p.setColor(QPalette::HighlightedText, d->selectedTextColor);
d->control->setPalette(p);
+ clearCache();
+ update();
emit selectedTextColorChanged(color);
}
diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp
index 882e981..e096305 100644
--- a/src/declarative/qml/qdeclarativebinding.cpp
+++ b/src/declarative/qml/qdeclarativebinding.cpp
@@ -54,27 +54,20 @@
QT_BEGIN_NAMESPACE
-QDeclarativeBindingData::QDeclarativeBindingData()
-: updating(false), enabled(false)
+void QDeclarativeBindingPrivate::refresh()
{
+ Q_Q(QDeclarativeBinding);
+ q->update();
}
-QDeclarativeBindingData::~QDeclarativeBindingData()
-{
- removeError();
-}
-
-void QDeclarativeBindingData::refresh()
+QDeclarativeBindingPrivate::QDeclarativeBindingPrivate()
+: updating(false), enabled(false), deleted(0)
{
- if (enabled && !updating && q) {
- QDeclarativeBinding *b = static_cast<QDeclarativeBinding *>(QDeclarativeExpressionPrivate::get(q));
- b->update();
- }
}
-QDeclarativeBindingPrivate::QDeclarativeBindingPrivate()
-: QDeclarativeExpressionPrivate(new QDeclarativeBindingData)
+QDeclarativeBindingPrivate::~QDeclarativeBindingPrivate()
{
+ if (deleted) *deleted = true;
}
QDeclarativeBinding::QDeclarativeBinding(void *data, QDeclarativeRefCount *rc, QObject *obj,
@@ -109,7 +102,7 @@ QDeclarativeBinding::~QDeclarativeBinding()
void QDeclarativeBinding::setTarget(const QDeclarativeProperty &prop)
{
Q_D(QDeclarativeBinding);
- d->bindingData()->property = prop;
+ d->property = prop;
update();
}
@@ -117,50 +110,53 @@ void QDeclarativeBinding::setTarget(const QDeclarativeProperty &prop)
QDeclarativeProperty QDeclarativeBinding::property() const
{
Q_D(const QDeclarativeBinding);
- return d->bindingData()->property;
+ return d->property;
}
void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags)
{
Q_D(QDeclarativeBinding);
- QDeclarativeBindingData *data = d->bindingData();
-
- if (!data->enabled || !data->context() || !data->context()->isValid())
+ if (!d->enabled || !d->context() || !d->context()->isValid())
return;
- data->addref();
-
- if (!data->updating) {
- data->updating = true;
+ if (!d->updating) {
+ d->updating = true;
+ bool wasDeleted = false;
+ d->deleted = &wasDeleted;
- if (data->property.propertyType() == qMetaTypeId<QDeclarativeBinding *>()) {
+ if (d->property.propertyType() == qMetaTypeId<QDeclarativeBinding *>()) {
- int idx = data->property.index();
+ int idx = d->property.index();
Q_ASSERT(idx != -1);
-
QDeclarativeBinding *t = this;
int status = -1;
void *a[] = { &t, 0, &status, &flags };
- QMetaObject::metacall(data->property.object(),
+ QMetaObject::metacall(d->property.object(),
QMetaObject::WriteProperty,
idx, a);
+ if (wasDeleted)
+ return;
+
} else {
- QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context()->engine);
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(d->context()->engine);
bool isUndefined = false;
QVariant value;
QScriptValue scriptValue = d->scriptValue(0, &isUndefined);
- if (data->property.propertyTypeCategory() == QDeclarativeProperty::List) {
+ if (wasDeleted)
+ return;
+
+ if (d->property.propertyTypeCategory() == QDeclarativeProperty::List) {
value = ep->scriptValueToVariant(scriptValue, qMetaTypeId<QList<QObject *> >());
} else if (scriptValue.isNull() &&
- data->property.propertyTypeCategory() == QDeclarativeProperty::Object) {
+ d->property.propertyTypeCategory() == QDeclarativeProperty::Object) {
value = QVariant::fromValue((QObject *)0);
} else {
- value = ep->scriptValueToVariant(scriptValue, data->property.propertyType());
+ value = ep->scriptValueToVariant(scriptValue, d->property.propertyType());
if (value.userType() == QMetaType::QObjectStar && !qvariant_cast<QObject*>(value)) {
// If the object is null, we extract the predicted type. While this isn't
// 100% reliable, in many cases it gives us better error messages if we
@@ -172,73 +168,78 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags)
}
- if (data->error.isValid()) {
+ if (d->error.isValid()) {
- } else if (isUndefined && data->property.isResettable()) {
+ } else if (isUndefined && d->property.isResettable()) {
- data->property.reset();
+ d->property.reset();
- } else if (isUndefined && data->property.propertyType() == qMetaTypeId<QVariant>()) {
+ } else if (isUndefined && d->property.propertyType() == qMetaTypeId<QVariant>()) {
- QDeclarativePropertyPrivate::write(data->property, QVariant(), flags);
+ QDeclarativePropertyPrivate::write(d->property, QVariant(), flags);
} else if (isUndefined) {
- QUrl url = QUrl(data->url);
- int line = data->line;
+ QUrl url = QUrl(d->url);
+ int line = d->line;
if (url.isEmpty()) url = QUrl(QLatin1String("<Unknown File>"));
- data->error.setUrl(url);
- data->error.setLine(line);
- data->error.setColumn(-1);
- data->error.setDescription(QLatin1String("Unable to assign [undefined] to ")
- + QLatin1String(QMetaType::typeName(data->property.propertyType()))
- + QLatin1String(" ") + data->property.name());
+ d->error.setUrl(url);
+ d->error.setLine(line);
+ d->error.setColumn(-1);
+ d->error.setDescription(QLatin1String("Unable to assign [undefined] to ") +
+ QLatin1String(QMetaType::typeName(d->property.propertyType())) +
+ QLatin1String(" ") + d->property.name());
} else if (!scriptValue.isRegExp() && scriptValue.isFunction()) {
- QUrl url = QUrl(data->url);
- int line = data->line;
+ QUrl url = QUrl(d->url);
+ int line = d->line;
if (url.isEmpty()) url = QUrl(QLatin1String("<Unknown File>"));
- data->error.setUrl(url);
- data->error.setLine(line);
- data->error.setColumn(-1);
- data->error.setDescription(QLatin1String("Unable to assign a function to a property."));
+ d->error.setUrl(url);
+ d->error.setLine(line);
+ d->error.setColumn(-1);
+ d->error.setDescription(QLatin1String("Unable to assign a function to a property."));
+
+ } else if (d->property.object() &&
+ !QDeclarativePropertyPrivate::write(d->property, value, flags)) {
- } else if (data->property.object() &&
- !QDeclarativePropertyPrivate::write(data->property, value, flags)) {
+ if (wasDeleted)
+ return;
- QUrl url = QUrl(data->url);
- int line = data->line;
+ QUrl url = QUrl(d->url);
+ int line = d->line;
if (url.isEmpty()) url = QUrl(QLatin1String("<Unknown File>"));
const char *valueType = 0;
if (value.userType() == QVariant::Invalid) valueType = "null";
else valueType = QMetaType::typeName(value.userType());
- data->error.setUrl(url);
- data->error.setLine(line);
- data->error.setColumn(-1);
- data->error.setDescription(QLatin1String("Unable to assign ") +
- QLatin1String(valueType) +
- QLatin1String(" to ") +
- QLatin1String(QMetaType::typeName(data->property.propertyType())));
+ d->error.setUrl(url);
+ d->error.setLine(line);
+ d->error.setColumn(-1);
+ d->error.setDescription(QLatin1String("Unable to assign ") +
+ QLatin1String(valueType) +
+ QLatin1String(" to ") +
+ QLatin1String(QMetaType::typeName(d->property.propertyType())));
}
- if (data->error.isValid()) {
- if (!data->addError(ep)) ep->warning(this->error());
+ if (wasDeleted)
+ return;
+
+ if (d->error.isValid()) {
+ if (!d->addError(ep)) ep->warning(this->error());
} else {
- data->removeError();
+ d->removeError();
}
}
- data->updating = false;
+ d->updating = false;
+ d->deleted = 0;
} else {
- qmlInfo(data->property.object()) << tr("Binding loop detected for property \"%1\"").arg(data->property.name());
+ qmlInfo(d->property.object()) << tr("Binding loop detected for property \"%1\"").arg(d->property.name());
}
-
- data->release();
}
void QDeclarativeBindingPrivate::emitValueChanged()
@@ -250,13 +251,13 @@ void QDeclarativeBindingPrivate::emitValueChanged()
void QDeclarativeBinding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteFlags flags)
{
Q_D(QDeclarativeBinding);
- d->bindingData()->enabled = e;
+ d->enabled = e;
setNotifyOnValueChanged(e);
QDeclarativeAbstractBinding::setEnabled(e, flags);
if (e) {
- addToObject(d->bindingData()->property.object());
+ addToObject(d->property.object());
update(flags);
} else {
removeFromObject();
@@ -266,14 +267,14 @@ void QDeclarativeBinding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteF
int QDeclarativeBinding::propertyIndex()
{
Q_D(QDeclarativeBinding);
- return QDeclarativePropertyPrivate::bindingIndex(d->bindingData()->property);
+ return QDeclarativePropertyPrivate::bindingIndex(d->property);
}
bool QDeclarativeBinding::enabled() const
{
Q_D(const QDeclarativeBinding);
- return d->bindingData()->enabled;
+ return d->enabled;
}
QString QDeclarativeBinding::expression() const
diff --git a/src/declarative/qml/qdeclarativebinding_p_p.h b/src/declarative/qml/qdeclarativebinding_p_p.h
index 617ec4b..6926158 100644
--- a/src/declarative/qml/qdeclarativebinding_p_p.h
+++ b/src/declarative/qml/qdeclarativebinding_p_p.h
@@ -60,30 +60,24 @@
QT_BEGIN_NAMESPACE
-class QDeclarativeBindingData : public QDeclarativeExpressionData
-{
-public:
- QDeclarativeBindingData();
- virtual ~QDeclarativeBindingData();
-
- bool updating:1;
- bool enabled:1;
-
- QDeclarativeProperty property;
-
- virtual void refresh();
-};
-
class QDeclarativeBindingPrivate : public QDeclarativeExpressionPrivate
{
Q_DECLARE_PUBLIC(QDeclarativeBinding)
public:
QDeclarativeBindingPrivate();
-
- QDeclarativeBindingData *bindingData() { return static_cast<QDeclarativeBindingData *>(data); }
- const QDeclarativeBindingData *bindingData() const { return static_cast<const QDeclarativeBindingData *>(data); }
+ ~QDeclarativeBindingPrivate();
virtual void emitValueChanged();
+
+protected:
+ virtual void refresh();
+
+private:
+ bool updating:1;
+ bool enabled:1;
+ QDeclarativeProperty property;
+
+ bool *deleted;
};
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h
index 1f5aaf1..c5a039a 100644
--- a/src/declarative/qml/qdeclarativecontext_p.h
+++ b/src/declarative/qml/qdeclarativecontext_p.h
@@ -198,6 +198,7 @@ public:
// context
QDeclarativeComponentAttached *componentAttached;
+ // Return the outermost id for obj, if any.
QString findObjectId(const QObject *obj) const;
static QDeclarativeContextData *get(QDeclarativeContext *context) {
diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp
index 00bc1b7..f2eb770 100644
--- a/src/declarative/qml/qdeclarativeengine.cpp
+++ b/src/declarative/qml/qdeclarativeengine.cpp
@@ -125,7 +125,7 @@ QT_BEGIN_NAMESPACE
QObject. See the QObject documentation for further details.
*/
/*!
- \qmlproperty string QtObject::objectName
+ \qmlproperty string QML:QtObject::objectName
This property allows you to give a name to this specific object instance.
See \l{scripting.html#accessing-child-qobjects}{Accessing Child QObjects}
@@ -219,7 +219,7 @@ of their use.
QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e)
-: captureProperties(false), rootContext(0), currentExpression(0), isDebugging(false),
+: captureProperties(false), rootContext(0), isDebugging(false),
outputWarningsToStdErr(true), contextClass(0), sharedContext(0), sharedScope(0),
objectClass(0), valueTypeClass(0), globalClass(0), cleanup(0), erroredBindings(0),
inProgressCreations(0), scriptEngine(this), workerScriptEngine(0), componentAttached(0),
@@ -237,8 +237,8 @@ QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e)
}
/*!
-\qmlmethod url Qt::resolvedUrl(url)
-Returns \c url resolved relative to the URL of the caller.
+ \qmlmethod url Qt::resolvedUrl(url)
+ Returns \c url resolved relative to the URL of the caller.
*/
QUrl QDeclarativeScriptEngine::resolvedUrl(QScriptContext *context, const QUrl& url)
{
@@ -1090,8 +1090,6 @@ If you are certain the files will be local, you could simplify to:
To create a QML object from an arbitrary string of QML (instead of a file),
use \l{QML:Qt::createQmlObject()}{Qt.createQmlObject()}.
-
-\sa {Dynamic Object Management}
*/
QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, QScriptEngine *engine)
@@ -1139,8 +1137,6 @@ Each object in this array has the members \c lineNumber, \c columnNumber, \c fil
Note that this function returns immediately, and therefore may not work if
the \a qml string loads new components (that is, external QML files that have not yet been loaded).
If this is the case, consider using \l{QML:Qt::createComponent()}{Qt.createComponent()} instead.
-
-\sa {Dynamic Object Management}
*/
QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QScriptEngine *engine)
diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h
index f457b53..a5c8c38 100644
--- a/src/declarative/qml/qdeclarativeengine_p.h
+++ b/src/declarative/qml/qdeclarativeengine_p.h
@@ -162,7 +162,6 @@ public:
QPODVector<CapturedProperty> capturedProperties;
QDeclarativeContext *rootContext;
- QDeclarativeExpression *currentExpression;
bool isDebugging;
bool outputWarningsToStdErr;
diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp
index 96cdec1..9935e38 100644
--- a/src/declarative/qml/qdeclarativeexpression.cpp
+++ b/src/declarative/qml/qdeclarativeexpression.cpp
@@ -71,109 +71,95 @@ bool QDeclarativeDelayedError::addError(QDeclarativeEnginePrivate *e)
return true;
}
-QDeclarativeExpressionData::QDeclarativeExpressionData()
-: q(0), dataRef(0), expressionFunctionValid(false), expressionRewritten(false), me(0),
- trackChange(false), isShared(false), line(-1), guardList(0), guardListLength(0)
+QDeclarativeQtScriptExpression::QDeclarativeQtScriptExpression()
+: dataRef(0), expressionFunctionMode(ExplicitContext), scopeObject(0), trackChange(false),
+ guardList(0), guardListLength(0), guardObject(0), guardObjectNotifyIndex(-1), deleted(0)
{
}
-QDeclarativeExpressionData::~QDeclarativeExpressionData()
+QDeclarativeQtScriptExpression::~QDeclarativeQtScriptExpression()
{
if (guardList) { delete [] guardList; guardList = 0; }
if (dataRef) dataRef->release();
+ if (deleted) *deleted = true;
}
QDeclarativeExpressionPrivate::QDeclarativeExpressionPrivate()
-: data(new QDeclarativeExpressionData)
+: expressionFunctionValid(true), line(-1)
{
- data->q = this;
-}
-
-QDeclarativeExpressionPrivate::QDeclarativeExpressionPrivate(QDeclarativeExpressionData *d)
-: data(d)
-{
- data->q = this;
}
QDeclarativeExpressionPrivate::~QDeclarativeExpressionPrivate()
{
- if (data) {
- delete [] data->guardList;
- data->guardList = 0;
- data->guardListLength = 0;
- data->q = 0;
- data->release();
- data = 0;
- }
}
void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, const QString &expr,
QObject *me)
{
- data->expression = expr;
+ expression = expr;
- data->QDeclarativeAbstractExpression::setContext(ctxt);
- data->me = me;
+ QDeclarativeAbstractExpression::setContext(ctxt);
+ scopeObject = me;
+ expressionFunctionValid = false;
}
-void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, void *expr, QDeclarativeRefCount *rc,
- QObject *me, const QString &url, int lineNumber)
+void QDeclarativeExpressionPrivate::init(QDeclarativeContextData *ctxt, void *expr,
+ QDeclarativeRefCount *rc,
+ QObject *me, const QString &srcUrl, int lineNumber)
{
- data->url = url;
- data->line = lineNumber;
+ url = srcUrl;
+ line = lineNumber;
- if (data->dataRef) data->dataRef->release();
- data->dataRef = rc;
- if (data->dataRef) data->dataRef->addref();
+ if (dataRef) dataRef->release();
+ dataRef = rc;
+ if (dataRef) dataRef->addref();
quint32 *exprData = (quint32 *)expr;
QDeclarativeCompiledData *dd = (QDeclarativeCompiledData *)rc;
- data->expressionRewritten = true;
- data->expression = QString::fromRawData((QChar *)(exprData + 2), exprData[1]);
+ expression = QString::fromRawData((QChar *)(exprData + 2), exprData[1]);
int progIdx = *(exprData);
- bool isShared = progIdx & 0x80000000;
+ bool isSharedProgram = progIdx & 0x80000000;
progIdx &= 0x7FFFFFFF;
QDeclarativeEngine *engine = ctxt->engine;
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
- if (isShared) {
+ if (isSharedProgram) {
if (!dd->cachedClosures.at(progIdx)) {
QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine);
scriptContext->pushScope(ep->contextClass->newSharedContext());
scriptContext->pushScope(ep->globalClass->staticGlobalObject());
- dd->cachedClosures[progIdx] = new QScriptValue(scriptEngine->evaluate(data->expression, data->url, data->line));
+ dd->cachedClosures[progIdx] = new QScriptValue(scriptEngine->evaluate(expression, url, line));
scriptEngine->popContext();
}
- data->expressionFunction = *dd->cachedClosures.at(progIdx);
- data->isShared = true;
- data->expressionFunctionValid = true;
+ expressionFunction = *dd->cachedClosures.at(progIdx);
+ expressionFunctionMode = SharedContext;
+ expressionFunctionValid = true;
} else {
#if !defined(Q_OS_SYMBIAN) //XXX Why doesn't this work?
if (!dd->cachedPrograms.at(progIdx)) {
- dd->cachedPrograms[progIdx] =
- new QScriptProgram(data->expression, data->url, data->line);
+ dd->cachedPrograms[progIdx] = new QScriptProgram(expression, url, line);
}
- data->expressionFunction = evalInObjectScope(ctxt, me, *dd->cachedPrograms.at(progIdx),
- &data->expressionContext);
+ expressionFunction = evalInObjectScope(ctxt, me, *dd->cachedPrograms.at(progIdx),
+ &expressionContext);
#else
- data->expressionFunction = evalInObjectScope(ctxt, me, data->expression,
- &data->expressionContext);
+ expressionFunction = evalInObjectScope(ctxt, me, expression, &expressionContext);
#endif
- data->expressionFunctionValid = true;
+ expressionFunctionMode = ExplicitContext;
+ expressionFunctionValid = true;
}
- data->QDeclarativeAbstractExpression::setContext(ctxt);
- data->me = me;
+ QDeclarativeAbstractExpression::setContext(ctxt);
+ scopeObject = me;
}
QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContextData *context, QObject *object,
@@ -240,6 +226,8 @@ QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContex
\endcode
*/
+static int QDeclarativeExpression_notifyIdx = -1;
+
/*!
Create an invalid QDeclarativeExpression.
@@ -249,6 +237,11 @@ QScriptValue QDeclarativeExpressionPrivate::evalInObjectScope(QDeclarativeContex
QDeclarativeExpression::QDeclarativeExpression()
: QObject(*new QDeclarativeExpressionPrivate, 0)
{
+ Q_D(QDeclarativeExpression);
+
+ if (QDeclarativeExpression_notifyIdx == -1)
+ QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
+ d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
}
/*! \internal */
@@ -260,6 +253,10 @@ QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, vo
{
Q_D(QDeclarativeExpression);
d->init(ctxt, expr, rc, me, url, lineNumber);
+
+ if (QDeclarativeExpression_notifyIdx == -1)
+ QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
+ d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
}
/*!
@@ -277,6 +274,10 @@ QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContext *ctxt,
{
Q_D(QDeclarativeExpression);
d->init(QDeclarativeContextData::get(ctxt), expression, scope);
+
+ if (QDeclarativeExpression_notifyIdx == -1)
+ QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
+ d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
}
/*!
@@ -288,6 +289,10 @@ QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, QO
{
Q_D(QDeclarativeExpression);
d->init(ctxt, expression, scope);
+
+ if (QDeclarativeExpression_notifyIdx == -1)
+ QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
+ d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
}
/*! \internal */
@@ -297,6 +302,10 @@ QDeclarativeExpression::QDeclarativeExpression(QDeclarativeContextData *ctxt, QO
{
Q_D(QDeclarativeExpression);
d->init(ctxt, expression, scope);
+
+ if (QDeclarativeExpression_notifyIdx == -1)
+ QDeclarativeExpression_notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
+ d->setNotifyObject(this, QDeclarativeExpression_notifyIdx);
}
/*!
@@ -313,7 +322,7 @@ QDeclarativeExpression::~QDeclarativeExpression()
QDeclarativeEngine *QDeclarativeExpression::engine() const
{
Q_D(const QDeclarativeExpression);
- return d->data->context()?d->data->context()->engine:0;
+ return d->context()?d->context()->engine:0;
}
/*!
@@ -323,7 +332,7 @@ QDeclarativeEngine *QDeclarativeExpression::engine() const
QDeclarativeContext *QDeclarativeExpression::context() const
{
Q_D(const QDeclarativeExpression);
- QDeclarativeContextData *data = d->data->context();
+ QDeclarativeContextData *data = d->context();
return data?data->asQDeclarativeContext():0;
}
@@ -333,7 +342,7 @@ QDeclarativeContext *QDeclarativeExpression::context() const
QString QDeclarativeExpression::expression() const
{
Q_D(const QDeclarativeExpression);
- return d->data->expression;
+ return d->expression;
}
/*!
@@ -343,12 +352,10 @@ void QDeclarativeExpression::setExpression(const QString &expression)
{
Q_D(QDeclarativeExpression);
- d->clearGuards();
-
- d->data->expression = expression;
- d->data->expressionFunctionValid = false;
- d->data->expressionRewritten = false;
- d->data->expressionFunction = QScriptValue();
+ d->resetNotifyOnChange();
+ d->expression = expression;
+ d->expressionFunctionValid = false;
+ d->expressionFunction = QScriptValue();
}
void QDeclarativeExpressionPrivate::exceptionToError(QScriptEngine *scriptEngine,
@@ -378,59 +385,108 @@ void QDeclarativeExpressionPrivate::exceptionToError(QScriptEngine *scriptEngine
}
}
-QScriptValue QDeclarativeExpressionPrivate::eval(QObject *secondaryScope, bool *isUndefined)
+bool QDeclarativeQtScriptExpression::notifyOnValueChange() const
{
- QDeclarativeExpressionData *data = this->data;
- QDeclarativeEngine *engine = data->context()->engine;
- QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
+ return trackChange;
+}
- QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
+void QDeclarativeQtScriptExpression::setNotifyOnValueChange(bool notify)
+{
+ trackChange = notify;
+ if (!notify && guardList)
+ clearGuards();
+}
- if (!data->expressionFunctionValid) {
+void QDeclarativeQtScriptExpression::resetNotifyOnChange()
+{
+ clearGuards();
+}
- QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine);
- data->expressionContext = ep->contextClass->newContext(data->context(), data->me);
- scriptContext->pushScope(data->expressionContext);
- scriptContext->pushScope(ep->globalClass->staticGlobalObject());
+void QDeclarativeQtScriptExpression::setNotifyObject(QObject *object, int notifyIndex)
+{
+ if (guardList) clearGuards();
+
+ if (!object || notifyIndex == -1) {
+ guardObject = 0;
+ notifyIndex = -1;
+ } else {
+ guardObject = object;
+ guardObjectNotifyIndex = notifyIndex;
+
+ }
+}
+
+QScriptValue QDeclarativeQtScriptExpression::scriptValue(QObject *secondaryScope, bool *isUndefined)
+{
+ Q_ASSERT(context() && context()->engine);
+ Q_ASSERT(!trackChange || (guardObject && guardObjectNotifyIndex != -1));
+
+ if (!expressionFunction.isValid()) {
+ if (isUndefined) *isUndefined = true;
+ return QScriptValue();
+ }
+
+ DeleteWatcher watcher(this);
+
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context()->engine);
+
+ bool lastCaptureProperties = ep->captureProperties;
+ QPODVector<QDeclarativeEnginePrivate::CapturedProperty> lastCapturedProperties;
+ ep->captureProperties = trackChange;
+ ep->capturedProperties.copyAndClear(lastCapturedProperties);
+
+ QScriptValue value = eval(secondaryScope, isUndefined);
+
+ if (!watcher.wasDeleted() && trackChange) {
+ if (ep->capturedProperties.count() == 0) {
+
+ if (guardList) clearGuards();
- if (data->expressionRewritten) {
- data->expressionFunction = scriptEngine->evaluate(data->expression,
- data->url, data->line);
} else {
- QDeclarativeRewrite::RewriteBinding rewriteBinding;
- bool ok = true;
- const QString code = rewriteBinding(data->expression, &ok);
- if (!ok) {
- scriptEngine->popContext();
- return QScriptValue();
- }
- data->expressionFunction = scriptEngine->evaluate(code, data->url, data->line);
- }
+ updateGuards(ep->capturedProperties);
- scriptEngine->popContext();
- data->expressionFunctionValid = true;
+ }
}
+ lastCapturedProperties.copyAndClear(ep->capturedProperties);
+ ep->captureProperties = lastCaptureProperties;
+
+ return value;
+}
+
+QScriptValue QDeclarativeQtScriptExpression::eval(QObject *secondaryScope, bool *isUndefined)
+{
+ Q_ASSERT(context() && context()->engine);
+
+ DeleteWatcher watcher(this);
+
+ QDeclarativeEngine *engine = context()->engine;
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
+
+ QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
+
QDeclarativeContextData *oldSharedContext = 0;
QObject *oldSharedScope = 0;
QObject *oldOverride = 0;
- if (data->isShared) {
+ bool isShared = (expressionFunctionMode == SharedContext);
+
+ if (isShared) {
oldSharedContext = ep->sharedContext;
oldSharedScope = ep->sharedScope;
- ep->sharedContext = data->context();
- ep->sharedScope = data->me;
+ ep->sharedContext = context();
+ ep->sharedScope = scopeObject;
} else {
- oldOverride = ep->contextClass->setOverrideObject(data->expressionContext, secondaryScope);
+ oldOverride = ep->contextClass->setOverrideObject(expressionContext, secondaryScope);
}
- QScriptValue svalue = data->expressionFunction.call();
+ QScriptValue svalue = expressionFunction.call(); // This could cause this to be deleted
- if (data->isShared) {
+ if (isShared) {
ep->sharedContext = oldSharedContext;
ep->sharedScope = oldSharedScope;
- } else {
- ep->contextClass->setOverrideObject(data->expressionContext, oldOverride);
+ } else if (!watcher.wasDeleted()) {
+ ep->contextClass->setOverrideObject(expressionContext, oldOverride);
}
if (isUndefined)
@@ -438,63 +494,134 @@ QScriptValue QDeclarativeExpressionPrivate::eval(QObject *secondaryScope, bool *
// Handle exception
if (scriptEngine->hasUncaughtException()) {
- exceptionToError(scriptEngine, data->error);
+ if (!watcher.wasDeleted())
+ QDeclarativeExpressionPrivate::exceptionToError(scriptEngine, error);
+
scriptEngine->clearExceptions();
return QScriptValue();
} else {
- data->error = QDeclarativeError();
+ if (!watcher.wasDeleted())
+ error = QDeclarativeError();
+
return svalue;
}
}
-QScriptValue QDeclarativeExpressionPrivate::scriptValue(QObject *secondaryScope, bool *isUndefined)
+void QDeclarativeQtScriptExpression::updateGuards(const QPODVector<QDeclarativeEnginePrivate::CapturedProperty> &properties)
{
- Q_Q(QDeclarativeExpression);
- Q_ASSERT(q->engine());
+ Q_ASSERT(guardObject);
+ Q_ASSERT(guardObjectNotifyIndex != -1);
- if (data->expression.isEmpty())
- return QScriptValue();
+ if (properties.count() != guardListLength) {
+ QDeclarativeNotifierEndpoint *newGuardList = new QDeclarativeNotifierEndpoint[properties.count()];
- QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(q->engine());
+ for (int ii = 0; ii < qMin(guardListLength, properties.count()); ++ii)
+ guardList[ii].copyAndClear(newGuardList[ii]);
- QDeclarativeExpression *lastCurrentExpression = ep->currentExpression;
- bool lastCaptureProperties = ep->captureProperties;
- QPODVector<QDeclarativeEnginePrivate::CapturedProperty> lastCapturedProperties;
- ep->capturedProperties.copyAndClear(lastCapturedProperties);
+ delete [] guardList;
+ guardList = newGuardList;
+ guardListLength = properties.count();
+ }
- ep->currentExpression = q;
- ep->captureProperties = data->trackChange;
+ bool outputWarningHeader = false;
+ bool noChanges = true;
+ for (int ii = 0; ii < properties.count(); ++ii) {
+ QDeclarativeNotifierEndpoint &guard = guardList[ii];
+ const QDeclarativeEnginePrivate::CapturedProperty &property = properties.at(ii);
- // This object might be deleted during the eval
- QDeclarativeExpressionData *localData = data;
- localData->addref();
+ guard.target = guardObject;
+ guard.targetMethod = guardObjectNotifyIndex;
- QScriptValue value = eval(secondaryScope, isUndefined);
+ if (property.notifier != 0) {
- ep->currentExpression = lastCurrentExpression;
- ep->captureProperties = lastCaptureProperties;
+ if (!noChanges && guard.isConnected(property.notifier)) {
+ // Nothing to do
- // Check if we were deleted
- if (localData->q) {
- if ((!data->trackChange || !ep->capturedProperties.count()) && data->guardList) {
- clearGuards();
- } else if(data->trackChange) {
- updateGuards(ep->capturedProperties);
+ } else {
+ noChanges = false;
+
+ bool existing = false;
+ for (int jj = 0; !existing && jj < ii; ++jj)
+ if (guardList[jj].isConnected(property.notifier))
+ existing = true;
+
+ if (existing) {
+ // duplicate
+ guard.disconnect();
+ } else {
+ guard.connect(property.notifier);
+ }
+ }
+
+
+ } else if (property.notifyIndex != -1) {
+
+ if (!noChanges && guard.isConnected(property.object, property.notifyIndex)) {
+ // Nothing to do
+
+ } else {
+ noChanges = false;
+
+ bool existing = false;
+ for (int jj = 0; !existing && jj < ii; ++jj)
+ if (guardList[jj].isConnected(property.object, property.notifyIndex))
+ existing = true;
+
+ if (existing) {
+ // duplicate
+ guard.disconnect();
+ } else {
+ guard.connect(property.object, property.notifyIndex);
+ }
+ }
+
+ } else {
+ if (!outputWarningHeader) {
+ outputWarningHeader = true;
+ qWarning() << "QDeclarativeExpression: Expression" << expression
+ << "depends on non-NOTIFYable properties:";
+ }
+
+ const QMetaObject *metaObj = property.object->metaObject();
+ QMetaProperty metaProp = metaObj->property(property.coreIndex);
+
+ qWarning().nospace() << " " << metaObj->className() << "::" << metaProp.name();
}
}
+}
- localData->release();
+QScriptValue QDeclarativeExpressionPrivate::scriptValue(QObject *secondaryScope, bool *isUndefined)
+{
+ if (!expressionFunctionValid) {
+ QDeclarativeEngine *engine = context()->engine;
+ QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
- lastCapturedProperties.copyAndClear(ep->capturedProperties);
+ QScriptEngine *scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
- return value;
+ QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(scriptEngine);
+ expressionContext = ep->contextClass->newContext(context(), scopeObject);
+ scriptContext->pushScope(expressionContext);
+ scriptContext->pushScope(ep->globalClass->staticGlobalObject());
+
+ QDeclarativeRewrite::RewriteBinding rewriteBinding;
+ bool ok = true;
+ const QString code = rewriteBinding(expression, &ok);
+ if (ok)
+ expressionFunction = scriptEngine->evaluate(code, url, line);
+
+ scriptEngine->popContext();
+ expressionFunctionMode = ExplicitContext;
+ expressionFunctionValid = true;
+ }
+
+ return QDeclarativeQtScriptExpression::scriptValue(secondaryScope, isUndefined);
}
QVariant QDeclarativeExpressionPrivate::value(QObject *secondaryScope, bool *isUndefined)
{
Q_Q(QDeclarativeExpression);
- if (!data || !data->context() || !data->context()->isValid()) {
+ if (!context() || !context()->isValid()) {
qWarning("QDeclarativeExpression: Attempted to evaluate an expression in an invalid context");
return QVariant();
}
@@ -526,7 +653,7 @@ value changes.
bool QDeclarativeExpression::notifyOnValueChanged() const
{
Q_D(const QDeclarativeExpression);
- return d->data->trackChange;
+ return d->notifyOnValueChange();
}
/*!
@@ -548,7 +675,7 @@ bool QDeclarativeExpression::notifyOnValueChanged() const
void QDeclarativeExpression::setNotifyOnValueChanged(bool notifyOnChange)
{
Q_D(QDeclarativeExpression);
- d->data->trackChange = notifyOnChange;
+ d->setNotifyOnValueChange(notifyOnChange);
}
/*!
@@ -558,7 +685,7 @@ void QDeclarativeExpression::setNotifyOnValueChanged(bool notifyOnChange)
QString QDeclarativeExpression::sourceFile() const
{
Q_D(const QDeclarativeExpression);
- return d->data->url;
+ return d->url;
}
/*!
@@ -568,7 +695,7 @@ QString QDeclarativeExpression::sourceFile() const
int QDeclarativeExpression::lineNumber() const
{
Q_D(const QDeclarativeExpression);
- return d->data->line;
+ return d->line;
}
/*!
@@ -578,8 +705,8 @@ int QDeclarativeExpression::lineNumber() const
void QDeclarativeExpression::setSourceLocation(const QString &url, int line)
{
Q_D(QDeclarativeExpression);
- d->data->url = url;
- d->data->line = line;
+ d->url = url;
+ d->line = line;
}
/*!
@@ -591,7 +718,7 @@ void QDeclarativeExpression::setSourceLocation(const QString &url, int line)
QObject *QDeclarativeExpression::scopeObject() const
{
Q_D(const QDeclarativeExpression);
- return d->data->me;
+ return d->scopeObject;
}
/*!
@@ -603,7 +730,7 @@ QObject *QDeclarativeExpression::scopeObject() const
bool QDeclarativeExpression::hasError() const
{
Q_D(const QDeclarativeExpression);
- return d->data->error.isValid();
+ return d->error.isValid();
}
/*!
@@ -615,7 +742,7 @@ bool QDeclarativeExpression::hasError() const
void QDeclarativeExpression::clearError()
{
Q_D(QDeclarativeExpression);
- d->data->error = QDeclarativeError();
+ d->error = QDeclarativeError();
}
/*!
@@ -628,7 +755,7 @@ void QDeclarativeExpression::clearError()
QDeclarativeError QDeclarativeExpression::error() const
{
Q_D(const QDeclarativeExpression);
- return d->data->error;
+ return d->error;
}
/*! \internal */
@@ -637,98 +764,11 @@ void QDeclarativeExpressionPrivate::_q_notify()
emitValueChanged();
}
-void QDeclarativeExpressionPrivate::clearGuards()
-{
- delete [] data->guardList;
- data->guardList = 0;
- data->guardListLength = 0;
-}
-
-void QDeclarativeExpressionPrivate::updateGuards(const QPODVector<QDeclarativeEnginePrivate::CapturedProperty> &properties)
+void QDeclarativeQtScriptExpression::clearGuards()
{
- Q_Q(QDeclarativeExpression);
-
- static int notifyIdx = -1;
- if (notifyIdx == -1)
- notifyIdx = QDeclarativeExpression::staticMetaObject.indexOfMethod("_q_notify()");
-
- if (properties.count() != data->guardListLength) {
- QDeclarativeNotifierEndpoint *newGuardList =
- new QDeclarativeNotifierEndpoint[properties.count()];
-
- for (int ii = 0; ii < qMin(data->guardListLength, properties.count()); ++ii)
- data->guardList[ii].copyAndClear(newGuardList[ii]);
-
- delete [] data->guardList;
- data->guardList = newGuardList;
- data->guardListLength = properties.count();
- }
-
- bool outputWarningHeader = false;
- bool noChanges = true;
- for (int ii = 0; ii < properties.count(); ++ii) {
- QDeclarativeNotifierEndpoint &guard = data->guardList[ii];
- const QDeclarativeEnginePrivate::CapturedProperty &property = properties.at(ii);
-
- guard.target = q;
- guard.targetMethod = notifyIdx;
-
- if (property.notifier != 0) {
-
- if (!noChanges && guard.isConnected(property.notifier)) {
- // Nothing to do
-
- } else {
- noChanges = false;
-
- bool existing = false;
- for (int jj = 0; !existing && jj < ii; ++jj)
- if (data->guardList[jj].isConnected(property.notifier))
- existing = true;
-
- if (existing) {
- // duplicate
- guard.disconnect();
- } else {
- guard.connect(property.notifier);
- }
- }
-
-
- } else if (property.notifyIndex != -1) {
-
- if (!noChanges && guard.isConnected(property.object, property.notifyIndex)) {
- // Nothing to do
-
- } else {
- noChanges = false;
-
- bool existing = false;
- for (int jj = 0; !existing && jj < ii; ++jj)
- if (data->guardList[jj].isConnected(property.object, property.notifyIndex))
- existing = true;
-
- if (existing) {
- // duplicate
- guard.disconnect();
- } else {
- guard.connect(property.object, property.notifyIndex);
- }
- }
-
- } else {
- if (!outputWarningHeader) {
- outputWarningHeader = true;
- qWarning() << "QDeclarativeExpression: Expression" << q->expression()
- << "depends on non-NOTIFYable properties:";
- }
-
- const QMetaObject *metaObj = property.object->metaObject();
- QMetaProperty metaProp = metaObj->property(property.coreIndex);
-
- qWarning().nospace() << " " << metaObj->className() << "::" << metaProp.name();
- }
- }
+ delete [] guardList;
+ guardList = 0;
+ guardListLength = 0;
}
/*!
diff --git a/src/declarative/qml/qdeclarativeexpression_p.h b/src/declarative/qml/qdeclarativeexpression_p.h
index 4ff3162..b629e20 100644
--- a/src/declarative/qml/qdeclarativeexpression_p.h
+++ b/src/declarative/qml/qdeclarativeexpression_p.h
@@ -107,56 +107,73 @@ private:
QDeclarativeDelayedError **prevError;
};
-class QDeclarativeExpressionData : public QDeclarativeAbstractExpression, public QDeclarativeDelayedError, public QDeclarativeRefCount
+class QDeclarativeQtScriptExpression : public QDeclarativeAbstractExpression,
+ public QDeclarativeDelayedError
{
public:
- QDeclarativeExpressionData();
- virtual ~QDeclarativeExpressionData();
+ enum Mode { SharedContext, ExplicitContext };
- QDeclarativeExpressionPrivate *q;
+ QDeclarativeQtScriptExpression();
+ virtual ~QDeclarativeQtScriptExpression();
QDeclarativeRefCount *dataRef;
+
QString expression;
- bool expressionFunctionValid:1;
- bool expressionRewritten:1;
+
+ Mode expressionFunctionMode;
QScriptValue expressionFunction;
- QScriptValue expressionContext;
- QObject *me;
- bool trackChange;
+ QScriptValue expressionContext; // Only used in ExplicitContext
+ QObject *scopeObject; // Only used in SharedContext
- bool isShared;
+ bool notifyOnValueChange() const;
+ void setNotifyOnValueChange(bool);
+ void resetNotifyOnChange();
+ void setNotifyObject(QObject *, int );
- QString url; // This is a QString for a reason. QUrls are slooooooow...
- int line;
+ QScriptValue scriptValue(QObject *secondaryScope, bool *isUndefined);
+
+ class DeleteWatcher {
+ public:
+ inline DeleteWatcher(QDeclarativeQtScriptExpression *data);
+ inline ~DeleteWatcher();
+ inline bool wasDeleted() const;
+ private:
+ bool *m_wasDeleted;
+ bool m_wasDeletedStorage;
+ QDeclarativeQtScriptExpression *m_d;
+ };
+
+private:
+ void clearGuards();
+ QScriptValue eval(QObject *secondaryScope, bool *isUndefined);
+ void updateGuards(const QPODVector<QDeclarativeEnginePrivate::CapturedProperty> &properties);
+
+ bool trackChange;
QDeclarativeNotifierEndpoint *guardList;
int guardListLength;
+
+ QObject *guardObject;
+ int guardObjectNotifyIndex;
+ bool *deleted;
};
class QDeclarativeExpression;
class QString;
-class QDeclarativeExpressionPrivate : public QObjectPrivate
+class QDeclarativeExpressionPrivate : public QObjectPrivate, public QDeclarativeQtScriptExpression
{
Q_DECLARE_PUBLIC(QDeclarativeExpression)
public:
QDeclarativeExpressionPrivate();
- QDeclarativeExpressionPrivate(QDeclarativeExpressionData *);
~QDeclarativeExpressionPrivate();
void init(QDeclarativeContextData *, const QString &, QObject *);
void init(QDeclarativeContextData *, void *, QDeclarativeRefCount *, QObject *, const QString &, int);
- QDeclarativeExpressionData *data;
-
QVariant value(QObject *secondaryScope = 0, bool *isUndefined = 0);
QScriptValue scriptValue(QObject *secondaryScope = 0, bool *isUndefined = 0);
- QScriptValue eval(QObject *secondaryScope, bool *isUndefined = 0);
-
- void updateGuards(const QPODVector<QDeclarativeEnginePrivate::CapturedProperty> &properties);
- void clearGuards();
-
static QDeclarativeExpressionPrivate *get(QDeclarativeExpression *expr) {
return static_cast<QDeclarativeExpressionPrivate *>(QObjectPrivate::get(expr));
}
@@ -172,8 +189,32 @@ public:
int, QScriptValue *);
static QScriptValue evalInObjectScope(QDeclarativeContextData *, QObject *, const QScriptProgram &,
QScriptValue *);
+
+ bool expressionFunctionValid:1;
+
+ QString url; // This is a QString for a reason. QUrls are slooooooow...
+ int line;
};
+QDeclarativeQtScriptExpression::DeleteWatcher::DeleteWatcher(QDeclarativeQtScriptExpression *data)
+: m_wasDeletedStorage(false), m_d(data)
+{
+ if (!m_d->deleted)
+ m_d->deleted = &m_wasDeletedStorage;
+ m_wasDeleted = m_d->deleted;
+}
+
+QDeclarativeQtScriptExpression::DeleteWatcher::~DeleteWatcher()
+{
+ if (false == *m_wasDeleted && m_wasDeleted == m_d->deleted)
+ m_d->deleted = 0;
+}
+
+bool QDeclarativeQtScriptExpression::DeleteWatcher::wasDeleted() const
+{
+ return *m_wasDeleted;
+}
+
QT_END_NAMESPACE
#endif // QDECLARATIVEEXPRESSION_P_H
diff --git a/src/declarative/qml/qdeclarativeimageprovider.cpp b/src/declarative/qml/qdeclarativeimageprovider.cpp
index f38da4e..a294c38 100644
--- a/src/declarative/qml/qdeclarativeimageprovider.cpp
+++ b/src/declarative/qml/qdeclarativeimageprovider.cpp
@@ -180,9 +180,13 @@ QDeclarativeImageProvider::ImageType QDeclarativeImageProvider::imageType() cons
Implement this method to return the image with \a id. The default
implementation returns an empty image.
- If \a requestedSize is a valid size, the image returned should be of that size.
+ The \a requestedSize corresponds to the \l {Image::sourceSize} requested by
+ an Image element. If \a requestedSize is a valid size, the image
+ returned should be of that size.
- In all cases, \a size must be set to the original size of the image.
+ In all cases, \a size must be set to the original size of the image. This
+ is used to set the \l {Item::}{width} and \l {Item::}{height} of image
+ elements that should be automatically sized to the loaded image.
\note this method may be called by multiple threads, so ensure the
implementation of this method is reentrant.
@@ -201,9 +205,13 @@ QImage QDeclarativeImageProvider::requestImage(const QString &id, QSize *size, c
Implement this method to return the pixmap with \a id. The default
implementation returns an empty pixmap.
- If \a requestedSize is a valid size, the image returned should be of that size.
+ The \a requestedSize corresponds to the \l {Image::sourceSize} requested by
+ an Image element. If \a requestedSize is a valid size, the image
+ returned should be of that size.
- In all cases, \a size must be set to the original size of the image.
+ In all cases, \a size must be set to the original size of the image. This
+ is used to set the \l {Item::}{width} and \l {Item::}{height} of image
+ elements that should be automatically sized to the loaded image.
\note this method may be called by multiple threads, so ensure the
implementation of this method is reentrant.
diff --git a/src/declarative/qml/qdeclarativelist.cpp b/src/declarative/qml/qdeclarativelist.cpp
index 7c89672..9598d98 100644
--- a/src/declarative/qml/qdeclarativelist.cpp
+++ b/src/declarative/qml/qdeclarativelist.cpp
@@ -306,7 +306,7 @@ int QDeclarativeListReference::count() const
/*!
\class QDeclarativeListProperty
\since 4.7
-\brief The QDeclarativeListProperty class allows applications to explose list-like
+\brief The QDeclarativeListProperty class allows applications to expose list-like
properties to QML.
QML has many list properties, where more than one object value can be assigned.
diff --git a/src/declarative/util/qdeclarativestateoperations.cpp b/src/declarative/util/qdeclarativestateoperations.cpp
index 51e6f99..5590449 100644
--- a/src/declarative/util/qdeclarativestateoperations.cpp
+++ b/src/declarative/util/qdeclarativestateoperations.cpp
@@ -1039,7 +1039,7 @@ public:
/*!
\qmlproperty Item AnchorChanges::target
- This property holds the Item whose anchors will change
+ This property holds the \l Item for which the anchor changes will be applied.
*/
QDeclarativeAnchorChanges::QDeclarativeAnchorChanges(QObject *parent)
diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp
index 00169db..9f4df22 100644
--- a/src/declarative/util/qdeclarativexmllistmodel.cpp
+++ b/src/declarative/util/qdeclarativexmllistmodel.cpp
@@ -508,8 +508,8 @@ void QDeclarativeXmlListModelPrivate::clear_role(QDeclarativeListProperty<QDecla
\since 4.7
\brief The XmlListModel element is used to specify a model using XPath expressions.
- XmlListModel is used to create a model from XML data. XmlListModel can be used as a data source
- for the view classes (such as ListView, PathView, GridView) and other classes that interact with model
+ XmlListModel is used to create a model from XML data. It can be used as a data source
+ for view elements (such as ListView, PathView, GridView) and other elements that interact with model
data (such as \l Repeater).
For example, if there is a XML document at http://www.mysite.com/feed.xml like this:
@@ -520,11 +520,11 @@ void QDeclarativeXmlListModelPrivate::clear_role(QDeclarativeListProperty<QDecla
...
<channel>
<item>
- <title>Item A</title>
+ <title>A blog post</title>
<pubDate>Sat, 07 Sep 2010 10:00:01 GMT</pubDate>
</item>
<item>
- <title>Item B</title>
+ <title>Another blog post</title>
<pubDate>Sat, 07 Sep 2010 15:35:01 GMT</pubDate>
</item>
</channel>
@@ -560,10 +560,17 @@ void QDeclarativeXmlListModelPrivate::clear_role(QDeclarativeListProperty<QDecla
ListView {
width: 180; height: 300
model: xmlModel
- delegate: Text { title + " (" + pubDate + ")" }
+ delegate: Text { text: title + " (" + pubDate + ")" }
}
\endqml
+ \image qml-xmllistmodel-example.png
+
+ The XmlListModel data is loaded asynchronously, and \l status
+ is set to \l XmlListModel::Ready when loading is complete.
+ Note this means when XmlListModel is used for a view, the view is not
+ populated until the model is loaded.
+
\section2 Using key XML roles
@@ -589,7 +596,7 @@ void QDeclarativeXmlListModelPrivate::clear_role(QDeclarativeListProperty<QDecla
with a combined value of all key roles that is not already present in
the model.
- \sa {demos/declarative/rssnews}{RSS News demo}
+ \sa {RSS News}
*/
QDeclarativeXmlListModel::QDeclarativeXmlListModel(QObject *parent)
diff --git a/src/gui/dialogs/qwizard_win.cpp b/src/gui/dialogs/qwizard_win.cpp
index e406cba..ad8801a 100644
--- a/src/gui/dialogs/qwizard_win.cpp
+++ b/src/gui/dialogs/qwizard_win.cpp
@@ -180,7 +180,8 @@ QVistaBackButton::QVistaBackButton(QWidget *widget)
QSize QVistaBackButton::sizeHint() const
{
ensurePolished();
- int width = 32, height = 32;
+ int size = int(QStyleHelper::dpiScaled(32));
+ int width = size, height = size;
/*
HANDLE theme = pOpenThemeData(0, L"Navigation");
SIZE size;
@@ -213,8 +214,8 @@ void QVistaBackButton::paintEvent(QPaintEvent *)
HANDLE theme = pOpenThemeData(0, L"Navigation");
//RECT rect;
RECT clipRect;
- int xoffset = QWidget::mapToParent(r.topLeft()).x();
- int yoffset = QWidget::mapToParent(r.topLeft()).y();
+ int xoffset = QWidget::mapToParent(r.topLeft()).x() - 1;
+ int yoffset = QWidget::mapToParent(r.topLeft()).y() - 1;
clipRect.top = r.top() + yoffset;
clipRect.bottom = r.bottom() + yoffset;
@@ -245,6 +246,11 @@ QVistaHelper::QVistaHelper(QWizard *wizard)
is_vista = resolveSymbols();
if (is_vista)
backButton_ = new QVistaBackButton(wizard);
+
+ // Handle diff between Windows 7 and Vista
+ iconSpacing = QStyleHelper::dpiScaled(7);
+ textSpacing = QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS7 ?
+ iconSpacing : QStyleHelper::dpiScaled(20);
}
QVistaHelper::~QVistaHelper()
@@ -308,18 +314,15 @@ bool QVistaHelper::setDWMTitleBar(TitleBarChangeType type)
void QVistaHelper::drawTitleBar(QPainter *painter)
{
- if (vistaState() == VistaAero)
- drawBlackRect(
- QRect(0, 0, wizard->width(), titleBarSize() + topOffset()),
- painter->paintEngine()->getDC());
+ HDC hdc = painter->paintEngine()->getDC();
+ if (vistaState() == VistaAero)
+ drawBlackRect(QRect(0, 0, wizard->width(),
+ titleBarSize() + topOffset()), hdc);
Q_ASSERT(backButton_);
const int btnTop = backButton_->mapToParent(QPoint()).y();
const int btnHeight = backButton_->size().height();
- const int verticalCenter = (btnTop + btnHeight / 2);
-
- wizard->windowIcon().paint(
- painter, QRect(leftMargin(), verticalCenter - iconSize() / 2, iconSize(), iconSize()));
+ const int verticalCenter = (btnTop + btnHeight / 2) - 1;
const QString text = wizard->window()->windowTitle();
const QFont font = QApplication::font("QWorkspaceTitleBar");
@@ -327,14 +330,25 @@ void QVistaHelper::drawTitleBar(QPainter *painter)
const QRect brect = fontMetrics.boundingRect(text);
int textHeight = brect.height();
int textWidth = brect.width();
+ int glowOffset = 0;
+
if (vistaState() == VistaAero) {
textHeight += 2 * glowSize();
textWidth += 2 * glowSize();
+ glowOffset = glowSize();
}
+
drawTitleText(
painter, text,
- QRect(titleOffset(), verticalCenter - textHeight / 2, textWidth, textHeight),
- painter->paintEngine()->getDC());
+ QRect(titleOffset() - glowOffset, verticalCenter - textHeight / 2, textWidth, textHeight),
+ hdc);
+
+ if (!wizard->windowIcon().isNull()) {
+ QRect rect(leftMargin(), verticalCenter - iconSize() / 2, iconSize(), iconSize());
+ HICON hIcon = wizard->windowIcon().pixmap(iconSize()).toWinHICON();
+ DrawIconEx(hdc, rect.left(), rect.top(), hIcon, 0, 0, 0, NULL, DI_NORMAL | DI_COMPAT);
+ DestroyIcon(hIcon);
+ }
}
void QVistaHelper::setTitleBarIconAndCaptionVisible(bool visible)
@@ -734,7 +748,7 @@ bool QVistaHelper::resolveSymbols()
int QVistaHelper::titleOffset()
{
- int iconOffset = wizard ->windowIcon().isNull() ? 0 : iconSize() + padding();
+ int iconOffset = wizard ->windowIcon().isNull() ? 0 : iconSize() + textSpacing;
return leftMargin() + iconOffset;
}
diff --git a/src/gui/dialogs/qwizard_win_p.h b/src/gui/dialogs/qwizard_win_p.h
index 5f3b6c2..caf018d 100644
--- a/src/gui/dialogs/qwizard_win_p.h
+++ b/src/gui/dialogs/qwizard_win_p.h
@@ -61,6 +61,7 @@
#include <qwidget.h>
#include <qabstractbutton.h>
#include <QtGui/private/qwidget_p.h>
+#include <QtGui/private/qstylehelper_p.h>
QT_BEGIN_NAMESPACE
@@ -100,9 +101,14 @@ public:
enum VistaState { VistaAero, VistaBasic, Classic, Dirty };
static VistaState vistaState();
static int titleBarSize() { return frameSize() + captionSize(); }
- static int topPadding() { return 8; }
- static int topOffset() { return titleBarSize() + (vistaState() == VistaAero ? 13 : 3); }
-
+ static int topPadding() { // padding under text
+ return int(QStyleHelper::dpiScaled(
+ QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS7 ? 4 : 6));
+ }
+ static int topOffset() {
+ static int aeroOffset = QSysInfo::WindowsVersion >= QSysInfo::WV_WINDOWS7 ?
+ QStyleHelper::dpiScaled(4) : QStyleHelper::dpiScaled(13);
+ return (titleBarSize() + (vistaState() == VistaAero ? aeroOffset : 3)); }
private:
static HFONT getCaptionFont(HANDLE hTheme);
bool drawTitleText(QPainter *painter, const QString &text, const QRect &rect, HDC hdc);
@@ -111,11 +117,10 @@ private:
static int frameSize() { return GetSystemMetrics(SM_CYSIZEFRAME); }
static int captionSize() { return GetSystemMetrics(SM_CYCAPTION); }
- static int backButtonSize() { return 31; } // ### should be queried from back button itself
+ static int backButtonSize() { return int(QStyleHelper::dpiScaled(30)); }
static int iconSize() { return 16; } // Standard Aero
- static int padding() { return 7; } // Standard Aero
- static int leftMargin() { return backButtonSize() + padding(); }
static int glowSize() { return 10; }
+ int leftMargin() { return backButton_->isVisible() ? backButtonSize() + iconSpacing : 0; }
int titleOffset();
bool resolveSymbols();
@@ -139,6 +144,10 @@ private:
QRect rtTitle;
QWizard *wizard;
QVistaBackButton *backButton_;
+
+ int titleBarOffset; // Extra spacing above the text
+ int iconSpacing; // Space between button and icon
+ int textSpacing; // Space between icon and text
};
diff --git a/src/gui/graphicsview/qgraphicsgridlayout.cpp b/src/gui/graphicsview/qgraphicsgridlayout.cpp
index 83db3ec..062b5ac 100644
--- a/src/gui/graphicsview/qgraphicsgridlayout.cpp
+++ b/src/gui/graphicsview/qgraphicsgridlayout.cpp
@@ -94,14 +94,13 @@ public:
#endif
};
+Q_GLOBAL_STATIC(QWidget, globalStyleInfoWidget);
+
QLayoutStyleInfo QGraphicsGridLayoutPrivate::styleInfo() const
{
- static QWidget *wid = 0;
- if (!wid)
- wid = new QWidget;
QGraphicsItem *item = parentItem();
QStyle *style = (item && item->isWidget()) ? static_cast<QGraphicsWidget*>(item)->style() : QApplication::style();
- return QLayoutStyleInfo(style, wid);
+ return QLayoutStyleInfo(style, globalStyleInfoWidget());
}
/*!
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 848de2c..bf36d9b 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -133,7 +133,8 @@
\img graphicsview-parentchild.png
- \section1 Transformation
+ \target Transformations
+ \section1 Transformations
QGraphicsItem supports projective transformations in addition to its base
position, pos(). There are several ways to change an item's transformation.
@@ -3257,6 +3258,8 @@ void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool clim
}
// Update the child focus chain.
+ if (scene && scene->focusItem())
+ scene->focusItem()->d_ptr->clearSubFocus();
f->d_ptr->setSubFocus();
// Update the scene's focus item.
@@ -7637,9 +7640,9 @@ int QGraphicsItemPrivate::children_count(QDeclarativeListProperty<QGraphicsObjec
QGraphicsObject *QGraphicsItemPrivate::children_at(QDeclarativeListProperty<QGraphicsObject> *list, int index)
{
QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(static_cast<QGraphicsObject *>(list->object));
- if (index >= 0 && index < d->children.count())
+ if (index >= 0 && index < d->children.count())
return d->children.at(index)->toGraphicsObject();
- else
+ else
return 0;
}
diff --git a/src/gui/graphicsview/qgraphicslinearlayout.cpp b/src/gui/graphicsview/qgraphicslinearlayout.cpp
index b828722..37408ef 100644
--- a/src/gui/graphicsview/qgraphicslinearlayout.cpp
+++ b/src/gui/graphicsview/qgraphicslinearlayout.cpp
@@ -171,14 +171,13 @@ int QGraphicsLinearLayoutPrivate::gridColumn(int index) const
return int(qMin(uint(index), uint(engine.columnCount())));
}
+Q_GLOBAL_STATIC(QWidget, globalStyleInfoWidget)
+
QLayoutStyleInfo QGraphicsLinearLayoutPrivate::styleInfo() const
{
- static QWidget *wid = 0;
- if (!wid)
- wid = new QWidget;
QGraphicsItem *item = parentItem();
QStyle *style = (item && item->isWidget()) ? static_cast<QGraphicsWidget*>(item)->style() : QApplication::style();
- return QLayoutStyleInfo(style, wid);
+ return QLayoutStyleInfo(style, globalStyleInfoWidget());
}
/*!
diff --git a/src/gui/graphicsview/qgraphicswidget_p.cpp b/src/gui/graphicsview/qgraphicswidget_p.cpp
index 28070da..f7850ca 100644
--- a/src/gui/graphicsview/qgraphicswidget_p.cpp
+++ b/src/gui/graphicsview/qgraphicswidget_p.cpp
@@ -761,7 +761,7 @@ void QGraphicsWidgetPrivate::fixFocusChainBeforeReparenting(QGraphicsWidget *new
QGraphicsWidget *firstOld = 0;
bool wasPreviousNew = true;
-
+
while (w != q) {
bool isCurrentNew = q->isAncestorOf(w);
if (isCurrentNew) {
@@ -796,7 +796,7 @@ void QGraphicsWidgetPrivate::fixFocusChainBeforeReparenting(QGraphicsWidget *new
newScene = newParent->scene();
if (oldScene && newScene != oldScene)
- oldScene->d_func()->tabFocusFirst = firstOld;
+ oldScene->d_func()->tabFocusFirst = (firstOld && firstOld->scene() == oldScene) ? firstOld : 0;
QGraphicsItem *topLevelItem = newParent ? newParent->topLevelItem() : 0;
QGraphicsWidget *topLevel = 0;
diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp
index 4fb93fc..97499f3 100644
--- a/src/gui/itemviews/qabstractitemview.cpp
+++ b/src/gui/itemviews/qabstractitemview.cpp
@@ -1363,7 +1363,7 @@ bool QAbstractItemView::dragEnabled() const
Note that the model used needs to provide support for drag and drop operations.
- \sa setDragDropMode() {Using Drag and Drop with Item Views}
+ \sa setDragDropMode() {Using drag & drop with item views}
*/
/*!
diff --git a/src/gui/itemviews/qfileiconprovider.cpp b/src/gui/itemviews/qfileiconprovider.cpp
index 5dbd1f0..4748f89 100644
--- a/src/gui/itemviews/qfileiconprovider.cpp
+++ b/src/gui/itemviews/qfileiconprovider.cpp
@@ -100,69 +100,80 @@ public:
QIcon getMacIcon(const QFileInfo &fi) const;
#endif
QFileIconProvider *q_ptr;
- QString homePath;
+ const QString homePath;
private:
- QIcon file;
- QIcon fileLink;
- QIcon directory;
- QIcon directoryLink;
- QIcon harddisk;
- QIcon floppy;
- QIcon cdrom;
- QIcon ram;
- QIcon network;
- QIcon computer;
- QIcon desktop;
- QIcon trashcan;
- QIcon generic;
- QIcon home;
+ mutable QIcon file;
+ mutable QIcon fileLink;
+ mutable QIcon directory;
+ mutable QIcon directoryLink;
+ mutable QIcon harddisk;
+ mutable QIcon floppy;
+ mutable QIcon cdrom;
+ mutable QIcon ram;
+ mutable QIcon network;
+ mutable QIcon computer;
+ mutable QIcon desktop;
+ mutable QIcon trashcan;
+ mutable QIcon generic;
+ mutable QIcon home;
};
-QFileIconProviderPrivate::QFileIconProviderPrivate()
+QFileIconProviderPrivate::QFileIconProviderPrivate() :
+ homePath(QDir::home().absolutePath())
{
- QStyle *style = QApplication::style();
- file = style->standardIcon(QStyle::SP_FileIcon);
- directory = style->standardIcon(QStyle::SP_DirIcon);
- fileLink = style->standardIcon(QStyle::SP_FileLinkIcon);
- directoryLink = style->standardIcon(QStyle::SP_DirLinkIcon);
- harddisk = style->standardIcon(QStyle::SP_DriveHDIcon);
- floppy = style->standardIcon(QStyle::SP_DriveFDIcon);
- cdrom = style->standardIcon(QStyle::SP_DriveCDIcon);
- network = style->standardIcon(QStyle::SP_DriveNetIcon);
- computer = style->standardIcon(QStyle::SP_ComputerIcon);
- desktop = style->standardIcon(QStyle::SP_DesktopIcon);
- trashcan = style->standardIcon(QStyle::SP_TrashIcon);
- home = style->standardIcon(QStyle::SP_DirHomeIcon);
- homePath = QDir::home().absolutePath();
}
QIcon QFileIconProviderPrivate::getIcon(QStyle::StandardPixmap name) const
{
switch (name) {
case QStyle::SP_FileIcon:
+ if (file.isNull())
+ file = QApplication::style()->standardIcon(name);
return file;
case QStyle::SP_FileLinkIcon:
+ if (fileLink.isNull())
+ fileLink = QApplication::style()->standardIcon(name);
return fileLink;
case QStyle::SP_DirIcon:
+ if (directory.isNull())
+ directory = QApplication::style()->standardIcon(name);
return directory;
case QStyle::SP_DirLinkIcon:
+ if (directoryLink.isNull())
+ directoryLink = QApplication::style()->standardIcon(name);
return directoryLink;
case QStyle::SP_DriveHDIcon:
+ if (harddisk.isNull())
+ harddisk = QApplication::style()->standardIcon(name);
return harddisk;
case QStyle::SP_DriveFDIcon:
+ if (floppy.isNull())
+ floppy = QApplication::style()->standardIcon(name);
return floppy;
case QStyle::SP_DriveCDIcon:
+ if (cdrom.isNull())
+ cdrom = QApplication::style()->standardIcon(name);
return cdrom;
case QStyle::SP_DriveNetIcon:
+ if (network.isNull())
+ network = QApplication::style()->standardIcon(name);
return network;
case QStyle::SP_ComputerIcon:
+ if (computer.isNull())
+ computer = QApplication::style()->standardIcon(name);
return computer;
case QStyle::SP_DesktopIcon:
+ if (desktop.isNull())
+ desktop = QApplication::style()->standardIcon(name);
return desktop;
case QStyle::SP_TrashIcon:
+ if (trashcan.isNull())
+ trashcan = QApplication::style()->standardIcon(name);
return trashcan;
case QStyle::SP_DirHomeIcon:
+ if (home.isNull())
+ home = QApplication::style()->standardIcon(name);
return home;
default:
return QIcon();
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index 94211fd..aaf479f 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -5294,6 +5294,7 @@ bool QApplication::keypadNavigationEnabled()
\sa QCoreApplication::instance()
*/
+#ifndef QT_NO_IM
// ************************************************************************
// Input Method support
// ************************************************************************
@@ -5359,6 +5360,7 @@ QInputContext *QApplication::inputContext() const
#endif
return d->inputContext;
}
+#endif // QT_NO_IM
//Returns the current platform used by keyBindings
uint QApplicationPrivate::currentPlatform(){
diff --git a/src/gui/kernel/qapplication.h b/src/gui/kernel/qapplication.h
index d31d9e5..799d4c2 100644
--- a/src/gui/kernel/qapplication.h
+++ b/src/gui/kernel/qapplication.h
@@ -267,8 +267,11 @@ public:
virtual void commitData(QSessionManager& sm);
virtual void saveState(QSessionManager& sm);
#endif
+
+#ifndef QT_NO_IM
void setInputContext(QInputContext *);
QInputContext *inputContext() const;
+#endif
static QLocale keyboardInputLocale();
static Qt::LayoutDirection keyboardInputDirection();
diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp
index 9e8a128..ec26e81 100644
--- a/src/gui/kernel/qapplication_win.cpp
+++ b/src/gui/kernel/qapplication_win.cpp
@@ -2485,7 +2485,7 @@ extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wPa
if (OkCommand)
QApplication::postEvent(widget, new QEvent(QEvent::OkRequest));
if (CancelCommand)
- QApplication::postEvent(widget, new QEvent(QEvent::Close));
+ widget->showMinimized();
else
#ifndef QT_NO_MENUBAR
QMenuBar::wceCommands(LOWORD(wParam));
diff --git a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
index 8652816..6795149 100644
--- a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
+++ b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
@@ -85,6 +85,8 @@ QT_END_NAMESPACE
- (BOOL)canBecomeKeyWindow
{
QWidget *widget = [self QT_MANGLE_NAMESPACE(qt_qwidget)];
+ if (!widget)
+ return NO; // This should happen only for qt_root_win
bool isToolTip = (widget->windowType() == Qt::ToolTip);
bool isPopup = (widget->windowType() == Qt::Popup);
@@ -94,6 +96,8 @@ QT_END_NAMESPACE
- (BOOL)canBecomeMainWindow
{
QWidget *widget = [self QT_MANGLE_NAMESPACE(qt_qwidget)];
+ if (!widget)
+ return NO; // This should happen only for qt_root_win
bool isToolTip = (widget->windowType() == Qt::ToolTip);
bool isPopup = (widget->windowType() == Qt::Popup);
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index 5c90e2e..1935531 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -269,6 +269,28 @@ static int qCocoaViewCount = 0;
dropData = new QCocoaDropData(dropPasteboard);
}
+- (void)changeDraggingCursor:(NSDragOperation)newOperation
+{
+ static SEL action = nil;
+ static bool operationSupported = false;
+ if (action == nil) {
+ action = NSSelectorFromString(@"operationNotAllowedCursor");
+ if ([NSCursor respondsToSelector:action]) {
+ operationSupported = true;
+ }
+ }
+ if (operationSupported) {
+ NSCursor *notAllowedCursor = [NSCursor performSelector:action];
+ bool isNotAllowedCursor = ([NSCursor currentCursor] == notAllowedCursor);
+ if (newOperation == NSDragOperationNone && !isNotAllowedCursor) {
+ [notAllowedCursor push];
+ } else if (newOperation != NSDragOperationNone && isNotAllowedCursor) {
+ [notAllowedCursor pop];
+ }
+
+ }
+}
+
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
{
// NB: This function is called from QCoocaWindow/QCocoaPanel rather than directly
@@ -300,6 +322,7 @@ static int qCocoaViewCount = 0;
if (!qDEEvent.isAccepted()) {
// widget is not interested in this drag, so ignore this drop data.
[self removeDropData];
+ [self changeDraggingCursor:NSDragOperationNone];
return NSDragOperationNone;
} else {
// save the mouse position, used by draggingExited handler.
@@ -321,6 +344,7 @@ static int qCocoaViewCount = 0;
nsActions = QT_PREPEND_NAMESPACE(qt_mac_mapDropAction)(qDMEvent.dropAction());
}
QT_PREPEND_NAMESPACE(qt_mac_copy_answer_rect)(qDMEvent);
+ [self changeDraggingCursor:nsActions];
return nsActions;
}
}
@@ -335,16 +359,21 @@ static int qCocoaViewCount = 0;
if (dragEnterSequence != [sender draggingSequenceNumber])
[self draggingEntered:sender];
// drag enter event was rejected, so ignore the move event.
- if (dropData == 0)
+ if (dropData == 0) {
+ [self changeDraggingCursor:NSDragOperationNone];
return NSDragOperationNone;
+ }
// return last value, if we are still in the answerRect.
NSPoint globalPoint = [[sender draggingDestinationWindow] convertBaseToScreen:windowPoint];
NSPoint localPoint = [self convertPoint:windowPoint fromView:nil];
NSDragOperation nsActions = [sender draggingSourceOperationMask];
QPoint posDrag(localPoint.x, localPoint.y);
if (qt_mac_mouse_inside_answer_rect(posDrag)
- && QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastOperation) == nsActions)
- return QT_PREPEND_NAMESPACE(qt_mac_mapDropActions)(QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastAction));
+ && QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastOperation) == nsActions) {
+ NSDragOperation operation = QT_PREPEND_NAMESPACE(qt_mac_mapDropActions)(QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastAction));
+ [self changeDraggingCursor:operation];
+ return operation;
+ }
// send drag move event to the widget
QT_PREPEND_NAMESPACE(qt_mac_dnd_answer_rec.lastOperation) = nsActions;
Qt::DropActions qtAllowed = QT_PREPEND_NAMESPACE(qt_mac_mapNSDragOperations)(nsActions);
@@ -373,6 +402,7 @@ static int qCocoaViewCount = 0;
qDMEvent.setDropAction(Qt::IgnoreAction);
}
qt_mac_copy_answer_rect(qDMEvent);
+ [self changeDraggingCursor:operation];
return operation;
}
@@ -388,6 +418,8 @@ static int qCocoaViewCount = 0;
QApplication::sendEvent(qwidget, &de);
[self removeDropData];
}
+ [self changeDraggingCursor:NSDragOperationEvery];
+
}
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
diff --git a/src/gui/kernel/qcocoaview_mac_p.h b/src/gui/kernel/qcocoaview_mac_p.h
index 33aaa24..b6b63ca 100644
--- a/src/gui/kernel/qcocoaview_mac_p.h
+++ b/src/gui/kernel/qcocoaview_mac_p.h
@@ -106,6 +106,7 @@ Q_GUI_EXPORT
- (void) qt_clearQWidget;
- (BOOL)qt_leftButtonIsRightButton;
- (void)qt_setLeftButtonIsRightButton:(BOOL)isSwapped;
+- (void)changeDraggingCursor:(NSDragOperation)newOperation;
+ (DnDParams*)currentMouseEvent;
@end
diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp
index 8264422..de80f86 100644
--- a/src/gui/kernel/qgesture.cpp
+++ b/src/gui/kernel/qgesture.cpp
@@ -41,6 +41,7 @@
#include "qgesture.h"
#include "private/qgesture_p.h"
+#include "private/qstandardgestures_p.h"
#ifndef QT_NO_GESTURES
@@ -744,6 +745,34 @@ void QTapAndHoldGesture::setPosition(const QPointF &value)
d_func()->position = value;
}
+/*!
+ Set the timeout, in milliseconds, before the gesture triggers.
+
+ The recognizer will detect a touch down and and if \a msecs
+ later the touch is still down, it will trigger the QTapAndHoldGesture.
+ The default value is 700 milliseconds.
+*/
+// static
+void QTapAndHoldGesture::setTimeout(int msecs)
+{
+ QTapAndHoldGesturePrivate::Timeout = msecs;
+}
+
+/*!
+ Gets the timeout, in milliseconds, before the gesture triggers.
+
+ The recognizer will detect a touch down and and if timeout()
+ later the touch is still down, it will trigger the QTapAndHoldGesture.
+ The default value is 700 milliseconds.
+*/
+// static
+int QTapAndHoldGesture::timeout()
+{
+ return QTapAndHoldGesturePrivate::Timeout;
+}
+
+int QTapAndHoldGesturePrivate::Timeout = 700; // in ms
+
QT_END_NAMESPACE
#endif // QT_NO_GESTURES
diff --git a/src/gui/kernel/qgesture.h b/src/gui/kernel/qgesture.h
index 8c10895..8f410b1 100644
--- a/src/gui/kernel/qgesture.h
+++ b/src/gui/kernel/qgesture.h
@@ -252,6 +252,9 @@ public:
QPointF position() const;
void setPosition(const QPointF &pos);
+ static void setTimeout(int msecs);
+ static int timeout();
+
friend class QTapAndHoldGestureRecognizer;
};
diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h
index f5474c1..29b923e 100644
--- a/src/gui/kernel/qgesture_p.h
+++ b/src/gui/kernel/qgesture_p.h
@@ -177,6 +177,7 @@ public:
QPointF position;
int timerId;
+ static int Timeout;
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp
index e43a560..fe9dd8a 100644
--- a/src/gui/kernel/qgesturemanager.cpp
+++ b/src/gui/kernel/qgesturemanager.cpp
@@ -71,7 +71,7 @@
QT_BEGIN_NAMESPACE
QGestureManager::QGestureManager(QObject *parent)
- : QObject(parent), state(NotGesture), m_lastCustomGestureId(0)
+ : QObject(parent), state(NotGesture), m_lastCustomGestureId(Qt::CustomGesture)
{
qRegisterMetaType<Qt::GestureState>();
@@ -119,7 +119,7 @@ Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *r
if (type == Qt::CustomGesture) {
// generate a new custom gesture id
++m_lastCustomGestureId;
- type = Qt::GestureType(Qt::CustomGesture + m_lastCustomGestureId);
+ type = Qt::GestureType(m_lastCustomGestureId);
}
m_recognizers.insertMulti(type, recognizer);
delete dummy;
diff --git a/src/gui/kernel/qguifunctions_wince.cpp b/src/gui/kernel/qguifunctions_wince.cpp
index f5004b0..377dfe3 100644
--- a/src/gui/kernel/qguifunctions_wince.cpp
+++ b/src/gui/kernel/qguifunctions_wince.cpp
@@ -76,6 +76,10 @@ struct AygSIPINFO
#define SHIDIF_SIZEDLGFULLSCREEN 0x0004
#endif
+#ifndef SHDB_HIDE
+#define SHDB_HIDE 0x0002
+#endif
+
#ifndef SHFS_SHOWTASKBAR
#define SHFS_SHOWTASKBAR 0x0001
#endif
@@ -112,10 +116,12 @@ struct AygSIPINFO
typedef BOOL (*AygInitDialog)(AygSHINITDLGINFO*);
typedef BOOL (*AygFullScreen)(HWND, DWORD);
typedef BOOL (*AygSHSipInfo)(UINT, UINT, PVOID, UINT);
+typedef BOOL (*AygSHDoneButton)(HWND, DWORD);
static AygInitDialog ptrAygInitDialog = 0;
static AygFullScreen ptrAygFullScreen = 0;
static AygSHSipInfo ptrAygSHSipInfo = 0;
+static AygSHDoneButton ptrAygSHDoneButton = 0;
static bool aygResolved = false;
static void resolveAygLibs()
@@ -128,18 +134,10 @@ static void resolveAygLibs()
ptrAygInitDialog = (AygInitDialog) ayglib.resolve("SHInitDialog");
ptrAygFullScreen = (AygFullScreen) ayglib.resolve("SHFullScreen");
ptrAygSHSipInfo = (AygSHSipInfo) ayglib.resolve("SHSipInfo");
+ ptrAygSHDoneButton = (AygSHDoneButton) ayglib.resolve("SHDoneButton");
}
}
-struct DIBINFO : public BITMAPINFO
-{
- RGBQUAD arColors[255];
-
- operator LPBITMAPINFO() { return (LPBITMAPINFO) this; }
- operator LPBITMAPINFOHEADER() { return &bmiHeader; }
- RGBQUAD* ColorTable() { return bmiColors; }
-};
-
int qt_wince_GetDIBits(HDC /*hdc*/ , HBITMAP hSourceBitmap, uint, uint, LPVOID lpvBits, LPBITMAPINFO, uint)
{
if (!lpvBits) {
@@ -323,6 +321,8 @@ void qt_wince_maximize(QWidget *widget)
shidi.dwFlags |= SHIDIF_CANCELBUTTON;
if (widget->windowFlags() & Qt::WindowOkButtonHint)
shidi.dwFlags |= SHIDIF_DONEBUTTON;
+ if (!(widget->windowFlags() & (Qt::WindowCancelButtonHint | Qt::WindowOkButtonHint)))
+ shidi.dwFlags |= SHIDIF_CANCELBUTTON;
resolveAygLibs();
if (ptrAygInitDialog)
ptrAygInitDialog(&shidi);
@@ -334,6 +334,16 @@ void qt_wince_maximize(QWidget *widget)
}
}
+void qt_wince_unmaximize(QWidget *widget)
+{
+ if (ptrAygSHDoneButton && qt_wince_is_mobile()
+ && !(widget->windowFlags() & (Qt::WindowCancelButtonHint | Qt::WindowOkButtonHint)))
+ {
+ // Hide the [X] button, we've added in qt_wince_maximize.
+ ptrAygSHDoneButton(widget->winId(), SHDB_HIDE);
+ }
+}
+
void qt_wince_minimize(HWND hwnd)
{
#ifdef Q_OS_WINCE_WM
diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp
index 62d8a53..e05f8cc 100644
--- a/src/gui/kernel/qstandardgestures.cpp
+++ b/src/gui/kernel/qstandardgestures.cpp
@@ -517,7 +517,6 @@ QTapAndHoldGestureRecognizer::recognize(QGesture *state, QObject *object,
const QMouseEvent *me = static_cast<const QMouseEvent *>(event);
const QGraphicsSceneMouseEvent *gsme = static_cast<const QGraphicsSceneMouseEvent *>(event);
- enum { TimerInterval = 2000 };
enum { TapRadius = 40 };
switch (event->type()) {
@@ -526,21 +525,21 @@ QTapAndHoldGestureRecognizer::recognize(QGesture *state, QObject *object,
q->setHotSpot(d->position);
if (d->timerId)
q->killTimer(d->timerId);
- d->timerId = q->startTimer(TimerInterval);
+ d->timerId = q->startTimer(QTapAndHoldGesturePrivate::Timeout);
return QGestureRecognizer::MayBeGesture; // we don't show a sign of life until the timeout
case QEvent::MouseButtonPress:
d->position = me->globalPos();
q->setHotSpot(d->position);
if (d->timerId)
q->killTimer(d->timerId);
- d->timerId = q->startTimer(TimerInterval);
+ d->timerId = q->startTimer(QTapAndHoldGesturePrivate::Timeout);
return QGestureRecognizer::MayBeGesture; // we don't show a sign of life until the timeout
case QEvent::TouchBegin:
d->position = ev->touchPoints().at(0).startScreenPos();
q->setHotSpot(d->position);
if (d->timerId)
q->killTimer(d->timerId);
- d->timerId = q->startTimer(TimerInterval);
+ d->timerId = q->startTimer(QTapAndHoldGesturePrivate::Timeout);
return QGestureRecognizer::MayBeGesture; // we don't show a sign of life until the timeout
case QEvent::GraphicsSceneMouseRelease:
case QEvent::MouseButtonRelease:
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 233df15..fed8d0a 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -338,8 +338,10 @@ QInputContext *QWidgetPrivate::inputContext() const
#ifndef QT_NO_IM
if (ic)
return ic;
-#endif
return qApp->inputContext();
+#else
+ return 0;
+#endif
}
/*!
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index e57ec77..c788711 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -4389,6 +4389,13 @@ void QWidgetPrivate::setGeometry_sys_helper(int x, int y, int w, int h, bool isM
data.window_state = data.window_state & ~Qt::WindowMaximized;
const bool visible = q->isVisible();
+ // Apply size restrictions, applicable for Windows & Widgets.
+ if (QWExtra *extra = extraData()) {
+ w = qMin(w, extra->maxw);
+ h = qMin(h, extra->maxh);
+ w = qMax(w, extra->minw);
+ h = qMax(h, extra->minh);
+ }
data.crect = QRect(x, y, w, h);
if (realWindow) {
diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp
index 0f05c6b..23f57da 100644
--- a/src/gui/kernel/qwidget_win.cpp
+++ b/src/gui/kernel/qwidget_win.cpp
@@ -70,6 +70,7 @@
#include "qguifunctions_wince.h"
QT_USE_NAMESPACE
extern void qt_wince_maximize(QWidget *widget); //defined in qguifunctions_wince.cpp
+extern void qt_wince_unmaximize(QWidget *widget); //defined in qguifunctions_wince.cpp
extern void qt_wince_minimize(HWND hwnd); //defined in qguifunctions_wince.cpp
extern void qt_wince_full_screen(HWND hwnd, bool fullScreen, UINT swpf); //defined in qguifunctions_wince.cpp
extern bool qt_wince_is_mobile(); //defined in qguifunctions_wince.cpp
diff --git a/src/gui/kernel/qwidget_wince.cpp b/src/gui/kernel/qwidget_wince.cpp
index fc1e52c..76532ed 100644
--- a/src/gui/kernel/qwidget_wince.cpp
+++ b/src/gui/kernel/qwidget_wince.cpp
@@ -498,6 +498,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
int style = GetWindowLong(internalWinId(), GWL_STYLE) | WS_BORDER | WS_POPUP | WS_CAPTION;
SetWindowLong(internalWinId(), GWL_STYLE, style);
SetWindowLong(internalWinId(), GWL_EXSTYLE, GetWindowLong (internalWinId(), GWL_EXSTYLE) & ~ WS_EX_NODRAG);
+ qt_wince_unmaximize(this);
}
if (isVisible() && newstate & Qt::WindowMaximized)
qt_wince_maximize(this);
diff --git a/src/gui/styles/qstyle.cpp b/src/gui/styles/qstyle.cpp
index 4cfa93f..687e587 100644
--- a/src/gui/styles/qstyle.cpp
+++ b/src/gui/styles/qstyle.cpp
@@ -2421,9 +2421,10 @@ QT_BEGIN_INCLUDE_NAMESPACE
#include <QDebug>
QT_END_INCLUDE_NAMESPACE
+#if !defined(QT_NO_DEBUG_STREAM)
QDebug operator<<(QDebug debug, QStyle::State state)
{
-#if !defined(QT_NO_DEBUG) && !defined(QT_NO_DEBUG_STREAM)
+#if !defined(QT_NO_DEBUG)
debug << "QStyle::State(";
QStringList states;
@@ -2458,6 +2459,7 @@ QDebug operator<<(QDebug debug, QStyle::State state)
#endif
return debug;
}
+#endif
/*!
\since 4.6
diff --git a/src/gui/styles/qstyle.h b/src/gui/styles/qstyle.h
index 439d626..439901a 100644
--- a/src/gui/styles/qstyle.h
+++ b/src/gui/styles/qstyle.h
@@ -878,7 +878,9 @@ private:
Q_DECLARE_OPERATORS_FOR_FLAGS(QStyle::State)
Q_DECLARE_OPERATORS_FOR_FLAGS(QStyle::SubControls)
+#if !defined(QT_NO_DEBUG_STREAM)
Q_GUI_EXPORT QDebug operator<<(QDebug debug, QStyle::State state);
+#endif
QT_END_NAMESPACE
diff --git a/src/gui/styles/qstyleoption.cpp b/src/gui/styles/qstyleoption.cpp
index c057a2b..4780edf 100644
--- a/src/gui/styles/qstyleoption.cpp
+++ b/src/gui/styles/qstyleoption.cpp
@@ -5419,9 +5419,10 @@ QStyleHintReturnVariant::QStyleHintReturnVariant() : QStyleHintReturn(Version, T
Returns a T or 0 depending on the type of \a hint.
*/
+#if !defined(QT_NO_DEBUG_STREAM)
QDebug operator<<(QDebug debug, const QStyleOption::OptionType &optionType)
{
-#if !defined(QT_NO_DEBUG) && !defined(QT_NO_DEBUG_STREAM)
+#if !defined(QT_NO_DEBUG)
switch (optionType) {
case QStyleOption::SO_Default:
debug << "SO_Default"; break;
@@ -5488,7 +5489,7 @@ QDebug operator<<(QDebug debug, const QStyleOption::OptionType &optionType)
QDebug operator<<(QDebug debug, const QStyleOption &option)
{
-#if !defined(QT_NO_DEBUG) && !defined(QT_NO_DEBUG_STREAM)
+#if !defined(QT_NO_DEBUG)
debug << "QStyleOption(";
debug << QStyleOption::OptionType(option.type);
debug << ',' << (option.direction == Qt::RightToLeft ? "RightToLeft" : "LeftToRight");
@@ -5498,5 +5499,6 @@ QDebug operator<<(QDebug debug, const QStyleOption &option)
#endif
return debug;
}
+#endif
QT_END_NAMESPACE
diff --git a/src/gui/styles/qstyleoption.h b/src/gui/styles/qstyleoption.h
index 95de8d5..e79d9a4 100644
--- a/src/gui/styles/qstyleoption.h
+++ b/src/gui/styles/qstyleoption.h
@@ -958,8 +958,10 @@ T qstyleoption_cast(QStyleHintReturn *hint)
return 0;
}
+#if !defined(QT_NO_DEBUG_STREAM)
Q_GUI_EXPORT QDebug operator<<(QDebug debug, const QStyleOption::OptionType &optionType);
Q_GUI_EXPORT QDebug operator<<(QDebug debug, const QStyleOption &option);
+#endif
QT_END_NAMESPACE
diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp
index daa40a1..769ab2f 100644
--- a/src/gui/text/qtextcursor.cpp
+++ b/src/gui/text/qtextcursor.cpp
@@ -1283,7 +1283,7 @@ void QTextCursor::setVisualNavigation(bool b)
/*!
\since 4.7
- Sets the visual x position for vertical cursor movements.
+ Sets the visual x position for vertical cursor movements to \a x.
The vertical movement x position is cleared automatically when the cursor moves horizontally, and kept
unchanged when the cursor moves vertically. The mechanism allows the cursor to move up and down on a
@@ -1335,8 +1335,8 @@ bool QTextCursor::keepPositionOnInsert() const
Defines whether the cursor should keep its current position when text gets inserted at the current position of the
cursor.
- If \b is true, the cursor keeps its current position when text gets inserted at the positing of the cursor.
- If \b is false, the cursor moves along with the inserted text.
+ If \a b is true, the cursor keeps its current position when text gets inserted at the positing of the cursor.
+ If \a b is false, the cursor moves along with the inserted text.
The default is false.
diff --git a/src/gui/text/qtextoption.cpp b/src/gui/text/qtextoption.cpp
index 8f31e46..9eeec0b 100644
--- a/src/gui/text/qtextoption.cpp
+++ b/src/gui/text/qtextoption.cpp
@@ -392,7 +392,12 @@ QList<QTextOption::Tab> QTextOption::tabs() const
/*!
\fn Tab::Tab(qreal pos, TabType tabType, QChar delim = QChar())
- Creates a tab with the given position, tab type, and (for DelimiterTab) delimiter
+
+ Creates a tab with the given position, tab type, and delimiter
+ (\a pos, \a tabType, \a delim).
+
+ \note \a delim is only used when \a tabType is DelimiterTab.
+
\since 4.7
*/
diff --git a/src/gui/text/qtexttable.cpp b/src/gui/text/qtexttable.cpp
index 5100176..e3985ce 100644
--- a/src/gui/text/qtexttable.cpp
+++ b/src/gui/text/qtexttable.cpp
@@ -754,19 +754,39 @@ void QTextTable::insertColumns(int pos, int num)
QTextFormatCollection *c = p->formatCollection();
p->beginEditBlock();
+ QList<int> extendedSpans;
for (int i = 0; i < d->nRows; ++i) {
int cell;
if (i == d->nRows - 1 && pos == d->nCols)
cell = d->fragment_end;
else
cell = d->grid[i*d->nCols + pos];
- QTextDocumentPrivate::FragmentIterator it(&p->fragmentMap(), cell);
- QTextCharFormat fmt = c->charFormat(it->format);
if (pos > 0 && pos < d->nCols && cell == d->grid[i*d->nCols + pos - 1]) {
// cell spans the insertion place, extend it
- fmt.setTableCellColumnSpan(fmt.tableCellColumnSpan() + num);
- p->setCharFormat(it.position(), 1, fmt);
+ if (!extendedSpans.contains(cell)) {
+ QTextDocumentPrivate::FragmentIterator it(&p->fragmentMap(), cell);
+ QTextCharFormat fmt = c->charFormat(it->format);
+ fmt.setTableCellColumnSpan(fmt.tableCellColumnSpan() + num);
+ p->setCharFormat(it.position(), 1, fmt);
+ d->dirty = true;
+ extendedSpans << cell;
+ }
} else {
+ /* If the next cell is spanned from the row above, we need to find the right position
+ to insert to */
+ if (i > 0 && pos < d->nCols && cell == d->grid[(i-1) * d->nCols + pos]) {
+ int gridIndex = i*d->nCols + pos;
+ const int gridEnd = d->nRows * d->nCols - 1;
+ while (gridIndex < gridEnd && cell == d->grid[gridIndex]) {
+ ++gridIndex;
+ }
+ if (gridIndex == gridEnd)
+ cell = d->fragment_end;
+ else
+ cell = d->grid[gridIndex];
+ }
+ QTextDocumentPrivate::FragmentIterator it(&p->fragmentMap(), cell);
+ QTextCharFormat fmt = c->charFormat(it->format);
fmt.setTableCellRowSpan(1);
fmt.setTableCellColumnSpan(1);
Q_ASSERT(fmt.objectIndex() == objectIndex());
diff --git a/src/gui/util/qcompleter.cpp b/src/gui/util/qcompleter.cpp
index 1abc2d9..04d6de9 100644
--- a/src/gui/util/qcompleter.cpp
+++ b/src/gui/util/qcompleter.cpp
@@ -154,6 +154,7 @@
#include "QtGui/qevent.h"
#include "QtGui/qheaderview.h"
#include "QtGui/qdesktopwidget.h"
+#include "QtGui/qlineedit.h"
QT_BEGIN_NAMESPACE
@@ -920,8 +921,9 @@ void QCompleterPrivate::showPopup(const QRect& rect)
void QCompleterPrivate::_q_fileSystemModelDirectoryLoaded(const QString &path)
{
Q_Q(QCompleter);
+ QLineEdit *lineEdit = qobject_cast<QLineEdit *>(widget);
//the path given by QFileSystemModel does not end with /
- if (!q->completionPrefix().isEmpty() && q->completionPrefix() != path + QLatin1Char('/'))
+ if (lineEdit && !lineEdit->text().isEmpty() && !q->completionPrefix().isEmpty() && q->completionPrefix() != path + QLatin1Char('/'))
q->complete();
}
diff --git a/src/imports/particles/qdeclarativeparticles.cpp b/src/imports/particles/qdeclarativeparticles.cpp
index a7c445d..8fe8a9f 100644
--- a/src/imports/particles/qdeclarativeparticles.cpp
+++ b/src/imports/particles/qdeclarativeparticles.cpp
@@ -158,6 +158,11 @@ void QDeclarativeParticleMotion::destroy(QDeclarativeParticle &particle)
\brief The ParticleMotionLinear object moves particles linearly.
\sa Particles
+
+ This is the default motion, and moves the particles according to the
+ properties specified in the Particles element.
+
+ It has no further properties.
*/
/*!
@@ -178,6 +183,13 @@ void QDeclarativeParticleMotionLinear::advance(QDeclarativeParticle &p, int inte
\since 4.7
\brief The ParticleMotionGravity object moves particles towards a point.
+ This motion attracts the particles to the specified point with the specified acceleration.
+ To mimic earth gravity, set yattractor to -6360000 and acceleration to 9.8.
+
+ The defaults are all 0, not earth gravity, and so no motion will occur without setting
+ at least the acceleration property.
+
+
\sa Particles
*/
@@ -186,6 +198,7 @@ void QDeclarativeParticleMotionLinear::advance(QDeclarativeParticle &p, int inte
\class QDeclarativeParticleMotionGravity
\ingroup group_effects
\brief The QDeclarativeParticleMotionGravity class moves the particles towards a point.
+
*/
/*!
@@ -305,14 +318,14 @@ Rectangle {
*/
/*!
- \qmlproperty real QDeclarativeParticleMotionWander::xvariance
- \qmlproperty real QDeclarativeParticleMotionWander::yvariance
+ \qmlproperty real ParticleMotionWander::xvariance
+ \qmlproperty real ParticleMotionWander::yvariance
These properties set the amount to wander in the x and y directions.
*/
/*!
- \qmlproperty real QDeclarativeParticleMotionWander::pace
+ \qmlproperty real ParticleMotionWander::pace
This property holds how quickly the paricles will move from side to side.
*/
@@ -1232,7 +1245,7 @@ void QDeclarativeParticles::burst(int count, int emissionRate)
void QDeclarativeParticlesPainter::updateSize()
{
- if (!d->_componentComplete)
+ if (!d->componentComplete)
return;
const int parentX = parentItem()->x();
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index 1afabec..9e2b85e 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -286,13 +286,8 @@ bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket
resend = false;
//create the response header to be used with QAuthenticatorPrivate.
- QHttpResponseHeader responseHeader;
QList<QPair<QByteArray, QByteArray> > fields = reply->header();
- QList<QPair<QByteArray, QByteArray> >::const_iterator it = fields.constBegin();
- while (it != fields.constEnd()) {
- responseHeader.addValue(QString::fromLatin1(it->first), QString::fromUtf8(it->second));
- it++;
- }
+
//find out the type of authentication protocol requested.
QAuthenticatorPrivate::Method authMethod = reply->d_func()->authenticationMethod(isProxy);
if (authMethod != QAuthenticatorPrivate::None) {
@@ -310,7 +305,7 @@ bool QHttpNetworkConnectionPrivate::handleAuthenticateChallenge(QAbstractSocket
if (auth->isNull())
auth->detach();
QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(*auth);
- priv->parseHttpResponse(responseHeader, isProxy);
+ priv->parseHttpResponse(fields, isProxy);
if (priv->phase == QAuthenticatorPrivate::Done) {
if ((isProxy && pendingProxyAuthSignal) ||(!isProxy && pendingAuthSignal)) {
diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp
index a6c5c02..f617244 100644
--- a/src/network/access/qnetworkaccesshttpbackend.cpp
+++ b/src/network/access/qnetworkaccesshttpbackend.cpp
@@ -944,10 +944,10 @@ bool QNetworkAccessHttpBackend::sendCacheContents(const QNetworkCacheMetaData &m
checkForRedirect(status);
- emit metaDataChanged();
-
- // invoke this asynchronously, else Arora/QtDemoBrowser don't like cached downloads
- // see task 250221 / 251801
+ // This needs to be emitted in the event loop because it can be reached at
+ // the direct code path of qnam.get(...) before the user has a chance
+ // to connect any signals.
+ QMetaObject::invokeMethod(this, "metaDataChanged", Qt::QueuedConnection);
qRegisterMetaType<QIODevice*>("QIODevice*");
QMetaObject::invokeMethod(this, "writeDownstreamData", Qt::QueuedConnection, Q_ARG(QIODevice*, contents));
diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp
index bccfec1..fa592c2 100644
--- a/src/network/access/qnetworkrequest.cpp
+++ b/src/network/access/qnetworkrequest.cpp
@@ -230,6 +230,14 @@ QT_BEGIN_NAMESPACE
\since 4.7
+ \omitvalue MaximumDownloadBufferSizeAttribute
+ \since 4.7
+ \internal
+
+ \omitvalue DownloadBufferAttribute
+ \since 4.7
+ \internal
+
\value User
Special type. Additional information can be passed in
QVariants with types ranging from User to UserMax. The default
diff --git a/src/network/access/qnetworkrequest.h b/src/network/access/qnetworkrequest.h
index d2945c4..cdadf0f 100644
--- a/src/network/access/qnetworkrequest.h
+++ b/src/network/access/qnetworkrequest.h
@@ -82,6 +82,8 @@ public:
CookieLoadControlAttribute,
AuthenticationReuseAttribute,
CookieSaveControlAttribute,
+ MaximumDownloadBufferSizeAttribute, // internal
+ DownloadBufferAttribute, // internal
User = 1000,
UserMax = 32767
diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp
index e4023c8..d61c686 100644
--- a/src/network/kernel/qauthenticator.cpp
+++ b/src/network/kernel/qauthenticator.cpp
@@ -50,6 +50,8 @@
#include <qdatastream.h>
#include <qendian.h>
#include <qstring.h>
+#include <qdatetime.h>
+
QT_BEGIN_NAMESPACE
@@ -83,6 +85,44 @@ static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phas
Note that, in particular, NTLM version 2 is not supported.
+ \section1 Options
+
+ In addition to the username and password required for authentication, a
+ QAuthenticator object can also contain additional options. The
+ options() function can be used to query incoming options sent by
+ the server; the setOption() function can
+ be used to set outgoing options, to be processed by the authenticator
+ calculation. The options accepted and provided depend on the authentication
+ type (see method()).
+
+ The following tables list known incoming options as well as accepted
+ outgoing options. The list of incoming options is not exhaustive, since
+ servers may include additional information at any time. The list of
+ outgoing options is exhaustive, however, and no unknown options will be
+ treated or sent back to the server.
+
+ \section2 Basic
+
+ \table
+ \header \o Option \o Direction \o Description
+ \row \o \tt{realm} \o Incoming \o Contains the realm of the authentication, the same as realm()
+ \endtable
+
+ The Basic authentication mechanism supports no outgoing options.
+
+ \section2 NTLM version 1
+
+ The NTLM authentication mechanism currently supports no incoming or outgoing options.
+
+ \section2 Digest-MD5
+
+ \table
+ \header \o Option \o Direction \o Description
+ \row \o \tt{realm} \o Incoming \o Contains the realm of the authentication, the same as realm()
+ \endtable
+
+ The Digest-MD5 authentication mechanism supports no outgoing options.
+
\sa QSslSocket
*/
@@ -138,7 +178,8 @@ bool QAuthenticator::operator==(const QAuthenticator &other) const
return d->user == other.d->user
&& d->password == other.d->password
&& d->realm == other.d->realm
- && d->method == other.d->method;
+ && d->method == other.d->method
+ && d->options == other.d->options;
}
/*!
@@ -162,7 +203,18 @@ QString QAuthenticator::user() const
void QAuthenticator::setUser(const QString &user)
{
detach();
- d->user = user;
+
+ int separatorPosn = 0;
+ separatorPosn = user.indexOf(QLatin1String("\\"));
+
+ if (separatorPosn == -1) {
+ //No domain name present
+ d->user = user;
+ } else {
+ //domain name is present
+ d->realm = user.left(separatorPosn);
+ d->user = user.mid(separatorPosn+1);
+ }
}
/*!
@@ -205,9 +257,49 @@ QString QAuthenticator::realm() const
return d ? d->realm : QString();
}
+/*!
+ \since 4.7
+ Returns the value related to option \a opt if it was set by the server.
+ See \l{QAuthenticator#Options} for more information on incoming options.
+ If option \a opt isn't found, an invalid QVariant will be returned.
+
+ \sa options(), QAuthenticator#Options
+*/
+QVariant QAuthenticator::option(const QString &opt) const
+{
+ return d ? d->options.value(opt) : QVariant();
+}
/*!
- returns true if the authenticator is null.
+ \since 4.7
+ Returns all incoming options set in this QAuthenticator object by parsing
+ the server reply. See \l{QAuthenticator#Options} for more information
+ on incoming options.
+
+ \sa option(), QAuthenticator#Options
+*/
+QVariantHash QAuthenticator::options() const
+{
+ return d ? d->options : QVariantHash();
+}
+
+/*!
+ \since 4.7
+
+ Sets the outgoing option \a opt to value \a value.
+ See \l{QAuthenticator#Options} for more information on outgoing options.
+
+ \sa options(), option(), QAuthenticator#Options
+*/
+void QAuthenticator::setOption(const QString &opt, const QVariant &value)
+{
+ detach();
+ d->options.insert(opt, value);
+}
+
+
+/*!
+ Returns true if the authenticator is null.
*/
bool QAuthenticator::isNull() const
{
@@ -228,7 +320,20 @@ QAuthenticatorPrivate::QAuthenticatorPrivate()
#ifndef QT_NO_HTTP
void QAuthenticatorPrivate::parseHttpResponse(const QHttpResponseHeader &header, bool isProxy)
{
- QList<QPair<QString, QString> > values = header.values();
+ const QList<QPair<QString, QString> > values = header.values();
+ QList<QPair<QByteArray, QByteArray> > rawValues;
+
+ QList<QPair<QString, QString> >::const_iterator it, end;
+ for (it = values.constBegin(), end = values.constEnd(); it != end; ++it)
+ rawValues.append(qMakePair(it->first.toLatin1(), it->second.toUtf8()));
+
+ // continue in byte array form
+ parseHttpResponse(rawValues, isProxy);
+}
+#endif
+
+void QAuthenticatorPrivate::parseHttpResponse(const QList<QPair<QByteArray, QByteArray> > &values, bool isProxy)
+{
const char *search = isProxy ? "proxy-authenticate" : "www-authenticate";
method = None;
@@ -242,38 +347,40 @@ void QAuthenticatorPrivate::parseHttpResponse(const QHttpResponseHeader &header,
authentication parameters.
*/
- QString headerVal;
+ QByteArray headerVal;
for (int i = 0; i < values.size(); ++i) {
- const QPair<QString, QString> &current = values.at(i);
- if (current.first.toLower() != QLatin1String(search))
+ const QPair<QByteArray, QByteArray> &current = values.at(i);
+ if (current.first.toLower() != search)
continue;
- QString str = current.second;
- if (method < Basic && str.startsWith(QLatin1String("Basic"), Qt::CaseInsensitive)) {
- method = Basic; headerVal = str.mid(6);
- } else if (method < Ntlm && str.startsWith(QLatin1String("NTLM"), Qt::CaseInsensitive)) {
+ QByteArray str = current.second.toLower();
+ if (method < Basic && str.startsWith("basic")) {
+ method = Basic;
+ headerVal = current.second.mid(6);
+ } else if (method < Ntlm && str.startsWith("ntlm")) {
method = Ntlm;
- headerVal = str.mid(5);
- } else if (method < DigestMd5 && str.startsWith(QLatin1String("Digest"), Qt::CaseInsensitive)) {
+ headerVal = current.second.mid(5);
+ } else if (method < DigestMd5 && str.startsWith("digest")) {
method = DigestMd5;
- headerVal = str.mid(7);
+ headerVal = current.second.mid(7);
}
}
- challenge = headerVal.trimmed().toLatin1();
+ challenge = headerVal.trimmed();
QHash<QByteArray, QByteArray> options = parseDigestAuthenticationChallenge(challenge);
switch(method) {
case Basic:
- realm = QString::fromLatin1(options.value("realm"));
+ if(realm.isEmpty())
+ this->options[QLatin1String("realm")] = realm = QString::fromLatin1(options.value("realm"));
if (user.isEmpty())
phase = Done;
break;
case Ntlm:
// #### extract from header
- realm.clear();
break;
case DigestMd5: {
- realm = QString::fromLatin1(options.value("realm"));
+ if(realm.isEmpty())
+ this->options[QLatin1String("realm")] = realm = QString::fromLatin1(options.value("realm"));
if (options.value("stale").toLower() == "true")
phase = Start;
if (user.isEmpty())
@@ -286,7 +393,6 @@ void QAuthenticatorPrivate::parseHttpResponse(const QHttpResponseHeader &header,
phase = Invalid;
}
}
-#endif
QByteArray QAuthenticatorPrivate::calculateResponse(const QByteArray &requestMethod, const QByteArray &path)
{
@@ -661,6 +767,20 @@ QByteArray QAuthenticatorPrivate::digestMd5Response(const QByteArray &challenge,
*/
#define NTLMSSP_NEGOTIATE_56 0x80000000
+/*
+ * AvId values
+ */
+#define AVTIMESTAMP 7
+
+//#define NTLMV1_CLIENT
+
+
+//************************Global variables***************************
+
+const int blockSize = 64; //As per RFC2104 Block-size is 512 bits
+const int nDigestLen = 16; //Trunctaion Length of the Hmac-Md5 digest
+const quint8 respversion = 1;
+const quint8 hirespversion = 1;
/* usage:
// fill up ctx with what we know.
@@ -803,6 +923,7 @@ public:
// extracted
QString targetNameStr, targetInfoStr;
+ QByteArray targetInfoBuff;
};
@@ -818,6 +939,7 @@ public:
// extracted
QByteArray lmResponseBuf, ntlmResponseBuf;
QString domainStr, userStr, workstationStr, sessionKeyStr;
+ QByteArray v2Hash;
};
@@ -899,7 +1021,7 @@ static QString qStringFromUcs2Le(const QByteArray& src)
return QString((const QChar *)src.data(), src.size()/2);
}
-
+#ifdef NTLMV1_CLIENT
static QByteArray qEncodeNtlmResponse(const QAuthenticatorPrivate *ctx, const QNtlmPhase2Block& ch)
{
QCryptographicHash md4(QCryptographicHash::Md4);
@@ -941,7 +1063,232 @@ static QByteArray qEncodeLmResponse(const QAuthenticatorPrivate *ctx, const QNtl
hash.fill(0);
return rc;
}
+#endif
+
+/*********************************************************************
+* Function Name: qEncodeHmacMd5
+* Params:
+* key: Type - QByteArray
+* - It is the Authentication key
+* message: Type - QByteArray
+* - This is the actual message which will be encoded
+* using HMacMd5 hash algorithm
+*
+* Return Value:
+* hmacDigest: Type - QByteArray
+*
+* Description:
+* This function will be used to encode the input message using
+* HMacMd5 hash algorithm.
+*
+* As per the RFC2104 the HMacMd5 algorithm can be specified
+* ---------------------------------------
+* MD5(K XOR opad, MD5(K XOR ipad, text))
+* ---------------------------------------
+*
+*********************************************************************/
+QByteArray qEncodeHmacMd5(QByteArray &key, const QByteArray &message)
+{
+ Q_ASSERT_X(!(message.isEmpty()),"qEncodeHmacMd5", "Empty message check");
+ Q_ASSERT_X(!(key.isEmpty()),"qEncodeHmacMd5", "Empty key check");
+
+ QCryptographicHash hash(QCryptographicHash::Md5);
+ QByteArray hMsg;
+
+ QByteArray iKeyPad(blockSize, 0x36);
+ QByteArray oKeyPad(blockSize, 0x5c);
+
+ hash.reset();
+ // Adjust the key length to blockSize
+
+ if(blockSize < key.length()) {
+ hash.addData(key);
+ key = hash.result(); //MD5 will always return 16 bytes length output
+ }
+
+ //Key will be <= 16 or 20 bytes as hash function (MD5 or SHA hash algorithms)
+ //key size can be max of Block size only
+ key = key.leftJustified(blockSize,0,true);
+
+ //iKeyPad, oKeyPad and key are all of same size "blockSize"
+
+ //xor of iKeyPad with Key and store the result into iKeyPad
+ for(int i = 0; i<key.size();i++) {
+ iKeyPad[i] = key[i]^iKeyPad[i];
+ }
+
+ //xor of oKeyPad with Key and store the result into oKeyPad
+ for(int i = 0; i<key.size();i++) {
+ oKeyPad[i] = key[i]^oKeyPad[i];
+ }
+
+ iKeyPad.append(message); // (K0 xor ipad) || text
+
+ hash.reset();
+ hash.addData(iKeyPad);
+ hMsg = hash.result();
+ //Digest gen after pass-1: H((K0 xor ipad)||text)
+
+ QByteArray hmacDigest;
+ oKeyPad.append(hMsg);
+ hash.reset();
+ hash.addData(oKeyPad);
+ hmacDigest = hash.result();
+ // H((K0 xor opad )|| H((K0 xor ipad) || text))
+
+ /*hmacDigest should not be less than half the length of the HMAC output
+ (to match the birthday attack bound) and not less than 80 bits
+ (a suitable lower bound on the number of bits that need to be
+ predicted by an attacker).
+ Refer RFC 2104 for more details on truncation part */
+
+ /*MD5 hash always returns 16 byte digest only and HMAC-MD5 spec
+ (RFC 2104) also says digest length should be 16 bytes*/
+ return hmacDigest;
+}
+
+static QByteArray qCreatev2Hash(const QAuthenticatorPrivate *ctx,
+ QNtlmPhase3Block *phase3)
+{
+ Q_ASSERT(phase3 != 0);
+ // since v2 Hash is need for both NTLMv2 and LMv2 it is calculated
+ // only once and stored and reused
+ if(phase3->v2Hash.size() == 0) {
+ QCryptographicHash md4(QCryptographicHash::Md4);
+ QByteArray passUnicode = qStringAsUcs2Le(ctx->password);
+ md4.addData(passUnicode.data(), passUnicode.size());
+
+ QByteArray hashKey = md4.result();
+ Q_ASSERT(hashKey.size() == 16);
+ // Assuming the user and domain is always unicode in challenge
+ QByteArray message =
+ qStringAsUcs2Le(ctx->user.toUpper()) +
+ qStringAsUcs2Le(ctx->realm);
+
+ phase3->v2Hash = qEncodeHmacMd5(hashKey, message);
+ }
+ return phase3->v2Hash;
+}
+
+static QByteArray clientChallenge(const QAuthenticatorPrivate *ctx)
+{
+ Q_ASSERT(ctx->cnonce.size() >= 8);
+ QByteArray clientCh = ctx->cnonce.right(8);
+ return clientCh;
+}
+
+// caller has to ensure a valid targetInfoBuff
+static bool qExtractServerTime(const QByteArray& targetInfoBuff,
+ quint64 *serverTime)
+{
+ Q_ASSERT(serverTime != 0);
+ bool retValue = false;
+ QDataStream ds(targetInfoBuff);
+ ds.setByteOrder(QDataStream::LittleEndian);
+
+ quint16 avId;
+ quint16 avLen;
+
+ ds >> avId;
+ ds >> avLen;
+ while(avId != 0) {
+ if(avId == AVTIMESTAMP) {
+ QByteArray timeArray(avLen, 0);
+ //avLen size of QByteArray is allocated
+ ds.readRawData(timeArray.data(), avLen);
+ bool ok;
+ *serverTime = timeArray.toHex().toLongLong(&ok, 16);
+ retValue = true;
+ break;
+ }
+ ds.skipRawData(avLen);
+ ds >> avId;
+ ds >> avLen;
+ }
+ return retValue;
+}
+
+static QByteArray qEncodeNtlmv2Response(const QAuthenticatorPrivate *ctx,
+ const QNtlmPhase2Block& ch,
+ QNtlmPhase3Block *phase3)
+{
+ Q_ASSERT(phase3 != 0);
+ // return value stored in phase3
+ qCreatev2Hash(ctx, phase3);
+
+ QByteArray temp;
+ QDataStream ds(&temp, QIODevice::WriteOnly);
+ ds.setByteOrder(QDataStream::LittleEndian);
+
+ ds << respversion;
+ ds << hirespversion;
+ //Reserved
+ QByteArray reserved1(6, 0);
+ ds.writeRawData(reserved1.constData(), reserved1.size());
+
+ quint64 time = 0;
+
+ //if server sends time, use it instead of current time
+ if(!(ch.targetInfo.len && qExtractServerTime(ch.targetInfoBuff, &time))) {
+ QDateTime currentTime(QDate::currentDate(),
+ QTime::currentTime(), Qt::UTC);
+
+ // number of seconds between 1601 and epoc(1970)
+ // 369 years, 89 leap years
+ // ((369 * 365) + 89) * 24 * 3600 = 11644473600
+
+ time = Q_UINT64_C(currentTime.toTime_t() + 11644473600);
+
+ // represented as 100 nano seconds
+ time = Q_UINT64_C(time * 10000000);
+ }
+ ds << time;
+
+ //8 byte client challenge
+ QByteArray clientCh = clientChallenge(ctx);
+ ds.writeRawData(clientCh.constData(), clientCh.size());
+
+ //Reserved
+ QByteArray reserved2(4, 0);
+ ds.writeRawData(reserved2.constData(), reserved2.size());
+
+ if (ch.targetInfo.len > 0) {
+ ds.writeRawData(ch.targetInfoBuff.constData(),
+ ch.targetInfoBuff.size());
+ }
+
+ //Reserved
+ QByteArray reserved3(4, 0);
+ ds.writeRawData(reserved3.constData(), reserved3.size());
+
+ QByteArray message((const char*)ch.challenge, sizeof(ch.challenge));
+ message.append(temp);
+
+ QByteArray ntChallengeResp = qEncodeHmacMd5(phase3->v2Hash, message);
+ ntChallengeResp.append(temp);
+
+ return ntChallengeResp;
+}
+
+static QByteArray qEncodeLmv2Response(const QAuthenticatorPrivate *ctx,
+ const QNtlmPhase2Block& ch,
+ QNtlmPhase3Block *phase3)
+{
+ Q_ASSERT(phase3 != 0);
+ // return value stored in phase3
+ qCreatev2Hash(ctx, phase3);
+
+ QByteArray message((const char*)ch.challenge, sizeof(ch.challenge));
+ QByteArray clientCh = clientChallenge(ctx);
+
+ message.append(clientCh);
+
+ QByteArray lmChallengeResp = qEncodeHmacMd5(phase3->v2Hash, message);
+ lmChallengeResp.append(clientCh);
+
+ return lmChallengeResp;
+}
static bool qNtlmDecodePhase2(const QByteArray& data, QNtlmPhase2Block& ch)
{
@@ -976,7 +1323,10 @@ static bool qNtlmDecodePhase2(const QByteArray& data, QNtlmPhase2Block& ch)
}
if (ch.targetInfo.len > 0) {
- // UNUSED right now
+ if (ch.targetInfo.len + ch.targetInfo.offset > (unsigned)data.size())
+ return false;
+
+ ch.targetInfoBuff = data.mid(ch.targetInfo.offset, ch.targetInfo.len);
}
return true;
@@ -996,7 +1346,8 @@ static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phas
bool unicode = ch.flags & NTLMSSP_NEGOTIATE_UNICODE;
- ctx->realm = ch.targetNameStr;
+ if(ctx->realm.isEmpty())
+ ctx->realm = ch.targetNameStr;
pb.flags = NTLMSSP_NEGOTIATE_NTLM;
if (unicode)
@@ -1010,6 +1361,7 @@ static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phas
offset = qEncodeNtlmString(pb.domain, offset, ctx->realm, unicode);
pb.domainStr = ctx->realm;
+
offset = qEncodeNtlmString(pb.user, offset, ctx->user, unicode);
pb.userStr = ctx->user;
@@ -1017,11 +1369,23 @@ static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phas
pb.workstationStr = ctx->workstation;
// Get LM response
+#ifdef NTLMV1_CLIENT
pb.lmResponseBuf = qEncodeLmResponse(ctx, ch);
+#else
+ if (ch.targetInfo.len > 0) {
+ pb.lmResponseBuf = QByteArray();
+ } else {
+ pb.lmResponseBuf = qEncodeLmv2Response(ctx, ch, &pb);
+ }
+#endif
offset = qEncodeNtlmBuffer(pb.lmResponse, offset, pb.lmResponseBuf);
// Get NTLM response
+#ifdef NTLMV1_CLIENT
pb.ntlmResponseBuf = qEncodeNtlmResponse(ctx, ch);
+#else
+ pb.ntlmResponseBuf = qEncodeNtlmv2Response(ctx, ch, &pb);
+#endif
offset = qEncodeNtlmBuffer(pb.ntlmResponse, offset, pb.ntlmResponseBuf);
diff --git a/src/network/kernel/qauthenticator.h b/src/network/kernel/qauthenticator.h
index 13ce593..983b7c0 100644
--- a/src/network/kernel/qauthenticator.h
+++ b/src/network/kernel/qauthenticator.h
@@ -43,6 +43,7 @@
#define QAUTHENTICATOR_H
#include <QtCore/qstring.h>
+#include <QtCore/qvariant.h>
QT_BEGIN_HEADER
@@ -73,6 +74,10 @@ public:
QString realm() const;
+ QVariant option(const QString &opt) const;
+ QVariantHash options() const;
+ void setOption(const QString &opt, const QVariant &value);
+
bool isNull() const;
void detach();
private:
diff --git a/src/network/kernel/qauthenticator_p.h b/src/network/kernel/qauthenticator_p.h
index e9ce9ac..1096601 100644
--- a/src/network/kernel/qauthenticator_p.h
+++ b/src/network/kernel/qauthenticator_p.h
@@ -57,12 +57,13 @@
#include <qbytearray.h>
#include <qstring.h>
#include <qauthenticator.h>
+#include <qvariant.h>
QT_BEGIN_NAMESPACE
class QHttpResponseHeader;
-class QAuthenticatorPrivate
+class Q_AUTOTEST_EXPORT QAuthenticatorPrivate
{
public:
enum Method { None, Basic, Plain, Login, Ntlm, CramMd5, DigestMd5 };
@@ -71,7 +72,7 @@ public:
QAtomicInt ref;
QString user;
QString password;
- QHash<QByteArray, QByteArray> options;
+ QVariantHash options;
Method method;
QString realm;
QByteArray challenge;
@@ -102,6 +103,7 @@ public:
#ifndef QT_NO_HTTP
void parseHttpResponse(const QHttpResponseHeader &, bool isProxy);
#endif
+ void parseHttpResponse(const QList<QPair<QByteArray, QByteArray> >&, bool isProxy);
};
diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp
index 5ae3acc..0bacf90 100644
--- a/src/network/kernel/qhostaddress.cpp
+++ b/src/network/kernel/qhostaddress.cpp
@@ -428,9 +428,9 @@ void QNetmaskAddress::setPrefixLength(QAbstractSocket::NetworkLayerProtocol prot
QHostAddress is normally used with the QTcpSocket, QTcpServer,
and QUdpSocket to connect to a host or to set up a server.
- A host address is set with setAddress(), checked for its type
- using isIPv4Address() or isIPv6Address(), and retrieved with
- toIPv4Address(), toIPv6Address(), or toString().
+ A host address is set with setAddress(), and retrieved with
+ toIPv4Address(), toIPv6Address(), or toString(). You can check the
+ type with protocol().
\note Please note that QHostAddress does not do DNS lookups.
QHostInfo is needed for that.
@@ -679,7 +679,8 @@ void QHostAddress::setAddress(const struct sockaddr *sockaddr)
For example, if the address is 127.0.0.1, the returned value is
2130706433 (i.e. 0x7f000001).
- This value is only valid if isIp4Addr() returns true.
+ This value is only valid if the Protocol() is
+ \l{QAbstractSocket::}{IPv4Protocol}.
\sa toString()
*/
@@ -704,7 +705,8 @@ QAbstractSocket::NetworkLayerProtocol QHostAddress::protocol() const
\snippet doc/src/snippets/code/src_network_kernel_qhostaddress.cpp 0
- This value is only valid if isIPv6Address() returns true.
+ This value is only valid if the protocol() is
+ \l{QAbstractSocket::}{IPv6Protocol}.
\sa toString()
*/
diff --git a/src/network/socket/qtcpserver.cpp b/src/network/socket/qtcpserver.cpp
index 55f926d..0640c7c 100644
--- a/src/network/socket/qtcpserver.cpp
+++ b/src/network/socket/qtcpserver.cpp
@@ -577,7 +577,7 @@ void QTcpServer::incomingConnection(int socketDescriptor)
/*!
This function is called by QTcpServer::incomingConnection()
- to add a socket to the list of pending incoming connections.
+ to add the \a socket to the list of pending incoming connections.
\note Don't forget to call this member from reimplemented
incomingConnection() if you do not want to break the
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index f85fa84..f73068e 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -574,7 +574,7 @@ void QSslSocket::setProtocol(QSsl::SslProtocol protocol)
certificate is valid.
The default mode is AutoVerifyPeer, which tells QSslSocket to use
- VerifyPeer for clients, QueryPeer for clients.
+ VerifyPeer for clients and QueryPeer for servers.
\sa setPeerVerifyMode(), peerVerifyDepth(), mode()
*/
@@ -594,7 +594,7 @@ QSslSocket::PeerVerifyMode QSslSocket::peerVerifyMode() const
certificate is valid.
The default mode is AutoVerifyPeer, which tells QSslSocket to use
- VerifyPeer for clients, QueryPeer for clients.
+ VerifyPeer for clients and QueryPeer for servers.
Setting this mode after encryption has started has no effect on the
current connection.
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 1d794ae..c297eea 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -475,27 +475,12 @@ bool QSslSocketPrivate::ensureLibraryLoaded()
void QSslSocketPrivate::ensureCiphersAndCertsLoaded()
{
+ QMutexLocker locker(openssl_locks()->initLock());
if (s_loadedCiphersAndCerts)
return;
s_loadedCiphersAndCerts = true;
resetDefaultCiphers();
- setDefaultCaCertificates(systemCaCertificates());
-}
-
-/*!
- \internal
-
- Declared static in QSslSocketPrivate, makes sure the SSL libraries have
- been initialized.
-*/
-
-void QSslSocketPrivate::ensureInitialized()
-{
- if (!supportsSsl())
- return;
-
- ensureCiphersAndCertsLoaded();
//load symbols needed to receive certificates from system store
#if defined(Q_OS_MAC)
@@ -532,6 +517,22 @@ void QSslSocketPrivate::ensureInitialized()
qWarning("could not load crypt32 library"); // should never happen
}
#endif
+ setDefaultCaCertificates(systemCaCertificates());
+}
+
+/*!
+ \internal
+
+ Declared static in QSslSocketPrivate, makes sure the SSL libraries have
+ been initialized.
+*/
+
+void QSslSocketPrivate::ensureInitialized()
+{
+ if (!supportsSsl())
+ return;
+
+ ensureCiphersAndCertsLoaded();
}
/*!
@@ -970,8 +971,20 @@ void QSslSocketBackendPrivate::transmit()
#endif
plainSocket->disconnectFromHost();
break;
+ case SSL_ERROR_SYSCALL: // some IO error
+ case SSL_ERROR_SSL: // error in the SSL library
+ // we do not know exactly what the error is, nor whether we can recover from it,
+ // so just return to prevent an endless loop in the outer "while" statement
+ q->setErrorString(QSslSocket::tr("Error while reading: %1").arg(SSL_ERRORSTR()));
+ q->setSocketError(QAbstractSocket::UnknownSocketError);
+ emit q->error(QAbstractSocket::UnknownSocketError);
+ return;
default:
- // ### Handle errors better.
+ // SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT: can only happen with a
+ // BIO_s_connect() or BIO_s_accept(), which we do not call.
+ // SSL_ERROR_WANT_X509_LOOKUP: can only happen with a
+ // SSL_CTX_set_client_cert_cb(), which we do not call.
+ // So this default case should never be triggered.
q->setErrorString(QSslSocket::tr("Error while reading: %1").arg(SSL_ERRORSTR()));
q->setSocketError(QAbstractSocket::UnknownSocketError);
emit q->error(QAbstractSocket::UnknownSocketError);
@@ -1105,17 +1118,16 @@ bool QSslSocketBackendPrivate::startHandshake()
QString peerName = (verificationPeerName.isEmpty () ? q->peerName() : verificationPeerName);
QString commonName = configuration.peerCertificate.subjectInfo(QSslCertificate::CommonName);
- QRegExp regexp(commonName, Qt::CaseInsensitive, QRegExp::Wildcard);
- if (!regexp.exactMatch(peerName)) {
+ if (!isMatchingHostname(commonName.toLower(), peerName.toLower())) {
bool matched = false;
foreach (const QString &altName, configuration.peerCertificate
.alternateSubjectNames().values(QSsl::DnsEntry)) {
- regexp.setPattern(altName);
- if (regexp.exactMatch(peerName)) {
+ if (isMatchingHostname(altName.toLower(), peerName.toLower())) {
matched = true;
break;
}
}
+
if (!matched) {
// No matches in common names or alternate names.
QSslError error(QSslError::HostNameMismatch, configuration.peerCertificate);
@@ -1245,4 +1257,39 @@ QList<QSslCertificate> QSslSocketBackendPrivate::STACKOFX509_to_QSslCertificates
return certificates;
}
+bool QSslSocketBackendPrivate::isMatchingHostname(const QString &cn, const QString &hostname)
+{
+ int wildcard = cn.indexOf(QLatin1Char('*'));
+
+ // Check this is a wildcard cert, if not then just compare the strings
+ if (wildcard < 0)
+ return cn == hostname;
+
+ int firstCnDot = cn.indexOf(QLatin1Char('.'));
+ int secondCnDot = cn.indexOf(QLatin1Char('.'), firstCnDot+1);
+
+ // Check at least 3 components
+ if ((-1 == secondCnDot) || (secondCnDot+1 >= cn.length()))
+ return false;
+
+ // Check * is last character of 1st component (ie. there's a following .)
+ if (wildcard+1 != firstCnDot)
+ return false;
+
+ // Check only one star
+ if (cn.lastIndexOf(QLatin1Char('*')) != wildcard)
+ return false;
+
+ // Check characters preceding * (if any) match
+ if (wildcard && (hostname.leftRef(wildcard) != cn.leftRef(wildcard)))
+ return false;
+
+ // Check characters following first . match
+ if (hostname.midRef(hostname.indexOf(QLatin1Char('.'))) != cn.midRef(firstCnDot))
+ return false;
+
+ // Ok, I guess this was a wildcard CN and the hostname matches.
+ return true;
+}
+
QT_END_NAMESPACE
diff --git a/src/network/ssl/qsslsocket_openssl_p.h b/src/network/ssl/qsslsocket_openssl_p.h
index 987dfae..7a4e6b6 100644
--- a/src/network/ssl/qsslsocket_openssl_p.h
+++ b/src/network/ssl/qsslsocket_openssl_p.h
@@ -116,6 +116,7 @@ public:
static QSslCipher QSslCipher_from_SSL_CIPHER(SSL_CIPHER *cipher);
static QList<QSslCertificate> STACKOFX509_to_QSslCertificates(STACK_OF(X509) *x509);
+ Q_AUTOTEST_EXPORT static bool isMatchingHostname(const QString &cn, const QString &hostname);
};
#if defined(Q_OS_SYMBIAN)
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index ee49a3d..d3f6a29 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -1128,7 +1128,7 @@ void QGL2PaintEngineEx::fill(const QVectorPath &path, const QBrush &brush)
d->fill(path);
}
-extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp
+extern Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp
void QGL2PaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index fc28a73..2fa33bf 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -1334,6 +1334,10 @@ QGLFormat::OpenGLVersionFlags Q_AUTOTEST_EXPORT qOpenGLVersionFlagsFromString(co
\value OpenGL_Version_3_2 OpenGL version 3.2 or higher is present.
+ \value OpenGL_Version_3_3 OpenGL version 3.3 or higher is present.
+
+ \value OpenGL_Version_4_0 OpenGL version 4.0 or higher is present.
+
\value OpenGL_ES_CommonLite_Version_1_0 OpenGL ES version 1.0 Common Lite or higher is present.
\value OpenGL_ES_Common_Version_1_0 OpenGL ES version 1.0 Common or higher is present.
@@ -5037,8 +5041,9 @@ void QGLWidget::deleteTexture(QMacCompatGLuint id)
/*!
\since 4.4
- Calls the corresponding QGLContext::drawTexture() on
- this widget's context.
+ Calls the corresponding QGLContext::drawTexture() with
+ \a target, \a textureId, and \a textureTarget for this
+ widget's context.
*/
void QGLWidget::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget)
{
@@ -5058,8 +5063,9 @@ void QGLWidget::drawTexture(const QRectF &target, QMacCompatGLuint textureId, QM
/*!
\since 4.4
- Calls the corresponding QGLContext::drawTexture() on
- this widget's context.
+ Calls the corresponding QGLContext::drawTexture() with
+ \a point, \a textureId, and \a textureTarget for this
+ widget's context.
*/
void QGLWidget::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget)
{
diff --git a/src/plugins/sqldrivers/db2/db2.pro b/src/plugins/sqldrivers/db2/db2.pro
index 5223beb..e053f37 100644
--- a/src/plugins/sqldrivers/db2/db2.pro
+++ b/src/plugins/sqldrivers/db2/db2.pro
@@ -1,10 +1,6 @@
-TARGET = qsqldb2
+TARGET = qsqldb2
-HEADERS = ../../../sql/drivers/db2/qsql_db2.h
-SOURCES = main.cpp \
- ../../../sql/drivers/db2/qsql_db2.cpp
-
-unix:!contains( LIBS, .*db2.* ):LIBS *= -ldb2
-win32:!contains( LIBS, .*db2.* ):LIBS *= -ldb2cli
+SOURCES = main.cpp
+include(../../../sql/drivers/db2/qsql_db2.pri)
include(../qsqldriverbase.pri)
diff --git a/src/plugins/sqldrivers/ibase/ibase.pro b/src/plugins/sqldrivers/ibase/ibase.pro
index ec2bc7b..7870ec8 100644
--- a/src/plugins/sqldrivers/ibase/ibase.pro
+++ b/src/plugins/sqldrivers/ibase/ibase.pro
@@ -1,14 +1,6 @@
-TARGET = qsqlibase
+TARGET = qsqlibase
-HEADERS = ../../../sql/drivers/ibase/qsql_ibase.h
-SOURCES = main.cpp \
- ../../../sql/drivers/ibase/qsql_ibase.cpp
-
-unix:!contains( LIBS, .*gds.* ):!contains( LIBS, .*libfb.* ):LIBS *= -lgds
-
-win32:!contains( LIBS, .*gds.* ):!contains( LIBS, .*fbclient.* ) {
- !win32-borland:LIBS *= -lgds32_ms
- win32-borland:LIBS += gds32.lib
-}
+SOURCES = main.cpp
+include(../../../sql/drivers/ibase/qsql_ibase.pri)
include(../qsqldriverbase.pri)
diff --git a/src/plugins/sqldrivers/mysql/mysql.pro b/src/plugins/sqldrivers/mysql/mysql.pro
index 9f5c619..b6d42ff 100644
--- a/src/plugins/sqldrivers/mysql/mysql.pro
+++ b/src/plugins/sqldrivers/mysql/mysql.pro
@@ -1,23 +1,6 @@
-TARGET = qsqlmysql
+TARGET = qsqlmysql
-HEADERS = ../../../sql/drivers/mysql/qsql_mysql.h
-SOURCES = main.cpp \
- ../../../sql/drivers/mysql/qsql_mysql.cpp
-
-unix: {
- isEmpty(QT_LFLAGS_MYSQL) {
- !contains(LIBS, .*mysqlclient.*):!contains(LIBS, .*mysqld.*) {
- use_libmysqlclient_r:LIBS *= -lmysqlclient_r
- else:LIBS *= -lmysqlclient
- }
- } else {
- LIBS *= $$QT_LFLAGS_MYSQL
- QMAKE_CXXFLAGS *= $$QT_CFLAGS_MYSQL
- }
-}
-
-win32:!contains(LIBS, .*mysql.*):!contains(LIBS, .*mysqld.*) {
- LIBS *= -llibmysql
-}
+SOURCES = main.cpp
+include(../../../sql/drivers/mysql/qsql_mysql.pri)
include(../qsqldriverbase.pri)
diff --git a/src/plugins/sqldrivers/oci/oci.pro b/src/plugins/sqldrivers/oci/oci.pro
index 3bf70a1..d7dcce9 100644
--- a/src/plugins/sqldrivers/oci/oci.pro
+++ b/src/plugins/sqldrivers/oci/oci.pro
@@ -1,13 +1,6 @@
-TARGET = qsqloci
+TARGET = qsqloci
-HEADERS = ../../../sql/drivers/oci/qsql_oci.h
-SOURCES = main.cpp \
- ../../../sql/drivers/oci/qsql_oci.cpp
-
-win32:LIBS *= -loci
-
-unix:!contains( LIBS, .*clnts.* ):LIBS *= -lclntsh
-
-macx:QMAKE_LFLAGS += -Wl,-flat_namespace,-U,_environ
+SOURCES = main.cpp
+include(../../../sql/drivers/oci/qsql_oci.pri)
include(../qsqldriverbase.pri)
diff --git a/src/plugins/sqldrivers/odbc/odbc.pro b/src/plugins/sqldrivers/odbc/odbc.pro
index 2bf85f1..677eb6e 100644
--- a/src/plugins/sqldrivers/odbc/odbc.pro
+++ b/src/plugins/sqldrivers/odbc/odbc.pro
@@ -1,19 +1,6 @@
-TARGET = qsqlodbc
+TARGET = qsqlodbc
-HEADERS = ../../../sql/drivers/odbc/qsql_odbc.h
-SOURCES = main.cpp \
- ../../../sql/drivers/odbc/qsql_odbc.cpp
-
-unix {
- !contains( LIBS, .*odbc.* ) {
- LIBS *= $$QT_LFLAGS_ODBC
- }
- DEFINES += UNICODE
-}
-
-win32 {
- !win32-borland:LIBS *= -lodbc32
- win32-borland:LIBS *= $(BCB)/lib/PSDK/odbc32.lib
-}
+SOURCES = main.cpp
+include(../../../sql/drivers/odbc/qsql_odbc.pri)
include(../qsqldriverbase.pri)
diff --git a/src/plugins/sqldrivers/psql/psql.pro b/src/plugins/sqldrivers/psql/psql.pro
index 80a5348..8276c0a 100644
--- a/src/plugins/sqldrivers/psql/psql.pro
+++ b/src/plugins/sqldrivers/psql/psql.pro
@@ -1,18 +1,6 @@
-TARGET = qsqlpsql
+TARGET = qsqlpsql
-HEADERS = ../../../sql/drivers/psql/qsql_psql.h
-SOURCES = main.cpp \
- ../../../sql/drivers/psql/qsql_psql.cpp
-
-unix|win32-g++*: {
- !isEmpty(QT_LFLAGS_PSQL) {
- !contains(QT_CONFIG, system-zlib): QT_LFLAGS_PSQL -= -lz
- !static:LIBS *= $$QT_LFLAGS_PSQL
- QMAKE_CXXFLAGS *= $$QT_CFLAGS_PSQL
- }
- !contains(LIBS, .*pq.*):LIBS *= -lpq
-}
-
-win32:!win32-g++*:!contains(LIBS, .*pq.* ) LIBS *= -llibpq -lws2_32 -ladvapi32
+SOURCES = main.cpp
+include(../../../sql/drivers/psql/qsql_psql.pri)
include(../qsqldriverbase.pri)
diff --git a/src/plugins/sqldrivers/sqlite/sqlite.pro b/src/plugins/sqldrivers/sqlite/sqlite.pro
index fb31233..f4c1671 100644
--- a/src/plugins/sqldrivers/sqlite/sqlite.pro
+++ b/src/plugins/sqldrivers/sqlite/sqlite.pro
@@ -1,18 +1,7 @@
-TARGET = qsqlite
+TARGET = qsqlite
-HEADERS = ../../../sql/drivers/sqlite/qsql_sqlite.h
-SOURCES = smain.cpp \
- ../../../sql/drivers/sqlite/qsql_sqlite.cpp
-
-!system-sqlite:!contains( LIBS, .*sqlite.* ) {
- CONFIG(release, debug|release):DEFINES *= NDEBUG
- DEFINES += SQLITE_OMIT_LOAD_EXTENSION SQLITE_OMIT_COMPLETE
- INCLUDEPATH += ../../../3rdparty/sqlite
- SOURCES += ../../../3rdparty/sqlite/sqlite3.c
-} else {
- LIBS *= $$QT_LFLAGS_SQLITE
- QMAKE_CXXFLAGS *= $$QT_CFLAGS_SQLITE
-}
+SOURCES = smain.cpp
+include(../../../sql/drivers/sqlite/qsql_sqlite.pri)
wince*: DEFINES += HAVE_LOCALTIME_S=0
diff --git a/src/plugins/sqldrivers/sqlite2/sqlite2.pro b/src/plugins/sqldrivers/sqlite2/sqlite2.pro
index 88db22a..e6197b9 100644
--- a/src/plugins/sqldrivers/sqlite2/sqlite2.pro
+++ b/src/plugins/sqldrivers/sqlite2/sqlite2.pro
@@ -1,9 +1,6 @@
-TARGET = qsqlite2
+TARGET = qsqlite2
-HEADERS = ../../../sql/drivers/sqlite2/qsql_sqlite2.h
-SOURCES = smain.cpp \
- ../../../sql/drivers/sqlite2/qsql_sqlite2.cpp
-
-!contains(LIBS, .*sqlite.*):LIBS *= -lsqlite
+SOURCES = smain.cpp
+include(../../../sql/drivers/sqlite2/qsql_sqlite2.pri)
include(../qsqldriverbase.pri)
diff --git a/src/plugins/sqldrivers/tds/tds.pro b/src/plugins/sqldrivers/tds/tds.pro
index 08a166b..b8e8ded 100644
--- a/src/plugins/sqldrivers/tds/tds.pro
+++ b/src/plugins/sqldrivers/tds/tds.pro
@@ -1,15 +1,6 @@
-TARGET = qsqltds
+TARGET = qsqltds
-HEADERS = ../../../sql/drivers/tds/qsql_tds.h
-
-SOURCES = main.cpp \
- ../../../sql/drivers/tds/qsql_tds.cpp
-
-unix:!contains( LIBS, .*sybdb.* ):LIBS *= -lsybdb
-
-win32 {
- !win32-borland:LIBS *= -lNTWDBLIB
- win32-borland:LIBS *= $(BCB)/lib/PSDK/NTWDBLIB.LIB
-}
+SOURCES = main.cpp
+include(../../../sql/drivers/tds/qsql_tds.pri)
include(../qsqldriverbase.pri)
diff --git a/src/s60installs/bwins/QtDeclarativeu.def b/src/s60installs/bwins/QtDeclarativeu.def
index e96f83f..8fdd72c 100644
--- a/src/s60installs/bwins/QtDeclarativeu.def
+++ b/src/s60installs/bwins/QtDeclarativeu.def
@@ -1675,4 +1675,5 @@ EXPORTS
?setBindingForObject@QDeclarativeEngineDebug@@QAE_NHABVQString@@ABVQVariant@@_N@Z @ 1674 NONAME ; bool QDeclarativeEngineDebug::setBindingForObject(int, class QString const &, class QVariant const &, bool)
??0QDeclarativeImageProvider@@QAE@W4ImageType@0@@Z @ 1675 NONAME ; QDeclarativeImageProvider::QDeclarativeImageProvider(enum QDeclarativeImageProvider::ImageType)
?setMethodBody@QDeclarativeEngineDebug@@QAE_NHABVQString@@0@Z @ 1676 NONAME ; bool QDeclarativeEngineDebug::setMethodBody(int, class QString const &, class QString const &)
+ ?resetBindingForObject@QDeclarativeEngineDebug@@QAE_NHABVQString@@@Z @ 1677 NONAME ; bool QDeclarativeEngineDebug::resetBindingForObject(int, class QString const &)
diff --git a/src/s60installs/eabi/QtDeclarativeu.def b/src/s60installs/eabi/QtDeclarativeu.def
index 083e07f..dd5103f 100644
--- a/src/s60installs/eabi/QtDeclarativeu.def
+++ b/src/s60installs/eabi/QtDeclarativeu.def
@@ -1706,4 +1706,5 @@ EXPORTS
_ZN25QDeclarativeImageProviderC1ENS_9ImageTypeE @ 1705 NONAME
_ZN25QDeclarativeImageProviderC2ENS_9ImageTypeE @ 1706 NONAME
_ZNK25QDeclarativeImageProvider9imageTypeEv @ 1707 NONAME
+ _ZN23QDeclarativeEngineDebug21resetBindingForObjectEiRK7QString @ 1708 NONAME
diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp
index 451d1b0..f6390bb 100644
--- a/src/script/api/qscriptvalue.cpp
+++ b/src/script/api/qscriptvalue.cpp
@@ -1268,6 +1268,7 @@ QDateTime QScriptValue::toDateTime() const
Q_D(const QScriptValue);
if (!d || !d->engine)
return QDateTime();
+ QScript::APIShim shim(d->engine);
return QScriptEnginePrivate::toDateTime(d->engine->currentFrame, d->jscValue);
}
@@ -1284,6 +1285,7 @@ QRegExp QScriptValue::toRegExp() const
Q_D(const QScriptValue);
if (!d || !d->engine)
return QRegExp();
+ QScript::APIShim shim(d->engine);
return QScriptEnginePrivate::toRegExp(d->engine->currentFrame, d->jscValue);
}
#endif // QT_NO_REGEXP
@@ -1303,6 +1305,7 @@ QObject *QScriptValue::toQObject() const
Q_D(const QScriptValue);
if (!d || !d->engine)
return 0;
+ QScript::APIShim shim(d->engine);
return QScriptEnginePrivate::toQObject(d->engine->currentFrame, d->jscValue);
}
@@ -1317,6 +1320,7 @@ const QMetaObject *QScriptValue::toQMetaObject() const
Q_D(const QScriptValue);
if (!d || !d->engine)
return 0;
+ QScript::APIShim shim(d->engine);
return QScriptEnginePrivate::toQMetaObject(d->engine->currentFrame, d->jscValue);
}
@@ -1407,6 +1411,7 @@ QScriptValue QScriptValue::property(quint32 arrayIndex,
Q_D(const QScriptValue);
if (!d || !d->isObject())
return QScriptValue();
+ QScript::APIShim shim(d->engine);
return d->engine->scriptValueFromJSCValue(d->property(arrayIndex, mode));
}
@@ -1434,6 +1439,7 @@ void QScriptValue::setProperty(quint32 arrayIndex, const QScriptValue &value,
"cannot set value created in a different engine");
return;
}
+ QScript::APIShim shim(d->engine);
JSC::JSValue jsValue = d->engine->scriptValueToJSCValue(value);
d->setProperty(arrayIndex, jsValue, flags);
}
diff --git a/src/sql/drivers/db2/qsql_db2.pri b/src/sql/drivers/db2/qsql_db2.pri
new file mode 100644
index 0000000..16557f0
--- /dev/null
+++ b/src/sql/drivers/db2/qsql_db2.pri
@@ -0,0 +1,8 @@
+HEADERS += $$PWD/qsql_db2.h
+SOURCES += $$PWD/qsql_db2.cpp
+
+unix {
+ !contains(LIBS, .*db2.*):LIBS += -ldb2
+} else:!win32-borland {
+ !contains(LIBS, .*db2.*):LIBS += -ldb2cli
+}
diff --git a/src/sql/drivers/drivers.pri b/src/sql/drivers/drivers.pri
index 05e7265..87cc0b1 100644
--- a/src/sql/drivers/drivers.pri
+++ b/src/sql/drivers/drivers.pri
@@ -1,119 +1,11 @@
-contains(sql-drivers, all ) {
- sql-driver += psql mysql odbc oci tds db2 sqlite ibase
-}
-
-contains(sql-drivers, psql) {
- HEADERS += drivers/psql/qsql_psql.h
- SOURCES += drivers/psql/qsql_psql.cpp
-
- unix|win32-g++* {
- !static:!isEmpty(QT_LFLAGS_PSQL) {
- !contains(QT_CONFIG, system-zlib): QT_LFLAGS_PSQL -= -lz
- !static:LIBS *= $$QT_LFLAGS_PSQL
- QMAKE_CXXFLAGS *= $$QT_CFLAGS_PSQL
- }
- !contains(LIBS, .*pq.*):LIBS *= -lpq
- } else:win32:!contains(LIBS, .*pq.* ) LIBS *= -llibpq -lws2_32 -ladvapi32
-}
-
-contains(sql-drivers, mysql) {
- HEADERS += drivers/mysql/qsql_mysql.h
- SOURCES += drivers/mysql/qsql_mysql.cpp
-
- unix {
- isEmpty(QT_LFLAGS_MYSQL) {
- !contains(LIBS, .*mysqlclient.*):!contains(LIBS, .*mysqld.*) {
- use_libmysqlclient_r:LIBS *= -lmysqlclient_r
- else:LIBS *= -lmysqlclient
- }
- } else {
- LIBS *= $$QT_LFLAGS_MYSQL
- QMAKE_CXXFLAGS *= $$QT_CFLAGS_MYSQL
- }
- }
-
- win32:!contains(LIBS, .*mysql.*):!contains(LIBS, .*mysqld.*) {
- !win32-g++*:LIBS *= -llibmysql
- else:LIBS *= -lmysql
- }
-}
-
-contains(sql-drivers, odbc) {
- HEADERS += drivers/odbc/qsql_odbc.h
- SOURCES += drivers/odbc/qsql_odbc.cpp
-
- mac:!contains( LIBS, .*odbc.* ):LIBS *= -liodbc
- unix:!contains( LIBS, .*odbc.* ):LIBS *= -lodbc
- unix:DEFINES += UNICODE
-
- win32 {
- !win32-borland:LIBS *= -lodbc32
- else:LIBS *= $(BCB)/lib/PSDK/odbc32.lib
- }
-}
-
-contains(sql-drivers, oci) {
- HEADERS += drivers/oci/qsql_oci.h
- SOURCES += drivers/oci/qsql_oci.cpp
-
- unix:!contains( LIBS, .*clnts.* ):LIBS += -lclntsh
-
- win32:LIBS += -loci
-}
-
-contains(sql-drivers, tds) {
- HEADERS += drivers/tds/qsql_tds.h
- SOURCES += drivers/tds/qsql_tds.cpp
-
- unix:LIBS += -L$SYBASE/lib -lsybdb
-
- win32 {
- !win32-borland:LIBS += -lNTWDBLIB
- else:LIBS += $(BCB)/lib/PSDK/NTWDBLIB.LIB
- }
-}
-
-contains(sql-drivers, db2) {
- HEADERS += drivers/db2/qsql_db2.h
- SOURCES += drivers/db2/qsql_db2.cpp
-
- unix:LIBS += -ldb2
-
- win32 {
- !win32-borland:LIBS += -ldb2cli
-# else:LIBS += $(BCB)/lib/PSDK/db2cli.lib
- }
-}
-
-contains(sql-drivers, ibase) {
- HEADERS += drivers/ibase/qsql_ibase.h
- SOURCES += drivers/ibase/qsql_ibase.cpp
-
- unix:LIBS *= -lgds
-
- win32 {
- !win32-borland:LIBS *= -lgds32_ms
- else:LIBS += gds32.lib
- }
-}
-
-contains(sql-drivers, sqlite2) {
- HEADERS += drivers/sqlite2/qsql_sqlite2.h
- SOURCES += drivers/sqlite2/qsql_sqlite2.cpp
- !contains(LIBS, .*sqlite.*):LIBS *= -lsqlite
-}
-
-contains(sql-drivers, sqlite) {
- !system-sqlite:!contains( LIBS, .*sqlite3.* ) {
- CONFIG(release, debug|release):DEFINES *= NDEBUG
- DEFINES += SQLITE_OMIT_LOAD_EXTENSION SQLITE_OMIT_COMPLETE
- INCLUDEPATH += ../3rdparty/sqlite
- SOURCES += ../3rdparty/sqlite/sqlite3.c
- } else {
- LIBS *= $$QT_LFLAGS_SQLITE
- QMAKE_CXXFLAGS *= $$QT_CFLAGS_SQLITE
- }
-
- HEADERS += drivers/sqlite/qsql_sqlite.h
- SOURCES += drivers/sqlite/qsql_sqlite.cpp
-}
+contains(sql-drivers, all):sql-driver += psql mysql odbc oci tds db2 sqlite ibase
+
+contains(sql-drivers, psql):include($$PWD/psql/qsql_psql.pri)
+contains(sql-drivers, mysql):include($$PWD/mysql/qsql_mysql.pri)
+contains(sql-drivers, odbc):include($$PWD/odbc/qsql_odbc.pri)
+contains(sql-drivers, oci):include($$PWD/oci/qsql_oci.pri)
+contains(sql-drivers, tds):include($$PWD/tds/qsql_tds.pri)
+contains(sql-drivers, db2):include($$PWD/db2/qsql_db2.pri)
+contains(sql-drivers, ibase):include($$PWD/ibase/qsql_ibase.pri)
+contains(sql-drivers, sqlite2):include($$PWD/sqlite2/qsql_sqlite2.pri)
+contains(sql-drivers, sqlite):include($$PWD/sqlite/qsql_sqlite.pri)
diff --git a/src/sql/drivers/ibase/qsql_ibase.pri b/src/sql/drivers/ibase/qsql_ibase.pri
new file mode 100644
index 0000000..33fbb0d
--- /dev/null
+++ b/src/sql/drivers/ibase/qsql_ibase.pri
@@ -0,0 +1,11 @@
+HEADERS += $$PWD/qsql_ibase.h
+SOURCES += $$PWD/qsql_ibase.cpp
+
+unix {
+ !contains(LIBS, .*gds.*):!contains(LIBS, .*libfb.*):LIBS += -lgds
+} else {
+ !contains(LIBS, .*gds.*):!contains(LIBS, .*fbclient.*) {
+ win32-borland:LIBS += gds32.lib
+ else:LIBS += -lgds32_ms
+ }
+}
diff --git a/src/sql/drivers/mysql/qsql_mysql.pri b/src/sql/drivers/mysql/qsql_mysql.pri
new file mode 100644
index 0000000..1b9c3dd
--- /dev/null
+++ b/src/sql/drivers/mysql/qsql_mysql.pri
@@ -0,0 +1,16 @@
+HEADERS += $$PWD/qsql_mysql.h
+SOURCES += $$PWD/qsql_mysql.cpp
+
+unix {
+ isEmpty(QT_LFLAGS_MYSQL) {
+ !contains(LIBS, .*mysqlclient.*):!contains(LIBS, .*mysqld.*) {
+ use_libmysqlclient_r:LIBS += -lmysqlclient_r
+ else:LIBS += -lmysqlclient
+ }
+ } else {
+ LIBS *= $$QT_LFLAGS_MYSQL
+ QMAKE_CXXFLAGS *= $$QT_CFLAGS_MYSQL
+ }
+} else {
+ !contains(LIBS, .*mysql.*):!contains(LIBS, .*mysqld.*):LIBS += -llibmysql
+}
diff --git a/src/sql/drivers/oci/qsql_oci.cpp b/src/sql/drivers/oci/qsql_oci.cpp
index 2f0cfdc..c56b995 100644
--- a/src/sql/drivers/oci/qsql_oci.cpp
+++ b/src/sql/drivers/oci/qsql_oci.cpp
@@ -648,7 +648,7 @@ QByteArray qMakeOraDate(const QDateTime& dt)
QDateTime qMakeDate(const char* oraDate)
{
- int century = oraDate[0];
+ int century = uchar(oraDate[0]);
if(century >= 100){
int year = uchar(oraDate[1]);
year = ((century-100)*100) + (year-100);
diff --git a/src/sql/drivers/oci/qsql_oci.pri b/src/sql/drivers/oci/qsql_oci.pri
new file mode 100644
index 0000000..60ccc4c
--- /dev/null
+++ b/src/sql/drivers/oci/qsql_oci.pri
@@ -0,0 +1,9 @@
+HEADERS += $$PWD/qsql_oci.h
+SOURCES += $$PWD/qsql_oci.cpp
+
+unix {
+ !contains(LIBS, .*clnts.*):LIBS += -lclntsh
+} else {
+ LIBS *= -loci
+}
+macx:QMAKE_LFLAGS += -Wl,-flat_namespace,-U,_environ
diff --git a/src/sql/drivers/odbc/qsql_odbc.pri b/src/sql/drivers/odbc/qsql_odbc.pri
new file mode 100644
index 0000000..66a8d51
--- /dev/null
+++ b/src/sql/drivers/odbc/qsql_odbc.pri
@@ -0,0 +1,13 @@
+HEADERS += $$PWD/qsql_odbc.h
+SOURCES += $$PWD/qsql_odbc.cpp
+
+unix {
+ DEFINES += UNICODE
+ !contains(LIBS, .*odbc.*) {
+ macx:LIBS += -liodbc
+ else:LIBS += $$QT_LFLAGS_ODBC
+ }
+} else {
+ win32-borland:LIBS *= $(BCB)/lib/PSDK/odbc32.lib
+ else:LIBS *= -lodbc32
+}
diff --git a/src/sql/drivers/psql/qsql_psql.pri b/src/sql/drivers/psql/qsql_psql.pri
new file mode 100644
index 0000000..97db4be
--- /dev/null
+++ b/src/sql/drivers/psql/qsql_psql.pri
@@ -0,0 +1,13 @@
+HEADERS += $$PWD/qsql_psql.h
+SOURCES += $$PWD/qsql_psql.cpp
+
+unix|win32-g++* {
+ !static:!isEmpty(QT_LFLAGS_PSQL) {
+ !contains(QT_CONFIG, system-zlib): QT_LFLAGS_PSQL -= -lz
+ LIBS *= $$QT_LFLAGS_PSQL
+ QMAKE_CXXFLAGS *= $$QT_CFLAGS_PSQL
+ }
+ !contains(LIBS, .*pq.*):LIBS += -lpq
+} else {
+ !contains(LIBS, .*pq.*):LIBS += -llibpq -lws2_32 -ladvapi32
+}
diff --git a/src/sql/drivers/sqlite/qsql_sqlite.pri b/src/sql/drivers/sqlite/qsql_sqlite.pri
new file mode 100644
index 0000000..7ad5936
--- /dev/null
+++ b/src/sql/drivers/sqlite/qsql_sqlite.pri
@@ -0,0 +1,9 @@
+HEADERS += $$PWD/qsql_sqlite.h
+SOURCES += $$PWD/qsql_sqlite.cpp
+
+!system-sqlite:!contains(LIBS, .*sqlite3.*) {
+ include($$PWD/../../../3rdparty/sqlite.pri)
+} else {
+ LIBS *= $$QT_LFLAGS_SQLITE
+ QMAKE_CXXFLAGS *= $$QT_CFLAGS_SQLITE
+}
diff --git a/src/sql/drivers/sqlite2/qsql_sqlite2.pri b/src/sql/drivers/sqlite2/qsql_sqlite2.pri
new file mode 100644
index 0000000..9a9f6cd
--- /dev/null
+++ b/src/sql/drivers/sqlite2/qsql_sqlite2.pri
@@ -0,0 +1,4 @@
+HEADERS += $$PWD/qsql_sqlite2.h
+SOURCES += $$PWD/qsql_sqlite2.cpp
+
+!contains(LIBS, .*sqlite.*):LIBS += -lsqlite
diff --git a/src/sql/drivers/tds/qsql_tds.pri b/src/sql/drivers/tds/qsql_tds.pri
new file mode 100644
index 0000000..c552ead
--- /dev/null
+++ b/src/sql/drivers/tds/qsql_tds.pri
@@ -0,0 +1,10 @@
+HEADERS += $$PWD/qsql_tds.h
+SOURCES += $$PWD/qsql_tds.cpp
+
+unix {
+ !contains(LIBS, .*sybdb.*):LIBS += -lsybdb
+} else:win32-borland {
+ LIBS *= $(BCB)/lib/PSDK/NTWDBLIB.LIB
+} else {
+ LIBS *= -lNTWDBLIB
+}