diff options
32 files changed, 483 insertions, 178 deletions
diff --git a/demos/embedded/anomaly/anomaly.pro b/demos/embedded/anomaly/anomaly.pro index 2871ba7..165ce89 100644 --- a/demos/embedded/anomaly/anomaly.pro +++ b/demos/embedded/anomaly/anomaly.pro @@ -8,7 +8,8 @@ HEADERS += src/BrowserWindow.h \ src/BookmarksView.h \ src/flickcharm.h \ src/ZoomStrip.h \ - src/ControlStrip.h + src/ControlStrip.h \ + src/webview.h SOURCES += src/Main.cpp \ src/BrowserWindow.cpp \ src/BrowserView.cpp \ @@ -18,7 +19,8 @@ SOURCES += src/Main.cpp \ src/BookmarksView.cpp \ src/flickcharm.cpp \ src/ZoomStrip.cpp \ - src/ControlStrip.cpp + src/ControlStrip.cpp \ + src/webview.cpp RESOURCES += src/anomaly.qrc symbian { diff --git a/demos/embedded/anomaly/src/BrowserView.cpp b/demos/embedded/anomaly/src/BrowserView.cpp index ab52e81..0945b89 100644 --- a/demos/embedded/anomaly/src/BrowserView.cpp +++ b/demos/embedded/anomaly/src/BrowserView.cpp @@ -48,6 +48,7 @@ #include "ControlStrip.h" #include "TitleBar.h" #include "flickcharm.h" +#include "webview.h" #include "ZoomStrip.h" #if defined (Q_OS_SYMBIAN) @@ -62,7 +63,7 @@ BrowserView::BrowserView(QWidget *parent) , m_currentZoom(100) { m_titleBar = new TitleBar(this); - m_webView = new QWebView(this); + m_webView = new WebView(this); m_zoomStrip = new ZoomStrip(this); m_controlStrip = new ControlStrip(this); @@ -95,7 +96,7 @@ void BrowserView::initialize() connect(m_webView, SIGNAL(loadFinished(bool)), SLOT(finish(bool))); connect(m_webView, SIGNAL(urlChanged(QUrl)), SLOT(updateTitleBar())); - m_webView->setHtml("Will try to load page soon!"); + m_webView->setHtml("about:blank"); m_webView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); m_webView->setFocus(); #ifdef Q_OS_SYMBIAN diff --git a/demos/embedded/anomaly/src/BrowserView.h b/demos/embedded/anomaly/src/BrowserView.h index fdc126d..5ab1dd7 100644 --- a/demos/embedded/anomaly/src/BrowserView.h +++ b/demos/embedded/anomaly/src/BrowserView.h @@ -49,6 +49,7 @@ class QUrl; class QWebView; class TitleBar; class ControlStrip; +class WebView; class ZoomStrip; class BrowserView : public QWidget @@ -81,7 +82,7 @@ protected: private: TitleBar *m_titleBar; - QWebView *m_webView; + WebView *m_webView; ZoomStrip *m_zoomStrip; ControlStrip *m_controlStrip; int m_progress; @@ -90,3 +91,4 @@ private: }; #endif // BROWSERVIEW_H + diff --git a/demos/embedded/anomaly/src/webview.cpp b/demos/embedded/anomaly/src/webview.cpp new file mode 100644 index 0000000..5cb913b --- /dev/null +++ b/demos/embedded/anomaly/src/webview.cpp @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the demos of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "webview.h" + +#include <QPaintEvent> +#include <QWebFrame> + +WebView::WebView(QWidget *parent) + : QWebView(parent) + , inLoading(false) +{ + connect(this, SIGNAL(loadStarted()), this, SLOT(newPageLoading())); + connect(this, SIGNAL(loadFinished(bool)), this, SLOT(pageLoaded(bool))); + page()->setPreferredContentsSize(QSize(1024, 768)); +} + +void WebView::paintEvent(QPaintEvent *event) +{ + if (inLoading && loadingTime.elapsed() < 750) { + QPainter painter(this); + painter.setBrush(Qt::white); + painter.setPen(Qt::NoPen); + foreach (const QRect &rect, event->region().rects()) { + painter.drawRect(rect); + } + } else { + QWebView::paintEvent(event); + } +} + +void WebView::newPageLoading() +{ + inLoading = true; + loadingTime.start(); +} + +void WebView::pageLoaded(bool) +{ + inLoading = false; + update(); +} diff --git a/demos/embedded/anomaly/src/webview.h b/demos/embedded/anomaly/src/webview.h new file mode 100644 index 0000000..ecd9f5a --- /dev/null +++ b/demos/embedded/anomaly/src/webview.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the demos of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WEBVIEW_H +#define WEBVIEW_H + +#include <QWebView> +#include <QTime> + +class WebView : public QWebView +{ + Q_OBJECT +public: + WebView(QWidget *parent = 0); + +protected: + void paintEvent(QPaintEvent *event); + +private slots: + void newPageLoading(); + void pageLoaded(bool ok); + +private: + QTime loadingTime; + bool inLoading; +}; + +#endif // WEBVIEW_H diff --git a/doc/src/getting-started/installation.qdoc b/doc/src/getting-started/installation.qdoc index 3867b3b..5f95c5a 100644 --- a/doc/src/getting-started/installation.qdoc +++ b/doc/src/getting-started/installation.qdoc @@ -640,17 +640,38 @@ If you are using pre-built binaries, follow the instructions given in the Congratulations, Qt is now ready to use. - \o Running Qt demos + \o Installing Qt libraries on the device - We've included a subset of the Qt demos in this package for you - to try out. An excellent starting point is the "fluidlauncher" - demo. To run the demo on a real device, you first have to install + To run the demo on a real device, you first have to install the Qt libraries on the device: \snippet doc/src/snippets/code/doc_src_installation.qdoc 29 - \note You will need to supply certificate that allows installation - of binaries with "All -Tcb" capability to your device. + The Qt libraries are built with "All -Tcb" capability, so that + they can support all types of application. + If you don't have a suitable certificate, it is possible to patch + the binaries as follows: + + \list A + \o Installing Qt without a certificate + + If you have no certificate, build a self signed Qt: + + \snippet doc/src/snippets/code/doc_src_installation.qdoc 34 + + \o Installing Qt with a Symbian developer certificate + + If you have a symbian-signed developer certificate, specify the + capabilities you can sign for, for example: + + \snippet doc/src/snippets/code/doc_src_installation.qdoc 35 + \endlist + + \o Running Qt demos + + We've included a subset of the Qt demos in this package for you + to try out. An excellent starting point is the "fluidlauncher" + demo. Similarly, install fluidlauncher to the device: diff --git a/doc/src/snippets/code/doc_src_installation.qdoc b/doc/src/snippets/code/doc_src_installation.qdoc index 7680ec8..b3c9903 100644 --- a/doc/src/snippets/code/doc_src_installation.qdoc +++ b/doc/src/snippets/code/doc_src_installation.qdoc @@ -222,3 +222,21 @@ abld build gcce urel //! [33] SYMBIANBUILD_DEPENDENCYOFF=1 //! [33] + +//! [34] +cd src\s60installs +patch_capabilities.pl Qt_template.pkg release-armv5 +make sis QT_SIS_OPTIONS=-i +cd ..\3rdparty\webkit\WebCore +patch_capabilities.pl QtWebkit_template.pkg release-armv5 +make sis QT_SIS_OPTIONS=-i +//! [34] + +//! [35] +cd src\s60installs +patch_capabilities.pl Qt_template.pkg release-armv5 "ALL -Tcb -AllFiles -DRM" +make sis QT_SIS_OPTIONS=-i QT_SIS_CERTIFICATE=<certificate file> QT_SIS_KEY=<certificate key file> +cd ..\3rdparty\webkit\WebCore +patch_capabilities.pl QtWebKit_template.pkg release-armv5 "ALL -Tcb -AllFiles -DRM" +make sis QT_SIS_OPTIONS=-i QT_SIS_CERTIFICATE=<certificate file> QT_SIS_KEY=<certificate key file> +//! [35] diff --git a/mkspecs/features/symbian/platform_paths.prf b/mkspecs/features/symbian/platform_paths.prf index f5caae0..c723d8c 100644 --- a/mkspecs/features/symbian/platform_paths.prf +++ b/mkspecs/features/symbian/platform_paths.prf @@ -59,7 +59,7 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { # No platform specific paths provided, use default paths - exists($${EPOCROOT}epoc32/include/platform) { # New SF structure + exists($${EPOCROOT}epoc32/include/mw) { # New SF structure # --------------------------------------- # Location, where the applications layer specific public headers are exported diff --git a/src/3rdparty/phonon/mmf/abstractaudioeffect.h b/src/3rdparty/phonon/mmf/abstractaudioeffect.h index 9878472..436e8e4 100644 --- a/src/3rdparty/phonon/mmf/abstractaudioeffect.h +++ b/src/3rdparty/phonon/mmf/abstractaudioeffect.h @@ -23,7 +23,7 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #include <AudioEffectBase.h> -#include <Phonon/EffectInterface> +#include <phonon/effectinterface.h> #include "audioplayer.h" #include "effectparameter.h" diff --git a/src/3rdparty/phonon/mmf/abstractplayer.h b/src/3rdparty/phonon/mmf/abstractplayer.h index dbcbe63..cec5568 100644 --- a/src/3rdparty/phonon/mmf/abstractplayer.h +++ b/src/3rdparty/phonon/mmf/abstractplayer.h @@ -19,8 +19,8 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #ifndef PHONON_MMF_ABSTRACTPLAYER_H #define PHONON_MMF_ABSTRACTPLAYER_H -#include <Phonon/phononnamespace.h> -#include <Phonon/MediaSource.h> +#include <phonon/phononnamespace.h> +#include <phonon/mediasource.h> #include <QObject> diff --git a/src/3rdparty/phonon/mmf/backend.h b/src/3rdparty/phonon/mmf/backend.h index 6b85625..9361544 100644 --- a/src/3rdparty/phonon/mmf/backend.h +++ b/src/3rdparty/phonon/mmf/backend.h @@ -22,8 +22,8 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #include "ancestormovemonitor.h" #include "effectfactory.h" -#include <Phonon/MediaSource> -#include <Phonon/BackendInterface> +#include <phonon/mediasource.h> +#include <phonon/backendinterface.h> #include <QScopedPointer> QT_BEGIN_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/effectparameter.h b/src/3rdparty/phonon/mmf/effectparameter.h index 27cc018..892ed4d 100644 --- a/src/3rdparty/phonon/mmf/effectparameter.h +++ b/src/3rdparty/phonon/mmf/effectparameter.h @@ -19,7 +19,7 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #ifndef PHONON_MMF_EFFECTPARAMETER_H #define PHONON_MMF_EFFECTPARAMETER_H -#include <Phonon/EffectParameter> +#include <phonon/effectparameter.h> QT_BEGIN_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/mediaobject.h b/src/3rdparty/phonon/mmf/mediaobject.h index c87d755..d6248e2 100644 --- a/src/3rdparty/phonon/mmf/mediaobject.h +++ b/src/3rdparty/phonon/mmf/mediaobject.h @@ -19,8 +19,8 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #ifndef PHONON_MMF_MEDIAOBJECT_H #define PHONON_MMF_MEDIAOBJECT_H -#include <Phonon/MediaSource> -#include <Phonon/MediaObjectInterface> +#include <phonon/mediasource.h> +#include <phonon/mediaobjectinterface.h> #include <QScopedPointer> #include <QTimer> diff --git a/src/3rdparty/phonon/mmf/mmf_medianode.h b/src/3rdparty/phonon/mmf/mmf_medianode.h index 0ed21c4..f2f64e0 100644 --- a/src/3rdparty/phonon/mmf/mmf_medianode.h +++ b/src/3rdparty/phonon/mmf/mmf_medianode.h @@ -20,7 +20,7 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #define PHONON_MMF_MEDIANODE_H #include <QObject> -#include <Phonon/EffectInterface> +#include <phonon/effectinterface.h> #include "audioplayer.h" QT_BEGIN_NAMESPACE diff --git a/src/3rdparty/phonon/mmf/videooutput.h b/src/3rdparty/phonon/mmf/videooutput.h index 2788401..3e9c036 100644 --- a/src/3rdparty/phonon/mmf/videooutput.h +++ b/src/3rdparty/phonon/mmf/videooutput.h @@ -24,7 +24,7 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #include <QRect> #include "defs.h" -#include <Phonon/VideoWidget> +#include <phonon/videowidget.h> #include <e32std.h> class RWindowBase; diff --git a/src/3rdparty/phonon/mmf/videowidget.h b/src/3rdparty/phonon/mmf/videowidget.h index a876748..899dca6 100644 --- a/src/3rdparty/phonon/mmf/videowidget.h +++ b/src/3rdparty/phonon/mmf/videowidget.h @@ -23,8 +23,8 @@ along with this library. If not, see <http://www.gnu.org/licenses/>. #include "videooutput.h" #include <QtGui/QWidget> -#include <Phonon/VideoWidget> -#include <Phonon/VideoWidgetInterface> +#include <phonon/videowidget.h> +#include <phonon/videowidgetinterface.h> QT_BEGIN_NAMESPACE diff --git a/src/3rdparty/webkit/WebCore/WebCore.pro b/src/3rdparty/webkit/WebCore/WebCore.pro index 9432217..1489fa0 100644 --- a/src/3rdparty/webkit/WebCore/WebCore.pro +++ b/src/3rdparty/webkit/WebCore/WebCore.pro @@ -23,7 +23,7 @@ symbian: { TARGET.UID3 = 0x200267C2 # RO text (code) section in qtwebkit.dll exceeds allocated space for gcce udeb target. # Move RW-section base address to start from 0xE00000 instead of the toolchain default 0x400000. - MMP_RULES += "LINKEROPTION armcc --rw-base 0xE00000" + QMAKE_LFLAGS.ARMCC += --rw-base 0xE00000 } include($$PWD/../WebKit.pri) diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index 4c7f3f0..728c316 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -650,7 +650,7 @@ QFile::remove() unsetError(); return true; } - d->setError(QFile::RemoveError, fileEngine()->errorString()); + d->setError(QFile::RemoveError, d->fileEngine->errorString()); } return false; } @@ -704,7 +704,7 @@ QFile::rename(const QString &newName) if (fileEngine()->rename(newName)) { unsetError(); // engine was able to handle the new name so we just reset it - fileEngine()->setFileName(newName); + d->fileEngine->setFileName(newName); d->fileName = newName; return true; } @@ -740,7 +740,7 @@ QFile::rename(const QString &newName) if (error) { out.remove(); } else { - fileEngine()->setFileName(newName); + d->fileEngine->setFileName(newName); setPermissions(permissions()); unsetError(); setFileName(newName); @@ -805,7 +805,7 @@ QFile::link(const QString &linkName) unsetError(); return true; } - d->setError(QFile::RenameError, fileEngine()->errorString()); + d->setError(QFile::RenameError, d->fileEngine->errorString()); return false; } @@ -994,10 +994,10 @@ bool QFile::open(OpenMode mode) seek(size()); return true; } - QFile::FileError err = fileEngine()->error(); + QFile::FileError err = d->fileEngine->error(); if(err == QFile::UnspecifiedError) err = QFile::OpenError; - d->setError(err, fileEngine()->errorString()); + d->setError(err, d->fileEngine->errorString()); return false; } @@ -1152,12 +1152,11 @@ bool QFile::open(int fd, OpenMode mode) int QFile::handle() const { - if (!isOpen()) + Q_D(const QFile); + if (!isOpen() || !d->fileEngine) return -1; - if (QAbstractFileEngine *engine = fileEngine()) - return engine->handle(); - return -1; + return d->fileEngine->handle(); } /*! @@ -1189,13 +1188,12 @@ QFile::handle() const uchar *QFile::map(qint64 offset, qint64 size, MemoryMapFlags flags) { Q_D(QFile); - QAbstractFileEngine *engine = fileEngine(); - if (engine - && engine->supportsExtension(QAbstractFileEngine::MapExtension)) { + if (fileEngine() + && d->fileEngine->supportsExtension(QAbstractFileEngine::MapExtension)) { unsetError(); - uchar *address = engine->map(offset, size, flags); + uchar *address = d->fileEngine->map(offset, size, flags); if (address == 0) - d->setError(engine->error(), engine->errorString()); + d->setError(d->fileEngine->error(), d->fileEngine->errorString()); return address; } return 0; @@ -1212,13 +1210,12 @@ uchar *QFile::map(qint64 offset, qint64 size, MemoryMapFlags flags) bool QFile::unmap(uchar *address) { Q_D(QFile); - QAbstractFileEngine *engine = fileEngine(); - if (engine - && engine->supportsExtension(QAbstractFileEngine::UnMapExtension)) { + if (fileEngine() + && d->fileEngine->supportsExtension(QAbstractFileEngine::UnMapExtension)) { unsetError(); - bool success = engine->unmap(address); + bool success = d->fileEngine->unmap(address); if (!success) - d->setError(engine->error(), engine->errorString()); + d->setError(d->fileEngine->error(), d->fileEngine->errorString()); return success; } return false; @@ -1251,13 +1248,14 @@ QFile::resize(qint64 sz) Q_D(QFile); if (!d->ensureFlushed()) return false; - if (isOpen() && fileEngine()->pos() > sz) + fileEngine(); + if (isOpen() && d->fileEngine->pos() > sz) seek(sz); - if(fileEngine()->setSize(sz)) { + if(d->fileEngine->setSize(sz)) { unsetError(); return true; } - d->setError(QFile::ResizeError, fileEngine()->errorString()); + d->setError(QFile::ResizeError, d->fileEngine->errorString()); return false; } @@ -1321,7 +1319,7 @@ QFile::setPermissions(Permissions permissions) unsetError(); return true; } - d->setError(QFile::PermissionsError, fileEngine()->errorString()); + d->setError(QFile::PermissionsError, d->fileEngine->errorString()); return false; } @@ -1354,23 +1352,27 @@ bool QFile::flush() { Q_D(QFile); + if (!d->fileEngine) { + qWarning("QFile::flush: No file engine. Is IODevice open?"); + return false; + } + if (!d->writeBuffer.isEmpty()) { qint64 size = d->writeBuffer.size(); - if (_qfile_writeData(d->fileEngine ? d->fileEngine : fileEngine(), - &d->writeBuffer) != size) { - QFile::FileError err = fileEngine()->error(); + if (_qfile_writeData(d->fileEngine, &d->writeBuffer) != size) { + QFile::FileError err = d->fileEngine->error(); if(err == QFile::UnspecifiedError) err = QFile::WriteError; - d->setError(err, fileEngine()->errorString()); + d->setError(err, d->fileEngine->errorString()); return false; } } - if (!fileEngine()->flush()) { - QFile::FileError err = fileEngine()->error(); + if (!d->fileEngine->flush()) { + QFile::FileError err = d->fileEngine->error(); if(err == QFile::UnspecifiedError) err = QFile::WriteError; - d->setError(err, fileEngine()->errorString()); + d->setError(err, d->fileEngine->errorString()); return false; } return true; @@ -1395,10 +1397,10 @@ QFile::close() d->writeBuffer.clear(); // keep earlier error from flush - if (fileEngine()->close() && flushed) + if (d->fileEngine->close() && flushed) unsetError(); else if (flushed) - d->setError(fileEngine()->error(), fileEngine()->errorString()); + d->setError(d->fileEngine->error(), d->fileEngine->errorString()); } /*! @@ -1451,10 +1453,10 @@ bool QFile::atEnd() const return false; // If the file engine knows best, say what it says. - if (fileEngine()->supportsExtension(QAbstractFileEngine::AtEndExtension)) { + if (d->fileEngine->supportsExtension(QAbstractFileEngine::AtEndExtension)) { // Check if the file engine supports AtEndExtension, and if it does, // check if the file engine claims to be at the end. - return fileEngine()->atEnd(); + return d->fileEngine->atEnd(); } // Fall back to checking how much is available (will stat files). @@ -1476,11 +1478,11 @@ bool QFile::seek(qint64 off) if (!d->ensureFlushed()) return false; - if (!fileEngine()->seek(off) || !QIODevice::seek(off)) { - QFile::FileError err = fileEngine()->error(); + if (!d->fileEngine->seek(off) || !QIODevice::seek(off)) { + QFile::FileError err = d->fileEngine->error(); if(err == QFile::UnspecifiedError) err = QFile::PositionError; - d->setError(err, fileEngine()->errorString()); + d->setError(err, d->fileEngine->errorString()); return false; } unsetError(); @@ -1496,8 +1498,8 @@ qint64 QFile::readLineData(char *data, qint64 maxlen) if (!d->ensureFlushed()) return -1; - if (fileEngine()->supportsExtension(QAbstractFileEngine::FastReadLineExtension)) - return fileEngine()->readLine(data, maxlen); + if (d->fileEngine->supportsExtension(QAbstractFileEngine::FastReadLineExtension)) + return d->fileEngine->readLine(data, maxlen); // Fall back to QIODevice's readLine implementation if the engine // cannot do it faster. @@ -1515,18 +1517,14 @@ qint64 QFile::readData(char *data, qint64 len) if (!d->ensureFlushed()) return -1; - qint64 ret = -1; - qint64 read = fileEngine()->read(data, len); - if (read != -1) - ret = read; - - if(ret < 0) { - QFile::FileError err = fileEngine()->error(); + qint64 read = d->fileEngine->read(data, len); + if(read < 0) { + QFile::FileError err = d->fileEngine->error(); if(err == QFile::UnspecifiedError) err = QFile::ReadError; - d->setError(err, fileEngine()->errorString()); + d->setError(err, d->fileEngine->errorString()); } - return ret; + return read; } /*! @@ -1606,13 +1604,12 @@ QFile::writeData(const char *data, qint64 len) // Write directly to the engine if the block size is larger than // the write buffer size. if (!buffered || len > QFILE_WRITEBUFFER_SIZE) { - QAbstractFileEngine *fe = d->fileEngine ? d->fileEngine : fileEngine(); - qint64 ret = fe->write(data, len); + qint64 ret = d->fileEngine->write(data, len); if(ret < 0) { - QFile::FileError err = fileEngine()->error(); + QFile::FileError err = d->fileEngine->error(); if(err == QFile::UnspecifiedError) err = QFile::WriteError; - d->setError(err, fileEngine()->errorString()); + d->setError(err, d->fileEngine->errorString()); } return ret; } diff --git a/src/gui/dialogs/qcolordialog.cpp b/src/gui/dialogs/qcolordialog.cpp index e9031ac..83ecc30 100644 --- a/src/gui/dialogs/qcolordialog.cpp +++ b/src/gui/dialogs/qcolordialog.cpp @@ -68,6 +68,10 @@ #include "private/qt_s60_p.h" #endif +#if defined(Q_WS_S60) || defined(Q_WS_MAEMO_5) +# define QT_SMALL_COLORDIALOG +#endif + QT_BEGIN_NAMESPACE //////////// QWellArray BEGIN @@ -1072,14 +1076,17 @@ QColorShower::QColorShower(QColorDialog *parent) gl->setMargin(gl->spacing()); lab = new QColorShowLabel(this); -#ifdef Q_WS_S60 +#ifdef QT_SMALL_COLORDIALOG +# ifdef Q_WS_S60 QS60Data s60Data = QS60Data(); const bool nonTouchUI = !s60Data.hasTouchscreen; +# elif defined Q_WS_MAEMO_5 + const bool nonTouchUI = false; +# endif #endif - #ifndef Q_WS_WINCE -#ifdef Q_WS_S60 +#ifdef QT_SMALL_COLORDIALOG lab->setMinimumHeight(60); #endif lab->setMinimumWidth(60); @@ -1090,7 +1097,7 @@ QColorShower::QColorShower(QColorDialog *parent) // In S60, due to small screen and different screen layouts need to re-arrange the widgets. // For QVGA screens only the comboboxes and color label are visible. // For nHD screens only color and luminence pickers and color label are visible. -#ifndef Q_WS_S60 +#if !defined(QT_SMALL_COLORDIALOG) gl->addWidget(lab, 0, 0, -1, 1); #else if (nonTouchUI) @@ -1108,7 +1115,7 @@ QColorShower::QColorShower(QColorDialog *parent) lblHue->setBuddy(hEd); #endif lblHue->setAlignment(Qt::AlignRight|Qt::AlignVCenter); -#ifndef Q_WS_S60 +#if !defined(QT_SMALL_COLORDIALOG) gl->addWidget(lblHue, 0, 1); gl->addWidget(hEd, 0, 2); #else @@ -1127,7 +1134,7 @@ QColorShower::QColorShower(QColorDialog *parent) lblSat->setBuddy(sEd); #endif lblSat->setAlignment(Qt::AlignRight|Qt::AlignVCenter); -#ifndef Q_WS_S60 +#if !defined(QT_SMALL_COLORDIALOG) gl->addWidget(lblSat, 1, 1); gl->addWidget(sEd, 1, 2); #else @@ -1146,7 +1153,7 @@ QColorShower::QColorShower(QColorDialog *parent) lblVal->setBuddy(vEd); #endif lblVal->setAlignment(Qt::AlignRight|Qt::AlignVCenter); -#ifndef Q_WS_S60 +#if !defined(QT_SMALL_COLORDIALOG) gl->addWidget(lblVal, 2, 1); gl->addWidget(vEd, 2, 2); #else @@ -1165,7 +1172,7 @@ QColorShower::QColorShower(QColorDialog *parent) lblRed->setBuddy(rEd); #endif lblRed->setAlignment(Qt::AlignRight|Qt::AlignVCenter); -#ifndef Q_WS_S60 +#if !defined(QT_SMALL_COLORDIALOG) gl->addWidget(lblRed, 0, 3); gl->addWidget(rEd, 0, 4); #else @@ -1184,7 +1191,7 @@ QColorShower::QColorShower(QColorDialog *parent) lblGreen->setBuddy(gEd); #endif lblGreen->setAlignment(Qt::AlignRight|Qt::AlignVCenter); -#ifndef Q_WS_S60 +#if !defined(QT_SMALL_COLORDIALOG) gl->addWidget(lblGreen, 1, 3); gl->addWidget(gEd, 1, 4); #else @@ -1203,7 +1210,7 @@ QColorShower::QColorShower(QColorDialog *parent) lblBlue->setBuddy(bEd); #endif lblBlue->setAlignment(Qt::AlignRight|Qt::AlignVCenter); -#ifndef Q_WS_S60 +#if !defined(QT_SMALL_COLORDIALOG) gl->addWidget(lblBlue, 2, 3); gl->addWidget(bEd, 2, 4); #else @@ -1222,7 +1229,7 @@ QColorShower::QColorShower(QColorDialog *parent) alphaLab->setBuddy(alphaEd); #endif alphaLab->setAlignment(Qt::AlignRight|Qt::AlignVCenter); -#ifndef Q_WS_S60 +#if !defined(QT_SMALL_COLORDIALOG) gl->addWidget(alphaLab, 3, 1, 1, 3); gl->addWidget(alphaEd, 3, 4); #else @@ -1467,7 +1474,7 @@ void QColorDialogPrivate::init(const QColor &initial) leftLay = 0; -#if (defined(Q_WS_WINCE) || defined(Q_WS_S60)) +#if defined(Q_WS_WINCE) || defined(QT_SMALL_COLORDIALOG) smallDisplay = true; const int lumSpace = 20; #else @@ -1497,9 +1504,13 @@ void QColorDialogPrivate::init(const QColor &initial) } #endif -#if defined(Q_WS_S60) +#if defined(QT_SMALL_COLORDIALOG) +# if defined(Q_WS_S60) QS60Data s60Data = QS60Data(); const bool nonTouchUI = !s60Data.hasTouchscreen; +# elif defined(Q_WS_MAEMO_5) + const bool nonTouchUI = false; +# endif #endif if (!smallDisplay) { @@ -1532,7 +1543,7 @@ void QColorDialogPrivate::init(const QColor &initial) leftLay->addWidget(addCusBt); } else { // better color picker size for small displays -#ifdef Q_WS_S60 +#if defined(QT_SMALL_COLORDIALOG) QSize screenSize = QApplication::desktop()->availableGeometry(QCursor::pos()).size(); pWidth = pHeight = qMin(screenSize.width(), screenSize.height()); pHeight -= 20; @@ -1558,7 +1569,7 @@ void QColorDialogPrivate::init(const QColor &initial) cp->setFrameStyle(QFrame::Panel + QFrame::Sunken); -#if defined(Q_WS_S60) +#if defined(QT_SMALL_COLORDIALOG) if (!nonTouchUI) { pickLay->addWidget(cp); cLay->addSpacing(lumSpace); @@ -1572,7 +1583,7 @@ void QColorDialogPrivate::init(const QColor &initial) cLay->addSpacing(lumSpace); lp = new QColorLuminancePicker(q); -#if defined(Q_WS_S60) +#if defined(QT_SMALL_COLORDIALOG) QSize screenSize = QApplication::desktop()->availableGeometry(QCursor::pos()).size(); const int minDimension = qMin(screenSize.height(), screenSize.width()); //set picker to be finger-usable @@ -1596,7 +1607,7 @@ void QColorDialogPrivate::init(const QColor &initial) QObject::connect(cs, SIGNAL(newCol(QRgb)), q, SLOT(_q_newColorTypedIn(QRgb))); QObject::connect(cs, SIGNAL(currentColorChanged(QColor)), q, SIGNAL(currentColorChanged(QColor))); -#if defined(Q_WS_S60) +#if defined(QT_SMALL_COLORDIALOG) if (!nonTouchUI) pWidth -= cp->size().width(); topLay->addWidget(cs); diff --git a/src/network/access/qfilenetworkreply.cpp b/src/network/access/qfilenetworkreply.cpp index 44dd9e7..8c5065c 100644 --- a/src/network/access/qfilenetworkreply.cpp +++ b/src/network/access/qfilenetworkreply.cpp @@ -44,35 +44,32 @@ #include "QtCore/qdatetime.h" #include <QtCore/QCoreApplication> #include <QtCore/QFileInfo> +#include <QDebug> QT_BEGIN_NAMESPACE QFileNetworkReplyPrivate::QFileNetworkReplyPrivate() - : QNetworkReplyPrivate(), realFileSize(0), finished(false) + : QNetworkReplyPrivate(), realFileSize(0) { } -QFileNetworkReply::QFileNetworkReply(QObject *parent, const QNetworkRequest &req) +QFileNetworkReply::~QFileNetworkReply() +{ +} + +QFileNetworkReply::QFileNetworkReply(QObject *parent, const QNetworkRequest &req, const QNetworkAccessManager::Operation op) : QNetworkReply(*new QFileNetworkReplyPrivate(), parent) { setRequest(req); setUrl(req.url()); - setOperation(QNetworkAccessManager::GetOperation); - QMetaObject::invokeMethod(this, "_q_startOperation", Qt::QueuedConnection); + setOperation(op); QNetworkReply::open(QIODevice::ReadOnly); -} -QFileNetworkReply::~QFileNetworkReply() -{ -} + qRegisterMetaType<QNetworkReply::NetworkError>("QNetworkReply::NetworkError"); -// This code is mostly inspired by QNetworkAccessFileBackend -// We also use its translation context for error messages -void QFileNetworkReplyPrivate::_q_startOperation() -{ - Q_Q(QFileNetworkReply); + QFileNetworkReplyPrivate *d = (QFileNetworkReplyPrivate*) d_func(); - QUrl url = q->url(); + QUrl url = req.url(); if (url.host() == QLatin1String("localhost")) url.setHost(QString()); @@ -81,81 +78,75 @@ void QFileNetworkReplyPrivate::_q_startOperation() if (!url.host().isEmpty()) { // we handle only local files QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Request for opening non-local file %1").arg(url.toString()); - q->setError(QNetworkReply::ProtocolInvalidOperationError, msg); - emit q->error(QNetworkReply::ProtocolInvalidOperationError); - doFinished(); + setError(QNetworkReply::ProtocolInvalidOperationError, msg); + QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, + Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ProtocolInvalidOperationError)); + QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); return; } #endif if (url.path().isEmpty()) url.setPath(QLatin1String("/")); - q->setUrl(url); + setUrl(url); QString fileName = url.toLocalFile(); if (fileName.isEmpty()) { fileName = url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery); } - realFile.setFileName(fileName); + d->realFile.setFileName(fileName); - QFileInfo fi(realFile); + QFileInfo fi(d->realFile); if (fi.isDir()) { QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Cannot open %1: Path is a directory").arg(url.toString()); - q->setError(QNetworkReply::ContentOperationNotPermittedError, msg); - emit q->error(QNetworkReply::ContentOperationNotPermittedError); - doFinished(); + setError(QNetworkReply::ContentOperationNotPermittedError, msg); + QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, + Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ContentOperationNotPermittedError)); + QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); return; } - bool opened = realFile.open(QIODevice::ReadOnly | QIODevice::Unbuffered); + bool opened = d->realFile.open(QIODevice::ReadOnly | QIODevice::Unbuffered); // could we open the file? if (!opened) { QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Error opening %1: %2") - .arg(realFile.fileName(), realFile.errorString()); + .arg(d->realFile.fileName(), d->realFile.errorString()); - if (realFile.exists()) { - q->setError(QNetworkReply::ContentAccessDenied, msg); - emit q->error(QNetworkReply::ContentAccessDenied); + if (d->realFile.exists()) { + setError(QNetworkReply::ContentAccessDenied, msg); + QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, + Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ContentAccessDenied)); } else { - q->setError(QNetworkReply::ContentNotFoundError, msg); - emit q->error(QNetworkReply::ContentNotFoundError); + setError(QNetworkReply::ContentNotFoundError, msg); + QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, + Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ContentNotFoundError)); } - doFinished(); + QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); return; } - realFileSize = fi.size(); - q->setHeader(QNetworkRequest::LastModifiedHeader, fi.lastModified()); - q->setHeader(QNetworkRequest::ContentLengthHeader, realFileSize); + d->realFileSize = fi.size(); + setHeader(QNetworkRequest::LastModifiedHeader, fi.lastModified()); + setHeader(QNetworkRequest::ContentLengthHeader, d->realFileSize); - emit q->metaDataChanged(); - emit q->downloadProgress(realFileSize, realFileSize); - emit q->readyRead(); - doFinished(); + QMetaObject::invokeMethod(this, "metaDataChanged", Qt::QueuedConnection); + QMetaObject::invokeMethod(this, "downloadProgress", Qt::QueuedConnection, + Q_ARG(qint64, d->realFileSize), Q_ARG(qint64, d->realFileSize)); + QMetaObject::invokeMethod(this, "readyRead", Qt::QueuedConnection); + QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); } bool QFileNetworkReplyPrivate::isFinished() const { - return finished; -} - -void QFileNetworkReplyPrivate::doFinished() -{ - Q_Q(QFileNetworkReply); - finished = true; - emit q->finished(); + return true; } - void QFileNetworkReply::close() { Q_D(QFileNetworkReply); QNetworkReply::close(); d->realFile.close(); - - if (!d->finished) - d->doFinished(); } void QFileNetworkReply::abort() @@ -163,9 +154,6 @@ void QFileNetworkReply::abort() Q_D(QFileNetworkReply); QNetworkReply::close(); d->realFile.close(); - - if (!d->finished) - d->doFinished(); } qint64 QFileNetworkReply::bytesAvailable() const diff --git a/src/network/access/qfilenetworkreply_p.h b/src/network/access/qfilenetworkreply_p.h index 6f10672..125fa2e 100644 --- a/src/network/access/qfilenetworkreply_p.h +++ b/src/network/access/qfilenetworkreply_p.h @@ -66,7 +66,7 @@ class QFileNetworkReply: public QNetworkReply { Q_OBJECT public: - QFileNetworkReply(QObject *parent, const QNetworkRequest &req); + QFileNetworkReply(QObject *parent, const QNetworkRequest &req, const QNetworkAccessManager::Operation op); ~QFileNetworkReply(); virtual void abort(); @@ -76,12 +76,9 @@ public: virtual bool isSequential () const; qint64 size() const; - virtual qint64 readData(char *data, qint64 maxlen); Q_DECLARE_PRIVATE(QFileNetworkReply) - Q_PRIVATE_SLOT(d_func(), void _q_startOperation()) - }; class QFileNetworkReplyPrivate: public QNetworkReplyPrivate @@ -92,12 +89,7 @@ public: QFile realFile; qint64 realFileSize; - void _q_startOperation(); - virtual bool isFinished() const; - void doFinished(); - bool finished; - Q_DECLARE_PUBLIC(QFileNetworkReply) }; diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index d27fbe7..e16aedc 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -687,10 +687,10 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera // Also if the scheme is empty we consider it a file. // The QNetworkAccessFileBackend will right now only be used // for PUT or qrc:// - if (op == QNetworkAccessManager::GetOperation + if ((op == QNetworkAccessManager::GetOperation || op == QNetworkAccessManager::HeadOperation) && (req.url().scheme() == QLatin1String("file") || req.url().scheme().isEmpty())) { - return new QFileNetworkReply(this, req); + return new QFileNetworkReply(this, req, op); } QNetworkRequest request = req; diff --git a/src/network/access/qnetworkreply.cpp b/src/network/access/qnetworkreply.cpp index 49a287f..0a8ea5d 100644 --- a/src/network/access/qnetworkreply.cpp +++ b/src/network/access/qnetworkreply.cpp @@ -239,7 +239,10 @@ QNetworkReplyPrivate::QNetworkReplyPrivate() \note Do not delete the object in the slot connected to this signal. Use deleteLater(). - \sa QNetworkAccessManager::finished() + You can also use isFinished() to check if a QNetworkReply + has finished even before you receive the finished() signal. + + \sa QNetworkAccessManager::finished(), isFinished() */ /*! diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index 81bffd9..8257545 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -994,9 +994,9 @@ qint64 QNativeSocketEnginePrivate::nativeWrite(const char *data, qint64 len) { Q_Q(QNativeSocketEngine); qint64 ret = 0; - // don't send more than 49152 per call to WSASendTo to avoid getting a WSAENOBUFS + qint64 bytesToSend = len; + for (;;) { - qint64 bytesToSend = qMin<qint64>(49152, len - ret); WSABUF buf; buf.buf = (char*)data + ret; buf.len = bytesToSend; @@ -1014,6 +1014,12 @@ qint64 QNativeSocketEnginePrivate::nativeWrite(const char *data, qint64 len) continue; } else if (WSAGetLastError() == WSAEWOULDBLOCK) { break; + } else if (WSAGetLastError() == WSAENOBUFS) { + // this function used to not send more than 49152 per call to WSASendTo + // to avoid getting a WSAENOBUFS. However this is a performance regression + // and we think it only appears with old windows versions. We now handle the + // WSAENOBUFS and hope it never appears anyway. + // just go on, the next loop run we will try a smaller number } else { int err = WSAGetLastError(); WS_ERROR_DEBUG(err); @@ -1029,6 +1035,9 @@ qint64 QNativeSocketEnginePrivate::nativeWrite(const char *data, qint64 len) } break; } + + // for next send: + bytesToSend = qMin<qint64>(49152, len - ret); } #if defined (QNATIVESOCKETENGINE_DEBUG) diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index dd50c38..8993e72 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -304,6 +304,7 @@ static QString _q_SubjectInfoToString(QSslCertificate::SubjectInfo info) */ QString QSslCertificate::issuerInfo(SubjectInfo info) const { + // lazy init if (d->issuerInfo.isEmpty() && d->x509) d->issuerInfo = _q_mapFromOnelineName(q_X509_NAME_oneline(q_X509_get_issuer_name(d->x509), 0, 0)); @@ -320,7 +321,11 @@ QString QSslCertificate::issuerInfo(SubjectInfo info) const */ QString QSslCertificate::issuerInfo(const QByteArray &tag) const { - // ### Use a QByteArray for the keys in the map + // lazy init + if (d->issuerInfo.isEmpty() && d->x509) + d->issuerInfo = + _q_mapFromOnelineName(q_X509_NAME_oneline(q_X509_get_issuer_name(d->x509), 0, 0)); + return d->issuerInfo.value(QString::fromLatin1(tag)); } @@ -335,6 +340,7 @@ QString QSslCertificate::issuerInfo(const QByteArray &tag) const */ QString QSslCertificate::subjectInfo(SubjectInfo info) const { + // lazy init if (d->subjectInfo.isEmpty() && d->x509) d->subjectInfo = _q_mapFromOnelineName(q_X509_NAME_oneline(q_X509_get_subject_name(d->x509), 0, 0)); @@ -350,7 +356,11 @@ QString QSslCertificate::subjectInfo(SubjectInfo info) const */ QString QSslCertificate::subjectInfo(const QByteArray &tag) const { - // ### Use a QByteArray for the keys in the map + // lazy init + if (d->subjectInfo.isEmpty() && d->x509) + d->subjectInfo = + _q_mapFromOnelineName(q_X509_NAME_oneline(q_X509_get_subject_name(d->x509), 0, 0)); + return d->subjectInfo.value(QString::fromLatin1(tag)); } diff --git a/src/script/bridge/qscriptqobject.cpp b/src/script/bridge/qscriptqobject.cpp index fb0dddb..db312bc 100644 --- a/src/script/bridge/qscriptqobject.cpp +++ b/src/script/bridge/qscriptqobject.cpp @@ -978,7 +978,8 @@ JSC::JSValue QtFunction::execute(JSC::ExecState *exec, JSC::JSValue thisValue, QScriptObjectDelegate *delegate = scriptObject->delegate(); Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::QtObject)); QObject *qobj = static_cast<QScript::QObjectDelegate*>(delegate)->value(); - Q_ASSERT_X(qobj != 0, "QtFunction::call", "handle the case when QObject has been deleted"); + if (!qobj) + return JSC::throwError(exec, JSC::GeneralError, QString::fromLatin1("cannot call function of deleted QObject")); QScriptEnginePrivate *engine = scriptEngineFromExec(exec); const QMetaObject *meta = qobj->metaObject(); @@ -2219,7 +2220,14 @@ void QObjectConnectionManager::execute(int slotIndex, void **argv) JSC::call(exec, slot, callType, callData, thisObject, jscArgs); if (exec->hadException()) { - engine->emitSignalHandlerException(); + if (slot.inherits(&QtFunction::info) && !static_cast<QtFunction*>(JSC::asObject(slot))->qobject()) { + // The function threw an error because the target QObject has been deleted. + // The connections list is stale; remove the signal handler and ignore the exception. + removeSignalHandler(sender(), signalIndex, receiver, slot); + exec->clearException(); + } else { + engine->emitSignalHandlerException(); + } } } diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index 33753f1..eec4797 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -838,13 +838,20 @@ void tst_QNetworkReply::stateChecking() QVERIFY(reply->isOpen()); QVERIFY(reply->isReadable()); QVERIFY(!reply->isWritable()); - QCOMPARE(reply->errorString(), QString("Unknown error")); + + // both behaviours are OK since we might change underlying behaviour again + if (!reply->isFinished()) + QCOMPARE(reply->errorString(), QString("Unknown error")); + else + QVERIFY(!reply->errorString().isEmpty()); + QCOMPARE(reply->manager(), &manager); QCOMPARE(reply->request(), req); QCOMPARE(int(reply->operation()), int(QNetworkAccessManager::GetOperation)); - QCOMPARE(reply->error(), QNetworkReply::NoError); - QCOMPARE(reply->isFinished(), false); + // error and not error are OK since we might change underlying behaviour again + if (!reply->isFinished()) + QCOMPARE(reply->error(), QNetworkReply::NoError); QCOMPARE(reply->url(), url); reply->abort(); @@ -1151,7 +1158,8 @@ void tst_QNetworkReply::getErrors() QNetworkReplyPtr reply = manager.get(request); reply->setParent(this); // we have expect-fails - QCOMPARE(reply->error(), QNetworkReply::NoError); + if (!reply->isFinished()) + QCOMPARE(reply->error(), QNetworkReply::NoError); // now run the request: connect(reply, SIGNAL(finished()), @@ -1512,6 +1520,7 @@ void tst_QNetworkReply::ioGetFromFile() QNetworkRequest request(QUrl::fromLocalFile(file.fileName())); QNetworkReplyPtr reply = manager.get(request); + QVERIFY(reply->isFinished()); // a file should immediatly be done DataReader reader(reply); connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); @@ -3170,12 +3179,13 @@ void tst_QNetworkReply::ioPostToHttpEmptyUploadProgress() void tst_QNetworkReply::lastModifiedHeaderForFile() { - QFileInfo fileInfo(SRCDIR "./bigfile"); + QFileInfo fileInfo(SRCDIR "/bigfile"); + QVERIFY(fileInfo.exists()); + QUrl url = QUrl::fromLocalFile(fileInfo.filePath()); QNetworkRequest request(url); QNetworkReplyPtr reply = manager.head(request); - QSignalSpy spy(reply, SIGNAL(uploadProgress(qint64,qint64))); connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); QTestEventLoop::instance().enterLoop(10); QVERIFY(!QTestEventLoop::instance().timeout()); @@ -3191,7 +3201,6 @@ void tst_QNetworkReply::lastModifiedHeaderForHttp() QNetworkRequest request(url); QNetworkReplyPtr reply = manager.head(request); - QSignalSpy spy(reply, SIGNAL(uploadProgress(qint64,qint64))); connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); QTestEventLoop::instance().enterLoop(10); QVERIFY(!QTestEventLoop::instance().timeout()); diff --git a/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp b/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp index 3415163..b4ce561 100644 --- a/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp +++ b/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp @@ -532,6 +532,7 @@ private slots: void prototypes(); void objectDeleted(); void connectToDestroyedSignal(); + void emitAfterReceiverDeleted(); private: QScriptEngine *m_engine; @@ -2913,7 +2914,8 @@ void tst_QScriptExtQObject::objectDeleted() v.setProperty("intProperty", QScriptValue(&eng, 123)); QCOMPARE(qobj->intProperty(), 123); qobj->resetQtFunctionInvoked(); - v.property("myInvokable").call(v); + QScriptValue invokable = v.property("myInvokable"); + invokable.call(v); QCOMPARE(qobj->qtFunctionInvoked(), 0); // now delete the object @@ -2951,6 +2953,14 @@ void tst_QScriptExtQObject::objectDeleted() QCOMPARE(ret.toString(), QLatin1String("Error: cannot access member `myInvokableWithIntArg' of deleted QObject")); } + // Meta-method wrappers are still valid, but throw error when called + QVERIFY(invokable.isFunction()); + { + QScriptValue ret = invokable.call(v); + QVERIFY(ret.isError()); + QCOMPARE(ret.toString(), QString::fromLatin1("Error: cannot call function of deleted QObject")); + } + // access from script eng.globalObject().setProperty("o", v); { @@ -3011,5 +3021,27 @@ void tst_QScriptExtQObject::connectToDestroyedSignal() #endif } +void tst_QScriptExtQObject::emitAfterReceiverDeleted() +{ + for (int x = 0; x < 2; ++x) { + MyQObject *obj = new MyQObject; + QScriptValue scriptObj = m_engine->newQObject(obj); + if (x == 0) { + // Connecting from JS + m_engine->globalObject().setProperty("obj", scriptObj); + QVERIFY(m_engine->evaluate("myObject.mySignal.connect(obj, 'mySlot()')").isUndefined()); + } else { + // Connecting from C++ + qScriptConnect(m_myObject, SIGNAL(mySignal()), scriptObj, scriptObj.property("mySlot")); + } + delete obj; + QSignalSpy signalHandlerExceptionSpy(m_engine, SIGNAL(signalHandlerException(QScriptValue))); + QVERIFY(!m_engine->hasUncaughtException()); + m_myObject->emitMySignal(); + QCOMPARE(signalHandlerExceptionSpy.count(), 0); + QVERIFY(!m_engine->hasUncaughtException()); + } +} + QTEST_MAIN(tst_QScriptExtQObject) #include "tst_qscriptextqobject.moc" diff --git a/tests/auto/qsslcertificate/tst_qsslcertificate.cpp b/tests/auto/qsslcertificate/tst_qsslcertificate.cpp index 892d745..44f8522 100644 --- a/tests/auto/qsslcertificate/tst_qsslcertificate.cpp +++ b/tests/auto/qsslcertificate/tst_qsslcertificate.cpp @@ -105,6 +105,7 @@ private slots: void fromPath_data(); void fromPath(); void certInfo(); + void certInfoQByteArray(); void task256066toPem(); void nulInCN(); void nulInSan(); @@ -697,6 +698,18 @@ void tst_QSslCertificate::certInfo() QCOMPARE(cert, QSslCertificate(QByteArray::fromHex(der), QSsl::Der)); } +void tst_QSslCertificate::certInfoQByteArray() +{ + QSslCertificate cert = QSslCertificate::fromPath("certificates/cert.pem", QSsl::Pem, + QRegExp::FixedString).first(); + QVERIFY(!cert.isNull()); + + // in this test, check the bytearray variants before the enum variants to see if + // we fixed a bug we had with lazy initialization of the values. + QCOMPARE(cert.issuerInfo("CN"), QString("Test CA (1024 bit)")); + QCOMPARE(cert.subjectInfo("CN"), QString("name/with/slashes")); +} + void tst_QSslCertificate::task256066toPem() { // a certificate whose PEM encoding's length is a multiple of 64 diff --git a/tests/benchmarks/qfile_vs_qnetworkaccessmanager/main.cpp b/tests/benchmarks/qfile_vs_qnetworkaccessmanager/main.cpp index 907ffb7..23e07db 100644 --- a/tests/benchmarks/qfile_vs_qnetworkaccessmanager/main.cpp +++ b/tests/benchmarks/qfile_vs_qnetworkaccessmanager/main.cpp @@ -55,11 +55,13 @@ class qfile_vs_qnetworkaccessmanager : public QObject // but.. this is a manual test anyway, so :) protected: void qnamFileRead_iteration(QNetworkAccessManager &manager, QNetworkRequest &request); + void qnamImmediateFileRead_iteration(QNetworkAccessManager &manager, QNetworkRequest &request); void qfileFileRead_iteration(); static const int iterations = 10; private slots: void qnamFileRead(); + void qnamImmediateFileRead(); void qfileFileRead(); void initTestCase(); @@ -124,6 +126,39 @@ void qfile_vs_qnetworkaccessmanager::qnamFileRead() qDebug() << "Speed:" << (qreal(size*iterations) / 1024.0) / (qreal(elapsed) / 1000.0) << "KB/sec"; } +void qfile_vs_qnetworkaccessmanager::qnamImmediateFileRead_iteration(QNetworkAccessManager &manager, QNetworkRequest &request) +{ + QNetworkReply* reply = manager.get(request); + QVERIFY(reply->isFinished()); // should be like that! + QByteArray qba = reply->readAll(); + delete reply; +} + +void qfile_vs_qnetworkaccessmanager::qnamImmediateFileRead() +{ + QNetworkAccessManager manager; + QTime t; + QNetworkRequest request(QUrl(testFile.fileName())); + + // do 3 dry runs for cache warmup + qnamImmediateFileRead_iteration(manager, request); + qnamImmediateFileRead_iteration(manager, request); + qnamImmediateFileRead_iteration(manager, request); + + t.start(); + // 10 real runs + QBENCHMARK_ONCE { + for (int i = 0; i < iterations; i++) { + qnamImmediateFileRead_iteration(manager, request); + } + } + + qint64 elapsed = t.elapsed(); + qDebug() << endl << "Finished!"; + qDebug() << "Bytes:" << size; + qDebug() << "Speed:" << (qreal(size*iterations) / 1024.0) / (qreal(elapsed) / 1000.0) << "KB/sec"; +} + void qfile_vs_qnetworkaccessmanager::qfileFileRead_iteration() { testFile.reset(); diff --git a/translations/translations.pri b/translations/translations.pri index 7a24a4f..8896654 100644 --- a/translations/translations.pri +++ b/translations/translations.pri @@ -8,8 +8,12 @@ defineReplace(prependAll) { return ($$result) } -LUPDATE = $$QT_BUILD_TREE/bin/lupdate -locations relative -no-ui-lines -LUPDATE ~= s,/,$$QMAKE_DIR_SEP, +LUPDATE = $$QT_BUILD_TREE/bin/lupdate +win32 { + LUPDATE ~= s,/,$$QMAKE_DIR_SEP, + LUPDATE = $${LUPDATE}.exe +} +LUPDATE += -locations relative -no-ui-lines ###### Qt Libraries diff --git a/translations/translations.pro b/translations/translations.pro index ef09dc3..f1b9c99 100644 --- a/translations/translations.pro +++ b/translations/translations.pro @@ -1,7 +1,10 @@ TRANSLATIONS = $$files(*.ts) LRELEASE = $$QT_BUILD_TREE/bin/lrelease -LRELEASE ~= s,/,$$QMAKE_DIR_SEP, +win32 { + LRELEASE ~= s,/,$$QMAKE_DIR_SEP, + LRELEASE = $${LRELEASE}.exe +} contains(TEMPLATE_PREFIX, vc):vcproj = 1 @@ -14,7 +17,8 @@ LIBS = updateqm.input = TRANSLATIONS updateqm.output = ${QMAKE_FILE_BASE}.qm isEmpty(vcproj):updateqm.variable_out = PRE_TARGETDEPS -updateqm.commands = @echo lrelease ${QMAKE_FILE_IN}; $$LRELEASE ${QMAKE_FILE_IN} -qm ${QMAKE_FILE_OUT} +updateqm.commands = $$LRELEASE ${QMAKE_FILE_IN} -qm ${QMAKE_FILE_OUT} +silent:updateqm.commands = @echo lrelease ${QMAKE_FILE_IN} && $$updateqm.commands updateqm.name = LRELEASE ${QMAKE_FILE_IN} updateqm.CONFIG += no_link QMAKE_EXTRA_COMPILERS += updateqm |