diff options
21 files changed, 633 insertions, 556 deletions
diff --git a/examples/network/http/httpwindow.cpp b/examples/network/http/httpwindow.cpp index 95fc82f..ec7cd33 100644 --- a/examples/network/http/httpwindow.cpp +++ b/examples/network/http/httpwindow.cpp @@ -49,9 +49,9 @@ HttpWindow::HttpWindow(QWidget *parent) : QDialog(parent) { #ifndef QT_NO_OPENSSL - urlLineEdit = new QLineEdit("https://"); + urlLineEdit = new QLineEdit("https://qt.nokia.com/"); #else - urlLineEdit = new QLineEdit("http://"); + urlLineEdit = new QLineEdit("http://qt.nokia.com/"); #endif urlLabel = new QLabel(tr("&URL:")); @@ -70,21 +70,14 @@ HttpWindow::HttpWindow(QWidget *parent) progressDialog = new QProgressDialog(this); - http = new QHttp(this); - connect(urlLineEdit, SIGNAL(textChanged(QString)), this, SLOT(enableDownloadButton())); - connect(http, SIGNAL(requestFinished(int,bool)), - this, SLOT(httpRequestFinished(int,bool))); - connect(http, SIGNAL(dataReadProgress(int,int)), - this, SLOT(updateDataReadProgress(int,int))); - connect(http, SIGNAL(responseHeaderReceived(QHttpResponseHeader)), - this, SLOT(readResponseHeader(QHttpResponseHeader))); - connect(http, SIGNAL(authenticationRequired(QString,quint16,QAuthenticator*)), - this, SLOT(slotAuthenticationRequired(QString,quint16,QAuthenticator*))); + + connect(&qnam, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), + this, SLOT(slotAuthenticationRequired(QNetworkReply*,QAuthenticator*))); #ifndef QT_NO_OPENSSL - connect(http, SIGNAL(sslErrors(QList<QSslError>)), - this, SLOT(sslErrors(QList<QSslError>))); + connect(&qnam, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)), + this, SLOT(sslErrors(QNetworkReply*,QList<QSslError>))); #endif connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelDownload())); connect(downloadButton, SIGNAL(clicked()), this, SLOT(downloadFile())); @@ -104,9 +97,21 @@ HttpWindow::HttpWindow(QWidget *parent) urlLineEdit->setFocus(); } +void HttpWindow::startRequest(QUrl url) +{ + reply = qnam.get(QNetworkRequest(url)); + connect(reply, SIGNAL(finished()), + this, SLOT(httpFinished())); + connect(reply, SIGNAL(readyRead()), + this, SLOT(httpReadyRead())); + connect(reply, SIGNAL(downloadProgress(qint64,qint64)), + this, SLOT(updateDataReadProgress(qint64,qint64))); +} + void HttpWindow::downloadFile() { - QUrl url(urlLineEdit->text()); + url = urlLineEdit->text(); + QFileInfo fileInfo(url.path()); QString fileName = fileInfo.fileName(); if (fileName.isEmpty()) @@ -132,35 +137,26 @@ void HttpWindow::downloadFile() return; } - QHttp::ConnectionMode mode = url.scheme().toLower() == "https" ? QHttp::ConnectionModeHttps : QHttp::ConnectionModeHttp; - http->setHost(url.host(), mode, url.port() == -1 ? 0 : url.port()); - - if (!url.userName().isEmpty()) - http->setUser(url.userName(), url.password()); - - httpRequestAborted = false; - QByteArray path = QUrl::toPercentEncoding(url.path(), "!$&'()*+,;=:@/"); - if (path.isEmpty()) - path = "/"; - httpGetId = http->get(path, file); progressDialog->setWindowTitle(tr("HTTP")); progressDialog->setLabelText(tr("Downloading %1.").arg(fileName)); downloadButton->setEnabled(false); + + // schedule the request + httpRequestAborted = false; + startRequest(url); } void HttpWindow::cancelDownload() { statusLabel->setText(tr("Download canceled.")); httpRequestAborted = true; - http->abort(); + reply->abort(); downloadButton->setEnabled(true); } -void HttpWindow::httpRequestFinished(int requestId, bool error) +void HttpWindow::httpFinished() { - if (requestId != httpGetId) - return; if (httpRequestAborted) { if (file) { file->close(); @@ -168,54 +164,58 @@ void HttpWindow::httpRequestFinished(int requestId, bool error) delete file; file = 0; } - + reply->deleteLater(); progressDialog->hide(); return; } - if (requestId != httpGetId) - return; - progressDialog->hide(); + file->flush(); file->close(); - if (error) { + + QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); + if (reply->error()) { file->remove(); QMessageBox::information(this, tr("HTTP"), tr("Download failed: %1.") - .arg(http->errorString())); + .arg(reply->errorString())); + downloadButton->setEnabled(true); + } else if (!redirectionTarget.isNull()) { + QUrl newUrl = url.resolved(redirectionTarget.toUrl()); + if (QMessageBox::question(this, tr("HTTP"), + tr("Redirect to %1 ?").arg(newUrl.toString()), + QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { + url = newUrl; + reply->deleteLater(); + file->open(QIODevice::WriteOnly); + file->resize(0); + startRequest(url); + return; + } } else { QString fileName = QFileInfo(QUrl(urlLineEdit->text()).path()).fileName(); statusLabel->setText(tr("Downloaded %1 to current directory.").arg(fileName)); + downloadButton->setEnabled(true); } - downloadButton->setEnabled(true); + reply->deleteLater(); + reply = 0; delete file; file = 0; } -void HttpWindow::readResponseHeader(const QHttpResponseHeader &responseHeader) +void HttpWindow::httpReadyRead() { - switch (responseHeader.statusCode()) { - case 200: // Ok - case 301: // Moved Permanently - case 302: // Found - case 303: // See Other - case 307: // Temporary Redirect - // these are not error conditions - break; - - default: - QMessageBox::information(this, tr("HTTP"), - tr("Download failed: %1.") - .arg(responseHeader.reasonPhrase())); - httpRequestAborted = true; - progressDialog->hide(); - http->abort(); - } + // this slot gets called everytime the QNetworkReply has new data. + // We read all of its new data and write it into the file. + // That way we use less RAM than when reading it at the finished() + // signal of the QNetworkReply + if (file) + file->write(reply->readAll()); } -void HttpWindow::updateDataReadProgress(int bytesRead, int totalBytes) +void HttpWindow::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes) { if (httpRequestAborted) return; @@ -229,14 +229,19 @@ void HttpWindow::enableDownloadButton() downloadButton->setEnabled(!urlLineEdit->text().isEmpty()); } -void HttpWindow::slotAuthenticationRequired(const QString &hostName, quint16, QAuthenticator *authenticator) +void HttpWindow::slotAuthenticationRequired(QNetworkReply*,QAuthenticator *authenticator) { QDialog dlg; Ui::Dialog ui; ui.setupUi(&dlg); dlg.adjustSize(); - ui.siteDescription->setText(tr("%1 at %2").arg(authenticator->realm()).arg(hostName)); - + ui.siteDescription->setText(tr("%1 at %2").arg(authenticator->realm()).arg(url.host())); + + // Did the URL have information? Fill the UI + // This is only relevant if the URL-supplied credentials were wrong + ui.userEdit->setText(url.userName()); + ui.passwordEdit->setText(url.password()); + if (dlg.exec() == QDialog::Accepted) { authenticator->setUser(ui.userEdit->text()); authenticator->setPassword(ui.passwordEdit->text()); @@ -244,7 +249,7 @@ void HttpWindow::slotAuthenticationRequired(const QString &hostName, quint16, QA } #ifndef QT_NO_OPENSSL -void HttpWindow::sslErrors(const QList<QSslError> &errors) +void HttpWindow::sslErrors(QNetworkReply*,const QList<QSslError> &errors) { QString errorString; foreach (const QSslError &error, errors) { @@ -253,10 +258,10 @@ void HttpWindow::sslErrors(const QList<QSslError> &errors) errorString += error.errorString(); } - if (QMessageBox::warning(this, tr("HTTP Example"), + if (QMessageBox::warning(this, tr("HTTP"), tr("One or more SSL errors has occurred: %1").arg(errorString), QMessageBox::Ignore | QMessageBox::Abort) == QMessageBox::Ignore) { - http->ignoreSslErrors(); + reply->ignoreSslErrors(); } } #endif diff --git a/examples/network/http/httpwindow.h b/examples/network/http/httpwindow.h index 9dca8a5..83898af 100644 --- a/examples/network/http/httpwindow.h +++ b/examples/network/http/httpwindow.h @@ -43,18 +43,21 @@ #define HTTPWINDOW_H #include <QDialog> +#include <QNetworkAccessManager> +#include <QUrl> QT_BEGIN_NAMESPACE class QDialogButtonBox; class QFile; -class QHttp; -class QHttpResponseHeader; class QLabel; class QLineEdit; class QProgressDialog; class QPushButton; class QSslError; class QAuthenticator; +class QNetworkReply; + + QT_END_NAMESPACE class HttpWindow : public QDialog @@ -64,16 +67,18 @@ class HttpWindow : public QDialog public: HttpWindow(QWidget *parent = 0); + void startRequest(QUrl url); + private slots: void downloadFile(); void cancelDownload(); - void httpRequestFinished(int requestId, bool error); - void readResponseHeader(const QHttpResponseHeader &responseHeader); - void updateDataReadProgress(int bytesRead, int totalBytes); + void httpFinished(); + void httpReadyRead(); + void updateDataReadProgress(qint64 bytesRead, qint64 totalBytes); void enableDownloadButton(); - void slotAuthenticationRequired(const QString &, quint16, QAuthenticator *); + void slotAuthenticationRequired(QNetworkReply*,QAuthenticator *); #ifndef QT_NO_OPENSSL - void sslErrors(const QList<QSslError> &errors); + void sslErrors(QNetworkReply*,const QList<QSslError> &errors); #endif private: @@ -85,7 +90,9 @@ private: QPushButton *quitButton; QDialogButtonBox *buttonBox; - QHttp *http; + QUrl url; + QNetworkAccessManager qnam; + QNetworkReply *reply; QFile *file; int httpGetId; bool httpRequestAborted; diff --git a/examples/network/http/main.cpp b/examples/network/http/main.cpp index ecbe100..817b2be 100644 --- a/examples/network/http/main.cpp +++ b/examples/network/http/main.cpp @@ -46,7 +46,6 @@ int main(int argc, char *argv[]) { QApplication app(argc, argv); - qWarning("The usage of QHttp is not recommended anymore, please use QNetworkAccessManager."); HttpWindow httpWin; httpWin.show(); return httpWin.exec(); diff --git a/examples/network/loopback/dialog.cpp b/examples/network/loopback/dialog.cpp index 27cff31..b504e36 100644 --- a/examples/network/loopback/dialog.cpp +++ b/examples/network/loopback/dialog.cpp @@ -44,12 +44,12 @@ #include "dialog.h" -#if !defined(Q_OS_WINCE) +#if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN) static const int TotalBytes = 50 * 1024 * 1024; #else static const int TotalBytes = 5 * 1024 * 1024; #endif -static const int PayloadSize = 65536; +static const int PayloadSize = 64 * 1024; // 64 KB Dialog::Dialog(QWidget *parent) : QDialog(parent) @@ -130,6 +130,7 @@ void Dialog::acceptConnection() void Dialog::startTransfer() { + // called when the TCP client connected to the loopback server bytesToWrite = TotalBytes - (int)tcpClient.write(QByteArray(PayloadSize, '@')); clientStatusLabel->setText(tr("Connected")); } @@ -155,8 +156,11 @@ void Dialog::updateServerProgress() void Dialog::updateClientProgress(qint64 numBytes) { + // callen when the TCP client has written some bytes bytesWritten += (int)numBytes; - if (bytesToWrite > 0) + + // only write more if not finished and when the Qt write buffer is below a certain size. + if (bytesToWrite > 0 && tcpClient.bytesToWrite() <= 4*PayloadSize) bytesToWrite -= (int)tcpClient.write(QByteArray(qMin(bytesToWrite, PayloadSize), '@')); clientProgressBar->setMaximum(TotalBytes); diff --git a/src/gui/dialogs/qfontdialog.cpp b/src/gui/dialogs/qfontdialog.cpp index 56580a9..a4bf15d 100644 --- a/src/gui/dialogs/qfontdialog.cpp +++ b/src/gui/dialogs/qfontdialog.cpp @@ -989,34 +989,24 @@ void QFontDialog::open(QObject *receiver, const char *member) void QFontDialog::setVisible(bool visible) { Q_D(QFontDialog); - if (visible) - d->selectedFont = QFont(); - -#if defined(Q_WS_MAC) - bool isCurrentlyVisible = (isVisible() || d->delegate); - - if (!visible == !isCurrentlyVisible) - return; - if (visible) { - if (!(d->opts & DontUseNativeDialog) && QFontDialogPrivate::sharedFontPanelAvailable) { - d->delegate = QFontDialogPrivate::openCocoaFontPanel( - currentFont(), parentWidget(), windowTitle(), options(), d); - QFontDialogPrivate::sharedFontPanelAvailable = false; - return; - } - - setWindowFlags(windowModality() == Qt::WindowModal ? Qt::Sheet : DefaultWindowFlags); - } else { - if (d->delegate) { - QFontDialogPrivate::closeCocoaFontPanel(d->delegate); - d->delegate = 0; - QFontDialogPrivate::sharedFontPanelAvailable = true; + if (testAttribute(Qt::WA_WState_ExplicitShowHide) && !testAttribute(Qt::WA_WState_Hidden)) return; + } else if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden)) + return; +#ifdef Q_WS_MAC + if (d->canBeNativeDialog()){ + if (d->setVisible_sys(visible)){ + d->nativeDialogInUse = true; + // Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below + // updates the state correctly, but skips showing the non-native version: + setAttribute(Qt::WA_DontShowOnScreen, true); + } else { + d->nativeDialogInUse = false; + setAttribute(Qt::WA_DontShowOnScreen, false); } } -#endif - +#endif // Q_WS_MAC QDialog::setVisible(visible); } @@ -1032,11 +1022,14 @@ void QFontDialog::done(int result) Q_D(QFontDialog); QDialog::done(result); if (result == Accepted) { - d->selectedFont = currentFont(); + // We check if this is the same font we had before, if so we emit currentFontChanged + QFont selectedFont = currentFont(); + if(selectedFont != d->selectedFont) + emit(currentFontChanged(selectedFont)); + d->selectedFont = selectedFont; emit fontSelected(d->selectedFont); - } else { + } else d->selectedFont = QFont(); - } if (d->receiverToDisconnectOnClose) { disconnect(this, SIGNAL(fontSelected(QFont)), d->receiverToDisconnectOnClose, d->memberToDisconnectOnClose); @@ -1045,6 +1038,23 @@ void QFontDialog::done(int result) d->memberToDisconnectOnClose.clear(); } +#ifdef Q_WS_MAC +bool QFontDialogPrivate::canBeNativeDialog() +{ + Q_Q(QFontDialog); + if (nativeDialogInUse) + return true; + if (q->testAttribute(Qt::WA_DontShowOnScreen)) + return false; + if (opts & QFontDialog::DontUseNativeDialog) + return false; + + QLatin1String staticName(QFontDialog::staticMetaObject.className()); + QLatin1String dynamicName(q->metaObject()->className()); + return (staticName == dynamicName); +} +#endif // Q_WS_MAC + /*! \fn QFont QFontDialog::getFont(bool *ok, const QFont &initial, QWidget* parent, const char* name) \since 4.5 diff --git a/src/gui/dialogs/qfontdialog.h b/src/gui/dialogs/qfontdialog.h index e6f209e..6035a3a 100644 --- a/src/gui/dialogs/qfontdialog.h +++ b/src/gui/dialogs/qfontdialog.h @@ -131,6 +131,9 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_styleHighlighted(int)) Q_PRIVATE_SLOT(d_func(), void _q_sizeHighlighted(int)) Q_PRIVATE_SLOT(d_func(), void _q_updateSample()) +#if defined(Q_WS_MAC) + Q_PRIVATE_SLOT(d_func(), void _q_macRunNativeAppModalPanel()) +#endif }; Q_DECLARE_OPERATORS_FOR_FLAGS(QFontDialog::FontDialogOptions) diff --git a/src/gui/dialogs/qfontdialog_mac.mm b/src/gui/dialogs/qfontdialog_mac.mm index 68f5f00..67d32b8 100644 --- a/src/gui/dialogs/qfontdialog_mac.mm +++ b/src/gui/dialogs/qfontdialog_mac.mm @@ -49,6 +49,7 @@ #include <private/qfontengine_p.h> #include <private/qt_cocoa_helpers_mac_p.h> #include <private/qt_mac_p.h> +#include <qabstracteventdispatcher.h> #include <qdebug.h> #import <AppKit/AppKit.h> #import <Foundation/Foundation.h> @@ -372,7 +373,12 @@ static QFont qfontForCocoaFont(NSFont *cocoaFont, const QFont &resolveFont) [NSApp endModalSession:mModalSession]; mModalSession = 0; } - + // Hack alert! + // Since this code path was never intended to be followed when starting from exec + // we need to force the dialog to communicate the new font, otherwise the signal + // won't get emitted. + if(code == NSOKButton) + mPriv->sampleEdit->setFont([self qtFont]); mPriv->done((code == NSOKButton) ? QDialog::Accepted : QDialog::Rejected); } else { [NSApp stopModalWithCode:code]; @@ -567,7 +573,6 @@ void *QFontDialogPrivate::openCocoaFontPanel(const QFont &initial, [ourPanel makeKeyAndOrderFront:ourPanel]; } } - return delegate; } @@ -640,6 +645,145 @@ void QFontDialogPrivate::setFont(void *delegate, const QFont &font) [static_cast<QCocoaFontPanelDelegate *>(delegate) setQtFont:font]; } +void *QFontDialogPrivate::_q_constructNativePanel() +{ + QMacCocoaAutoReleasePool pool; + + bool sharedFontPanelExisted = [NSFontPanel sharedFontPanelExists]; + NSFontPanel *sharedFontPanel = [NSFontPanel sharedFontPanel]; + [sharedFontPanel setHidesOnDeactivate:false]; + + // hack to ensure that QCocoaApplication's validModesForFontPanel: + // implementation is honored + if (!sharedFontPanelExisted) { + [sharedFontPanel makeKeyAndOrderFront:sharedFontPanel]; + [sharedFontPanel close]; + } + + NSPanel *ourPanel = 0; + NSView *stolenContentView = 0; + NSButton *okButton = 0; + NSButton *cancelButton = 0; + + CGFloat dialogExtraWidth = 0.0; + CGFloat dialogExtraHeight = 0.0; + + // compute dialogExtra{Width,Height} + dialogExtraWidth = 2.0 * DialogSideMargin; + dialogExtraHeight = DialogTopMargin + ButtonTopMargin + ButtonMinHeight + + ButtonBottomMargin; + + // compute initial contents rectangle + NSRect contentRect = [sharedFontPanel contentRectForFrameRect:[sharedFontPanel frame]]; + contentRect.size.width += dialogExtraWidth; + contentRect.size.height += dialogExtraHeight; + + // create the new panel + ourPanel = [[NSPanel alloc] initWithContentRect:contentRect + styleMask:StyleMask + backing:NSBackingStoreBuffered + defer:YES]; + [ourPanel setReleasedWhenClosed:YES]; + + stolenContentView = [sharedFontPanel contentView]; + + // steal the font panel's contents view + [stolenContentView retain]; + [sharedFontPanel setContentView:0]; + + { + // create a new content view and add the stolen one as a subview + NSRect frameRect = { { 0.0, 0.0 }, { 0.0, 0.0 } }; + NSView *ourContentView = [[NSView alloc] initWithFrame:frameRect]; + [ourContentView addSubview:stolenContentView]; + + // create OK and Cancel buttons and add these as subviews + okButton = macCreateButton("&OK", ourContentView); + cancelButton = macCreateButton("Cancel", ourContentView); + + [ourPanel setContentView:ourContentView]; + [ourPanel setDefaultButtonCell:[okButton cell]]; + } + // create a delegate and set it + QCocoaFontPanelDelegate *delegate = + [[QCocoaFontPanelDelegate alloc] initWithFontPanel:sharedFontPanel + stolenContentView:stolenContentView + okButton:okButton + cancelButton:cancelButton + priv:this + extraWidth:dialogExtraWidth + extraHeight:dialogExtraHeight]; + [ourPanel setDelegate:delegate]; + [[NSFontManager sharedFontManager] setDelegate:delegate]; +#ifdef QT_MAC_USE_COCOA + [[NSFontManager sharedFontManager] setTarget:delegate]; +#endif + setFont(delegate, QApplication::font()); + + { + // hack to get correct initial layout + NSRect frameRect = [ourPanel frame]; + frameRect.size.width += 1.0; + [ourPanel setFrame:frameRect display:NO]; + frameRect.size.width -= 1.0; + frameRect.size = [delegate windowWillResize:ourPanel toSize:frameRect.size]; + [ourPanel setFrame:frameRect display:NO]; + [ourPanel center]; + } + NSString *title = @"Select font"; + [ourPanel setTitle:title]; + + [delegate setModalSession:[NSApp beginModalSessionForWindow:ourPanel]]; + return delegate; +} + +void QFontDialogPrivate::mac_nativeDialogModalHelp() +{ + // Copied from QFileDialogPrivate + // Do a queued meta-call to open the native modal dialog so it opens after the new + // event loop has started to execute (in QDialog::exec). Using a timer rather than + // a queued meta call is intentional to ensure that the call is only delivered when + // [NSApp run] runs (timers are handeled special in cocoa). If NSApp is not + // running (which is the case if e.g a top-most QEventLoop has been + // interrupted, and the second-most event loop has not yet been reactivated (regardless + // if [NSApp run] is still on the stack)), showing a native modal dialog will fail. + if (nativeDialogInUse) { + Q_Q(QFontDialog); + QTimer::singleShot(1, q, SLOT(_q_macRunNativeAppModalPanel())); + } +} + +// The problem with the native font dialog is that OS X does not +// offer a proper dialog, but a panel (i.e. without Ok and Cancel buttons). +// This means we need to "construct" a native dialog by taking the panel +// and "adding" the buttons. +void QFontDialogPrivate::_q_macRunNativeAppModalPanel() +{ + QBoolBlocker nativeDialogOnTop(QApplicationPrivate::native_modal_dialog_active); + Q_Q(QFontDialog); + QCocoaFontPanelDelegate *delegate = (QCocoaFontPanelDelegate *)_q_constructNativePanel(); + NSWindow *ourPanel = [delegate actualPanel]; + [ourPanel retain]; + int rval = [NSApp runModalForWindow:ourPanel]; + QAbstractEventDispatcher::instance()->interrupt(); + [ourPanel release]; + [delegate cleanUpAfterMyself]; + [delegate release]; + bool isOk = (rval == NSOKButton); + if(isOk) + rescode = QDialog::Accepted; + else + rescode = QDialog::Rejected; +} + +bool QFontDialogPrivate::setVisible_sys(bool visible) +{ + Q_Q(QFontDialog); + if (!visible == q->isHidden()) + return false; + return visible; +} + QT_END_NAMESPACE #endif diff --git a/src/gui/dialogs/qfontdialog_p.h b/src/gui/dialogs/qfontdialog_p.h index ca2b10b..7654a80 100644 --- a/src/gui/dialogs/qfontdialog_p.h +++ b/src/gui/dialogs/qfontdialog_p.h @@ -152,6 +152,12 @@ public: inline QFontDialog *fontDialog() { return q_func(); } void *delegate; + bool nativeDialogInUse; + bool canBeNativeDialog(); + bool setVisible_sys(bool visible); + void *_q_constructNativePanel(); + void _q_macRunNativeAppModalPanel(); + void mac_nativeDialogModalHelp(); static bool sharedFontPanelAvailable; #endif diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 0a4869b..aac834d 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -1905,8 +1905,13 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam break; if (!msg.wParam) { +#ifdef Q_WS_WINCE + // On Windows CE, lParam parameter is a constant, not a char pointer. + if (msg.lParam == INI_INTL) { +#else QString area = QString::fromWCharArray((wchar_t*)msg.lParam); if (area == QLatin1String("intl")) { +#endif QLocalePrivate::updateSystemPrivate(); if (!widget->testAttribute(Qt::WA_SetLocale)) widget->dptr()->setLocale_helper(QLocale(), true); diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp index b36294a..c550938 100644 --- a/src/gui/styles/qstylesheetstyle.cpp +++ b/src/gui/styles/qstylesheetstyle.cpp @@ -5743,6 +5743,13 @@ QRect QStyleSheetStyle::subElementRect(SubElement se, const QStyleOption *opt, c return positionRect(w, subRule, subRule2, pe, opt->rect, opt->direction); } +#ifndef QT_NO_TOOLBAR + case SE_ToolBarHandle: + if (hasStyleRule(w, PseudoElement_ToolBarHandle)) + return ParentStyle::subElementRect(se, opt, w); + break; +#endif //QT_NO_TOOLBAR + default: break; } diff --git a/src/multimedia/audio/qaudioinput.cpp b/src/multimedia/audio/qaudioinput.cpp index 45cafc1..fd892dd 100644 --- a/src/multimedia/audio/qaudioinput.cpp +++ b/src/multimedia/audio/qaudioinput.cpp @@ -190,18 +190,18 @@ QAudioInput::~QAudioInput() Passing a QIODevice allows the data to be transfered without any extra code. All that is required is to open the QIODevice. + If able to successfully get audio data from the systems audio device the + state() is set to either QAudio::ActiveState or QAudio::IdleState, + error() is set to QAudio::NoError and the stateChanged() signal is emitted. + + If a problem occurs during this process the error() is set to QAudio::OpenError, + state() is set to QAudio::StoppedState and stateChanged() signal is emitted. + \sa QIODevice */ void QAudioInput::start(QIODevice* device) { - /* - -If currently not StoppedState, stop - -If previous start was push mode, delete internal QIODevice. - -open audio input. - If ok, NoError and ActiveState, else OpenError and StoppedState. - -emit stateChanged() - */ d->start(device); } @@ -210,19 +210,18 @@ void QAudioInput::start(QIODevice* device) transfer. This QIODevice can be used to read() audio data directly. + If able to access the systems audio device the state() is set to + QAudio::IdleState, error() is set to QAudio::NoError + and the stateChanged() signal is emitted. + + If a problem occurs during this process the error() is set to QAudio::OpenError, + state() is set to QAudio::StoppedState and stateChanged() signal is emitted. + \sa QIODevice */ QIODevice* QAudioInput::start() { - /* - -If currently not StoppedState, stop - -If no internal QIODevice, create one. - -open audio input. - -If ok, NoError and IdleState, else OpenError and StoppedState - -emit stateChanged() - -return internal QIODevice - */ return d->start(0); } @@ -236,17 +235,14 @@ QAudioFormat QAudioInput::format() const } /*! - Stops the audio input. + Stops the audio input, detaching from the system resource. + + Sets error() to QAudio::NoError, state() to QAudio::StoppedState and + emit stateChanged() signal. */ void QAudioInput::stop() { - /* - -If StoppedState, return - -set to StoppedState - -detach from audio device - -emit stateChanged() - */ d->stop(); } @@ -256,42 +252,32 @@ void QAudioInput::stop() void QAudioInput::reset() { - /* - -drop all buffered audio, set buffers to zero. - -call stop() - */ d->reset(); } /*! Stops processing audio data, preserving buffered audio data. + + Sets error() to QAudio::NoError, state() to QAudio::SuspendedState and + emit stateChanged() signal. */ void QAudioInput::suspend() { - /* - -If not ActiveState|IdleState, return - -stop processing audio, saving all buffered audio data - -set NoError and SuspendedState - -emit stateChanged() - */ d->suspend(); } /*! Resumes processing audio data after a suspend(). + + Sets error() to QAudio::NoError. + Sets state() to QAudio::ActiveState if you previously called start(QIODevice*). + Sets state() to QAudio::IdleState if you previously called start(). + emits stateChanged() signal. */ void QAudioInput::resume() { - /* - -If SuspendedState, return - -resume audio - -(PULL MODE): set ActiveState, NoError - -(PUSH MODE): set IdleState, NoError - -kick start audio if needed - -emit stateChanged() - */ d->resume(); } @@ -327,6 +313,9 @@ int QAudioInput::bufferSize() const /*! Returns the amount of audio data available to read in bytes. + + NOTE: returned value is only valid while in QAudio::ActiveState or QAudio::IdleState + state, otherwise returns zero. */ int QAudioInput::bytesReady() const @@ -352,7 +341,10 @@ int QAudioInput::periodSize() const /*! Sets the interval for notify() signal to be emitted. This is based on the \a ms of audio data processed - not on actual real-time. The resolution of the timer is platform specific. + not on actual real-time. + The minimum resolution of the timer is platform specific and values + should be checked with notifyInterval() to confirm actual value + being used. */ void QAudioInput::setNotifyInterval(int ms) diff --git a/src/multimedia/audio/qaudioinput_alsa_p.cpp b/src/multimedia/audio/qaudioinput_alsa_p.cpp index 26e46b3..6010f3c 100644 --- a/src/multimedia/audio/qaudioinput_alsa_p.cpp +++ b/src/multimedia/audio/qaudioinput_alsa_p.cpp @@ -217,9 +217,11 @@ QIODevice* QAudioInputPrivate::start(QIODevice* device) //set to pull mode pullMode = true; audioSource = device; + deviceState = QAudio::ActiveState; } else { //set to push mode pullMode = false; + deviceState = QAudio::IdleState; audioSource = new InputPrivate(this); audioSource->open(QIODevice::ReadOnly | QIODevice::Unbuffered); } @@ -413,7 +415,6 @@ bool QAudioInputPrivate::open() timer->start(period_time*chunks/2000); errorState = QAudio::NoError; - deviceState = QAudio::ActiveState; totalTimeValue = 0; @@ -439,7 +440,7 @@ int QAudioInputPrivate::bytesReady() const if(resuming) return period_size; - if(deviceState != QAudio::ActiveState) + if(deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState) return 0; int frames = snd_pcm_avail_update(handle); if((int)frames > (int)buffer_frames) @@ -450,8 +451,8 @@ int QAudioInputPrivate::bytesReady() const qint64 QAudioInputPrivate::read(char* data, qint64 len) { - Q_UNUSED(data) Q_UNUSED(len) + // Read in some audio data and write it to QIODevice, pull mode if ( !handle ) return 0; @@ -468,7 +469,7 @@ qint64 QAudioInputPrivate::read(char* data, qint64 len) if (readFrames >= 0) { err = snd_pcm_frames_to_bytes(handle, readFrames); #ifdef DEBUG_AUDIO - qDebug()<<QString::fromLatin1("PULL: read in bytes = %1 (frames=%2)").arg(err).arg(readFrames).toLatin1().constData(); + qDebug()<<QString::fromLatin1("read in bytes = %1 (frames=%2)").arg(err).arg(readFrames).toLatin1().constData(); #endif break; } else if((readFrames == -EAGAIN) || (readFrames == -EINTR)) { @@ -489,28 +490,46 @@ qint64 QAudioInputPrivate::read(char* data, qint64 len) if(err > 0) { // got some send it onward #ifdef DEBUG_AUDIO - qDebug()<<"PULL: frames to write to QIODevice = "<< + qDebug()<<"frames to write to QIODevice = "<< snd_pcm_bytes_to_frames( handle, (int)err )<<" ("<<err<<") bytes"; #endif - if(deviceState != QAudio::ActiveState) + if(deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState) return 0; + if (pullMode) { + qint64 l = audioSource->write(audioBuffer,err); + if(l < 0) { + close(); + errorState = QAudio::IOError; + deviceState = QAudio::StoppedState; + emit stateChanged(deviceState); + } else if(l == 0) { + if (deviceState != QAudio::IdleState) { + errorState = QAudio::NoError; + deviceState = QAudio::IdleState; + emit stateChanged(deviceState); + } + } else { + totalTimeValue += err; + resuming = false; + if (deviceState != QAudio::ActiveState) { + errorState = QAudio::NoError; + deviceState = QAudio::ActiveState; + emit stateChanged(deviceState); + } + } + return l; - qint64 l = audioSource->write(audioBuffer,err); - if(l < 0) { - close(); - errorState = QAudio::IOError; - deviceState = QAudio::StoppedState; - emit stateChanged(deviceState); - } else if(l == 0) { - errorState = QAudio::NoError; - deviceState = QAudio::IdleState; } else { - totalTimeValue += snd_pcm_bytes_to_frames(handle, err)*1000000/settings.frequency(); + memcpy(data,audioBuffer,err); + totalTimeValue += err; resuming = false; - errorState = QAudio::NoError; - deviceState = QAudio::ActiveState; + if (deviceState != QAudio::ActiveState) { + errorState = QAudio::NoError; + deviceState = QAudio::ActiveState; + emit stateChanged(deviceState); + } + return err; } - return l; } return 0; } @@ -569,7 +588,7 @@ int QAudioInputPrivate::notifyInterval() const qint64 QAudioInputPrivate::processedUSecs() const { - return totalTimeValue; + return qint64(1000000) * totalTimeValue / settings.frequency(); } void QAudioInputPrivate::suspend() @@ -617,34 +636,10 @@ bool QAudioInputPrivate::deviceReady() qint64 QAudioInputPrivate::elapsedUSecs() const { - if(!handle) - return 0; - if (deviceState == QAudio::StoppedState) return 0; -#if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14) - snd_pcm_status_t* status; - snd_pcm_status_alloca(&status); - - snd_timestamp_t t1,t2; - if( snd_pcm_status(handle, status) >= 0) { - snd_pcm_status_get_tstamp(status,&t1); - snd_pcm_status_get_trigger_tstamp(status,&t2); - t1.tv_sec-=t2.tv_sec; - - signed long l = (signed long)t1.tv_usec - (signed long)t2.tv_usec; - if(l < 0) { - t1.tv_sec--; - l = -l; - l %= 1000000; - } - return ((t1.tv_sec * 1000000)+l); - } else - return 0; -#else return clockStamp.elapsed()*1000; -#endif } void QAudioInputPrivate::reset() @@ -670,43 +665,7 @@ InputPrivate::~InputPrivate() qint64 InputPrivate::readData( char* data, qint64 len) { - // push mode, user read() called - if((audioDevice->state() != QAudio::ActiveState) && !audioDevice->resuming) - return 0; - - int readFrames; - int count=0, err = 0; - - while(count < 5) { - int frames = snd_pcm_bytes_to_frames(audioDevice->handle, len); - readFrames = snd_pcm_readi(audioDevice->handle, data, frames); - if (readFrames >= 0) { - err = snd_pcm_frames_to_bytes(audioDevice->handle, readFrames); -#ifdef DEBUG_AUDIO - qDebug()<<QString::fromLatin1("PUSH: read in bytes = %1 (frames=%2)").arg(err).arg(readFrames).toLatin1().constData(); -#endif - break; - } else if((readFrames == -EAGAIN) || (readFrames == -EINTR)) { - audioDevice->errorState = QAudio::IOError; - err = 0; - break; - } else { - if(readFrames == -EPIPE) { - audioDevice->errorState = QAudio::UnderrunError; - err = snd_pcm_prepare(audioDevice->handle); - } else if(readFrames == -ESTRPIPE) { - err = snd_pcm_prepare(audioDevice->handle); - } - if(err != 0) break; - } - count++; - } - if(err > 0 && readFrames > 0) { - audioDevice->totalTimeValue += readFrames*1000/audioDevice->settings.frequency()*1000; - audioDevice->deviceState = QAudio::ActiveState; - return err; - } - return 0; + return audioDevice->read(data,len); } qint64 InputPrivate::writeData(const char* data, qint64 len) diff --git a/src/multimedia/audio/qaudiooutput.cpp b/src/multimedia/audio/qaudiooutput.cpp index afd8a84..b0b5244 100644 --- a/src/multimedia/audio/qaudiooutput.cpp +++ b/src/multimedia/audio/qaudiooutput.cpp @@ -202,18 +202,18 @@ QAudioFormat QAudioOutput::format() const Passing a QIODevice allows the data to be transfered without any extra code. All that is required is to open the QIODevice. + If able to successfully output audio data to the systems audio device the + state() is set to QAudio::ActiveState, error() is set to QAudio::NoError + and the stateChanged() signal is emitted. + + If a problem occurs during this process the error() is set to QAudio::OpenError, + state() is set to QAudio::StoppedState and stateChanged() signal is emitted. + \sa QIODevice */ void QAudioOutput::start(QIODevice* device) { - /* - -If currently not StoppedState, stop. - -If previous start was push mode, delete internal QIODevice. - -open audio output. - -If ok, NoError and ActiveState, else OpenError and StoppedState - -emit stateChanged() - */ d->start(device); } @@ -221,34 +221,30 @@ void QAudioOutput::start(QIODevice* device) Returns a pointer to the QIODevice being used to handle the data transfer. This QIODevice can be used to write() audio data directly. + If able to access the systems audio device the state() is set to + QAudio::IdleState, error() is set to QAudio::NoError + and the stateChanged() signal is emitted. + + If a problem occurs during this process the error() is set to QAudio::OpenError, + state() is set to QAudio::StoppedState and stateChanged() signal is emitted. + \sa QIODevice */ QIODevice* QAudioOutput::start() { - /* - -If currently not StoppedState, stop. - -If no internal QIODevice, create one. - -open audio output. - -If ok, NoError and IdleState, else OpenError and StoppedState - -emit stateChanged() - -return internal QIODevice - */ return d->start(0); } /*! - Stops the audio output. + Stops the audio output, detaching from the system resource. + + Sets error() to QAudio::NoError, state() to QAudio::StoppedState and + emit stateChanged() signal. */ void QAudioOutput::stop() { - /* - -If StoppedState, return - -set to StoppedState - -detach from audio device - -emit stateChanged() - */ d->stop(); } @@ -258,55 +254,44 @@ void QAudioOutput::stop() void QAudioOutput::reset() { - /* - -drop all buffered audio, set buffers to zero. - -call stop() - */ d->reset(); } /*! Stops processing audio data, preserving buffered audio data. + + Sets error() to QAudio::NoError, state() to QAudio::SuspendedState and + emit stateChanged() signal. */ void QAudioOutput::suspend() { - /* - -If not ActiveState|IdleState, return - -stop processing audio, saving all buffered audio data - -set NoError and SuspendedState - -emit stateChanged() - */ d->suspend(); } /*! Resumes processing audio data after a suspend(). + + Sets error() to QAudio::NoError. + Sets state() to QAudio::ActiveState if you previously called start(QIODevice*). + Sets state() to QAudio::IdleState if you previously called start(). + emits stateChanged() signal. */ void QAudioOutput::resume() { - /* - -If SuspendedState, return - -resume audio - -(PULL MODE): set ActiveState, NoError - -(PUSH MODE): set IdleState, NoError - -kick start audio if needed - -emit stateChanged() - */ d->resume(); } /*! Returns the free space available in bytes in the audio buffer. + + NOTE: returned value is only valid while in QAudio::ActiveState or QAudio::IdleState + state, otherwise returns zero. */ int QAudioOutput::bytesFree() const { - /* - -If not ActiveState|IdleState, return 0 - -return space available in audio buffer in bytes - */ return d->bytesFree(); } @@ -353,7 +338,10 @@ int QAudioOutput::bufferSize() const /*! Sets the interval for notify() signal to be emitted. This is based on the \a ms of audio data processed - not on actual real-time. The resolution of the timer is platform specific. + not on actual real-time. + The minimum resolution of the timer is platform specific and values + should be checked with notifyInterval() to confirm actual value + being used. */ void QAudioOutput::setNotifyInterval(int ms) diff --git a/src/multimedia/audio/qaudiooutput_alsa_p.cpp b/src/multimedia/audio/qaudiooutput_alsa_p.cpp index 7b89cef..b127103 100644 --- a/src/multimedia/audio/qaudiooutput_alsa_p.cpp +++ b/src/multimedia/audio/qaudiooutput_alsa_p.cpp @@ -259,6 +259,7 @@ void QAudioOutputPrivate::stop() { if(deviceState == QAudio::StoppedState) return; + errorState = QAudio::NoError; deviceState = QAudio::StoppedState; close(); emit stateChanged(deviceState); @@ -494,10 +495,13 @@ qint64 QAudioOutputPrivate::write( const char *data, qint64 len ) err = snd_pcm_writei( handle, data, frames ); } if(err > 0) { - totalTimeValue += err*1000000/settings.frequency(); + totalTimeValue += err; resuming = false; errorState = QAudio::NoError; - deviceState = QAudio::ActiveState; + if (deviceState != QAudio::ActiveState) { + deviceState = QAudio::ActiveState; + emit stateChanged(deviceState); + } return snd_pcm_frames_to_bytes( handle, err ); } else err = xrun_recovery(err); @@ -542,7 +546,7 @@ int QAudioOutputPrivate::notifyInterval() const qint64 QAudioOutputPrivate::processedUSecs() const { - return totalTimeValue; + return qint64(1000000) * totalTimeValue / settings.frequency(); } void QAudioOutputPrivate::resume() @@ -562,10 +566,8 @@ void QAudioOutputPrivate::resume() bytesAvailable = (int)snd_pcm_frames_to_bytes(handle, buffer_frames); } resuming = true; - if(pullMode) - deviceState = QAudio::ActiveState; - else - deviceState = QAudio::IdleState; + + deviceState = QAudio::ActiveState; errorState = QAudio::NoError; timer->start(period_time/1000); @@ -637,7 +639,9 @@ bool QAudioOutputPrivate::deviceReady() // Got some data to output if(deviceState != QAudio::ActiveState) return true; - write(audioBuffer,l); + qint64 bytesWritten = write(audioBuffer,l); + if (bytesWritten != l) + audioSource->seek(audioSource->pos()-(l-bytesWritten)); bytesAvailable = bytesFree(); } else if(l == 0) { @@ -645,9 +649,11 @@ bool QAudioOutputPrivate::deviceReady() bytesAvailable = bytesFree(); if(bytesAvailable > snd_pcm_frames_to_bytes(handle, buffer_frames-period_frames)) { // Underrun - errorState = QAudio::UnderrunError; - deviceState = QAudio::IdleState; - emit stateChanged(deviceState); + if (deviceState != QAudio::IdleState) { + errorState = QAudio::UnderrunError; + deviceState = QAudio::IdleState; + emit stateChanged(deviceState); + } } } else if(l < 0) { @@ -655,8 +661,17 @@ bool QAudioOutputPrivate::deviceReady() errorState = QAudio::IOError; emit stateChanged(deviceState); } - } else + } else { bytesAvailable = bytesFree(); + if(bytesAvailable > snd_pcm_frames_to_bytes(handle, buffer_frames-period_frames)) { + // Underrun + if (deviceState != QAudio::IdleState) { + errorState = QAudio::UnderrunError; + deviceState = QAudio::IdleState; + emit stateChanged(deviceState); + } + } + } if(deviceState != QAudio::ActiveState) return true; @@ -671,35 +686,10 @@ bool QAudioOutputPrivate::deviceReady() qint64 QAudioOutputPrivate::elapsedUSecs() const { - if(!handle) - return 0; - if (deviceState == QAudio::StoppedState) return 0; -#if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14) - snd_pcm_status_t* status; - snd_pcm_status_alloca(&status); - - snd_timestamp_t t1,t2; - if( snd_pcm_status(handle, status) >= 0) { - snd_pcm_status_get_tstamp(status,&t1); - snd_pcm_status_get_trigger_tstamp(status,&t2); - t1.tv_sec-=t2.tv_sec; - - signed long l = (signed long)t1.tv_usec - (signed long)t2.tv_usec; - if(l < 0) { - t1.tv_sec--; - l = -l; - l %= 1000000; - } - return ((t1.tv_sec * 1000000)+l); - } else - return 0; -#else return clockStamp.elapsed()*1000; -#endif - return 0; } void QAudioOutputPrivate::reset() diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index a2bef67..c4ff24d 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -138,6 +138,8 @@ QT_BEGIN_NAMESPACE default follow redirections: it's up to the application to determine if the requested redirection should be allowed, according to its security policies. + The returned URL might be relative. Use QUrl::resolved() + to create an absolute URL out of it. \value ConnectionEncryptedAttribute Replies only, type: QVariant::Bool (default: false) diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 829df89..275c436 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -155,6 +155,9 @@ See the \l network/fortuneclient and \l network/blockingfortuneclient examples for an overview of both approaches. + \note We discourage the use of the blocking functions together + with signals. One of the two possibilities should be used. + QAbstractSocket can be used with QTextStream and QDataStream's stream operators (operator<<() and operator>>()). There is one issue to be aware of, though: You must make sure that enough data @@ -1682,9 +1685,12 @@ static int qt_timeout_value(int msecs, int elapsed) If msecs is -1, this function will not time out. - Note: This function may wait slightly longer than \a msecs, + \note This function may wait slightly longer than \a msecs, depending on the time it takes to complete the host lookup. + \note Multiple calls to this functions do not accumulate the time. + If the function times out, the connecting process will be aborted. + \sa connectToHost(), connected() */ bool QAbstractSocket::waitForConnected(int msecs) @@ -1722,7 +1728,7 @@ bool QAbstractSocket::waitForConnected(int msecs) d->_q_startConnecting(QHostInfo::fromName(d->hostName)); } if (state() == UnconnectedState) - return false; + return false; // connect not im progress anymore! bool timedOut = true; #if defined (QABSTRACTSOCKET_DEBUG) diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index da47f06..4192dbb 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -131,8 +131,9 @@ public: void draw(VGPath path, const QPen& pen, const QBrush& brush, VGint rule = VG_EVEN_ODD); void stroke(VGPath path, const QPen& pen); void fill(VGPath path, const QBrush& brush, VGint rule = VG_EVEN_ODD); - VGPath vectorPathToVGPath(const QVectorPath& path); - VGPath painterPathToVGPath(const QPainterPath& path); + inline void releasePath(VGPath path); + VGPath vectorPathToVGPath(const QVectorPath& path, bool forceNewPath = false); + VGPath painterPathToVGPath(const QPainterPath& path, bool forceNewPath = false); VGPath roundedRectPath(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode); VGPaintType setBrush (VGPaint paint, const QBrush& brush, VGMatrixMode mode, @@ -178,6 +179,8 @@ public: VGPath roundRectPath; // Cached path for quick drawing of rounded rects. #endif + VGPath reusablePath; // Reusable path for vectorPathToVGPath(), etc. + QTransform transform; // Currently active transform. bool simpleTransform; // True if the transform is simple (non-projective). qreal penScale; // Pen scaling factor from "transform". @@ -350,6 +353,8 @@ void QVGPaintEnginePrivate::init() roundRectPath = 0; #endif + reusablePath = 0; + simpleTransform = true; pathTransformSet = false; penScale = 1.0; @@ -446,6 +451,15 @@ void QVGPaintEnginePrivate::initObjects() VG_PATH_CAPABILITY_ALL); vgAppendPathData(linePath, 2, segments, coords); #endif + + // This path can be reused over and over by calling vgClearPath(). + reusablePath = vgCreatePath(VG_PATH_FORMAT_STANDARD, + VG_PATH_DATATYPE_F, + 1.0f, // scale + 0.0f, // bias + 32 + 1, // segmentCapacityHint + 32 * 2, // coordCapacityHint + VG_PATH_CAPABILITY_ALL); } void QVGPaintEnginePrivate::destroy() @@ -465,6 +479,8 @@ void QVGPaintEnginePrivate::destroy() if (roundRectPath) vgDestroyPath(roundRectPath); #endif + if (reusablePath) + vgDestroyPath(reusablePath); #if !defined(QVG_NO_DRAW_GLYPHS) QVGFontCache::Iterator it; @@ -541,19 +557,32 @@ void QVGPaintEnginePrivate::updateTransform(QPaintDevice *pdev) qt_scaleForTransform(transform, &penScale); } -VGPath QVGPaintEnginePrivate::vectorPathToVGPath(const QVectorPath& path) +inline void QVGPaintEnginePrivate::releasePath(VGPath path) +{ + if (path == reusablePath) + vgClearPath(path, VG_PATH_CAPABILITY_ALL); + else + vgDestroyPath(path); +} + +VGPath QVGPaintEnginePrivate::vectorPathToVGPath(const QVectorPath& path, bool forceNewPath) { int count = path.elementCount(); const qreal *points = path.points(); const QPainterPath::ElementType *elements = path.elements(); - VGPath vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD, - VG_PATH_DATATYPE_F, - 1.0f, // scale - 0.0f, // bias - count + 1, // segmentCapacityHint - count * 2, // coordCapacityHint - VG_PATH_CAPABILITY_ALL); + VGPath vgpath; + if (forceNewPath) { + vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD, + VG_PATH_DATATYPE_F, + 1.0f, // scale + 0.0f, // bias + count + 1, // segmentCapacityHint + count * 2, // coordCapacityHint + VG_PATH_CAPABILITY_ALL); + } else { + vgpath = reusablePath; + } // Size is sufficient segments for drawRoundedRect() paths. QVarLengthArray<VGubyte, 20> segments; @@ -725,17 +754,22 @@ VGPath QVGPaintEnginePrivate::vectorPathToVGPath(const QVectorPath& path) return vgpath; } -VGPath QVGPaintEnginePrivate::painterPathToVGPath(const QPainterPath& path) +VGPath QVGPaintEnginePrivate::painterPathToVGPath(const QPainterPath& path, bool forceNewPath) { int count = path.elementCount(); - VGPath vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD, - VG_PATH_DATATYPE_F, - 1.0f, // scale - 0.0f, // bias - count + 1, // segmentCapacityHint - count * 2, // coordCapacityHint - VG_PATH_CAPABILITY_ALL); + VGPath vgpath; + if (forceNewPath) { + vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD, + VG_PATH_DATATYPE_F, + 1.0f, // scale + 0.0f, // bias + count + 1, // segmentCapacityHint + count * 2, // coordCapacityHint + VG_PATH_CAPABILITY_ALL); + } else { + vgpath = reusablePath; + } if (count == 0) return vgpath; @@ -954,13 +988,7 @@ VGPath QVGPaintEnginePrivate::roundedRectPath(const QRectF &rect, qreal xRadius, vgModifyPathCoords(vgpath, 0, 9, pts); } #else - VGPath vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD, - VG_PATH_DATATYPE_F, - 1.0f, // scale - 0.0f, // bias - 10, // segmentCapacityHint - 17 * 2, // coordCapacityHint - VG_PATH_CAPABILITY_ALL); + VGPath vgpath = reusablePath; vgAppendPathData(vgpath, 10, roundedrect_types, pts); #endif @@ -1516,7 +1544,7 @@ void QVGPaintEngine::draw(const QVectorPath &path) d->draw(vgpath, s->pen, s->brush, VG_EVEN_ODD); else d->draw(vgpath, s->pen, s->brush, VG_NON_ZERO); - vgDestroyPath(vgpath); + d->releasePath(vgpath); } void QVGPaintEngine::fill(const QVectorPath &path, const QBrush &brush) @@ -1527,7 +1555,7 @@ void QVGPaintEngine::fill(const QVectorPath &path, const QBrush &brush) d->fill(vgpath, brush, VG_EVEN_ODD); else d->fill(vgpath, brush, VG_NON_ZERO); - vgDestroyPath(vgpath); + d->releasePath(vgpath); } void QVGPaintEngine::stroke(const QVectorPath &path, const QPen &pen) @@ -1535,7 +1563,7 @@ void QVGPaintEngine::stroke(const QVectorPath &path, const QPen &pen) Q_D(QVGPaintEngine); VGPath vgpath = d->vectorPathToVGPath(path); d->stroke(vgpath, pen); - vgDestroyPath(vgpath); + d->releasePath(vgpath); } // Determine if a co-ordinate transform is simple enough to allow @@ -1731,7 +1759,7 @@ void QVGPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) default: break; } - vgDestroyPath(vgpath); + d->releasePath(vgpath); vgSeti(VG_MASKING, VG_TRUE); d->maskValid = true; @@ -2048,7 +2076,7 @@ void QVGPaintEngine::clip(const QPainterPath &path, Qt::ClipOperation op) default: break; } - vgDestroyPath(vgpath); + d->releasePath(vgpath); vgSeti(VG_MASKING, VG_TRUE); d->maskValid = true; @@ -2487,7 +2515,7 @@ void QVGPaintEngine::drawRoundedRect(const QRectF &rect, qreal xrad, qreal yrad, VGPath vgpath = d->roundedRectPath(rect, xrad, yrad, mode); d->draw(vgpath, s->pen, s->brush); #if defined(QVG_NO_MODIFY_PATH) - vgDestroyPath(vgpath); + d->releasePath(vgpath); #endif } else { QPaintEngineEx::drawRoundedRect(rect, xrad, yrad, mode); @@ -2636,13 +2664,7 @@ void QVGPaintEngine::drawEllipse(const QRectF &r) Q_D(QVGPaintEngine); if (d->simpleTransform) { QVGPainterState *s = state(); - VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD, - VG_PATH_DATATYPE_F, - 1.0f, // scale - 0.0f, // bias - 4, // segmentCapacityHint - 12, // coordCapacityHint - VG_PATH_CAPABILITY_ALL); + VGPath path = d->reusablePath; static VGubyte segments[4] = { VG_MOVE_TO_ABS, VG_SCCWARC_TO_REL, @@ -2666,7 +2688,7 @@ void QVGPaintEngine::drawEllipse(const QRectF &r) coords[11] = 0.0f; vgAppendPathData(path, 4, segments, coords); d->draw(path, s->pen, s->brush); - vgDestroyPath(path); + d->releasePath(path); } else { // The projective transform version of an ellipse is difficult. // Generate a QVectorPath containing cubic curves and transform that. @@ -2690,7 +2712,7 @@ void QVGPaintEngine::drawPath(const QPainterPath &path) d->draw(vgpath, s->pen, s->brush, VG_EVEN_ODD); else d->draw(vgpath, s->pen, s->brush, VG_NON_ZERO); - vgDestroyPath(vgpath); + d->releasePath(vgpath); } void QVGPaintEngine::drawPoints(const QPointF *points, int pointCount) @@ -2765,13 +2787,7 @@ void QVGPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonD { Q_D(QVGPaintEngine); QVGPainterState *s = state(); - VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD, - VG_PATH_DATATYPE_F, - 1.0f, // scale - 0.0f, // bias - pointCount + 1, // segmentCapacityHint - pointCount * 2, // coordCapacityHint - VG_PATH_CAPABILITY_ALL); + VGPath path = d->reusablePath; QVarLengthArray<VGfloat, 16> coords; QVarLengthArray<VGubyte, 10> segments; for (int i = 0; i < pointCount; ++i, ++points) { @@ -2805,20 +2821,14 @@ void QVGPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonD d->draw(path, s->pen, s->brush, VG_EVEN_ODD); break; } - vgDestroyPath(path); + d->releasePath(path); } void QVGPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode) { Q_D(QVGPaintEngine); QVGPainterState *s = state(); - VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD, - VG_PATH_DATATYPE_F, - 1.0f, // scale - 0.0f, // bias - pointCount + 1, // segmentCapacityHint - pointCount * 2, // coordCapacityHint - VG_PATH_CAPABILITY_ALL); + VGPath path = d->reusablePath; QVarLengthArray<VGfloat, 16> coords; QVarLengthArray<VGubyte, 10> segments; for (int i = 0; i < pointCount; ++i, ++points) { @@ -2852,7 +2862,7 @@ void QVGPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDr d->draw(path, s->pen, s->brush, VG_EVEN_ODD); break; } - vgDestroyPath(path); + d->releasePath(path); } void QVGPaintEnginePrivate::setImageOptions() @@ -3251,7 +3261,7 @@ void QVGFontGlyphCache::cacheGlyphs ti.fontEngine->getUnscaledGlyph(glyph, &path, &metrics); VGPath vgPath; if (!path.isEmpty()) { - vgPath = d->painterPathToVGPath(path); + vgPath = d->painterPathToVGPath(path, true); } else { // Probably a "space" character with no visible outline. vgPath = VG_INVALID_HANDLE; diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 1bd7377..1199263 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -768,7 +768,7 @@ static QScriptValue __setupPackage__(QScriptContext *ctx, QScriptEngine *eng) } // namespace QScript QScriptEnginePrivate::QScriptEnginePrivate() - : registeredScriptValues(0), freeScriptValues(0), + : registeredScriptValues(0), freeScriptValues(0), freeScriptValuesCount(0), registeredScriptStrings(0), inEval(false) { qMetaTypeId<QScriptValue>(); diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h index 6780b2c..401d6d2 100644 --- a/src/script/api/qscriptengine_p.h +++ b/src/script/api/qscriptengine_p.h @@ -255,6 +255,8 @@ public: int agentLineNumber; QScriptValuePrivate *registeredScriptValues; QScriptValuePrivate *freeScriptValues; + static const int maxFreeScriptValues = 256; + int freeScriptValuesCount; QScriptStringPrivate *registeredScriptStrings; QHash<int, QScriptTypeInfo*> m_typeInfos; int processEventsInterval; @@ -377,6 +379,7 @@ inline QScriptValuePrivate *QScriptEnginePrivate::allocateScriptValuePrivate(siz if (freeScriptValues) { QScriptValuePrivate *p = freeScriptValues; freeScriptValues = p->next; + --freeScriptValuesCount; return p; } return reinterpret_cast<QScriptValuePrivate*>(qMalloc(size)); @@ -384,8 +387,13 @@ inline QScriptValuePrivate *QScriptEnginePrivate::allocateScriptValuePrivate(siz inline void QScriptEnginePrivate::freeScriptValuePrivate(QScriptValuePrivate *p) { - p->next = freeScriptValues; - freeScriptValues = p; + if (freeScriptValuesCount < maxFreeScriptValues) { + p->next = freeScriptValues; + freeScriptValues = p; + ++freeScriptValuesCount; + } else { + qFree(p); + } } inline void QScriptEnginePrivate::registerScriptValue(QScriptValuePrivate *value) diff --git a/tests/benchmarks/gui/kernel/qwidget/tst_qwidget.cpp b/tests/benchmarks/gui/kernel/qwidget/tst_qwidget.cpp index f21bd44..8c30be4 100644 --- a/tests/benchmarks/gui/kernel/qwidget/tst_qwidget.cpp +++ b/tests/benchmarks/gui/kernel/qwidget/tst_qwidget.cpp @@ -42,33 +42,35 @@ #include <qtest.h> #include <QtGui> -class tst_QWidget : public QObject +static void processEvents() { - Q_OBJECT - - -private slots: - void update_data(); - void updateOpaque_data(); - void updateOpaque(); - void updateTransparent_data(); - void updateTransparent(); - void updatePartial_data(); - void updatePartial(); - void updateComplex_data(); - void updateComplex(); - - void complexToplevelResize(); -}; + QApplication::flush(); + QApplication::processEvents(); + QApplication::processEvents(); +} class UpdateWidget : public QWidget { public: - UpdateWidget(int rows, int columns) : QWidget(0) + UpdateWidget(int rows, int columns) + : QWidget(0), rowCount(0), columnCount(0), opaqueChildren(false) { + fill(rows, columns); + } + + UpdateWidget(QWidget *parent = 0) + : QWidget(parent), rowCount(0), columnCount(0), opaqueChildren(false) {} + + void fill(int rows, int columns) + { + if (rows == rowCount && columns == columnCount) + return; + delete layout(); QGridLayout *layout = new QGridLayout; - for (int row = 0; row < rows; ++row) { - for (int column = 0; column < columns; ++column) { + rowCount = rows; + columnCount = columns; + for (int row = 0; row < rowCount; ++row) { + for (int column = 0; column < columnCount; ++column) { UpdateWidget *widget = new UpdateWidget; widget->setFixedSize(20, 20); layout->addWidget(widget, row, column); @@ -76,9 +78,20 @@ public: } } setLayout(layout); + adjustSize(); + QTest::qWait(250); + processEvents(); } - UpdateWidget(QWidget *parent = 0) : QWidget(parent) {} + void setOpaqueChildren(bool enable) + { + if (opaqueChildren != enable) { + foreach (QWidget *w, children) + w->setAttribute(Qt::WA_OpaquePaintEvent, enable); + opaqueChildren = enable; + processEvents(); + } + } void paintEvent(QPaintEvent *) { @@ -93,75 +106,86 @@ public: QRegion updateRegion; QList<UpdateWidget*> children; + int rowCount; + int columnCount; + bool opaqueChildren; }; -void tst_QWidget::update_data() +class tst_QWidget : public QObject { - QTest::addColumn<int>("rows"); - QTest::addColumn<int>("columns"); - QTest::addColumn<int>("numUpdates"); - - QTest::newRow("10x10x1") << 10 << 10 << 1; - QTest::newRow("10x10x10") << 10 << 10 << 10; - QTest::newRow("25x25x1") << 25 << 25 << 1; - QTest::newRow("25x25x10") << 25 << 25 << 10; - QTest::newRow("25x25x100") << 25 << 25 << 100; -} + Q_OBJECT -void tst_QWidget::updateOpaque_data() -{ - update_data(); -} +public slots: + void initTestCase(); + void init(); -void tst_QWidget::updateOpaque() -{ - QFETCH(int, rows); - QFETCH(int, columns); - QFETCH(int, numUpdates); +private slots: + void update_data(); + void update(); + void updatePartial_data(); + void updatePartial(); + void updateComplex_data(); + void updateComplex(); - UpdateWidget widget(rows, columns); - foreach (QWidget *w, widget.children) { - w->setAttribute(Qt::WA_OpaquePaintEvent); - } +private: + UpdateWidget widget; +}; +void tst_QWidget::initTestCase() +{ widget.show(); - QApplication::processEvents(); + QTest::qWaitForWindowShown(&widget); + QTest::qWait(300); + processEvents(); +} - int i = 0; - const int n = widget.children.size(); - QBENCHMARK { - for (int j = 0; j < numUpdates; ++j) { - widget.children[i]->update(); - QApplication::processEvents(); - i = (i + 1) % n; - } - } +void tst_QWidget::init() +{ + QVERIFY(widget.isVisible()); + for (int i = 0; i < 3; ++i) + processEvents(); } -void tst_QWidget::updateTransparent_data() +void tst_QWidget::update_data() { - update_data(); + QTest::addColumn<int>("rows"); + QTest::addColumn<int>("columns"); + QTest::addColumn<int>("numUpdates"); + QTest::addColumn<bool>("opaque"); + + QTest::newRow("10x10x1 transparent") << 10 << 10 << 1 << false; + QTest::newRow("10x10x10 transparent") << 10 << 10 << 10 << false; + QTest::newRow("10x10x100 transparent") << 10 << 10 << 100 << false; + QTest::newRow("10x10x1 opaque") << 10 << 10 << 1 << true; + QTest::newRow("10x10x10 opaque") << 10 << 10 << 10 << true; + QTest::newRow("10x10x100 opaque") << 10 << 10 << 100 << true; + QTest::newRow("25x25x1 transparent ") << 25 << 25 << 1 << false; + QTest::newRow("25x25x10 transparent") << 25 << 25 << 10 << false; + QTest::newRow("25x25x100 transparent") << 25 << 25 << 100 << false; + QTest::newRow("25x25x1 opaque") << 25 << 25 << 1 << true; + QTest::newRow("25x25x10 opaque") << 25 << 25 << 10 << true; + QTest::newRow("25x25x100 opaque") << 25 << 25 << 100 << true; } -void tst_QWidget::updateTransparent() +void tst_QWidget::update() { QFETCH(int, rows); QFETCH(int, columns); QFETCH(int, numUpdates); + QFETCH(bool, opaque); - UpdateWidget widget(rows, columns); - widget.show(); - QApplication::processEvents(); + widget.fill(rows, columns); + widget.setOpaqueChildren(opaque); - int i = 0; - const int n = widget.children.size(); QBENCHMARK { - for (int j = 0; j < numUpdates; ++j) { - widget.children[i]->update(); + for (int i = 0; i < widget.children.size(); ++i) { + for (int j = 0; j < numUpdates; ++j) + widget.children.at(i)->update(); QApplication::processEvents(); - i = (i + 1) % n; } } + + QApplication::flush(); } void tst_QWidget::updatePartial_data() @@ -174,24 +198,23 @@ void tst_QWidget::updatePartial() QFETCH(int, rows); QFETCH(int, columns); QFETCH(int, numUpdates); + QFETCH(bool, opaque); - UpdateWidget widget(rows, columns); - widget.show(); - QApplication::processEvents(); + widget.fill(rows, columns); + widget.setOpaqueChildren(opaque); - int i = 0; - const int n = widget.children.size(); QBENCHMARK { - for (int j = 0; j < numUpdates; ++j) { + for (int i = 0; i < widget.children.size(); ++i) { QWidget *w = widget.children[i]; const int x = w->width() / 2; const int y = w->height() / 2; - w->update(0, 0, x, y); - w->update(x, 0, x, y); - w->update(0, y, x, y); - w->update(x, y, x, y); + for (int j = 0; j < numUpdates; ++j) { + w->update(0, 0, x, y); + w->update(x, 0, x, y); + w->update(0, y, x, y); + w->update(x, y, x, y); + } QApplication::processEvents(); - i = (i + 1) % n; } } } @@ -206,127 +229,27 @@ void tst_QWidget::updateComplex() QFETCH(int, rows); QFETCH(int, columns); QFETCH(int, numUpdates); + QFETCH(bool, opaque); - UpdateWidget widget(rows, columns); - widget.show(); - QApplication::processEvents(); + widget.fill(rows, columns); + widget.setOpaqueChildren(opaque); - int i = 0; - const int n = widget.children.size(); QBENCHMARK { - for (int j = 0; j < numUpdates; ++j) { + for (int i = 0; i < widget.children.size(); ++i) { QWidget *w = widget.children[i]; const int x = w->width() / 2; const int y = w->height() / 2; - w->update(QRegion(0, 0, x, y, QRegion::Ellipse)); - w->update(QRegion(x, y, x, y, QRegion::Ellipse)); + QRegion r1(0, 0, x, y, QRegion::Ellipse); + QRegion r2(x, y, x, y, QRegion::Ellipse); + for (int j = 0; j < numUpdates; ++j) { + w->update(r1); + w->update(r2); + } QApplication::processEvents(); - i = (i + 1) % n; } } } -class ResizeWidget : public QWidget -{ -public: - ResizeWidget(); -}; - -ResizeWidget::ResizeWidget() : QWidget(0) -{ - QBoxLayout *topLayout = new QVBoxLayout; - - QMenuBar *menubar = new QMenuBar; - QMenu* popup = menubar->addMenu("&File"); - popup->addAction("&Quit", qApp, SLOT(quit())); - topLayout->setMenuBar(menubar); - - QBoxLayout *buttons = new QHBoxLayout; - buttons->setMargin(5); - buttons->addStretch(10); - for (int i = 1; i <= 4; i++ ) { - QPushButton* button = new QPushButton; - button->setText(QString("Button %1").arg(i)); - buttons->addWidget(button); - } - topLayout->addLayout(buttons); - - buttons = new QHBoxLayout; - buttons->addStretch(10); - for (int i = 11; i <= 16; i++) { - QPushButton* button = new QPushButton; - button->setText(QString("Button %1").arg(i)); - buttons->addWidget(button); - } - topLayout->addLayout(buttons); - - QBoxLayout *buttons2 = new QHBoxLayout; - buttons2->addStretch(10); - topLayout->addLayout(buttons2); - - QPushButton *button = new QPushButton; - button->setText("Button five"); - buttons2->addWidget(button); - - button = new QPushButton; - button->setText("Button 6"); - buttons2->addWidget(button); - - QTextEdit *bigWidget = new QTextEdit; - bigWidget->setText("This widget will get all the remaining space"); - bigWidget->setFrameStyle(QFrame::Panel | QFrame::Plain); - topLayout->addWidget(bigWidget); - - const int numRows = 6; - const int labelCol = 0; - const int linedCol = 1; - const int multiCol = 2; - - QGridLayout *grid = new QGridLayout; - for (int row = 0; row < numRows; row++) { - QLineEdit *lineEdit = new QLineEdit; - grid->addWidget(lineEdit, row, linedCol); - QLabel *label = new QLabel(QString("Line &%1").arg(row + 1)); - grid->addWidget(label, row, labelCol); - } - topLayout->addLayout(grid); - - QTextEdit *multiLineEdit = new QTextEdit; - grid->addWidget(multiLineEdit, 0, labelCol + 1, multiCol, multiCol); - - grid->setColumnStretch(linedCol, 10); - grid->setColumnStretch(multiCol, 20); - - QLabel* statusBar = new QLabel; - statusBar->setText("Let's pretend this is a status bar"); - statusBar->setFrameStyle(QFrame::Panel | QFrame::Sunken); - statusBar->setFixedHeight(statusBar->sizeHint().height()); - statusBar->setAlignment(Qt::AlignVCenter | Qt::AlignLeft); - topLayout->addWidget(statusBar); - - topLayout->activate(); - setLayout(topLayout); -} - -void tst_QWidget::complexToplevelResize() -{ - ResizeWidget w; - w.show(); - - QApplication::processEvents(); - - const int minSize = 100; - const int maxSize = 800; - int size = minSize; - - QBENCHMARK { - w.resize(size, size); - size = qMax(minSize, (size + 10) % maxSize); - QApplication::processEvents(); - QApplication::processEvents(); - } -} - QTEST_MAIN(tst_QWidget) #include "tst_qwidget.moc" diff --git a/tests/benchmarks/gui/styles/qstylesheetstyle/main.cpp b/tests/benchmarks/gui/styles/qstylesheetstyle/main.cpp index 226b661..d051b12 100644 --- a/tests/benchmarks/gui/styles/qstylesheetstyle/main.cpp +++ b/tests/benchmarks/gui/styles/qstylesheetstyle/main.cpp @@ -82,6 +82,7 @@ void tst_qstylesheetstyle::empty() { QWidget *w = buildSimpleWidgets(); w->setStyleSheet("/* */"); + QApplication::processEvents(); int i = 0; QBENCHMARK { w->setStyleSheet("/*" + QString::number(i) + "*/"); @@ -94,6 +95,7 @@ void tst_qstylesheetstyle::empty_events() { QWidget *w = buildSimpleWidgets(); w->setStyleSheet("/* */"); + QApplication::processEvents(); int i = 0; QBENCHMARK { w->setStyleSheet("/*" + QString::number(i) + "*/"); @@ -112,6 +114,7 @@ void tst_qstylesheetstyle::simple() { QWidget *w = buildSimpleWidgets(); w->setStyleSheet("/* */"); + QApplication::processEvents(); int i = 0; QBENCHMARK { w->setStyleSheet(QString(simple_css) + "/*" + QString::number(i) + "*/"); @@ -124,6 +127,7 @@ void tst_qstylesheetstyle::simple_events() { QWidget *w = buildSimpleWidgets(); w->setStyleSheet("/* */"); + QApplication::processEvents(); int i = 0; QBENCHMARK { w->setStyleSheet(QString(simple_css) + "/*" + QString::number(i) + "*/"); @@ -175,8 +179,13 @@ void tst_qstylesheetstyle::grid() w->setStyleSheet("/* */"); if(show) { w->show(); + QTest::qWaitForWindowShown(w); + QApplication::flush(); + QApplication::processEvents(); QTest::qWait(30); + QApplication::processEvents(); } + QApplication::processEvents(); int i = 0; QBENCHMARK { w->setStyleSheet(stylesheet + "/*" + QString::number(i) + "*/"); |