From ec68f67ee55944e1f05bdbe1362832ee2ab156c7 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Sat, 20 Sep 2014 18:08:16 +0200 Subject: XCB: silence warnings about possibly undefined shifts The code shifts "1" by a uint32 number. If that number is >= 32, we're triggering undefined behavior, and Coverity rightfully complains about that. Add some asserts to silence those warnings. Change-Id: Ib91085a279b0a2b7ad37afad05ec1d764c0496b1 Reviewed-by: Uli Schlachter Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbkeyboard.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index a873ba97d7..9bf4f90c20 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -865,6 +865,10 @@ QList QXcbKeyboard::possibleKeys(const QKeyEvent *event) const xkb_mod_index_t altMod = xkb_keymap_mod_get_index(xkb_keymap, "Alt"); xkb_mod_index_t controlMod = xkb_keymap_mod_get_index(xkb_keymap, "Control"); + Q_ASSERT(shiftMod < 32); + Q_ASSERT(altMod < 32); + Q_ASSERT(controlMod < 32); + xkb_mod_mask_t depressed; struct xkb_keymap *fallback_keymap = 0; int qtKey = 0; -- cgit v1.2.3 From 8d8000b5feb35fd284d11118891d9d72fafef3cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Mon, 22 Sep 2014 16:03:00 +0200 Subject: Android: Don't call requestLayout() when changing the geometry. requestLayout() is already called when setLayoutParams() is called, so calling it again is extremely wasteful. Change-Id: Iddfb488830a6b7277a653a84ffacabf966baf0b5 Reviewed-by: BogDan Vatra --- src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index 6dad8888ce..ed5be81d80 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -1090,8 +1090,6 @@ public class QtActivityDelegate Log.e(QtNative.QtTAG, "Surface " + id +" not found!"); return; } - - m_layout.requestLayout(); } public void destroySurface(int id) { -- cgit v1.2.3 From 7755b4af417e6b6da3dac0617eb2ce3a37b9a53c Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Wed, 8 Oct 2014 09:51:10 +0200 Subject: Android: null pointer check Task-number: QTBUG-41680 Change-Id: I740fb2a6df5613a8ee724b59dab08674a3337236 Reviewed-by: Kai Uwe Broulik Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/android/jar/src/org/qtproject/qt5/android/QtInputConnection.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtInputConnection.java b/src/android/jar/src/org/qtproject/qt5/android/QtInputConnection.java index 6de66fe512..80028e1b02 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtInputConnection.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtInputConnection.java @@ -174,6 +174,9 @@ public class QtInputConnection extends BaseInputConnection QtExtractedText qExtractedText = QtNativeInputConnection.getExtractedText(request.hintMaxChars, request.hintMaxLines, flags); + if (qExtractedText == null) + return null; + ExtractedText extractedText = new ExtractedText(); extractedText.partialEndOffset = qExtractedText.partialEndOffset; extractedText.partialStartOffset = qExtractedText.partialStartOffset; -- cgit v1.2.3 From c712ec4543bb9a3db469ffd909e01d97c48ff697 Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Mon, 22 Sep 2014 14:22:53 +0200 Subject: Android: Thread fix/optimization Do the cheap test before sending an expensive query that might use a mutex. Task-number: QTBUG-41369 Change-Id: I78f03c84e5bbf0492f1b7ea18d1baa752a1beff2 Reviewed-by: Christian Stromme --- src/plugins/platforms/android/qandroidinputcontext.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp index a23d05520c..ca9d1e69c9 100644 --- a/src/plugins/platforms/android/qandroidinputcontext.cpp +++ b/src/plugins/platforms/android/qandroidinputcontext.cpp @@ -642,13 +642,13 @@ jboolean QAndroidInputContext::deleteSurroundingText(jint leftLength, jint right // Android docs say the cursor must not move jboolean QAndroidInputContext::finishComposingText() { + if (m_composingText.isEmpty()) + return JNI_TRUE; // not composing + QSharedPointer query = focusObjectInputMethodQueryThreadSafe(); if (query.isNull()) return JNI_FALSE; - if (m_composingText.isEmpty()) - return JNI_TRUE; // not composing - const int blockPos = getBlockPosition(query); const int localCursorPos = m_composingCursor - blockPos; -- cgit v1.2.3 From e31a7e46eaeb7c3590f3099a08ed085edb21c906 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 9 Oct 2014 12:42:13 +0200 Subject: Android: Support QClipboard::clear() QClipboard::clear() is implemented by calling QPlatformClipboard::setMimeData() with a null pointer. Since we would do nothing in this case on Android, then the clear() function would have no effect. [ChangeLog][Android] Added support for QClipboard::clear() Task-number: QTBUG-41854 Change-Id: Id569b102f2e561e46967b52f89d9b54031d92456 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/android/qandroidplatformclipboard.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/android/qandroidplatformclipboard.cpp b/src/plugins/platforms/android/qandroidplatformclipboard.cpp index 86fd152bff..70bdbad11f 100644 --- a/src/plugins/platforms/android/qandroidplatformclipboard.cpp +++ b/src/plugins/platforms/android/qandroidplatformclipboard.cpp @@ -53,10 +53,8 @@ QMimeData *QAndroidPlatformClipboard::mimeData(QClipboard::Mode mode) void QAndroidPlatformClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode) { - if (!data || !data->hasText() || QClipboard::Clipboard != mode) - return; - - QtAndroidClipboard::setClipboardText(data->text()); + Q_ASSERT(supportsMode(mode)); + QtAndroidClipboard::setClipboardText(data != 0 && data->hasText() ? data->text() : QString()); } bool QAndroidPlatformClipboard::supportsMode(QClipboard::Mode mode) const -- cgit v1.2.3 From 5f1f955524d003af4714e43c19062fa07c1d58f8 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 9 Oct 2014 12:43:57 +0200 Subject: Android: Fix memory leak in QClipboard::setMimeData() The ownership of the object passed into QClipboard::setMimeData() is documented to be transferred to the clipboard, but we never deleted it, thus all these objects would leak. [ChangeLog][Android] Fixed memory leak in QClipboard::setMimeData() Change-Id: I43e6bad1071be5f56c219cb9341584edba54d2bd Task-number: QTBUG-41852 Reviewed-by: BogDan Vatra --- src/plugins/platforms/android/qandroidplatformclipboard.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/platforms/android/qandroidplatformclipboard.cpp b/src/plugins/platforms/android/qandroidplatformclipboard.cpp index 70bdbad11f..3515be436d 100644 --- a/src/plugins/platforms/android/qandroidplatformclipboard.cpp +++ b/src/plugins/platforms/android/qandroidplatformclipboard.cpp @@ -55,6 +55,7 @@ void QAndroidPlatformClipboard::setMimeData(QMimeData *data, QClipboard::Mode mo { Q_ASSERT(supportsMode(mode)); QtAndroidClipboard::setClipboardText(data != 0 && data->hasText() ? data->text() : QString()); + delete data; } bool QAndroidPlatformClipboard::supportsMode(QClipboard::Mode mode) const -- cgit v1.2.3 From 9ddf2fb3768e87cc1f6dbb181261d68f266f4327 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Siedlarek?= Date: Sat, 4 Oct 2014 10:58:09 +0200 Subject: Prevent parsing of SSL certificates from 0-size buffers. When QSslCertificatePrivate::certificatesFromDer() was passed count == -1 to extract unlimied number of certificates from buffer, it also tried to parse the 0-sized fragment after the last certificate. This has caused d2i_X509() to report an error on latest OpenSSL. Task-number: QTBUG-41774 Change-Id: Ifa36b7ac5b4236bd2fb53b9d7fe53c5db3cb078c Reviewed-by: Peter Hartmann --- src/network/ssl/qsslcertificate_openssl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/ssl/qsslcertificate_openssl.cpp b/src/network/ssl/qsslcertificate_openssl.cpp index 664f5eba08..850654835d 100644 --- a/src/network/ssl/qsslcertificate_openssl.cpp +++ b/src/network/ssl/qsslcertificate_openssl.cpp @@ -683,7 +683,7 @@ QList QSslCertificatePrivate::certificatesFromDer(const QByteAr #endif int size = der.size(); - while (count == -1 || certificates.size() < count) { + while (size > 0 && (count == -1 || certificates.size() < count)) { if (X509 *x509 = q_d2i_X509(0, &data, size)) { certificates << QSslCertificate_from_X509(x509); q_X509_free(x509); -- cgit v1.2.3 From 8fc34e42a88835c4f1ceda1a23b9bbefcfb9039e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Siedlarek?= Date: Sat, 4 Oct 2014 11:44:18 +0200 Subject: Add information about unsupported SSL protocol when creating context. When creating SSL context failed due to unsupported protocol being demanded, no explanation was given. It's because QSslContext::fromConfiguration() extracted explanation for error message from OpenSSL, which at that point hasn't even been called yet. This patch adds explicit message informing that an unsupported protocol was chosen. Task-number: QTBUG-41775 Change-Id: I9d2710da4ba314a16837a90afcdc5d9256179bef Reviewed-by: Peter Hartmann --- src/network/ssl/qsslcontext_openssl.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/network/ssl/qsslcontext_openssl.cpp b/src/network/ssl/qsslcontext_openssl.cpp index 1f787b0da3..6daddebba3 100644 --- a/src/network/ssl/qsslcontext_openssl.cpp +++ b/src/network/ssl/qsslcontext_openssl.cpp @@ -124,13 +124,16 @@ QSslContext* QSslContext::fromConfiguration(QSslSocket::SslMode mode, const QSsl bool client = (mode == QSslSocket::SslClientMode); bool reinitialized = false; + bool unsupportedProtocol = false; init_context: switch (sslContext->sslConfiguration.protocol()) { case QSsl::SslV2: #ifndef OPENSSL_NO_SSL2 sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv2_client_method() : q_SSLv2_server_method()); #else - sslContext->ctx = 0; // SSL 2 not supported by the system, but chosen deliberately -> error + // SSL 2 not supported by the system, but chosen deliberately -> error + sslContext->ctx = 0; + unsupportedProtocol = true; #endif break; case QSsl::SslV3: @@ -149,14 +152,18 @@ init_context: #if OPENSSL_VERSION_NUMBER >= 0x10001000L sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_1_client_method() : q_TLSv1_1_server_method()); #else - sslContext->ctx = 0; // TLS 1.1 not supported by the system, but chosen deliberately -> error + // TLS 1.1 not supported by the system, but chosen deliberately -> error + sslContext->ctx = 0; + unsupportedProtocol = true; #endif break; case QSsl::TlsV1_2: #if OPENSSL_VERSION_NUMBER >= 0x10001000L sslContext->ctx = q_SSL_CTX_new(client ? q_TLSv1_2_client_method() : q_TLSv1_2_server_method()); #else - sslContext->ctx = 0; // TLS 1.2 not supported by the system, but chosen deliberately -> error + // TLS 1.2 not supported by the system, but chosen deliberately -> error + sslContext->ctx = 0; + unsupportedProtocol = true; #endif break; } @@ -169,7 +176,9 @@ init_context: goto init_context; } - sslContext->errorStr = QSslSocket::tr("Error creating SSL context (%1)").arg(QSslSocketBackendPrivate::getErrorsFromOpenSsl()); + sslContext->errorStr = QSslSocket::tr("Error creating SSL context (%1)").arg( + unsupportedProtocol ? QSslSocket::tr("unsupported protocol") : QSslSocketBackendPrivate::getErrorsFromOpenSsl() + ); sslContext->errorCode = QSslError::UnspecifiedError; return sslContext; } -- cgit v1.2.3 From 26c104d120aff93f9da24dfeba3b64864d9f6a37 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 9 Oct 2014 16:38:38 +0200 Subject: Add a warning when using QOpenGLWidget as a native child Just like it is done for QQuickWidget. Task-number: QTBUG-41779 Change-Id: I1b27c2ed34ecb2520edf82843b675dbf6b0eab8e Reviewed-by: Michael Bruning Reviewed-by: Paul Olav Tvete --- src/widgets/kernel/qopenglwidget.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index 543f59d7d1..7782c4c1d4 100644 --- a/src/widgets/kernel/qopenglwidget.cpp +++ b/src/widgets/kernel/qopenglwidget.cpp @@ -506,6 +506,12 @@ void QOpenGLWidgetPaintDevice::ensureActiveTarget() GLuint QOpenGLWidgetPrivate::textureId() const { + Q_Q(const QOpenGLWidget); + if (!q->isWindow() && q->internalWinId()) { + qWarning() << "QOpenGLWidget cannot be used as a native child widget." + << "Consider setting Qt::AA_DontCreateNativeWidgetAncestors and Siblings."; + return 0; + } return resolvedFbo ? resolvedFbo->texture() : (fbo ? fbo->texture() : 0); } -- cgit v1.2.3 From f813a3e8ad65f6a38da866dff7683650abff334d Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Fri, 10 Oct 2014 12:16:36 +0200 Subject: Print warning when unable to query physical screen size This warning was removed when re-factoring code in: 328f2f9c35f3cc5e7049a060a608c3f72876484a Change-Id: I5a9d7fbbf2b78e6e80a79478f4e9fb08ccaec431 Reviewed-by: Laszlo Agocs --- src/platformsupport/eglconvenience/qeglconvenience.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/platformsupport/eglconvenience/qeglconvenience.cpp b/src/platformsupport/eglconvenience/qeglconvenience.cpp index b7ce6dfaf3..1fdeec3adb 100644 --- a/src/platformsupport/eglconvenience/qeglconvenience.cpp +++ b/src/platformsupport/eglconvenience/qeglconvenience.cpp @@ -487,6 +487,11 @@ QSizeF q_physicalScreenSizeFromFb(int framebufferDevice, const QSize &screenSize size.setWidth(w <= 0 ? screenResolution.width() * Q_MM_PER_INCH / defaultPhysicalDpi : qreal(w)); size.setHeight(h <= 0 ? screenResolution.height() * Q_MM_PER_INCH / defaultPhysicalDpi : qreal(h)); + + if (w <= 0 || h <= 0) + qWarning("Unable to query physical screen size, defaulting to %d dpi.\n" + "To override, set QT_QPA_EGLFS_PHYSICAL_WIDTH " + "and QT_QPA_EGLFS_PHYSICAL_HEIGHT (in millimeters).", defaultPhysicalDpi); } return size; -- cgit v1.2.3 From bf73ab490de127d1a22cb31acb2e251b1daef328 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 9 Oct 2014 08:25:41 +0200 Subject: Disable tst_qhostinfo on OS X. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-41847 Change-Id: Idfb4058a50a0baecce1b3e430629ec6b2867550b Reviewed-by: Morten Johan Sørvig --- tests/auto/network/kernel/kernel.pro | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/auto/network/kernel/kernel.pro b/tests/auto/network/kernel/kernel.pro index 8594ad5932..bb13c7dd7d 100644 --- a/tests/auto/network/kernel/kernel.pro +++ b/tests/auto/network/kernel/kernel.pro @@ -14,6 +14,9 @@ winrt: SUBDIRS -= \ qnetworkproxy \ qnetworkproxyfactory \ +osx: SUBDIRS -= \ # QTBUG-41847 + qhostinfo \ + !contains(QT_CONFIG, private_tests): SUBDIRS -= \ qauthenticator \ qhostinfo \ -- cgit v1.2.3 From eaf04207bddd778380cae178db1bf3cce7d6b9df Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 8 Oct 2014 16:57:07 +0200 Subject: Improve threadedqopenglwidget example. Retrieve vendor/renderer name similar to context info and exclude renderers that do not support threaded Open GL (ANGLE/noveau). Change-Id: I690c2fc277538bf28bf1f6032c2e017ede15e434 Reviewed-by: Laszlo Agocs --- examples/opengl/threadedqopenglwidget/glwidget.h | 2 +- examples/opengl/threadedqopenglwidget/main.cpp | 47 +++++++++++++++++----- .../opengl/threadedqopenglwidget/mainwindow.cpp | 1 + 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/examples/opengl/threadedqopenglwidget/glwidget.h b/examples/opengl/threadedqopenglwidget/glwidget.h index 8319faf322..c063e846dc 100644 --- a/examples/opengl/threadedqopenglwidget/glwidget.h +++ b/examples/opengl/threadedqopenglwidget/glwidget.h @@ -100,7 +100,7 @@ class GLWidget : public QOpenGLWidget { Q_OBJECT public: - GLWidget(QWidget *parent); + explicit GLWidget(QWidget *parent = 0); ~GLWidget(); protected: diff --git a/examples/opengl/threadedqopenglwidget/main.cpp b/examples/opengl/threadedqopenglwidget/main.cpp index 75b7f5e46f..2c94469b7c 100644 --- a/examples/opengl/threadedqopenglwidget/main.cpp +++ b/examples/opengl/threadedqopenglwidget/main.cpp @@ -40,10 +40,19 @@ #include #include +#include #include +#include #include "mainwindow.h" #include "glwidget.h" +static QString getGlString(QOpenGLFunctions *functions, GLenum name) +{ + if (const GLubyte *p = functions->glGetString(name)) + return QString::fromLatin1(reinterpret_cast(p)); + return QString(); +} + int main( int argc, char ** argv ) { QApplication a( argc, argv ); @@ -54,20 +63,38 @@ int main( int argc, char ** argv ) // Two top-level windows with two QOpenGLWidget children in each. // The rendering for the four QOpenGLWidgets happens on four separate threads. - MainWindow mw1; - mw1.setMinimumSize(800, 400); - mw1.show(); + GLWidget topLevelGlWidget; + QPoint pos = QApplication::desktop()->availableGeometry(&topLevelGlWidget).topLeft() + QPoint(200, 200); + topLevelGlWidget.setWindowTitle(QStringLiteral("Threaded QOpenGLWidget example top level")); + topLevelGlWidget.resize(200, 200); + topLevelGlWidget.move(pos); + topLevelGlWidget.show(); + + const QString glInfo = getGlString(topLevelGlWidget.context()->functions(), GL_VENDOR) + + QLatin1Char('/') + getGlString(topLevelGlWidget.context()->functions(), GL_RENDERER); + + const bool supportsThreading = !glInfo.contains(QLatin1String("nouveau"), Qt::CaseInsensitive) + && !glInfo.contains(QLatin1String("ANGLE"), Qt::CaseInsensitive); + + const QString toolTip = supportsThreading ? glInfo : glInfo + QStringLiteral("\ndoes not support threaded OpenGL."); + topLevelGlWidget.setToolTip(toolTip); + + QScopedPointer mw1; QScopedPointer mw2; - if (!QApplication::arguments().contains(QStringLiteral("--single"))) { + if (supportsThreading && !QApplication::arguments().contains(QStringLiteral("--single"))) { + pos += QPoint(100, 100); + mw1.reset(new MainWindow); + mw1->setToolTip(toolTip); + mw1->move(pos); + mw1->setWindowTitle(QStringLiteral("Threaded QOpenGLWidget example #1")); + mw1->show(); + pos += QPoint(100, 100); mw2.reset(new MainWindow); - mw2->setMinimumSize(800, 400); + mw2->setToolTip(toolTip); + mw2->move(pos); + mw2->setWindowTitle(QStringLiteral("Threaded QOpenGLWidget example #2")); mw2->show(); - - // And a top-level. - GLWidget *bonus = new GLWidget(0); - bonus->resize(200, 200); - bonus->show(); } return a.exec(); diff --git a/examples/opengl/threadedqopenglwidget/mainwindow.cpp b/examples/opengl/threadedqopenglwidget/mainwindow.cpp index 29c59573cf..de866f5615 100644 --- a/examples/opengl/threadedqopenglwidget/mainwindow.cpp +++ b/examples/opengl/threadedqopenglwidget/mainwindow.cpp @@ -43,6 +43,7 @@ MainWindow::MainWindow() { + setMinimumSize(800, 400); GLWidget *glwidget1 = new GLWidget(this); glwidget1->resize(400, 400); -- cgit v1.2.3 From 8ddaf5c74150d18f2639aeca495ec40efd8e8add Mon Sep 17 00:00:00 2001 From: Tomasz Olszak Date: Fri, 3 Oct 2014 16:48:06 +0200 Subject: Gcc 4.5.* build fix. Q_COMPILER_DEFAULT_MEMBERS and Q_COMPILER_DELETE_MEMBERS are now set starting from gcc 4.6. Pre-4.6 compilers implement a non-final snapshot of N2346, hence default and delete functions are supported only if they are public. Starting from 4.6, GCC handles final version - the access modifier is not relevant. Compiler error: qsharedpointer_impl.h:717:31: error: 'QEnableSharedFromThis::QEnableSharedFromThis()' declared with non-public access cannot be defaulted in the class body Change-Id: If1d3d4696f91912a09ca72bd4aa1fb07f491a0cb Reviewed-by: Marc Mutz Reviewed-by: Thiago Macieira --- src/corelib/global/qcompilerdetection.h | 7 +++++-- tests/auto/other/compiler/tst_compiler.cpp | 15 ++++++++++++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index ac60d47c7e..8e52c50322 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -730,8 +730,6 @@ /* C++11 features supported in GCC 4.4: */ # define Q_COMPILER_AUTO_FUNCTION # define Q_COMPILER_AUTO_TYPE -# define Q_COMPILER_DEFAULT_MEMBERS -# define Q_COMPILER_DELETE_MEMBERS # define Q_COMPILER_EXTERN_TEMPLATES # define Q_COMPILER_UNIFORM_INIT # define Q_COMPILER_UNICODE_STRINGS @@ -748,6 +746,11 @@ # define Q_COMPILER_CLASS_ENUM # endif # if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 + /* Pre-4.6 compilers implement a non-final snapshot of N2346, hence default and delete + * functions are supported only if they are public. Starting from 4.6, GCC handles + * final version - the access modifier is not relevant. */ +# define Q_COMPILER_DEFAULT_MEMBERS +# define Q_COMPILER_DELETE_MEMBERS /* C++11 features supported in GCC 4.6: */ # define Q_COMPILER_CONSTEXPR # define Q_COMPILER_NULLPTR diff --git a/tests/auto/other/compiler/tst_compiler.cpp b/tests/auto/other/compiler/tst_compiler.cpp index 47345bfc43..8253a283f5 100644 --- a/tests/auto/other/compiler/tst_compiler.cpp +++ b/tests/auto/other/compiler/tst_compiler.cpp @@ -784,12 +784,19 @@ void tst_Compiler::cxx11_default_members() #ifndef Q_COMPILER_DEFAULT_MEMBERS QSKIP("Compiler does not support C++11 feature"); #else - struct DefaultMembers + class DefaultMembers { + protected: DefaultMembers() = default; + public: DefaultMembers(int) {} }; - DefaultMembers dm; + class DefaultMembersChild: public DefaultMembers + { + public: + DefaultMembersChild():DefaultMembers() {}; + }; + DefaultMembersChild dm; Q_UNUSED(dm); #endif } @@ -799,9 +806,11 @@ void tst_Compiler::cxx11_delete_members() #ifndef Q_COMPILER_DELETE_MEMBERS QSKIP("Compiler does not support C++11 feature"); #else - struct DeleteMembers + class DeleteMembers { + protected: DeleteMembers() = delete; + public: DeleteMembers(const DeleteMembers &) = delete; ~DeleteMembers() = delete; }; -- cgit v1.2.3 From aa0002057835065d6ddb2be4d3c4deeda3276785 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 9 Oct 2014 11:40:04 +0200 Subject: Android: Support QSysInfo::productVersion() Gets the user-readable string for the current running Android version. Task-number: QTBUG-41764 Change-Id: Iefea4a4f5291bfddc99bbf901676ccd33fbc23d6 Reviewed-by: Thiago Macieira Reviewed-by: J-P Nurmi --- src/corelib/global/qglobal.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 2696df9e39..ae3e86629e 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -2519,7 +2519,9 @@ QString QSysInfo::productVersion() // fall through // Android and Blackberry should not fall through to the Unix code -#elif defined(Q_OS_ANDROID) +#elif defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_NO_SDK) + return QJNIObjectPrivate::getStaticObjectField("android/os/Build$VERSION", "RELEASE", "Ljava/lang/String;").toString(); +#elif defined(Q_OS_ANDROID) // Q_OS_ANDROID_NO_SDK // TBD #elif defined(Q_OS_BLACKBERRY) deviceinfo_details_t *deviceInfo; -- cgit v1.2.3 From 9685c72e37d618cf44aa15c892375b3c8d27e578 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 9 Oct 2014 12:37:56 +0200 Subject: Android: Return empty mime data instead of 0 from empty clipboard This is consistent with other platforms such as iOS and XCB, which return a QMimeData with an empty text when the clipboard is empty. [ChangeLog][Android] QClipboard::mimeData() now returns an empty object instead of null pointer from QClipboard when clipboard is empty for consistency with other platforms. Change-Id: I17068f0afcb63690cf11048ffa60e19dc9b08691 Task-number: QTBUG-41817 Reviewed-by: Paul Olav Tvete --- src/plugins/platforms/android/qandroidplatformclipboard.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/android/qandroidplatformclipboard.cpp b/src/plugins/platforms/android/qandroidplatformclipboard.cpp index 3515be436d..a975f4a852 100644 --- a/src/plugins/platforms/android/qandroidplatformclipboard.cpp +++ b/src/plugins/platforms/android/qandroidplatformclipboard.cpp @@ -44,10 +44,10 @@ QAndroidPlatformClipboard::QAndroidPlatformClipboard() QMimeData *QAndroidPlatformClipboard::mimeData(QClipboard::Mode mode) { - if (QClipboard::Clipboard != mode || !QtAndroidClipboard::hasClipboardText()) - return 0; - - m_mimeData.setText(QtAndroidClipboard::clipboardText()); + Q_ASSERT(supportsMode(mode)); + m_mimeData.setText(QtAndroidClipboard::hasClipboardText() + ? QtAndroidClipboard::clipboardText() + : QString()); return &m_mimeData; } -- cgit v1.2.3 From 74a20b77a67ec4d5a8be0f59302075d34151dc05 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 9 Oct 2014 12:46:04 +0200 Subject: Fix memory leak in QClipboard::setMimeData() The setMimeData() function is documented to take ownership of the object passed in, but in the case where the platform plugin did not support the requested mode, we would simply return without deleting the object nor telling the application, so it would cause a potential memory leak. We need to honor the contract, even when we fail to set the mime data. Test was updated to avoid verifying the leak in cases where the platform does not support all modes. [ChangeLog][QtGui][Clipboard] Fixed a memory leak in setMimeData() when the platform plugin did not support the requested mode. Task-number: QTBUG-41852 Change-Id: I2112da1613199fe1b56724e7ccf097b9e912c117 Reviewed-by: Richard Moe Gustavsen --- src/gui/kernel/qclipboard.cpp | 11 ++++++++--- tests/auto/gui/kernel/qclipboard/tst_qclipboard.cpp | 18 ++++++++++++------ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/gui/kernel/qclipboard.cpp b/src/gui/kernel/qclipboard.cpp index ec9a8fdcf0..5be9f19b3e 100644 --- a/src/gui/kernel/qclipboard.cpp +++ b/src/gui/kernel/qclipboard.cpp @@ -463,9 +463,14 @@ const QMimeData* QClipboard::mimeData(Mode mode) const void QClipboard::setMimeData(QMimeData* src, Mode mode) { QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard(); - if (!clipboard->supportsMode(mode)) return; - - clipboard->setMimeData(src,mode); + if (!clipboard->supportsMode(mode)) { + if (src != 0) { + qWarning("Data set on unsupported clipboard mode. QMimeData object will be deleted."); + src->deleteLater(); + } + } else { + clipboard->setMimeData(src,mode); + } } /*! diff --git a/tests/auto/gui/kernel/qclipboard/tst_qclipboard.cpp b/tests/auto/gui/kernel/qclipboard/tst_qclipboard.cpp index 167e4b41bc..a88f41f7b8 100644 --- a/tests/auto/gui/kernel/qclipboard/tst_qclipboard.cpp +++ b/tests/auto/gui/kernel/qclipboard/tst_qclipboard.cpp @@ -340,8 +340,10 @@ void tst_QClipboard::setMimeData() data->setText("foo"); QGuiApplication::clipboard()->setMimeData(data, QClipboard::Clipboard); - QGuiApplication::clipboard()->setMimeData(data, QClipboard::Selection); - QGuiApplication::clipboard()->setMimeData(data, QClipboard::FindBuffer); + if (QGuiApplication::clipboard()->supportsSelection()) + QGuiApplication::clipboard()->setMimeData(data, QClipboard::Selection); + if (QGuiApplication::clipboard()->supportsFindBuffer()) + QGuiApplication::clipboard()->setMimeData(data, QClipboard::FindBuffer); QSignalSpy spySelection(QGuiApplication::clipboard(), SIGNAL(selectionChanged())); QSignalSpy spyData(QGuiApplication::clipboard(), SIGNAL(dataChanged())); @@ -373,8 +375,10 @@ void tst_QClipboard::setMimeData() data->setText("foo"); QGuiApplication::clipboard()->setMimeData(data, QClipboard::Clipboard); - QGuiApplication::clipboard()->setMimeData(data, QClipboard::Selection); - QGuiApplication::clipboard()->setMimeData(data, QClipboard::FindBuffer); + if (QGuiApplication::clipboard()->supportsSelection()) + QGuiApplication::clipboard()->setMimeData(data, QClipboard::Selection); + if (QGuiApplication::clipboard()->supportsFindBuffer()) + QGuiApplication::clipboard()->setMimeData(data, QClipboard::FindBuffer); QMimeData *newData = new QMimeData; newData->setText("bar"); @@ -385,8 +389,10 @@ void tst_QClipboard::setMimeData() spyFindBuffer.clear(); QGuiApplication::clipboard()->setMimeData(newData, QClipboard::Clipboard); - QGuiApplication::clipboard()->setMimeData(newData, QClipboard::Selection); // used to crash on X11 - QGuiApplication::clipboard()->setMimeData(newData, QClipboard::FindBuffer); + if (QGuiApplication::clipboard()->supportsSelection()) + QGuiApplication::clipboard()->setMimeData(newData, QClipboard::Selection); // used to crash on X11 + if (QGuiApplication::clipboard()->supportsFindBuffer()) + QGuiApplication::clipboard()->setMimeData(newData, QClipboard::FindBuffer); if (QGuiApplication::clipboard()->supportsSelection()) QCOMPARE(spySelection.count(), 1); -- cgit v1.2.3 From 0647f24c7ddd73b1c4e273a71497f852573b4911 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Thu, 9 Oct 2014 14:10:04 +0200 Subject: QMenu: ensure that a menu item's icon can be removed dynamically Task-number: QTBUG-41348 Change-Id: Iad3b7f000ebce51530f5e196868aefffad2e1eab Reviewed-by: Gabriel de Dietrich --- src/widgets/widgets/qmenu.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index f2aefe6ea9..0fd645a4d3 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -2980,6 +2980,8 @@ static void copyActionToPlatformItem(const QAction *action, QPlatformMenuItem* i QStyleOption opt; item->setIconSize(qApp->style()->pixelMetric(QStyle::PM_SmallIconSize, &opt, 0)); } + } else { + item->setIcon(QIcon()); } item->setVisible(action->isVisible()); item->setShortcut(action->shortcut()); -- cgit v1.2.3 From 01f5ba006eb8b7910b36909727c7b1a0b053ea09 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 29 Sep 2014 15:30:08 +0200 Subject: Fix patching of installation date Marking qt_eval_expiry_date alone as volatile apparently didn't stop the compiler from optimizing away the calculation of the expiry date. Task-number: QTBUG-41612 Change-Id: Ia51fb83f03250346952a76c8a1a641096b4ff9e7 Reviewed-by: Oswald Buddenhagen Reviewed-by: Friedemann Kleint Reviewed-by: Kalle Viironen Reviewed-by: Iikka Eklund --- src/corelib/kernel/qtcore_eval.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qtcore_eval.cpp b/src/corelib/kernel/qtcore_eval.cpp index c0f8897b3b..eb1019534c 100644 --- a/src/corelib/kernel/qtcore_eval.cpp +++ b/src/corelib/kernel/qtcore_eval.cpp @@ -111,10 +111,11 @@ static EvaluationStatus qt_eval_is_supported() static int qt_eval_days_left() { - const char *expiry_date = const_cast(qt_eval_expiry_date + 12); + const volatile char *const expiry_date = qt_eval_expiry_date + 12; QDate today = QDate::currentDate(); - QDate lastday = QDate::fromString(QString::fromLatin1(expiry_date), Qt::ISODate); + QDate lastday = QDate::fromString( + QString::fromLatin1(const_cast(expiry_date)), Qt::ISODate); return today.daysTo(lastday); } -- cgit v1.2.3 From e4493c41b641273e76558b568196a4629a7c4ea6 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 10 Oct 2014 10:46:26 +0200 Subject: DPI-scale PM_SubMenuOverlap after all This actually isn't a magic value and needs to be scaled. This partially reverts commit be1635e2d6a4e42f3f828e7831e5dbf867ba161d. Task-number: QTBUG-41864 Change-Id: Ie03c96c8b5343386f55c3ae9b988e79f943f334e Reviewed-by: Alessandro Portale --- src/widgets/styles/qfusionstyle.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp index 8d7ca42934..c1d6d879a8 100644 --- a/src/widgets/styles/qfusionstyle.cpp +++ b/src/widgets/styles/qfusionstyle.cpp @@ -3098,7 +3098,8 @@ int QFusionStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, co val = 2; break; case PM_SubMenuOverlap: - return -1; // Do not dpi-scale because the value is magic + val = -1; + break; case PM_DockWidgetHandleExtent: case PM_SplitterWidth: val = 4; -- cgit v1.2.3 From 9bbf08fcf3ad141b92dda3af2103dac28ff40f00 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 10 Oct 2014 14:31:47 +0200 Subject: Android: Make memory handling in QClipboard consistent with iOS On iOS we do deleteLater() on the mime data instead of deleting it directly, in case the application should happen to use the pointer again directly after setting it on the clipboard. Technically it would be a bug in the application, but using deleteLater() is safer and it's better to be consistent with iOS so that a buggy application crashes in the same places in both. Change-Id: I2996d6c7816a2f83615a43609f5be207aaa72c86 Task-number: QTBUG-41853 Reviewed-by: BogDan Vatra --- src/plugins/platforms/android/qandroidplatformclipboard.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/android/qandroidplatformclipboard.cpp b/src/plugins/platforms/android/qandroidplatformclipboard.cpp index a975f4a852..fb73db8455 100644 --- a/src/plugins/platforms/android/qandroidplatformclipboard.cpp +++ b/src/plugins/platforms/android/qandroidplatformclipboard.cpp @@ -55,7 +55,8 @@ void QAndroidPlatformClipboard::setMimeData(QMimeData *data, QClipboard::Mode mo { Q_ASSERT(supportsMode(mode)); QtAndroidClipboard::setClipboardText(data != 0 && data->hasText() ? data->text() : QString()); - delete data; + if (data != 0) + data->deleteLater(); } bool QAndroidPlatformClipboard::supportsMode(QClipboard::Mode mode) const -- cgit v1.2.3 From 8c538d10da618add00aba1acbc8d8dc2f24445b4 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Fri, 10 Oct 2014 14:00:44 +0200 Subject: OS X: rename special menu items instead of duplicating Two-part fix: QCocoaMenu::syncMenuItem, when selecting the "old" menu, if an item was merged, 'applicationMenu' was always selected, but this is wrong for any item with a role >= CutRole (such an item still can be "merged", but it's not in the application menu). QCocoaMenuItem::sync - item can be merged with itself: after item's role detected, the search for an item to merge with can find exactly the same item we've just detected the role for (since a data-member is modified) - try to avoid this. Task-number: QTBUG-39934 Change-Id: Ibe1df9e92973380652101143067e14922afdfb9e Reviewed-by: Shawn Rutledge --- src/plugins/platforms/cocoa/qcocoamenu.mm | 9 +++++++-- src/plugins/platforms/cocoa/qcocoamenuitem.mm | 11 +++++++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 736e02a3ca..d849389907 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -366,9 +366,14 @@ void QCocoaMenu::syncMenuItem(QPlatformMenuItem *menuItem) } bool wasMerged = cocoaItem->isMerged(); - NSMenu *oldMenu = wasMerged ? [getMenuLoader() applicationMenu] : m_nativeMenu; - NSMenuItem *oldItem = [oldMenu itemWithTag:(NSInteger) cocoaItem]; + NSMenu *oldMenu = m_nativeMenu; + if (wasMerged) { + QPlatformMenuItem::MenuRole role = cocoaItem->effectiveRole(); + if (role >= QPlatformMenuItem::ApplicationSpecificRole && role < QPlatformMenuItem::CutRole) + oldMenu = [getMenuLoader() applicationMenu]; + } + NSMenuItem *oldItem = [oldMenu itemWithTag:(NSInteger) cocoaItem]; if (cocoaItem->sync() != oldItem) { // native item was changed for some reason if (oldItem) { diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index 3d3b6bf598..791b0805d0 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -256,8 +256,8 @@ NSMenuItem *QCocoaMenuItem::sync() if (depth == 3 || !menubar) break; // Menu item too deep in the hierarchy, or not connected to any menubar - m_detectedRole = detectMenuRole(m_text); - switch (m_detectedRole) { + MenuRole newDetectedRole = detectMenuRole(m_text); + switch (newDetectedRole) { case QPlatformMenuItem::AboutRole: if (m_text.indexOf(QRegExp(QString::fromLatin1("qt$"), Qt::CaseInsensitive)) == -1) mergeItem = [loader aboutMenuItem]; @@ -271,12 +271,15 @@ NSMenuItem *QCocoaMenuItem::sync() mergeItem = [loader quitMenuItem]; break; default: - if (m_detectedRole >= CutRole && m_detectedRole < RoleCount && menubar) - mergeItem = menubar->itemForRole(m_detectedRole); + if (newDetectedRole >= CutRole && newDetectedRole < RoleCount && menubar) + mergeItem = menubar->itemForRole(newDetectedRole); if (!m_text.isEmpty()) m_textSynced = true; break; } + + m_detectedRole = newDetectedRole; + break; } -- cgit v1.2.3 From 7c90778487fee7c53e27766ac895c620ad566049 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Fri, 10 Oct 2014 12:04:17 +0200 Subject: Account for the country/language settings when checking for duplicates When a file has the same alias but a different country or language setting then it should not warn about it being a potential duplicate. Task-number: QTBUG-19286 Change-Id: I60a9c422ff02214399bdea3791374a65c9f6c604 Reviewed-by: hjk --- src/tools/rcc/rcc.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp index 6d4cc12d5c..11a99d136d 100644 --- a/src/tools/rcc/rcc.cpp +++ b/src/tools/rcc/rcc.cpp @@ -610,11 +610,18 @@ bool RCCResourceLibrary::addFile(const QString &alias, const RCCFileInfo &file) const QString filename = nodes.at(nodes.size()-1); RCCFileInfo *s = new RCCFileInfo(file); s->m_parent = parent; - if (parent->m_children.contains(filename)) { - foreach (const QString &fileName, m_fileNames) - qWarning("%s: Warning: potential duplicate alias detected: '%s'", - qPrintable(fileName), qPrintable(filename)); + typedef QHash::const_iterator ChildConstIterator; + const ChildConstIterator cbegin = parent->m_children.constFind(filename); + const ChildConstIterator cend = parent->m_children.constEnd(); + for (ChildConstIterator it = cbegin; it != cend; ++it) { + if (it.key() == filename && it.value()->m_language == s->m_language && + it.value()->m_country == s->m_country) { + foreach (const QString &name, m_fileNames) + qWarning("%s: Warning: potential duplicate alias detected: '%s'", + qPrintable(name), qPrintable(filename)); + break; } + } parent->m_children.insertMulti(filename, s); return true; } -- cgit v1.2.3 From 65c542bc87bd40da90c63e322d1275045de19bff Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 10 Oct 2014 09:57:31 +0200 Subject: qiosclipboard: take ownership over mime data QClipboard is documented to take ownership over the mime data set with "setMimeData" and the value returned by "mimeData". So we need to implement this to avoid memory leaks. Change-Id: Ieb3a17368ed3a698c29a7f92c8ee87a0cca86b46 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/plugins/platforms/ios/qiosclipboard.h | 4 ++++ src/plugins/platforms/ios/qiosclipboard.mm | 11 ++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/qiosclipboard.h b/src/plugins/platforms/ios/qiosclipboard.h index 7d758e3a56..f532eba3de 100644 --- a/src/plugins/platforms/ios/qiosclipboard.h +++ b/src/plugins/platforms/ios/qiosclipboard.h @@ -36,6 +36,7 @@ #import +#include #include @class QUIClipboard; @@ -46,6 +47,8 @@ class QIOSClipboard : public QPlatformClipboard { public: QIOSClipboard(); + ~QIOSClipboard(); + QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE; void setMimeData(QMimeData *mimeData, QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE; bool supportsMode(QClipboard::Mode mode) const Q_DECL_OVERRIDE; @@ -53,6 +56,7 @@ public: private: QUIClipboard *m_clipboard; + QMap m_mimeData; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosclipboard.mm b/src/plugins/platforms/ios/qiosclipboard.mm index e18ad53b2c..5ed6d3be62 100644 --- a/src/plugins/platforms/ios/qiosclipboard.mm +++ b/src/plugins/platforms/ios/qiosclipboard.mm @@ -194,10 +194,17 @@ QIOSClipboard::QIOSClipboard() { } +QIOSClipboard::~QIOSClipboard() +{ + qDeleteAll(m_mimeData); +} + QMimeData *QIOSClipboard::mimeData(QClipboard::Mode mode) { Q_ASSERT(supportsMode(mode)); - return new QIOSMimeData(mode); + if (!m_mimeData.contains(mode)) + return *m_mimeData.insert(mode, new QIOSMimeData(mode)); + return m_mimeData[mode]; } void QIOSClipboard::setMimeData(QMimeData *mimeData, QClipboard::Mode mode) @@ -209,6 +216,8 @@ void QIOSClipboard::setMimeData(QMimeData *mimeData, QClipboard::Mode mode) pb.items = [NSArray array]; return; } + + mimeData->deleteLater(); NSMutableDictionary *pbItem = [NSMutableDictionary dictionaryWithCapacity:mimeData->formats().size()]; foreach (const QString &mimeType, mimeData->formats()) { -- cgit v1.2.3 From d16f76cde3a78287b565215e6d6906f54616b756 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Hunold?= Date: Thu, 9 Oct 2014 08:40:18 +0200 Subject: Remove duplicate of clang + libc++ mkspec The same funcionality is already supported, so we avoid confusion. The corresponding mkspec is name "linux-clang-libc++" Change-Id: Ib087595298b48c73ad5da8d92cca2d1bac89f2be Reviewed-by: Joerg Bornemann --- mkspecs/unsupported/linux-libc++-clang/qmake.conf | 20 ----- .../unsupported/linux-libc++-clang/qplatformdefs.h | 92 ---------------------- 2 files changed, 112 deletions(-) delete mode 100644 mkspecs/unsupported/linux-libc++-clang/qmake.conf delete mode 100644 mkspecs/unsupported/linux-libc++-clang/qplatformdefs.h diff --git a/mkspecs/unsupported/linux-libc++-clang/qmake.conf b/mkspecs/unsupported/linux-libc++-clang/qmake.conf deleted file mode 100644 index bf0abb2a54..0000000000 --- a/mkspecs/unsupported/linux-libc++-clang/qmake.conf +++ /dev/null @@ -1,20 +0,0 @@ -# -# qmake configuration for linux-clang -# - -MAKEFILE_GENERATOR = UNIX -CONFIG += incremental - -QMAKE_INCREMENTAL_STYLE = sublib - -include(../../common/linux.conf) -include(../../common/gcc-base-unix.conf) -include(../../common/clang.conf) - -QMAKE_CFLAGS_RELEASE = -Os -QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE - -QMAKE_CXXFLAGS_CXX11 += -std=c++11 -stdlib=libc++ -QMAKE_LFLAGS_CXX11 += -stdlib=libc++ -lc++abi - -load(qt_config) diff --git a/mkspecs/unsupported/linux-libc++-clang/qplatformdefs.h b/mkspecs/unsupported/linux-libc++-clang/qplatformdefs.h deleted file mode 100644 index 0f0c60b148..0000000000 --- a/mkspecs/unsupported/linux-libc++-clang/qplatformdefs.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the qmake spec of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPLATFORMDEFS_H -#define QPLATFORMDEFS_H - -// Get Qt defines/settings - -#include "qglobal.h" - -// Set any POSIX/XOPEN defines at the top of this file to turn on specific APIs - -// 1) need to reset default environment if _BSD_SOURCE is defined -// 2) need to specify POSIX thread interfaces explicitly in glibc 2.0 -// 3) it seems older glibc need this to include the X/Open stuff -#ifndef _GNU_SOURCE -# define _GNU_SOURCE -#endif - -#include - - -// We are hot - unistd.h should have turned on the specific APIs we requested - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef QT_NO_IPV6IFNAME -#include -#endif - -#define QT_USE_XOPEN_LFS_EXTENSIONS -#include "../../common/posix/qplatformdefs.h" - -#undef QT_SOCKLEN_T - -#if defined(__GLIBC__) && (__GLIBC__ >= 2) -#define QT_SOCKLEN_T socklen_t -#else -#define QT_SOCKLEN_T int -#endif - -#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500) -#define QT_SNPRINTF ::snprintf -#define QT_VSNPRINTF ::vsnprintf -#endif - -#endif // QPLATFORMDEFS_H -- cgit v1.2.3 From 38c39341b3394f5c9223a96bd65b52984308740c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 9 Oct 2014 12:44:30 +0200 Subject: Use :- instead of - for empty environment variables We set the variables to empty when we start processing, so ${FOO-foo} will never print "foo". We need to use ${FOO:-foo}. Change-Id: I00c28edb10d8eaa09df689905a302b576b246806 Reviewed-by: Oswald Buddenhagen --- configure | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure b/configure index 6597262053..7d6ba9f4d6 100755 --- a/configure +++ b/configure @@ -6492,10 +6492,10 @@ echo " Configure summary" echo if [ "$XPLATFORM" = "$PLATFORM" ]; then # the missing space before $CFG_FEATURES is intentional - echo "Build type: $PLATFORM ($CFG_ARCH, CPU features:${CFG_CPUFEATURES- none detected})" + echo "Build type: $PLATFORM ($CFG_ARCH, CPU features:${CFG_CPUFEATURES:- none detected})" else - echo "Building on: $PLATFORM ($CFG_HOST_ARCH, CPU features:${CFG_HOST_CPUFEATURES- none detected})" - echo "Building for: $XPLATFORM ($CFG_ARCH, CPU features:${CFG_CPUFEATURES- none detected})" + echo "Building on: $PLATFORM ($CFG_HOST_ARCH, CPU features:${CFG_HOST_CPUFEATURES:- none detected})" + echo "Building for: $XPLATFORM ($CFG_ARCH, CPU features:${CFG_CPUFEATURES:- none detected})" fi -- cgit v1.2.3 From 955c9562bdb07927069f281a8635ce20405051c3 Mon Sep 17 00:00:00 2001 From: David Faure Date: Tue, 23 Sep 2014 23:33:40 +0200 Subject: QSettings: undo unintentional change of config dir on non-XDG platforms. c99dfd8f631289 only meant to be able to switch to the test mode of QStandardPaths, not to move the default dir on OS X, iOS, BB10 and Android. So this commit restores it to the previous behavior, to avoid migration issues. The use of XDG_CONFIG_HOME, defaulting to ~/.config, on OS X, is even documented in the current QSettings documentation, even though these paths are non-standard on OS X (granted, the use of ini-style config files isn't either). Task-number: QTBUG-41461 Change-Id: I5eb610ff7ccbdaf6f955ef7f8f7c2658cbecbb86 Reviewed-by: Eike Ziller Reviewed-by: Oswald Buddenhagen Reviewed-by: Thiago Macieira --- src/corelib/io/qsettings.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index f6cd5aa7c9..fd35ae33dc 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -100,6 +100,10 @@ using namespace ABI::Windows::Storage; #define CSIDL_APPDATA 0x001a // \Application Data #endif +#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(Q_OS_BLACKBERRY) && !defined(Q_OS_ANDROID) +#define Q_XDG_PLATFORM +#endif + // ************************************************************************ // QConfFile @@ -1041,7 +1045,9 @@ static void initDefaultPaths(QMutexLocker *locker) windowsConfigPath(CSIDL_COMMON_APPDATA) + QDir::separator()); #else -#ifdef QT_NO_STANDARDPATHS +#if defined(QT_NO_STANDARDPATHS) || !defined(Q_XDG_PLATFORM) + // Non XDG platforms (OS X, iOS, Blackberry, Android...) have used this code path erroneously + // for some time now. Moving away from that would require migrating existing settings. QString userPath; char *env = getenv("XDG_CONFIG_HOME"); if (env == 0) { @@ -1056,6 +1062,9 @@ static void initDefaultPaths(QMutexLocker *locker) userPath += QFile::decodeName(env); } #else + // When using a proper XDG platform, use QStandardPaths rather than the above hand-written code; + // it makes the use of test mode from unit tests possible. + // Ideally all platforms should use this, but see above for the migration issue. QString userPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation); #endif userPath += QLatin1Char('/'); -- cgit v1.2.3 From 1910454fe00cce8b815b1abc0a18a04d3d387ccf Mon Sep 17 00:00:00 2001 From: Tom Hirst Date: Fri, 10 Oct 2014 17:02:17 +0100 Subject: prevent if_nametoindex being called with empty string Calling if_nametoindex with an empty string will always return 0, but on ARM linux platforms this call seems to be very expensive (~30ms), adding a large overhead to calls such as QUdpSocket::writeDatagram() Task-number: QTBUG-37092 Change-Id: Iad00867585d9534af1ddaee936dd4e4dc5e03611 Reviewed-by: Giuseppe D'Angelo Reviewed-by: Thiago Macieira --- src/network/socket/qnativesocketengine_unix.cpp | 33 ++++++++++++++++--------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index 60f971a2fb..ad170e187c 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -384,12 +384,15 @@ bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &addr, quint16 sockAddrIPv6.sin6_port = htons(port); QString scopeid = addr.scopeId(); - bool ok; - sockAddrIPv6.sin6_scope_id = scopeid.toInt(&ok); + + if (!scopeid.isEmpty()) { + bool ok; + sockAddrIPv6.sin6_scope_id = scopeid.toInt(&ok); #ifndef QT_NO_IPV6IFNAME - if (!ok) - sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.toLatin1()); + if (!ok) + sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.toLatin1()); #endif + } Q_IPV6ADDR ip6 = addr.toIPv6Address(); memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &ip6, sizeof(ip6)); @@ -498,11 +501,16 @@ bool QNativeSocketEnginePrivate::nativeBind(const QHostAddress &address, quint16 memset(&sockAddrIPv6, 0, sizeof(sockAddrIPv6)); sockAddrIPv6.sin6_family = AF_INET6; sockAddrIPv6.sin6_port = htons(port); + QString scopeid = address.scopeId(); + + if (!scopeid.isEmpty()) { + bool ok; + sockAddrIPv6.sin6_scope_id = scopeid.toInt(&ok); #ifndef QT_NO_IPV6IFNAME - sockAddrIPv6.sin6_scope_id = ::if_nametoindex(address.scopeId().toLatin1().data()); -#else - sockAddrIPv6.sin6_scope_id = address.scopeId().toInt(); + if (!ok) + sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.toLatin1()); #endif + } Q_IPV6ADDR tmp = address.toIPv6Address(); memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &tmp, sizeof(tmp)); sockAddrSize = sizeof(sockAddrIPv6); @@ -917,12 +925,15 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l Q_IPV6ADDR tmp = host.toIPv6Address(); memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &tmp, sizeof(tmp)); QString scopeid = host.scopeId(); - bool ok; - sockAddrIPv6.sin6_scope_id = scopeid.toInt(&ok); + + if (!scopeid.isEmpty()) { + bool ok; + sockAddrIPv6.sin6_scope_id = scopeid.toInt(&ok); #ifndef QT_NO_IPV6IFNAME - if (!ok) - sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.toLatin1()); + if (!ok) + sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.toLatin1()); #endif + } sockAddrSize = sizeof(sockAddrIPv6); sockAddrPtr = (struct sockaddr *)&sockAddrIPv6; } else if (host.protocol() == QAbstractSocket::IPv4Protocol) { -- cgit v1.2.3 From e3bfd9bea65cc7a9e1742b0cb7ca9af22c42f730 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 3 Oct 2014 13:50:30 +0200 Subject: QMacStyle: Use NSRect instead of CGRect in drawNSViewInRect() Change-Id: I90fd62dea377dfa9569d1730a67136c7a5dc6f82 Reviewed-by: Timur Pocheptsov Reviewed-by: Andy Shaw --- src/widgets/styles/qmacstyle_mac.mm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index 82718eea7f..9347a6ea90 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -1897,11 +1897,11 @@ void QMacStylePrivate::drawNSViewInRect(NSView *view, const QRect &qtRect, QPain [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:ctx flipped:YES]]; - CGRect rect = CGRectMake(qtRect.x() + 1, qtRect.y(), qtRect.width(), qtRect.height()); + NSRect rect = NSMakeRect(qtRect.x() + 1, qtRect.y(), qtRect.width(), qtRect.height()); [backingStoreNSView addSubview:view]; - view.frame = NSRectFromCGRect(rect); - [view drawRect:NSRectFromCGRect(rect)]; + view.frame = rect; + [view drawRect:rect]; [view removeFromSuperviewWithoutNeedingDisplay]; [NSGraphicsContext restoreGraphicsState]; -- cgit v1.2.3 From 8304c8087d269b5b48621cc18d3ebe2bd369ebf4 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Thu, 9 Jan 2014 15:29:28 +0100 Subject: Doc: Update description of QKeyEvent class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update the description on how to use the QKeyEvent pointer passed to key event handlers, and remove an outdated note about multimedia key events. Change-Id: I67a3f0054e28b84d5a0e367c02a329f4670221c7 Task-number: QTBUG-35155 Reviewed-by: Topi Reiniö --- src/gui/kernel/qevent.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index f99f28d6e0..a8539e8013 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -897,12 +897,11 @@ QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, when keys are pressed or released. A key event contains a special accept flag that indicates whether - the receiver will handle the key event. You should call ignore() - if the key press or release event is not handled by your widget. - A key event is propagated up the parent widget chain until a - widget accepts it with accept() or an event filter consumes it. - Key events for multimedia keys are ignored by default. You should - call accept() if your widget handles those events. + the receiver will handle the key event. This flag is set by default, + so there is no need to call accept() when acting on a key event. + Calling ignore() on a key event will propagate it to the parent widget. + The event is propagated up the parent widget chain until a widget + accepts it or an event filter consumes it. The QWidget::setEnable() function can be used to enable or disable mouse and keyboard events for a widget. -- cgit v1.2.3 From df2afcad2fc58effc73797402176a67d0964637a Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 9 Oct 2014 22:42:50 +0200 Subject: QTableGenerator: replace a call to a member function with direct element access Saves one copy of a vector. Change-Id: I3a14c46e306c3d44a64c6e0d8cd2f120b2c208d7 Reviewed-by: Thiago Macieira Reviewed-by: Friedemann Kleint --- src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp index c0aaed2525..4e90f61876 100644 --- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp +++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp @@ -442,7 +442,7 @@ void TableGenerator::parseKeySequence(char *line) void TableGenerator::printComposeTable() const { #ifdef DEBUG_GENERATOR - if (composeTable().isEmpty()) + if (m_composeTable.isEmpty()) return; QString output; -- cgit v1.2.3 From 26fbeecfa55ee3250c81da6d2e14567ec2051e23 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Sat, 20 Sep 2014 17:23:31 +0200 Subject: Initialize QFileSystemMetaData::size_ data member There's a code path which reads that member before it got anything assigned to it, triggering undefined behavior. The code path goes as follows: 1. an instance is created in QFSFileEngineIterator::advance 2. the instance is passed to QFileSystemIterator::advance, which fills in only some members (not size_) 3. the instance is passed to QFileInfoPrivate which does a deep copy, reading an uninitialized size_ Change-Id: I6835ee701a83b63ca4bad6235feeb6a23566fcd3 Reviewed-by: Marc Mutz Reviewed-by: Thiago Macieira --- src/corelib/io/qfilesystemmetadata_p.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index de79ec32d3..27e2dac2e4 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -74,7 +74,8 @@ class QFileSystemMetaData { public: QFileSystemMetaData() - : knownFlagsMask(0) + : knownFlagsMask(0), + size_(-1) { } -- cgit v1.2.3 From 2b4cda3852cf92fdff3ce4956f8752a99e44cf56 Mon Sep 17 00:00:00 2001 From: Dyami Caliri Date: Thu, 9 Oct 2014 15:25:07 -0700 Subject: QMacStyle: save context state before changing to avoid crash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qt_drawFocusRingOnPath was saving the graphics state after setting a new context. This leads to zombie NSBitmapGraphicsContext access with QFileDialog. Task-number: QTBUG-41879 Change-Id: I7fc7d959d2b0f01cb3491d639023083f1b46d175 Reviewed-by: Gabriel de Dietrich Reviewed-by: Morten Johan Sørvig --- src/widgets/styles/qmacstyle_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index 70daafc88c..db971eba1b 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -1102,9 +1102,9 @@ static QAquaWidgetSize qt_aqua_guess_size(const QWidget *widg, QSize large, QSiz static void qt_drawFocusRingOnPath(CGContextRef cg, NSBezierPath *focusRingPath) { CGContextSaveGState(cg); + [NSGraphicsContext saveGraphicsState]; [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:(CGContextRef)cg flipped:NO]]; - [NSGraphicsContext saveGraphicsState]; NSSetFocusRingStyle(NSFocusRingOnly); [focusRingPath setClip]; // Clear clip path to avoid artifacts when rendering the cursor at zero pos [focusRingPath fill]; -- cgit v1.2.3 From 4cbb99c5e23cb56633b78636bdb7113cd9914a61 Mon Sep 17 00:00:00 2001 From: Maximilian Hrabowski Date: Wed, 8 Oct 2014 20:07:31 +0200 Subject: QAbstractItemView: fix CTRL+A select all behavior The check for Qt::Key_A to handle selectAll was changed to directly compare to QKeySequence::SelectAll as this will only match Ctrl. The former implementation also triggered when e.g. Shift was pressed. Added a check that selectAll is only called when selection is not disabled, i.e. selectionMode=NoSelection. Added a unit test for selectAll(). Task-number: QTBUG-26687 Change-Id: I721e7ab590b55d7d754b3b74ef01756fa5aa1315 Reviewed-by: Olivier Goffart --- src/widgets/itemviews/qabstractitemview.cpp | 5 +- .../itemviews/qtableview/tst_qtableview.cpp | 159 +++++++++++++++++++++ 2 files changed, 161 insertions(+), 3 deletions(-) diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index a77448cbc4..34e0a8faa0 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -2409,12 +2409,11 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event) } break; #endif - case Qt::Key_A: - if (event->modifiers() & Qt::ControlModifier) { + default: { + if (event == QKeySequence::SelectAll && selectionMode() != NoSelection) { selectAll(); break; } - default: { #ifdef Q_WS_MAC if (event->key() == Qt::Key_O && event->modifiers() & Qt::ControlModifier && currentIndex().isValid()) { emit activated(currentIndex()); diff --git a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp index 38367fb4ee..826c2acb78 100644 --- a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp +++ b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp @@ -125,6 +125,9 @@ private slots: void selectColumn_data(); void selectColumn(); + void selectall_data(); + void selectall(); + void visualRect_data(); void visualRect(); @@ -1890,6 +1893,162 @@ void tst_QTableView::selectColumn() QCOMPARE(view.selectionModel()->selectedIndexes().at(i).column(), column); } +void tst_QTableView::selectall_data() +{ + QTest::addColumn("rowCount"); + QTest::addColumn("columnCount"); + QTest::addColumn("row"); + QTest::addColumn("column"); + QTest::addColumn("rowSpan"); + QTest::addColumn("columnSpan"); + QTest::addColumn("hideRow"); + QTest::addColumn("hideColumn"); + QTest::addColumn("moveRowFrom"); + QTest::addColumn("moveRowTo"); + QTest::addColumn("moveColumnFrom"); + QTest::addColumn("moveColumnTo"); + QTest::addColumn("rowHeight"); + QTest::addColumn("columnWidth"); + QTest::addColumn("selectedCount"); // ### make this more detailed + + QTest::newRow("no span, no hidden, no moved") + << 10 << 10 // dim + << -1 << -1 // pos + << 1 << 1 // span + << -1 << -1 // hide + << -1 << -1 // move row + << -1 << -1 // move col + << 40 << 40 // cell size + << 100; // selected count + + QTest::newRow("row span, no hidden, no moved") + << 10 << 10 // dim + << 1 << 1 // pos + << 2 << 1 // span + << -1 << -1 // hide + << -1 << -1 // move row + << -1 << -1 // move col + << 40 << 40 // cell size + << 99; // selected count + + QTest::newRow("col span, no hidden, no moved") + << 10 << 10 // dim + << 1 << 1 // pos + << 1 << 2 // span + << -1 << -1 // hide + << -1 << -1 // move row + << -1 << -1 // move col + << 40 << 40 // cell size + << 99; // selected count + + QTest::newRow("no span, row hidden, no moved") + << 10 << 10 // dim + << -1 << -1 // pos + << 1 << 1 // span + << 1 << -1 // hide + << -1 << -1 // move row + << -1 << -1 // move col + << 40 << 40 // cell size + << 90; // selected count + + QTest::newRow("no span, col hidden, no moved") + << 10 << 10 // dim + << -1 << -1 // pos + << 1 << 1 // span + << -1 << 1 // hide + << -1 << -1 // move row + << -1 << -1 // move col + << 40 << 40 // cell size + << 90; // selected count + + QTest::newRow("no span, no hidden, row moved") + << 10 << 10 // dim + << -1 << -1 // pos + << 1 << 1 // span + << -1 << -1 // hide + << 1 << 3 // move row + << -1 << -1 // move col + << 40 << 40 // cell size + << 100; // selected count + + QTest::newRow("no span, no hidden, col moved") + << 10 << 10 // dim + << -1 << -1 // pos + << 1 << 1 // span + << -1 << -1 // hide + << -1 << -1 // move row + << 1 << 3 // move col + << 40 << 40 // cell size + << 100; // selected count +} + +void QTest__keySequence(QWidget* widget, QKeySequence ks) +{ + for (int i=0; imoveSection(moveRowFrom, moveRowTo); + view.horizontalHeader()->moveSection(moveColumnFrom, moveColumnTo); + + for (int r = 0; r < rowCount; ++r) + view.setRowHeight(r, rowHeight); + for (int c = 0; c < columnCount; ++c) + view.setColumnWidth(c, columnWidth); + + // try slot first + view.clearSelection(); + QCOMPARE(view.selectedIndexes().count(), 0); + view.selectAll(); + QCOMPARE(view.selectedIndexes().count(), selectedCount); + + // try by key sequence + view.clearSelection(); + QCOMPARE(view.selectedIndexes().count(), 0); + QTest__keySequence(&view, QKeySequence(QKeySequence::SelectAll)); + QCOMPARE(view.selectedIndexes().count(), selectedCount); + + // check again with no selection mode + view.clearSelection(); + view.setSelectionMode(QAbstractItemView::NoSelection); + QCOMPARE(view.selectedIndexes().count(), 0); + QTest__keySequence(&view, QKeySequence(QKeySequence::SelectAll)); + QCOMPARE(view.selectedIndexes().count(), 0); +} + void tst_QTableView::visualRect_data() { QTest::addColumn("rowCount"); -- cgit v1.2.3 From b380bcc7e244f07d5f2c1f64fc34b6c780f9b781 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 26 Sep 2014 18:55:42 +0200 Subject: QMacStyle: Fix QPushButton with menu appearance on 10.10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As usual, this includes small and mini control sizes. Flat and oversized buttons will fall back to the HITheme rendering for now. Task-number: QTBUG-40833 Change-Id: I08d67c48b2e72681af4dc4a37ea498f7aac1dca0 Reviewed-by: Morten Johan Sørvig --- src/widgets/styles/qmacstyle_mac.mm | 57 ++++++++++++++++++++++++---------- src/widgets/styles/qmacstyle_mac_p_p.h | 1 + 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index db971eba1b..bad436f846 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -1800,7 +1800,8 @@ NSView *QMacStylePrivate::cocoaControl(QCocoaWidget widget, QPoint *offset) cons NSView *bv = cocoaControls[widget]; if (!bv) { - if (widget.first == QCocoaPopupButton) + if (widget.first == QCocoaPopupButton + || widget.first == QCocoaPullDownButton) bv = [[NSPopUpButton alloc] init]; else if (widget.first == QCocoaComboBox) bv = [[NSComboBox alloc] init]; @@ -1830,6 +1831,11 @@ NSView *QMacStylePrivate::cocoaControl(QCocoaWidget widget, QPoint *offset) cons bc.bezelStyle = NSRoundedBezelStyle; break; } + case QCocoaPullDownButton: { + NSPopUpButton *bc = (NSPopUpButton *)bv; + bc.pullsDown = YES; + break; + } default: break; } @@ -1872,6 +1878,12 @@ NSView *QMacStylePrivate::cocoaControl(QCocoaWidget widget, QPoint *offset) cons *offset = QPoint(7, 5); else if (widget == QCocoaWidget(QCocoaPopupButton, QAquaSizeMini)) *offset = QPoint(2, -1); + else if (widget == QCocoaWidget(QCocoaPullDownButton, QAquaSizeLarge)) + *offset = QPoint(3, -1); + else if (widget == QCocoaWidget(QCocoaPullDownButton, QAquaSizeSmall)) + *offset = QPoint(2, 1); + else if (widget == QCocoaWidget(QCocoaPullDownButton, QAquaSizeMini)) + *offset = QPoint(5, 0); } return bv; @@ -3802,21 +3814,24 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter else if (d->pressedButton == opt->styleObject) d->pressedButton = 0; + bool hasMenu = btn->features & QStyleOptionButton::HasMenu; HIThemeButtonDrawInfo bdi; d->initHIThemePushButton(btn, w, tds, &bdi); if (yosemiteOrLater) { - // HITheme is not drawing a nice focus frame around buttons. - // We'll do it ourselves further down. - bdi.adornment &= ~kThemeAdornmentFocus; - - // We can't rely on an animation existing to test for the default look. That means a bit - // more logic (notice that the logic is slightly different for the bevel and the label). - if (tds == kThemeStateActive - && (btn->features & QStyleOptionButton::DefaultButton - || (btn->features & QStyleOptionButton::AutoDefaultButton - && d->autoDefaultButton == btn->styleObject))) - bdi.adornment |= kThemeAdornmentDefault; + if (!hasMenu) { + // HITheme is not drawing a nice focus frame around buttons. + // We'll do it ourselves further down. + bdi.adornment &= ~kThemeAdornmentFocus; + + // We can't rely on an animation existing to test for the default look. That means a bit + // more logic (notice that the logic is slightly different for the bevel and the label). + if (tds == kThemeStateActive + && (btn->features & QStyleOptionButton::DefaultButton + || (btn->features & QStyleOptionButton::AutoDefaultButton + && d->autoDefaultButton == btn->styleObject))) + bdi.adornment |= kThemeAdornmentDefault; + } } else { // the default button animation is paused meanwhile any button // is pressed or an auto-default button is animated instead @@ -3856,8 +3871,18 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter newRect.size.width -= QMacStylePrivate::PushButtonRightOffset - 4; } - bool hasMenu = btn->features & QStyleOptionButton::HasMenu; - if (hasMenu && bdi.state == kThemeStatePressed && QSysInfo::macVersion() > QSysInfo::MV_10_6) + if (hasMenu && yosemiteOrLater && bdi.kind != kThemeBevelButton) { + QCocoaWidget w = cocoaWidgetFromHIThemeButtonKind(bdi.kind); + QPoint offset; + NSPopUpButton *pdb = (NSPopUpButton *)d->cocoaControl(QCocoaWidget(QCocoaPullDownButton, w.second), &offset); + [pdb highlight:(bdi.state == kThemeStatePressed)]; + pdb.enabled = bdi.state != kThemeStateUnavailable && bdi.state != kThemeStateUnavailableInactive; + QRect rect = opt->rect; + rect.adjust(0, 0, w.second == QAquaSizeSmall ? -4 : w.second == QAquaSizeMini ? -9 : -6, 0); + p->translate(offset); + d->drawNSViewInRect(pdb, rect, p); + p->translate(-offset); + } else if (hasMenu && bdi.state == kThemeStatePressed && QSysInfo::macVersion() > QSysInfo::MV_10_6) d->drawColorlessButton(newRect, &bdi, p, opt); else HIThemeDrawButton(&newRect, &bdi, cg, kHIThemeOrientationNormal, 0); @@ -3893,7 +3918,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter qt_drawFocusRingOnPath(cg, pushButtonFocusRingPath); } - if (hasMenu) { + if (hasMenu && (!yosemiteOrLater || bdi.kind == kThemeBevelButton)) { int mbi = proxy()->pixelMetric(QStyle::PM_MenuButtonIndicator, btn, w); QRect ir = btn->rect; int arrowXOffset = 0; @@ -3947,7 +3972,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter bool hasIcon = !btn.icon.isNull(); bool hasText = !btn.text.isEmpty(); - if (QSysInfo::QSysInfo::MacintoshVersion > QSysInfo::MV_10_9) { + if (!hasMenu && QSysInfo::QSysInfo::MacintoshVersion > QSysInfo::MV_10_9) { if (tds == kThemeStatePressed || (tds == kThemeStateActive && ((btn.features & QStyleOptionButton::DefaultButton && !d->autoDefaultButton) diff --git a/src/widgets/styles/qmacstyle_mac_p_p.h b/src/widgets/styles/qmacstyle_mac_p_p.h index 8fdeab9163..d8ce9b9250 100644 --- a/src/widgets/styles/qmacstyle_mac_p_p.h +++ b/src/widgets/styles/qmacstyle_mac_p_p.h @@ -134,6 +134,7 @@ enum QCocoaWidgetKind { QCocoaCheckBox, QCocoaComboBox, // Editable QComboBox QCocoaPopupButton, // Non-editable QComboBox + QCocoaPullDownButton, // QPushButton with menu QCocoaPushButton, QCocoaRadioButton }; -- cgit v1.2.3 From d0a6fcd925dc2a1553e2086e85f59ba76db85bef Mon Sep 17 00:00:00 2001 From: Lorn Potter Date: Wed, 8 Oct 2014 09:11:30 +1000 Subject: Fix QtBearer connman backend report correctly on lte network Task-number: QTBUG-41813 Change-Id: I977facc2ee59571d24e60ac9d5d41e957403b344 Reviewed-by: Richard J. Moore --- src/plugins/bearer/connman/qconnmanengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/bearer/connman/qconnmanengine.cpp b/src/plugins/bearer/connman/qconnmanengine.cpp index ee219f00ac..d55db05b1b 100644 --- a/src/plugins/bearer/connman/qconnmanengine.cpp +++ b/src/plugins/bearer/connman/qconnmanengine.cpp @@ -435,7 +435,7 @@ QNetworkConfiguration::BearerType QConnmanEngine::ofonoTechToBearerType(const QS } else if (currentTechnology == QLatin1String("hspa")) { return QNetworkConfiguration::BearerHSPA; } else if (currentTechnology == QLatin1String("lte")) { - return QNetworkConfiguration::BearerWiMAX; //not exact + return QNetworkConfiguration::BearerLTE; } } return QNetworkConfiguration::BearerUnknown; -- cgit v1.2.3 From d92a9ca2d33ae737b4b4362561209324ade3c95b Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 13 Oct 2014 11:57:13 +0200 Subject: Update QOffscreenSurface docs regarding threads Change-Id: Ic2e3230835aa7fc1b1c3ac0530a65cd478e1ec5f Reviewed-by: Gunnar Sletta --- src/gui/kernel/qoffscreensurface.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/gui/kernel/qoffscreensurface.cpp b/src/gui/kernel/qoffscreensurface.cpp index 56c4fbbf8b..5cf77de5d8 100644 --- a/src/gui/kernel/qoffscreensurface.cpp +++ b/src/gui/kernel/qoffscreensurface.cpp @@ -64,6 +64,12 @@ QT_BEGIN_NAMESPACE typically use a pixel buffer (pbuffer). If the platform doesn't implement or support offscreen surfaces, QOffscreenSurface will use an invisible QWindow internally. + \note Due to the fact that QOffscreenSurface is backed by a QWindow on some platforms, + cross-platform applications must ensure that create() is only called on the main (GUI) + thread. The QOffscreenSurface is then safe to be used with + \l{QOpenGLContext::makeCurrent()}{makeCurrent()} on other threads, but the + initialization and destruction must always happen on the main (GUI) thread. + \note In order to create an offscreen surface that is guaranteed to be compatible with a given context and window, make sure to set the format to the context's or the window's actual format, that is, the QSurfaceFormat returned from @@ -152,6 +158,8 @@ QOffscreenSurface::SurfaceType QOffscreenSurface::surfaceType() const Call destroy() to free the platform resources if necessary. + \note Some platforms require this function to be called on the main (GUI) thread. + \sa destroy() */ void QOffscreenSurface::create() -- cgit v1.2.3 From afefc89d0ff5ad562706b5513662c112e08e1b41 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 13 Oct 2014 10:02:02 +0200 Subject: osx: let qcombobox specify target rect when showing popup Let qcombobox use the new API for showing a native popup menu (introduced with 1a47595). Change-Id: Id08ef9e59fdd47b2c1df84fa72e3a2c69fe187b0 Reviewed-by: Friedemann Kleint --- src/widgets/widgets/qcombobox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 2fa197b2c8..44e22555db 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -2439,7 +2439,7 @@ bool QComboBoxPrivate::showNativePopup() offset = QPoint(-1, 7); else if (q->testAttribute(Qt::WA_MacMiniSize)) offset = QPoint(-2, 6); - menu->showPopup(tlw, tlw->mapFromGlobal(q->mapToGlobal(offset)), currentItem); + menu->showPopup(tlw, QRect(tlw->mapFromGlobal(q->mapToGlobal(offset)), QSize()), currentItem); menu->deleteLater(); Q_FOREACH (QPlatformMenuItem *item, items) item->deleteLater(); -- cgit v1.2.3 From 5d9dcac0f2dc8da1a1ac79dbdd309654d6deabac Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 30 Sep 2014 10:42:43 +0200 Subject: qplatformmenu: remove unused and deprecated function Now that all platforms use the popup function that takes a target rect, lets remove the deprecated one. This is sort of important, since QtQuick controls now uses the new version. So if a (new) platform ends up only implementing the old version, that can end up not working correctly. Change-Id: I34814b3de5ea4954cf21b161e8a834e39e5534c8 Reviewed-by: Friedemann Kleint --- src/gui/kernel/qplatformmenu.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/gui/kernel/qplatformmenu.h b/src/gui/kernel/qplatformmenu.h index c832de0be6..0093ef1538 100644 --- a/src/gui/kernel/qplatformmenu.h +++ b/src/gui/kernel/qplatformmenu.h @@ -108,11 +108,6 @@ public: virtual void setFont(const QFont &font) { Q_UNUSED(font); } virtual void setMenuType(MenuType type) { Q_UNUSED(type); } - virtual void showPopup(const QWindow *parentWindow, QPoint pos, const QPlatformMenuItem *item) - { - showPopup(parentWindow, QRect(pos, QSize()), item); - } - virtual void showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item) { Q_UNUSED(parentWindow); -- cgit v1.2.3 From 4bf0660ae4e695ceb79f585b92dedf00d7757f31 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 13 Oct 2014 08:49:16 +0200 Subject: Make QStringRef::right() consistent with QString::right() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The implementation was inconsistent with QString::right(), and did not return the N rightmost characters but actually did the same as QString::mid(N) (returning the rightmost size - N characters.) Since this function is fairly recent (Qt 5.2), is documented to behave the same as QString::right(), and since these APIs are meant to be interchangeable, this needs to be fixed, even though it changes behavior. [ChangeLog][Important Behavior Changes] Changed QStringRef::right() to be consistent with QString::right(). The function now returns the N right-most characters, like the documentation already claimed. Change-Id: I2d1cd6d958dfa9354aa09f16bd27b1ed209c2d11 Task-number: QTBUG-41858 Reviewed-by: Thiago Macieira Reviewed-by: Jędrzej Nowacki --- src/corelib/tools/qdatetime.cpp | 2 +- src/corelib/tools/qstring.cpp | 2 +- tests/auto/corelib/tools/qstringref/tst_qstringref.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 75f2a93e45..f0f6a56755 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -4419,7 +4419,7 @@ QDateTime QDateTime::fromString(const QString& string, Qt::DateFormat format) if (size == 10) return QDateTime(date); - isoString = isoString.right(11); + isoString = isoString.right(isoString.length() - 11); int offset = 0; // Check end of string for Time Zone definition, either Z for UTC or [+-]HH:MM for Offset if (isoString.endsWith(QLatin1Char('Z'))) { diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index b805ec792e..48f251e3f4 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -9020,7 +9020,7 @@ QStringRef QStringRef::right(int n) const { if (uint(n) >= uint(m_size)) return *this; - return QStringRef(m_string, n + m_position, m_size - n); + return QStringRef(m_string, m_size - n + m_position, n); } /*! diff --git a/tests/auto/corelib/tools/qstringref/tst_qstringref.cpp b/tests/auto/corelib/tools/qstringref/tst_qstringref.cpp index a38707ef08..3ba901061c 100644 --- a/tests/auto/corelib/tools/qstringref/tst_qstringref.cpp +++ b/tests/auto/corelib/tools/qstringref/tst_qstringref.cpp @@ -1870,9 +1870,9 @@ void tst_QStringRef::right() QStringRef ref = originalString.rightRef(originalString.size() - 1); QCOMPARE(ref.toString(), QLatin1String("OrginalString")); - QCOMPARE(ref.right(ref.size() - 6).toString(), QLatin1String("String")); + QCOMPARE(ref.right(6).toString(), QLatin1String("String")); QCOMPARE(ref.right(ref.size()).toString(), QLatin1String("OrginalString")); - QCOMPARE(ref.right(0).toString(), QLatin1String("OrginalString")); + QCOMPARE(ref.right(0).toString(), QLatin1String("")); QStringRef nullRef; QVERIFY(nullRef.isNull()); -- cgit v1.2.3 From ebc835c2aa02f0b3dc6e4806bde03f33513d3556 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 14 Oct 2014 12:07:41 +0200 Subject: Fix QOpenGLWidget on Cocoa when used as viewport MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Having a QOpenGLWidget as a graphics view viewport was not functioning on OS X: it was showing incomplete content due to accessing the texture attached to the framebuffer object before the rendering is complete. On the normal path, when rendering is done via paintGL(), the flush was there. When used as a viewport however, this path is not used. The missing flush is now added for the other case too. For performance reasons, we will not flush on every paint engine end(). Instead, the flush is deferred until composition starts. QGLWidget also featured a weird on-by-default autoFillBackground concept. To maintain compatibility with apps that used QGLWidget as the viewport for QGraphicsView, we will now do the same for QOpenGLWidget, but only when it is used as a viewport. For regular QOpenGLWidgets autoFillBackground defaults to false, like for any other widget. The docs are extended with a small section about differences between QGLWidget and QOpenGLWidget. Task-number: QTBUG-41046 Change-Id: I42c2033fdd2ef5815783fd640fe11373761061e0 Reviewed-by: Jørgen Lind --- src/gui/opengl/qopenglpaintdevice.cpp | 27 ++++++++++- src/gui/opengl/qopenglpaintdevice.h | 2 + src/gui/opengl/qopenglpaintengine.cpp | 4 ++ src/widgets/kernel/qopenglwidget.cpp | 70 +++++++++++++++++++++++++++-- src/widgets/kernel/qwidget_p.h | 2 + src/widgets/widgets/qabstractscrollarea.cpp | 3 ++ 6 files changed, 103 insertions(+), 5 deletions(-) diff --git a/src/gui/opengl/qopenglpaintdevice.cpp b/src/gui/opengl/qopenglpaintdevice.cpp index 59bca6efdf..c2f3295bc3 100644 --- a/src/gui/opengl/qopenglpaintdevice.cpp +++ b/src/gui/opengl/qopenglpaintdevice.cpp @@ -350,15 +350,40 @@ bool QOpenGLPaintDevice::paintFlipped() const return d_ptr->flipped; } +/*! + This virtual method is called when starting to paint. + + The default implementation does nothing. + + \sa endPaint() + */ +void QOpenGLPaintDevice::beginPaint() +{ +} + /*! This virtual method is provided as a callback to allow re-binding a target frame buffer object or context when different QOpenGLPaintDevice instances are issuing draw calls alternately. - QPainter::beginNativePainting will also trigger this method. + \l{QPainter::beginNativePainting()}{beginNativePainting()} will also trigger + this method. + + The default implementation does nothing. */ void QOpenGLPaintDevice::ensureActiveTarget() { } +/*! + This virtual method is called when the painting has finished. + + The default implementation does nothing. + + \sa beginPaint() +*/ +void QOpenGLPaintDevice::endPaint() +{ +} + QT_END_NAMESPACE diff --git a/src/gui/opengl/qopenglpaintdevice.h b/src/gui/opengl/qopenglpaintdevice.h index e1be9b525d..d88992d6db 100644 --- a/src/gui/opengl/qopenglpaintdevice.h +++ b/src/gui/opengl/qopenglpaintdevice.h @@ -73,7 +73,9 @@ public: void setPaintFlipped(bool flipped); bool paintFlipped() const; + virtual void beginPaint(); virtual void ensureActiveTarget(); + virtual void endPaint(); protected: int metric(QPaintDevice::PaintDeviceMetric metric) const; diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp index 21bc4a95e8..40c836b2bb 100644 --- a/src/gui/opengl/qopenglpaintengine.cpp +++ b/src/gui/opengl/qopenglpaintengine.cpp @@ -1994,6 +1994,8 @@ bool QOpenGL2PaintEngineEx::begin(QPaintDevice *pdev) d->ctx = QOpenGLContext::currentContext(); d->ctx->d_func()->active_engine = this; + d->device->beginPaint(); + d->funcs.initializeOpenGLFunctions(); for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) @@ -2044,6 +2046,8 @@ bool QOpenGL2PaintEngineEx::end() { Q_D(QOpenGL2PaintEngineEx); + d->device->endPaint(); + QOpenGLContext *ctx = d->ctx; d->funcs.glUseProgram(0); d->transferMode(BrushDrawingMode); diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index 7782c4c1d4..dd8dd64470 100644 --- a/src/widgets/kernel/qopenglwidget.cpp +++ b/src/widgets/kernel/qopenglwidget.cpp @@ -239,6 +239,28 @@ QT_BEGIN_NAMESPACE \note Avoid calling winId() on a QOpenGLWidget. This function triggers the creation of a native window, resulting in reduced performance and possibly rendering glitches. + \section1 Differences to QGLWidget + + Besides the main conceptual difference of being backed by a framebuffer object, there + are a number of smaller, internal differences between QOpenGLWidget and the older + QGLWidget: + + \list + + \li OpenGL state when invoking paintGL(). QOpenGLWidget sets up the viewport via + glViewport(). It does not perform any clearing. + + \li Clearing when starting to paint via QPainter. Unlike regular widgets, QGLWidget + defaulted to a value of \c true for + \l{QWidget::autoFillBackground()}{autoFillBackground}. It then performed clearing to the + palette's background color every time QPainter::begin() was used. QOpenGLWidget does not + follow this: \l{QWidget::autoFillBackground()}{autoFillBackground} defaults to false, + like for any other widget. The only exception is when being used as a viewport for other + widgets like QGraphicsView. In such a case autoFillBackground will be automatically set + to true to ensure compatibility with QGLWidget-based viewports. + + \endlist + \section1 Multisampling To enable multisampling, set the number of requested samples on the @@ -436,6 +458,7 @@ class QOpenGLWidgetPaintDevice : public QOpenGLPaintDevice { public: QOpenGLWidgetPaintDevice(QOpenGLWidget *widget) : w(widget) { } + void beginPaint() Q_DECL_OVERRIDE; void ensureActiveTarget() Q_DECL_OVERRIDE; private: @@ -454,7 +477,8 @@ public: initialized(false), fakeHidden(false), paintDevice(0), - inBackingStorePaint(false) + inBackingStorePaint(false), + flushPending(false) { requestedFormat = QSurfaceFormat::defaultFormat(); } @@ -478,6 +502,7 @@ public: void endBackingStorePainting() Q_DECL_OVERRIDE { inBackingStorePaint = false; } void beginCompose() Q_DECL_OVERRIDE; void endCompose() Q_DECL_OVERRIDE; + void initializeViewportFramebuffer() Q_DECL_OVERRIDE; void resizeViewportFramebuffer() Q_DECL_OVERRIDE; void resolveSamples() Q_DECL_OVERRIDE; @@ -490,8 +515,28 @@ public: QOpenGLPaintDevice *paintDevice; bool inBackingStorePaint; QSurfaceFormat requestedFormat; + bool flushPending; }; +void QOpenGLWidgetPaintDevice::beginPaint() +{ + // NB! autoFillBackground is and must be false by default. Otherwise we would clear on + // every QPainter begin() which is not desirable. This is only for legacy use cases, + // like using QOpenGLWidget as the viewport of a graphics view, that expect clearing + // with the palette's background color. + if (w->autoFillBackground()) { + QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); + if (w->testAttribute(Qt::WA_TranslucentBackground)) { + f->glClearColor(0, 0, 0, 0); + } else { + QColor c = w->palette().brush(w->backgroundRole()).color(); + float alpha = c.alphaF(); + f->glClearColor(c.redF() * alpha, c.greenF() * alpha, c.blueF() * alpha, alpha); + } + f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + } +} + void QOpenGLWidgetPaintDevice::ensureActiveTarget() { QOpenGLWidgetPrivate *d = static_cast(QWidgetPrivate::get(w)); @@ -502,6 +547,11 @@ void QOpenGLWidgetPaintDevice::ensureActiveTarget() w->makeCurrent(); else d->fbo->bind(); + + // When used as a viewport, drawing is done via opening a QPainter on the widget + // without going through paintEvent(). We will have to make sure a glFlush() is done + // before the texture is accessed also in this case. + d->flushPending = true; } GLuint QOpenGLWidgetPrivate::textureId() const @@ -572,6 +622,11 @@ void QOpenGLWidgetPrivate::recreateFbo() void QOpenGLWidgetPrivate::beginCompose() { Q_Q(QOpenGLWidget); + if (flushPending) { + flushPending = false; + q->makeCurrent(); + context->functions()->glFlush(); + } emit q->aboutToCompose(); } @@ -653,9 +708,10 @@ void QOpenGLWidgetPrivate::invokeUserPaint() { Q_Q(QOpenGLWidget); QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); - f->glViewport(0, 0, q->width() * q->devicePixelRatio(), q->height() * q->devicePixelRatio()); + f->glViewport(0, 0, q->width() * q->devicePixelRatio(), q->height() * q->devicePixelRatio()); q->paintGL(); + f->glFlush(); } void QOpenGLWidgetPrivate::render() @@ -667,7 +723,6 @@ void QOpenGLWidgetPrivate::render() q->makeCurrent(); invokeUserPaint(); - context->functions()->glFlush(); } extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha); @@ -686,6 +741,14 @@ QImage QOpenGLWidgetPrivate::grabFramebuffer() return res; } +void QOpenGLWidgetPrivate::initializeViewportFramebuffer() +{ + Q_Q(QOpenGLWidget); + // Legacy behavior for compatibility with QGLWidget when used as a graphics view + // viewport: enable clearing on each painter begin. + q->setAutoFillBackground(true); +} + void QOpenGLWidgetPrivate::resizeViewportFramebuffer() { Q_Q(QOpenGLWidget); @@ -929,7 +992,6 @@ void QOpenGLWidget::resizeEvent(QResizeEvent *e) d->recreateFbo(); resizeGL(width(), height()); d->invokeUserPaint(); - d->context->functions()->glFlush(); d->resolveSamples(); } diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index e80447c477..bbdbabc14b 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -641,6 +641,8 @@ public: } } static void sendComposeStatus(QWidget *w, bool end); + // Called on setViewport(). + virtual void initializeViewportFramebuffer() { } // When using a QOpenGLWidget as viewport with QAbstractScrollArea, resize events are // filtered away from the widget. This is fine for QGLWidget but bad for QOpenGLWidget // since the fbo must be resized. We need an alternative way to notify. diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp index 3b75591998..4cafeafcec 100644 --- a/src/widgets/widgets/qabstractscrollarea.cpp +++ b/src/widgets/widgets/qabstractscrollarea.cpp @@ -609,6 +609,9 @@ void QAbstractScrollArea::setViewport(QWidget *widget) #endif #endif d->layoutChildren(); +#ifndef QT_NO_OPENGL + QWidgetPrivate::get(d->viewport)->initializeViewportFramebuffer(); +#endif if (isVisible()) d->viewport->show(); setupViewport(widget); -- cgit v1.2.3 From f5cf06f4afc48198780e3c3d0d1a52afce425507 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Thu, 9 Oct 2014 20:13:40 +0200 Subject: Cocoa: Send obscure events on OcclusionStateHidden This disables animations for windows that are completely obscured by other windows. On examples/quick/animation, obscured CPU usage goes from 10% to 1%. Change-Id: I9945431e6387e406e2064c08d5aa01d5d96ef602 Reviewed-by: Laszlo Agocs Reviewed-by: Gabriel de Dietrich --- src/plugins/platforms/cocoa/qnsview.mm | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 10a92667c1..06680228bc 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -420,12 +420,10 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; #pragma clang diagnostic ignored "-Wobjc-method-access" enum { NSWindowOcclusionStateVisible = 1UL << 1 }; #endif - // Older versions managed in -[QNSView viewDidMoveToWindow]. - // Support QWidgetAction in NSMenu. Mavericks only sends this notification. - // Ideally we should support this in Qt as well, in order to disable animations - // when the window is occluded. if ((NSUInteger)[self.window occlusionState] & NSWindowOcclusionStateVisible) m_platformWindow->exposeWindow(); + else + m_platformWindow->obscureWindow(); #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_9 #pragma clang diagnostic pop #endif -- cgit v1.2.3 From 3edce263fb92ca96f6d7b5f90baf000bb2e0d74a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 13 Oct 2014 13:57:35 +0200 Subject: Prevent 'recursive' update events when calling QToolButton::setMenu() Commit bb3d2ca9f18 (QToolButton: properly reset the size hint when a menu is set on it) didn't take the case of re-setting the same menu into account, and the result was that we would unconditionally cause an update, resulting in the following backtrace again and again, as each posted update event was processed by the event loop: frame #0: QToolButton::setMenu(this=0x7af59500, menu=0x00000000) frame #1: QToolBarLayout::setUsePopupMenu(this=0x7ae65a30, set=false) frame #2: QToolBarLayout::checkUsePopupMenu(this=0x7ae65a30) frame #3: QToolBarAreaLayoutLine::fitLayout(this=0x78e5f870) frame #4: QToolBarAreaLayoutInfo::fitLayout(this=0x790be278) ... Besides consuming needless CPU time this also uncovered a case on iOS where Qt would starve native events and animations from being processed, preventing eg. rotation animations from running. Change-Id: Ib6bd4ba21d8e84ca73fb0a75b598016dbd9ae0fd Reviewed-by: Richard Moe Gustavsen --- src/widgets/widgets/qtoolbutton.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/widgets/widgets/qtoolbutton.cpp b/src/widgets/widgets/qtoolbutton.cpp index 3d3f42605e..bb3f2d74a8 100644 --- a/src/widgets/widgets/qtoolbutton.cpp +++ b/src/widgets/widgets/qtoolbutton.cpp @@ -636,6 +636,9 @@ void QToolButton::setMenu(QMenu* menu) { Q_D(QToolButton); + if (d->menuAction == (menu ? menu->menuAction() : 0)) + return; + if (d->menuAction) removeAction(d->menuAction); -- cgit v1.2.3 From 29ad07d0a486dd234267fce9a0310ad89683b7d1 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 29 Sep 2014 14:55:12 +0200 Subject: Avoid sleeping 100ms in QProcessPrivate::drainOutputPipes() There is no point in waiting 100 milliseconds after each iteration, as all data that we may possibly read will be already in the pipe. We only need to give the notifier thread a chance to inform us, which is best achieved with a yield. Task-number: QTBUG-41282 Change-Id: Id654b688246508494a5549c11900f9ad2957f192 Reviewed-by: Alessandro Portale Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qprocess_win.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index 980fb58865..ee6b7e13f4 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -634,7 +634,7 @@ bool QProcessPrivate::drainOutputPipes() someReadyReadEmitted |= readyReadEmitted; if (!readOperationActive || !readyReadEmitted) break; - Sleep(100); + QThread::yieldCurrentThread(); } return someReadyReadEmitted; -- cgit v1.2.3 From 648623ff235c36e2482ad64a0578a4f7c36ad15a Mon Sep 17 00:00:00 2001 From: Jan Arve Saether Date: Thu, 2 Oct 2014 10:20:28 +0200 Subject: Consolidate how contentDescription is calculated. Previously, the behavior was different depending on if the contentDescription was calculated as a result of an event, or if it was calculated as a result of hierarchy traversal. Refactor the functionality into one single function that will be used in both scenarios. 'contentDescription' will now receive its value from one of the following sources, listed in prioritised order (QAI == QAccessibleInterface): 1. QAI::text(QAccessible::Name) 2. QAI::text(QAccessible::Description) 3. QAI::text(QAccessible::Value) 4. QAI::valueInterface()->currentValue() Change-Id: I2e4958a1e95b5f20d01da37c23ecbc09842360bc Reviewed-by: Frederik Gladhorn --- .../platforms/android/androidjniaccessibility.cpp | 28 ++++++++++++++-------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp index 7229fd7af5..5c927da9c5 100644 --- a/src/plugins/platforms/android/androidjniaccessibility.cpp +++ b/src/plugins/platforms/android/androidjniaccessibility.cpp @@ -187,18 +187,30 @@ if (!clazz) { \ //__android_log_print(ANDROID_LOG_FATAL, m_qtTag, m_methodErrorMsg, METHOD_NAME, METHOD_SIGNATURE); - static jstring descriptionForAccessibleObject(JNIEnv *env, jobject /*thiz*/, jint objectId) + + static jstring descriptionForAccessibleObject_helper(JNIEnv *env, QAccessibleInterface *iface) { QString desc; - QAccessibleInterface *iface = interfaceFromId(objectId); if (iface && iface->isValid()) { desc = iface->text(QAccessible::Name); if (desc.isEmpty()) desc = iface->text(QAccessible::Description); + if (desc.isEmpty()) { + desc = iface->text(QAccessible::Value); + if (desc.isEmpty()) { + if (QAccessibleValueInterface *valueIface = iface->valueInterface()) { + desc= valueIface->currentValue().toString(); + } + } + } } + return env->NewString((jchar*) desc.constData(), (jsize) desc.size()); + } - jstring jdesc = env->NewString((jchar*) desc.constData(), (jsize) desc.size()); - return jdesc; + static jstring descriptionForAccessibleObject(JNIEnv *env, jobject /*thiz*/, jint objectId) + { + QAccessibleInterface *iface = interfaceFromId(objectId); + return descriptionForAccessibleObject_helper(env, iface); } static bool populateNode(JNIEnv *env, jobject /*thiz*/, jint objectId, jobject node) @@ -216,11 +228,8 @@ if (!clazz) { \ const bool hasDecreaseAction = actions.contains(QAccessibleActionInterface::decreaseAction()); // try to fill in the text property, this is what the screen reader reads - QString desc = iface->text(QAccessible::Value); - if (desc.isEmpty()) - desc = iface->text(QAccessible::Name); - if (desc.isEmpty()) - desc = iface->text(QAccessible::Description); + jstring jdesc = descriptionForAccessibleObject_helper(env, iface); + if (QAccessibleTextInterface *textIface = iface->textInterface()) { if (m_setTextSelectionMethodID && textIface->selectionCount() > 0) { int startSelection; @@ -252,7 +261,6 @@ if (!clazz) { \ env->CallVoidMethod(node, m_addActionMethodID, (int)8192); // ACTION_SCROLL_BACKWARD defined in AccessibilityNodeInfo - jstring jdesc = env->NewString((jchar*) desc.constData(), (jsize) desc.size()); //CALL_METHOD(node, "setText", "(Ljava/lang/CharSequence;)V", jdesc) env->CallVoidMethod(node, m_setContentDescriptionMethodID, jdesc); -- cgit v1.2.3 From 65b563fe57e1fe6dcaa2165ed5030b2ce0999011 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Tue, 14 Oct 2014 12:16:44 +0200 Subject: qdoc: Fixed recursion of \sincelist command handling QDoc uses a recursive method of resolving all the classes, QML types, properties, functions etc. added since a specified Qt version. The code entered the next level of recursion only if its parent had set a \since version, which was not always the case. Task-number: QTBUG-41862 Change-Id: I3803ed9ffa472165754358f3906955430a893de1 Reviewed-by: Martin Smith --- src/tools/qdoc/qdocdatabase.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tools/qdoc/qdocdatabase.cpp b/src/tools/qdoc/qdocdatabase.cpp index fff78b1cbc..36dd05bb92 100644 --- a/src/tools/qdoc/qdocdatabase.cpp +++ b/src/tools/qdoc/qdocdatabase.cpp @@ -1253,11 +1253,11 @@ void QDocDatabase::findAllSince(InnerNode* node) nsmap.value().insert(name,(*child)); } } - // Recursively find child nodes with since commands. - if ((*child)->isInnerNode()) { - findAllSince(static_cast(*child)); - } } + // Recursively find child nodes with since commands. + if ((*child)->isInnerNode()) + findAllSince(static_cast(*child)); + ++child; } } -- cgit v1.2.3 From 7095cdabc9e5465a33adb9d68782b4541853d964 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 14 Oct 2014 11:45:36 +0200 Subject: QTestLib: Remove valgrind version check. Version 3.3 is now assumed to be widely available. Task-number: QTBUG-41453 Change-Id: I453ce26d170b2bbb8179ddf4b91155ddd3e6379a Reviewed-by: Kai Koehne Reviewed-by: Jason McDonald --- src/testlib/qbenchmarkvalgrind.cpp | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/src/testlib/qbenchmarkvalgrind.cpp b/src/testlib/qbenchmarkvalgrind.cpp index c480753675..f107645ab5 100644 --- a/src/testlib/qbenchmarkvalgrind.cpp +++ b/src/testlib/qbenchmarkvalgrind.cpp @@ -45,33 +45,15 @@ QT_BEGIN_NAMESPACE -// Returns \c true iff a sufficiently recent valgrind is available. +// Returns \c true if valgrind is available. bool QBenchmarkValgrindUtils::haveValgrind() { #ifdef NVALGRIND return false; #else QProcess process; - QStringList args; - args << QLatin1String("--version"); - process.start(QLatin1String("valgrind"), args); - if (!process.waitForFinished(-1)) - return false; - const QByteArray out = process.readAllStandardOutput(); - QRegExp rx(QLatin1String("^valgrind-([0-9]+).([0-9]+).[0-9]+")); - if (rx.indexIn(QLatin1String(out.data())) == -1) - return false; - bool ok; - const int major = rx.cap(1).toInt(&ok); - if (!ok) - return false; - const int minor = rx.cap(2).toInt(&ok); - if (!ok) - return false; -// return (major > 3 || (major == 3 && minor >= 3)); // v >= 3.3 for --callgrind-out-file option - Q_UNUSED(major); - Q_UNUSED(minor); - return true; // skip version restriction for now + process.start(QLatin1String("valgrind"), QStringList(QLatin1String("--version"))); + return process.waitForStarted() && process.waitForFinished(-1); #endif } -- cgit v1.2.3 From a4ac4b326318ed9034466305222280ed8d1651b5 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 14 Oct 2014 14:39:06 +0200 Subject: QWindowsGuiEventDispatcher: Register timers in constructor. Port change 3716a76704273fdbe5ad4ec978438daeda606c26 (Qt 4) to Qt 5. Enforce the creation of the internal window and registering of timers in the event dispatcher constructor for GUI applications instead of delaying it to processEvents() is called. Move the call to virtual wakeUp() out of createInternalHwnd(). Task-number: QTBUG-40881 Change-Id: I82a4748897da140a39feff882c75ad5ac6155148 Reviewed-by: Joerg Bornemann --- src/corelib/kernel/qeventdispatcher_win.cpp | 8 +++----- src/corelib/kernel/qeventdispatcher_win_p.h | 2 +- src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp | 1 + 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 7816edd3f9..a3d00faf31 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -639,7 +639,6 @@ void QEventDispatcherWin32::createInternalHwnd() { Q_D(QEventDispatcherWin32); - Q_ASSERT(!d->internalHwnd); if (d->internalHwnd) return; d->internalHwnd = qt_create_internal_window(this); @@ -664,9 +663,6 @@ void QEventDispatcherWin32::createInternalHwnd() // start all normal timers for (int i = 0; i < d->timerVec.count(); ++i) d->registerTimer(d->timerVec.at(i)); - - // trigger a call to sendPostedEvents() - wakeUp(); } QEventDispatcherWin32::QEventDispatcherWin32(QObject *parent) @@ -686,8 +682,10 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) { Q_D(QEventDispatcherWin32); - if (!d->internalHwnd) + if (!d->internalHwnd) { createInternalHwnd(); + wakeUp(); // trigger a call to sendPostedEvents() + } d->interrupt = false; emit awake(); diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h index f9bb06a5c5..369c276615 100644 --- a/src/corelib/kernel/qeventdispatcher_win_p.h +++ b/src/corelib/kernel/qeventdispatcher_win_p.h @@ -65,8 +65,8 @@ class Q_CORE_EXPORT QEventDispatcherWin32 : public QAbstractEventDispatcher Q_OBJECT Q_DECLARE_PRIVATE(QEventDispatcherWin32) +protected: void createInternalHwnd(); - friend class QGuiEventDispatcherWin32; public: explicit QEventDispatcherWin32(QObject *parent = 0); diff --git a/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp b/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp index 73988b6db5..593b5eac7a 100644 --- a/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp +++ b/src/plugins/platforms/windows/qwindowsguieventdispatcher.cpp @@ -62,6 +62,7 @@ QWindowsGuiEventDispatcher::QWindowsGuiEventDispatcher(QObject *parent) : QEventDispatcherWin32(parent), m_flags(0) { setObjectName(QStringLiteral("QWindowsGuiEventDispatcher")); + createInternalHwnd(); // QTBUG-40881: Do not delay registering timers, etc. for QtMfc. } bool QWindowsGuiEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags) -- cgit v1.2.3 From 6d1c4c8862161fd4aaffe307c7267ceeb408d8d8 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 14 Oct 2014 12:07:41 +0200 Subject: Avoid breaking BC with new virtuals in QOpenGLPaintDevice Task-number: QTBUG-41046 Change-Id: Iab628d2d6811d528e2cc513b6f8a74baa628541d Reviewed-by: Gunnar Sletta --- src/gui/opengl/opengl.pri | 1 + src/gui/opengl/qopenglpaintdevice.cpp | 48 ++++----------------- src/gui/opengl/qopenglpaintdevice.h | 4 +- src/gui/opengl/qopenglpaintdevice_p.h | 81 +++++++++++++++++++++++++++++++++++ src/gui/opengl/qopenglpaintengine.cpp | 5 ++- src/widgets/kernel/qopenglwidget.cpp | 33 +++++++++----- 6 files changed, 117 insertions(+), 55 deletions(-) create mode 100644 src/gui/opengl/qopenglpaintdevice_p.h diff --git a/src/gui/opengl/opengl.pri b/src/gui/opengl/opengl.pri index f82401c973..adf5428c49 100644 --- a/src/gui/opengl/opengl.pri +++ b/src/gui/opengl/opengl.pri @@ -11,6 +11,7 @@ contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2) { opengl/qopenglframebufferobject.h \ opengl/qopenglframebufferobject_p.h \ opengl/qopenglpaintdevice.h \ + opengl/qopenglpaintdevice_p.h \ opengl/qopenglbuffer.h \ opengl/qopenglshaderprogram.h \ opengl/qopenglextensions_p.h \ diff --git a/src/gui/opengl/qopenglpaintdevice.cpp b/src/gui/opengl/qopenglpaintdevice.cpp index c2f3295bc3..e908fd8e91 100644 --- a/src/gui/opengl/qopenglpaintdevice.cpp +++ b/src/gui/opengl/qopenglpaintdevice.cpp @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -98,23 +99,6 @@ QT_BEGIN_NAMESPACE */ -class QOpenGLPaintDevicePrivate -{ -public: - QOpenGLPaintDevicePrivate(const QSize &size); - - QSize size; - QOpenGLContext *ctx; - - qreal dpmx; - qreal dpmy; - qreal devicePixelRatio; - - bool flipped; - - QPaintEngine *engine; -}; - /*! Constructs a QOpenGLPaintDevice. @@ -151,6 +135,14 @@ QOpenGLPaintDevice::QOpenGLPaintDevice(int width, int height) { } +/*! + \internal + */ +QOpenGLPaintDevice::QOpenGLPaintDevice(QOpenGLPaintDevicePrivate *dd) + : d_ptr(dd) +{ +} + /*! Destroys the QOpenGLPaintDevice. */ @@ -350,17 +342,6 @@ bool QOpenGLPaintDevice::paintFlipped() const return d_ptr->flipped; } -/*! - This virtual method is called when starting to paint. - - The default implementation does nothing. - - \sa endPaint() - */ -void QOpenGLPaintDevice::beginPaint() -{ -} - /*! This virtual method is provided as a callback to allow re-binding a target frame buffer object or context when different QOpenGLPaintDevice instances @@ -375,15 +356,4 @@ void QOpenGLPaintDevice::ensureActiveTarget() { } -/*! - This virtual method is called when the painting has finished. - - The default implementation does nothing. - - \sa beginPaint() -*/ -void QOpenGLPaintDevice::endPaint() -{ -} - QT_END_NAMESPACE diff --git a/src/gui/opengl/qopenglpaintdevice.h b/src/gui/opengl/qopenglpaintdevice.h index d88992d6db..dda3bfe43f 100644 --- a/src/gui/opengl/qopenglpaintdevice.h +++ b/src/gui/opengl/qopenglpaintdevice.h @@ -44,7 +44,6 @@ QT_BEGIN_NAMESPACE - class QOpenGLPaintDevicePrivate; class Q_GUI_EXPORT QOpenGLPaintDevice : public QPaintDevice @@ -54,6 +53,7 @@ public: QOpenGLPaintDevice(); explicit QOpenGLPaintDevice(const QSize &size); QOpenGLPaintDevice(int width, int height); + QOpenGLPaintDevice(QOpenGLPaintDevicePrivate *dd); virtual ~QOpenGLPaintDevice(); int devType() const { return QInternal::OpenGL; } @@ -73,9 +73,7 @@ public: void setPaintFlipped(bool flipped); bool paintFlipped() const; - virtual void beginPaint(); virtual void ensureActiveTarget(); - virtual void endPaint(); protected: int metric(QPaintDevice::PaintDeviceMetric metric) const; diff --git a/src/gui/opengl/qopenglpaintdevice_p.h b/src/gui/opengl/qopenglpaintdevice_p.h new file mode 100644 index 0000000000..0b01129a84 --- /dev/null +++ b/src/gui/opengl/qopenglpaintdevice_p.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** 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 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QOPENGL_PAINTDEVICE_P_H +#define QOPENGL_PAINTDEVICE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of the Qt OpenGL classes. This header file may change from +// version to version without notice, or even be removed. +// +// We mean it. +// + +#include + +QT_BEGIN_NAMESPACE + +class QOpenGLContext; +class QPaintEngine; + +class Q_GUI_EXPORT QOpenGLPaintDevicePrivate +{ +public: + QOpenGLPaintDevicePrivate(const QSize &size); + virtual ~QOpenGLPaintDevicePrivate() { } + + static QOpenGLPaintDevicePrivate *get(QOpenGLPaintDevice *dev) { return dev->d_func(); } + + virtual void beginPaint() { } + virtual void endPaint() { } + +public: + QSize size; + QOpenGLContext *ctx; + + qreal dpmx; + qreal dpmy; + qreal devicePixelRatio; + + bool flipped; + + QPaintEngine *engine; +}; + +QT_END_NAMESPACE + +#endif // QOPENGL_PAINTDEVICE_P_H diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp index 40c836b2bb..c490726359 100644 --- a/src/gui/opengl/qopenglpaintengine.cpp +++ b/src/gui/opengl/qopenglpaintengine.cpp @@ -59,6 +59,7 @@ #include "qopenglgradientcache_p.h" #include "qopengltexturecache_p.h" #include "qopenglpaintengine_p.h" +#include "qopenglpaintdevice_p.h" #include //for memcpy #include @@ -1994,7 +1995,7 @@ bool QOpenGL2PaintEngineEx::begin(QPaintDevice *pdev) d->ctx = QOpenGLContext::currentContext(); d->ctx->d_func()->active_engine = this; - d->device->beginPaint(); + QOpenGLPaintDevicePrivate::get(d->device)->beginPaint(); d->funcs.initializeOpenGLFunctions(); @@ -2046,7 +2047,7 @@ bool QOpenGL2PaintEngineEx::end() { Q_D(QOpenGL2PaintEngineEx); - d->device->endPaint(); + QOpenGLPaintDevicePrivate::get(d->device)->endPaint(); QOpenGLContext *ctx = d->ctx; d->funcs.glUseProgram(0); diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index dd8dd64470..8a4e0c8ffd 100644 --- a/src/widgets/kernel/qopenglwidget.cpp +++ b/src/widgets/kernel/qopenglwidget.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include QT_BEGIN_NAMESPACE @@ -454,17 +455,26 @@ QT_BEGIN_NAMESPACE due to resizing the widget. */ -class QOpenGLWidgetPaintDevice : public QOpenGLPaintDevice +class QOpenGLWidgetPaintDevicePrivate : public QOpenGLPaintDevicePrivate { public: - QOpenGLWidgetPaintDevice(QOpenGLWidget *widget) : w(widget) { } + QOpenGLWidgetPaintDevicePrivate(QOpenGLWidget *widget) + : QOpenGLPaintDevicePrivate(QSize()), + w(widget) { } + void beginPaint() Q_DECL_OVERRIDE; - void ensureActiveTarget() Q_DECL_OVERRIDE; -private: QOpenGLWidget *w; }; +class QOpenGLWidgetPaintDevice : public QOpenGLPaintDevice +{ +public: + QOpenGLWidgetPaintDevice(QOpenGLWidget *widget) + : QOpenGLPaintDevice(new QOpenGLWidgetPaintDevicePrivate(widget)) { } + void ensureActiveTarget() Q_DECL_OVERRIDE; +}; + class QOpenGLWidgetPrivate : public QWidgetPrivate { Q_DECLARE_PUBLIC(QOpenGLWidget) @@ -518,7 +528,7 @@ public: bool flushPending; }; -void QOpenGLWidgetPaintDevice::beginPaint() +void QOpenGLWidgetPaintDevicePrivate::beginPaint() { // NB! autoFillBackground is and must be false by default. Otherwise we would clear on // every QPainter begin() which is not desirable. This is only for legacy use cases, @@ -539,19 +549,20 @@ void QOpenGLWidgetPaintDevice::beginPaint() void QOpenGLWidgetPaintDevice::ensureActiveTarget() { - QOpenGLWidgetPrivate *d = static_cast(QWidgetPrivate::get(w)); - if (!d->initialized) + QOpenGLWidgetPaintDevicePrivate *d = static_cast(d_ptr.data()); + QOpenGLWidgetPrivate *wd = static_cast(QWidgetPrivate::get(d->w)); + if (!wd->initialized) return; - if (QOpenGLContext::currentContext() != d->context) - w->makeCurrent(); + if (QOpenGLContext::currentContext() != wd->context) + d->w->makeCurrent(); else - d->fbo->bind(); + wd->fbo->bind(); // When used as a viewport, drawing is done via opening a QPainter on the widget // without going through paintEvent(). We will have to make sure a glFlush() is done // before the texture is accessed also in this case. - d->flushPending = true; + wd->flushPending = true; } GLuint QOpenGLWidgetPrivate::textureId() const -- cgit v1.2.3 From d904533acba1267431ca2c5f0d3e85cc59a20a26 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Mon, 6 Oct 2014 19:22:00 +0400 Subject: xcb: Don't return 0 as a possible key for a shortcut QXcbKeyboard::keysymToQtKey() may return a value of 0 for keysyms that are not supported by Qt (e.g. for XK_ISO_Next_Group). It is then translated to an empty QKeySequence which in turn is detected as a partial match for any shortcut. The behavior of QShortcutMap::nextState() becomes broken because it sets current state to QKeySequence::PartialMatch while there is no match at all. Task-number: QTCREATORBUG-9589 Change-Id: I1e2a4511a876dfa418db9906d10382255a2e4d62 Reviewed-by: Gatis Paeglis Reviewed-by: Sergey Belyashov --- src/plugins/platforms/xcb/qxcbkeyboard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 7e70e7258d..8c12b29a99 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -903,7 +903,7 @@ QList QXcbKeyboard::possibleKeys(const QKeyEvent *event) const Qt::KeyboardModifiers mods = modifiers & ~neededMods; qtKey = keysymToQtKey(sym, mods, lookupString(kb_state, event->nativeScanCode())); - if (qtKey == baseQtKey) + if (qtKey == baseQtKey || qtKey == 0) continue; result += (qtKey + mods); -- cgit v1.2.3 From e8e1616cf2f4346995cbb222010173ef0850a53d Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Thu, 2 Oct 2014 17:36:41 +0400 Subject: Reduce code duplication in QFontconfigDatabase Extract common part from fontEngine() methods to setupFontEngine(). Change-Id: Id4aee43b2a477f9fd40dc564d96a2335bfde9e22 Reviewed-by: Allan Sandfeld Jensen --- .../fontconfig/qfontconfigdatabase.cpp | 238 ++++++++------------- .../fontconfig/qfontconfigdatabase_p.h | 5 + 2 files changed, 97 insertions(+), 146 deletions(-) diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp index 62dc9a9c6b..1aac0791cd 100644 --- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp +++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp @@ -587,92 +587,18 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, void *usrPtr) { if (!usrPtr) return 0; - QFontDef fontDef = f; - QFontEngineFT *engine; FontFile *fontfile = static_cast (usrPtr); QFontEngine::FaceId fid; fid.filename = QFile::encodeName(fontfile->fileName); fid.index = fontfile->indexValue; - bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias); - bool forcedAntialiasSetting = !antialias; - engine = new QFontEngineFT(fontDef); - - const QPlatformServices *services = QGuiApplicationPrivate::platformIntegration()->services(); - bool useXftConf = (services && (services->desktopEnvironment() == "GNOME" || services->desktopEnvironment() == "UNITY")); - if (useXftConf) { - void *antialiasResource = - QGuiApplication::platformNativeInterface()->nativeResourceForScreen("antialiasingEnabled", - QGuiApplication::primaryScreen()); - int antialiasingEnabled = int(reinterpret_cast(antialiasResource)); - if (antialiasingEnabled > 0) { - antialias = antialiasingEnabled - 1; - forcedAntialiasSetting = true; - } - } + QFontEngineFT *engine = new QFontEngineFT(f); + engine->face_id = fid; - QFontEngine::GlyphFormat format; - // try and get the pattern - FcPattern *pattern = FcPatternCreate(); + setupFontEngine(engine, f); - FcValue value; - value.type = FcTypeString; - QByteArray cs = fontDef.family.toUtf8(); - value.u.s = (const FcChar8 *)cs.data(); - FcPatternAdd(pattern,FC_FAMILY,value,true); - - value.u.s = (const FcChar8 *)fid.filename.data(); - FcPatternAdd(pattern,FC_FILE,value,true); - - value.type = FcTypeInteger; - value.u.i = fid.index; - FcPatternAdd(pattern,FC_INDEX,value,true); - - FcResult result; - - FcConfigSubstitute(0, pattern, FcMatchPattern); - FcDefaultSubstitute(pattern); - - FcPattern *match = FcFontMatch(0, pattern, &result); - if (match) { - engine->setDefaultHintStyle(defaultHintStyleFromMatch((QFont::HintingPreference)f.hintingPreference, match, useXftConf)); - - FcBool fc_autohint; - if (FcPatternGetBool(match, FC_AUTOHINT,0, &fc_autohint) == FcResultMatch) - engine->forceAutoHint = fc_autohint; - -#if defined(FT_LCD_FILTER_H) - int lcdFilter; - if (FcPatternGetInteger(match, FC_LCD_FILTER, 0, &lcdFilter) == FcResultMatch) - engine->lcdFilterType = lcdFilter; -#endif - - if (!forcedAntialiasSetting) { - FcBool fc_antialias; - if (FcPatternGetBool(match, FC_ANTIALIAS,0, &fc_antialias) == FcResultMatch) - antialias = fc_antialias; - } - - if (antialias) { - QFontEngine::SubpixelAntialiasingType subpixelType = QFontEngine::Subpixel_None; - if (!(f.styleStrategy & QFont::NoSubpixelAntialias)) - subpixelType = subpixelTypeFromMatch(match, useXftConf); - engine->subpixelType = subpixelType; - - format = (subpixelType == QFontEngine::Subpixel_None) - ? QFontEngine::Format_A8 - : QFontEngine::Format_A32; - } else - format = QFontEngine::Format_Mono; - - FcPatternDestroy(match); - } else - format = antialias ? QFontEngine::Format_A8 : QFontEngine::Format_Mono; - - FcPatternDestroy(pattern); - - if (!engine->init(fid, antialias, format) || engine->invalid()) { + if (!engine->init(fid, engine->antialias, engine->defaultFormat) || engine->invalid()) { delete engine; engine = 0; } @@ -686,74 +612,7 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QByteArray &fontData, qreal p if (engine == 0) return 0; - QFontDef fontDef = engine->fontDef; - - bool forcedAntialiasSetting = false; - const QPlatformServices *services = QGuiApplicationPrivate::platformIntegration()->services(); - bool useXftConf = (services && (services->desktopEnvironment() == "GNOME" || services->desktopEnvironment() == "UNITY")); - if (useXftConf) { - void *antialiasResource = - QGuiApplication::platformNativeInterface()->nativeResourceForScreen("antialiasingEnabled", - QGuiApplication::primaryScreen()); - int antialiasingEnabled = int(reinterpret_cast(antialiasResource)); - if (antialiasingEnabled > 0) { - engine->antialias = antialiasingEnabled - 1; - forcedAntialiasSetting = true; - } - } - - QFontEngine::GlyphFormat format; - // try and get the pattern - FcPattern *pattern = FcPatternCreate(); - - FcValue value; - value.type = FcTypeString; - QByteArray cs = fontDef.family.toUtf8(); - value.u.s = (const FcChar8 *)cs.data(); - FcPatternAdd(pattern,FC_FAMILY,value,true); - - FcResult result; - - FcConfigSubstitute(0, pattern, FcMatchPattern); - FcDefaultSubstitute(pattern); - - FcPattern *match = FcFontMatch(0, pattern, &result); - if (match) { - engine->setDefaultHintStyle(defaultHintStyleFromMatch(hintingPreference, match, useXftConf)); - - FcBool fc_autohint; - if (FcPatternGetBool(match, FC_AUTOHINT,0, &fc_autohint) == FcResultMatch) - engine->forceAutoHint = fc_autohint; - -#if defined(FT_LCD_FILTER_H) - int lcdFilter; - if (FcPatternGetInteger(match, FC_LCD_FILTER, 0, &lcdFilter) == FcResultMatch) - engine->lcdFilterType = lcdFilter; -#endif - - if (!forcedAntialiasSetting) { - FcBool fc_antialias; - if (FcPatternGetBool(match, FC_ANTIALIAS,0, &fc_antialias) == FcResultMatch) - engine->antialias = fc_antialias; - } - - if (engine->antialias) { - QFontEngine::SubpixelAntialiasingType subpixelType = subpixelTypeFromMatch(match, useXftConf); - engine->subpixelType = subpixelType; - - format = subpixelType == QFontEngine::Subpixel_None - ? QFontEngine::Format_A8 - : QFontEngine::Format_A32; - } else - format = QFontEngine::Format_Mono; - FcPatternDestroy(match); - } else - format = QFontEngine::Format_A8; - - FcPatternDestroy(pattern); - - engine->defaultFormat = format; - engine->glyphFormat = format; + setupFontEngine(engine, engine->fontDef); return engine; } @@ -947,4 +806,91 @@ QFont QFontconfigDatabase::defaultFont() const return QFont(resolved); } +void QFontconfigDatabase::setupFontEngine(QFontEngineFT *engine, const QFontDef &fontDef) const +{ + bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias); + bool forcedAntialiasSetting = !antialias; + + const QPlatformServices *services = QGuiApplicationPrivate::platformIntegration()->services(); + bool useXftConf = (services && (services->desktopEnvironment() == "GNOME" || services->desktopEnvironment() == "UNITY")); + if (useXftConf) { + void *antialiasResource = + QGuiApplication::platformNativeInterface()->nativeResourceForScreen("antialiasingEnabled", + QGuiApplication::primaryScreen()); + int antialiasingEnabled = int(reinterpret_cast(antialiasResource)); + if (antialiasingEnabled > 0) { + antialias = antialiasingEnabled - 1; + forcedAntialiasSetting = true; + } + } + + QFontEngine::GlyphFormat format; + // try and get the pattern + FcPattern *pattern = FcPatternCreate(); + + FcValue value; + value.type = FcTypeString; + QByteArray cs = fontDef.family.toUtf8(); + value.u.s = (const FcChar8 *)cs.data(); + FcPatternAdd(pattern,FC_FAMILY,value,true); + + QFontEngine::FaceId fid = engine->faceId(); + + if (!fid.filename.isEmpty()) { + value.u.s = (const FcChar8 *)fid.filename.data(); + FcPatternAdd(pattern,FC_FILE,value,true); + + value.type = FcTypeInteger; + value.u.i = fid.index; + FcPatternAdd(pattern,FC_INDEX,value,true); + } + + FcResult result; + + FcConfigSubstitute(0, pattern, FcMatchPattern); + FcDefaultSubstitute(pattern); + + FcPattern *match = FcFontMatch(0, pattern, &result); + if (match) { + engine->setDefaultHintStyle(defaultHintStyleFromMatch((QFont::HintingPreference)fontDef.hintingPreference, match, useXftConf)); + + FcBool fc_autohint; + if (FcPatternGetBool(match, FC_AUTOHINT,0, &fc_autohint) == FcResultMatch) + engine->forceAutoHint = fc_autohint; + +#if defined(FT_LCD_FILTER_H) + int lcdFilter; + if (FcPatternGetInteger(match, FC_LCD_FILTER, 0, &lcdFilter) == FcResultMatch) + engine->lcdFilterType = lcdFilter; +#endif + + if (!forcedAntialiasSetting) { + FcBool fc_antialias; + if (FcPatternGetBool(match, FC_ANTIALIAS,0, &fc_antialias) == FcResultMatch) + antialias = fc_antialias; + } + + if (antialias) { + QFontEngine::SubpixelAntialiasingType subpixelType = QFontEngine::Subpixel_None; + if (!(fontDef.styleStrategy & QFont::NoSubpixelAntialias)) + subpixelType = subpixelTypeFromMatch(match, useXftConf); + engine->subpixelType = subpixelType; + + format = (subpixelType == QFontEngine::Subpixel_None) + ? QFontEngine::Format_A8 + : QFontEngine::Format_A32; + } else + format = QFontEngine::Format_Mono; + + FcPatternDestroy(match); + } else + format = antialias ? QFontEngine::Format_A8 : QFontEngine::Format_Mono; + + FcPatternDestroy(pattern); + + engine->antialias = antialias; + engine->defaultFormat = format; + engine->glyphFormat = format; +} + QT_END_NAMESPACE diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h index 91ecb52e7b..745d12b825 100644 --- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h +++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h @@ -50,6 +50,8 @@ QT_BEGIN_NAMESPACE +class QFontEngineFT; + class QFontconfigDatabase : public QBasicFontDatabase { public: @@ -61,6 +63,9 @@ public: QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName); QString resolveFontFamilyAlias(const QString &family) const; QFont defaultFont() const; + +private: + void setupFontEngine(QFontEngineFT *engine, const QFontDef &fontDef) const; }; QT_END_NAMESPACE -- cgit v1.2.3 From 50398708cd70121b8864f4a82bca5412bde11415 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Wed, 24 Sep 2014 13:41:21 +0400 Subject: Accessibility Linux: Make a full copy of a key event Otherwise native values (scan code, modifiers, virtual key) of the key event will be lost if an event listener is registered. Change-Id: I5eebb1f91ad7de6801f7efb0bf0891c4430f9cf5 Reviewed-by: Frederik Gladhorn --- src/platformsupport/linuxaccessibility/application.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/platformsupport/linuxaccessibility/application.cpp b/src/platformsupport/linuxaccessibility/application.cpp index dcf17143fa..2ee6b0a203 100644 --- a/src/platformsupport/linuxaccessibility/application.cpp +++ b/src/platformsupport/linuxaccessibility/application.cpp @@ -196,7 +196,9 @@ bool QSpiApplicationAdaptor::eventFilter(QObject *target, QEvent *event) QKeyEvent* QSpiApplicationAdaptor::copyKeyEvent(QKeyEvent* old) { - return new QKeyEvent(old->type(), old->key(), old->modifiers(), old->text(), old->isAutoRepeat(), old->count()); + return new QKeyEvent(old->type(), old->key(), old->modifiers(), + old->nativeScanCode(), old->nativeVirtualKey(), old->nativeModifiers(), + old->text(), old->isAutoRepeat(), old->count()); } void QSpiApplicationAdaptor::notifyKeyboardListenerCallback(const QDBusMessage& message) -- cgit v1.2.3 From 1b8c5f450ba7dc3be04149020ec788a8ca03e47f Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Mon, 6 Oct 2014 19:03:35 +0400 Subject: xcb: Fix a type of variables for xkb modifiers masks Change-Id: I05c7c6a649a55fc0648b1cb84e1c402160c9d998 Reviewed-by: Friedemann Kleint Reviewed-by: Gatis Paeglis --- src/plugins/platforms/xcb/qxcbkeyboard.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 8c12b29a99..d956d6abd3 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -841,8 +841,8 @@ QList QXcbKeyboard::possibleKeys(const QKeyEvent *event) const xkb_layout_index_t baseLayout = xkb_state_serialize_layout(xkb_state, XKB_STATE_LAYOUT_DEPRESSED); xkb_layout_index_t latchedLayout = xkb_state_serialize_layout(xkb_state, XKB_STATE_LAYOUT_LATCHED); xkb_layout_index_t lockedLayout = xkb_state_serialize_layout(xkb_state, XKB_STATE_LAYOUT_LOCKED); - xkb_mod_index_t latchedMods = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LATCHED); - xkb_mod_index_t lockedMods = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LOCKED); + xkb_mod_mask_t latchedMods = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LATCHED); + xkb_mod_mask_t lockedMods = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LOCKED); xkb_state_update_mask(kb_state, 0, latchedMods, lockedMods, baseLayout, latchedLayout, lockedLayout); -- cgit v1.2.3 From 0368b24a7f53c945b582097cc8ad22a053856d22 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 9 Oct 2014 09:43:23 +0200 Subject: QSettings: Prevent assert when passing empty keys. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ChangeLog][Important behavior changes][QSettings] QSettings::value() now returns an invalid QVariant when passing an empty key. The code path ran into an assert, which was only noticeable in debug builds. Task-number: QTBUG-41812 Change-Id: I5cc32be3aa267a132e9d6639ecd6cb0bbafc15b0 Reviewed-by: Stéphane Fabry, Cutesoft Reviewed-by: Thiago Macieira --- src/corelib/io/qsettings.cpp | 8 ++++++++ tests/auto/corelib/io/qsettings/tst_qsettings.cpp | 11 +++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index fd35ae33dc..d896da176a 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -3121,6 +3121,10 @@ bool QSettings::isWritable() const void QSettings::setValue(const QString &key, const QVariant &value) { Q_D(QSettings); + if (key.isEmpty()) { + qWarning("QSettings::setValue: Empty key passed"); + return; + } QString k = d->actualKey(key); d->set(k, value); d->requestUpdate(); @@ -3253,6 +3257,10 @@ bool QSettings::event(QEvent *event) QVariant QSettings::value(const QString &key, const QVariant &defaultValue) const { Q_D(const QSettings); + if (key.isEmpty()) { + qWarning("QSettings::value: Empty key passed"); + return QVariant(); + } QVariant result = defaultValue; QString k = d->actualKey(key); d->get(k, &result); diff --git a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp index 77a60997a6..3e68e4859f 100644 --- a/tests/auto/corelib/io/qsettings/tst_qsettings.cpp +++ b/tests/auto/corelib/io/qsettings/tst_qsettings.cpp @@ -118,6 +118,7 @@ private slots: void testUpdateRequestEvent(); void testThreadSafety(); void testEmptyData(); + void testEmptyKey(); void testResourceFiles(); void testRegistryShortRootNames(); void trailingWhitespace(); @@ -2025,6 +2026,16 @@ void tst_QSettings::testEmptyData() QFile::remove(filename); } +void tst_QSettings::testEmptyKey() +{ + QSettings settings; + QTest::ignoreMessage(QtWarningMsg, "QSettings::value: Empty key passed"); + const QVariant value = settings.value(QString()); + QCOMPARE(value, QVariant()); + QTest::ignoreMessage(QtWarningMsg, "QSettings::setValue: Empty key passed"); + settings.setValue(QString(), value); +} + void tst_QSettings::testResourceFiles() { QSettings settings(":/resourcefile.ini", QSettings::IniFormat); -- cgit v1.2.3 From 16df1ad322689190f9b8107b010d74c92bb19e8b Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Mon, 13 Oct 2014 11:57:02 +0200 Subject: Export QFSFileEngine symbols Although it's private API the symbols are used e.g. in the Qt Installer Framework. Change-Id: I557d3b86dbf87cb1b712bae09c3e8fecf6f15e67 Reviewed-by: hjk --- src/corelib/io/qfsfileengine_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qfsfileengine_p.h b/src/corelib/io/qfsfileengine_p.h index 5d5a29243e..3963a9cb11 100644 --- a/src/corelib/io/qfsfileengine_p.h +++ b/src/corelib/io/qfsfileengine_p.h @@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE class QFSFileEnginePrivate; -class Q_AUTOTEST_EXPORT QFSFileEngine : public QAbstractFileEngine +class Q_CORE_EXPORT QFSFileEngine : public QAbstractFileEngine { Q_DECLARE_PRIVATE(QFSFileEngine) public: -- cgit v1.2.3 From db069e7f3009075937a772e780df40c63a871999 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 1 Oct 2014 14:48:29 +0200 Subject: XCB: Always set X window attributes in QXcbWindow::setWindowFlags(). QDockWidget and QToolBar set the Qt::BypassWindowManagerHint window flag when unplugging and clear it in the endDrag() methods. This does not have any effect since the attribute is not taken into account in QXcbWindow::setWindowFlags(). Change the method to always set the attributes, which should also make it possible to set/clear Qt::WindowTransparentForInput. Task-number: QTBUG-41189 Task-number: QTBUG-38964 Change-Id: Id9eddc642489d18f44c7597f8fc1a1df71971306 Reviewed-by: Andy Shaw Reviewed-by: Gatis Paeglis --- src/plugins/platforms/xcb/qxcbwindow.cpp | 51 +++++++++++++++++++------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index c4cf3b4416..0c2e9d047c 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -251,6 +251,27 @@ QXcbWindow::QXcbWindow(QWindow *window) m_window = window->winId(); } +#ifdef Q_COMPILER_CLASS_ENUM +enum : quint32 { +#else +enum { +#endif + baseEventMask + = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY + | XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_FOCUS_CHANGE, + + defaultEventMask = baseEventMask + | XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE + | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE + | XCB_EVENT_MASK_BUTTON_MOTION | XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW + | XCB_EVENT_MASK_POINTER_MOTION, + + transparentForInputEventMask = baseEventMask + | XCB_EVENT_MASK_VISIBILITY_CHANGE | XCB_EVENT_MASK_RESIZE_REDIRECT + | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT + | XCB_EVENT_MASK_COLOR_MAP_CHANGE | XCB_EVENT_MASK_OWNER_GRAB_BUTTON +}; + void QXcbWindow::create() { destroy(); @@ -285,18 +306,7 @@ void QXcbWindow::create() // XCB_CW_SAVE_UNDER type == Qt::Popup || type == Qt::Tool || type == Qt::SplashScreen || type == Qt::ToolTip || type == Qt::Drawer, // XCB_CW_EVENT_MASK - XCB_EVENT_MASK_EXPOSURE - | XCB_EVENT_MASK_STRUCTURE_NOTIFY - | XCB_EVENT_MASK_KEY_PRESS - | XCB_EVENT_MASK_KEY_RELEASE - | XCB_EVENT_MASK_BUTTON_PRESS - | XCB_EVENT_MASK_BUTTON_RELEASE - | XCB_EVENT_MASK_BUTTON_MOTION - | XCB_EVENT_MASK_ENTER_WINDOW - | XCB_EVENT_MASK_LEAVE_WINDOW - | XCB_EVENT_MASK_POINTER_MOTION - | XCB_EVENT_MASK_PROPERTY_CHANGE - | XCB_EVENT_MASK_FOCUS_CHANGE + defaultEventMask }; // Parameters to XCreateWindow() are frame corner + inner size. @@ -985,14 +995,15 @@ void QXcbWindow::setWindowFlags(Qt::WindowFlags flags) if (type == Qt::Popup) flags |= Qt::X11BypassWindowManagerHint; - if (flags & Qt::WindowTransparentForInput) { - uint32_t mask = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_VISIBILITY_CHANGE - | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_RESIZE_REDIRECT - | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT - | XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_PROPERTY_CHANGE - | XCB_EVENT_MASK_COLOR_MAP_CHANGE | XCB_EVENT_MASK_OWNER_GRAB_BUTTON; - xcb_change_window_attributes(xcb_connection(), xcb_window(), XCB_CW_EVENT_MASK, &mask); - } + const quint32 mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK; + const quint32 values[] = { + // XCB_CW_OVERRIDE_REDIRECT + (flags & Qt::BypassWindowManagerHint) ? 1u : 0, + // XCB_CW_EVENT_MASK + (flags & Qt::WindowTransparentForInput) ? transparentForInputEventMask : defaultEventMask + }; + + xcb_change_window_attributes(xcb_connection(), xcb_window(), mask, values); setNetWmWindowFlags(flags); setMotifWindowFlags(flags); -- cgit v1.2.3 From 45485d9eb47d3129b8a74c2e9d854c07673161cd Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 16 Oct 2014 10:39:44 +0200 Subject: Fix undefined behavior in QLoggingRegistry::defaultCategoryFilter() Report by asan: READ of size 2 at 0x00000041dd40 thread T0 #0 0x2af097b84da6 in QLoggingRegistry::defaultCategoryFilter(QLoggingCategory*) (lib/libQt5Core.so.5+0x566da6) #1 0x2af097b8387b in QLoggingRegistry::registerCategory(QLoggingCategory*, QtMsgType) (lib/libQt5Core.so.5+0x56587b) #2 0x4067f7 in tst_QLogging::QLoggingCategory_categoryName() tests/auto/corelib/io/qloggingcategory/tst_qloggingcategory.cpp:238 0x00000041dd41 is located 0 bytes to the right of global variable '*.LC115' defined in 'tests/auto/corelib/io/qloggingcategory/tst_qloggingcategory.cpp' (0x41dd40) of size 1 '*.LC115' is ascii string '' At face value, memcmp("", "qt", 2) should not return 0, but since the code invokes undefined behavior, the compiler can do whatever it wants, including returning 0 here, further proving the fact that there are *no* benign cases of undefined behavior. Change-Id: I0c38622c47d1dcea450ea549370be1673b47b18d Reviewed-by: Kai Koehne Reviewed-by: Olivier Goffart --- src/corelib/io/qloggingregistry.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp index e9ee8d9458..8af1487834 100644 --- a/src/corelib/io/qloggingregistry.cpp +++ b/src/corelib/io/qloggingregistry.cpp @@ -398,9 +398,11 @@ void QLoggingRegistry::defaultCategoryFilter(QLoggingCategory *cat) // hard-wired implementation of // qt.*.debug=false // qt.debug=false - char c; - if (!memcmp(cat->categoryName(), "qt", 2) && (!(c = cat->categoryName()[2]) || c == '.')) - debug = false; + if (const char *categoryName = cat->categoryName()) { + // == "qt" or startsWith("qt.") + if (strcmp(categoryName, "qt") == 0 || strncmp(categoryName, "qt.", 3) == 0) + debug = false; + } QString categoryName = QLatin1String(cat->categoryName()); foreach (const QLoggingRule &item, reg->rules) { -- cgit v1.2.3 From cf8f369f8575dcb9ca4d5116f3afc7cff4a080af Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Wed, 15 Oct 2014 13:50:27 +0200 Subject: Move Qt Core examples under a common subdirectory Qt Core examples were scattered into several subdirectories under qtbase/examples. This caused an issue with the example manifest file generated by QDoc; it expects to find all examples under a common directory in order to produde correct paths to the example .pro files. Qt Creator will not find the examples without a valid manifest file. This change moves the examples and edits the documentation files accordingly. Task-number: QTBUG-41963 Change-Id: I51d86782e0ba21c5c9bae5f15401ec774abe5cf8 Reviewed-by: Friedemann Kleint Reviewed-by: Oswald Buddenhagen Reviewed-by: Leena Miettinen --- doc/global/manifest-meta.qdocconf | 7 +- examples/corelib/corelib.pro | 8 + examples/corelib/ipc/README | 5 + .../ipc/doc/images/localfortuneclient-example.png | Bin 0 -> 8402 bytes .../ipc/doc/images/localfortuneserver-example.png | Bin 0 -> 5715 bytes .../ipc/doc/images/sharedmemory-example_1.png | Bin 0 -> 14926 bytes .../ipc/doc/images/sharedmemory-example_2.png | Bin 0 -> 21976 bytes .../corelib/ipc/doc/src/localfortuneclient.qdoc | 40 +++ .../corelib/ipc/doc/src/localfortuneserver.qdoc | 39 +++ examples/corelib/ipc/doc/src/sharedmemory.qdoc | 131 ++++++++ examples/corelib/ipc/ipc.pro | 6 + examples/corelib/ipc/localfortuneclient/client.cpp | 153 +++++++++ examples/corelib/ipc/localfortuneclient/client.h | 82 +++++ .../ipc/localfortuneclient/localfortuneclient.pro | 8 + examples/corelib/ipc/localfortuneclient/main.cpp | 51 +++ .../ipc/localfortuneserver/localfortuneserver.pro | 8 + examples/corelib/ipc/localfortuneserver/main.cpp | 55 +++ examples/corelib/ipc/localfortuneserver/server.cpp | 111 +++++++ examples/corelib/ipc/localfortuneserver/server.h | 69 ++++ examples/corelib/ipc/sharedmemory/dialog.cpp | 188 +++++++++++ examples/corelib/ipc/sharedmemory/dialog.h | 70 ++++ examples/corelib/ipc/sharedmemory/dialog.ui | 47 +++ examples/corelib/ipc/sharedmemory/image.png | Bin 0 -> 10199 bytes examples/corelib/ipc/sharedmemory/main.cpp | 53 +++ examples/corelib/ipc/sharedmemory/qt.png | Bin 0 -> 2383 bytes examples/corelib/ipc/sharedmemory/sharedmemory.pro | 15 + examples/corelib/json/json.pro | 2 + examples/corelib/json/savegame/character.cpp | 101 ++++++ examples/corelib/json/savegame/character.h | 76 +++++ .../corelib/json/savegame/doc/src/savegame.qdoc | 184 ++++++++++ examples/corelib/json/savegame/game.cpp | 164 +++++++++ examples/corelib/json/savegame/game.h | 75 +++++ examples/corelib/json/savegame/level.cpp | 83 +++++ examples/corelib/json/savegame/level.h | 65 ++++ examples/corelib/json/savegame/main.cpp | 70 ++++ examples/corelib/json/savegame/savegame.pro | 22 ++ examples/corelib/threads/README | 7 + .../threads/doc/images/mandelbrot-example.png | Bin 0 -> 84202 bytes .../threads/doc/images/mandelbrot_scroll1.png | Bin 0 -> 19615 bytes .../threads/doc/images/mandelbrot_scroll2.png | Bin 0 -> 13901 bytes .../threads/doc/images/mandelbrot_scroll3.png | Bin 0 -> 18976 bytes .../threads/doc/images/mandelbrot_zoom1.png | Bin 0 -> 16000 bytes .../threads/doc/images/mandelbrot_zoom2.png | Bin 0 -> 8163 bytes .../threads/doc/images/mandelbrot_zoom3.png | Bin 0 -> 9848 bytes .../doc/images/queuedcustomtype-example.png | Bin 0 -> 44851 bytes examples/corelib/threads/doc/src/mandelbrot.qdoc | 370 +++++++++++++++++++++ .../corelib/threads/doc/src/queuedcustomtype.qdoc | 166 +++++++++ examples/corelib/threads/doc/src/semaphores.qdoc | 147 ++++++++ .../corelib/threads/doc/src/waitconditions.qdoc | 154 +++++++++ examples/corelib/threads/mandelbrot/main.cpp | 53 +++ examples/corelib/threads/mandelbrot/mandelbrot.pro | 13 + .../threads/mandelbrot/mandelbrotwidget.cpp | 239 +++++++++++++ .../corelib/threads/mandelbrot/mandelbrotwidget.h | 86 +++++ .../corelib/threads/mandelbrot/renderthread.cpp | 215 ++++++++++++ examples/corelib/threads/mandelbrot/renderthread.h | 87 +++++ .../corelib/threads/queuedcustomtype/block.cpp | 73 ++++ examples/corelib/threads/queuedcustomtype/block.h | 70 ++++ examples/corelib/threads/queuedcustomtype/main.cpp | 128 +++++++ .../threads/queuedcustomtype/queuedcustomtype.pro | 14 + .../threads/queuedcustomtype/renderthread.cpp | 109 ++++++ .../threads/queuedcustomtype/renderthread.h | 76 +++++ .../corelib/threads/queuedcustomtype/window.cpp | 136 ++++++++ examples/corelib/threads/queuedcustomtype/window.h | 76 +++++ examples/corelib/threads/semaphores/semaphores.cpp | 112 +++++++ examples/corelib/threads/semaphores/semaphores.pro | 9 + examples/corelib/threads/threads.pro | 7 + .../threads/waitconditions/waitconditions.cpp | 137 ++++++++ .../threads/waitconditions/waitconditions.pro | 9 + examples/corelib/tools/README | 9 + .../tools/contiguouscache/contiguouscache.pro | 9 + examples/corelib/tools/contiguouscache/main.cpp | 55 +++ .../tools/contiguouscache/randomlistmodel.cpp | 96 ++++++ .../tools/contiguouscache/randomlistmodel.h | 66 ++++ examples/corelib/tools/customtype/customtype.pro | 8 + examples/corelib/tools/customtype/main.cpp | 73 ++++ examples/corelib/tools/customtype/message.cpp | 89 +++++ examples/corelib/tools/customtype/message.h | 75 +++++ .../tools/customtypesending/customtypesending.pro | 10 + examples/corelib/tools/customtypesending/main.cpp | 67 ++++ .../corelib/tools/customtypesending/message.cpp | 71 ++++ examples/corelib/tools/customtypesending/message.h | 71 ++++ .../corelib/tools/customtypesending/window.cpp | 79 +++++ examples/corelib/tools/customtypesending/window.h | 72 ++++ .../corelib/tools/doc/src/contiguouscache.qdoc | 83 +++++ examples/corelib/tools/doc/src/customtype.qdoc | 143 ++++++++ examples/corelib/tools/tools.pro | 7 + examples/examples.pro | 5 +- examples/ipc/README | 5 - .../ipc/doc/images/localfortuneclient-example.png | Bin 8402 -> 0 bytes .../ipc/doc/images/localfortuneserver-example.png | Bin 5715 -> 0 bytes examples/ipc/doc/images/sharedmemory-example_1.png | Bin 14926 -> 0 bytes examples/ipc/doc/images/sharedmemory-example_2.png | Bin 21976 -> 0 bytes examples/ipc/doc/src/localfortuneclient.qdoc | 40 --- examples/ipc/doc/src/localfortuneserver.qdoc | 39 --- examples/ipc/doc/src/sharedmemory.qdoc | 131 -------- examples/ipc/ipc.pro | 6 - examples/ipc/localfortuneclient/client.cpp | 153 --------- examples/ipc/localfortuneclient/client.h | 82 ----- .../ipc/localfortuneclient/localfortuneclient.pro | 8 - examples/ipc/localfortuneclient/main.cpp | 51 --- .../ipc/localfortuneserver/localfortuneserver.pro | 8 - examples/ipc/localfortuneserver/main.cpp | 55 --- examples/ipc/localfortuneserver/server.cpp | 111 ------- examples/ipc/localfortuneserver/server.h | 69 ---- examples/ipc/sharedmemory/dialog.cpp | 188 ----------- examples/ipc/sharedmemory/dialog.h | 70 ---- examples/ipc/sharedmemory/dialog.ui | 47 --- examples/ipc/sharedmemory/image.png | Bin 10199 -> 0 bytes examples/ipc/sharedmemory/main.cpp | 53 --- examples/ipc/sharedmemory/qt.png | Bin 2383 -> 0 bytes examples/ipc/sharedmemory/sharedmemory.pro | 15 - examples/json/json.pro | 2 - examples/json/savegame/character.cpp | 101 ------ examples/json/savegame/character.h | 76 ----- examples/json/savegame/doc/src/savegame.qdoc | 184 ---------- examples/json/savegame/game.cpp | 164 --------- examples/json/savegame/game.h | 75 ----- examples/json/savegame/level.cpp | 83 ----- examples/json/savegame/level.h | 65 ---- examples/json/savegame/main.cpp | 70 ---- examples/json/savegame/savegame.pro | 22 -- examples/threads/README | 7 - examples/threads/doc/images/mandelbrot-example.png | Bin 84202 -> 0 bytes examples/threads/doc/images/mandelbrot_scroll1.png | Bin 19615 -> 0 bytes examples/threads/doc/images/mandelbrot_scroll2.png | Bin 13901 -> 0 bytes examples/threads/doc/images/mandelbrot_scroll3.png | Bin 18976 -> 0 bytes examples/threads/doc/images/mandelbrot_zoom1.png | Bin 16000 -> 0 bytes examples/threads/doc/images/mandelbrot_zoom2.png | Bin 8163 -> 0 bytes examples/threads/doc/images/mandelbrot_zoom3.png | Bin 9848 -> 0 bytes .../doc/images/queuedcustomtype-example.png | Bin 44851 -> 0 bytes examples/threads/doc/src/mandelbrot.qdoc | 370 --------------------- examples/threads/doc/src/queuedcustomtype.qdoc | 166 --------- examples/threads/doc/src/semaphores.qdoc | 147 -------- examples/threads/doc/src/waitconditions.qdoc | 154 --------- examples/threads/mandelbrot/main.cpp | 53 --- examples/threads/mandelbrot/mandelbrot.pro | 13 - examples/threads/mandelbrot/mandelbrotwidget.cpp | 239 ------------- examples/threads/mandelbrot/mandelbrotwidget.h | 86 ----- examples/threads/mandelbrot/renderthread.cpp | 215 ------------ examples/threads/mandelbrot/renderthread.h | 87 ----- examples/threads/queuedcustomtype/block.cpp | 73 ---- examples/threads/queuedcustomtype/block.h | 70 ---- examples/threads/queuedcustomtype/main.cpp | 128 ------- .../threads/queuedcustomtype/queuedcustomtype.pro | 14 - examples/threads/queuedcustomtype/renderthread.cpp | 109 ------ examples/threads/queuedcustomtype/renderthread.h | 76 ----- examples/threads/queuedcustomtype/window.cpp | 136 -------- examples/threads/queuedcustomtype/window.h | 76 ----- examples/threads/semaphores/semaphores.cpp | 112 ------- examples/threads/semaphores/semaphores.pro | 9 - examples/threads/threads.pro | 7 - examples/threads/waitconditions/waitconditions.cpp | 137 -------- examples/threads/waitconditions/waitconditions.pro | 9 - examples/tools/README | 9 - examples/tools/contiguouscache/contiguouscache.pro | 9 - examples/tools/contiguouscache/main.cpp | 55 --- examples/tools/contiguouscache/randomlistmodel.cpp | 96 ------ examples/tools/contiguouscache/randomlistmodel.h | 66 ---- examples/tools/customtype/customtype.pro | 8 - examples/tools/customtype/main.cpp | 73 ---- examples/tools/customtype/message.cpp | 89 ----- examples/tools/customtype/message.h | 75 ----- .../tools/customtypesending/customtypesending.pro | 10 - examples/tools/customtypesending/main.cpp | 67 ---- examples/tools/customtypesending/message.cpp | 71 ---- examples/tools/customtypesending/message.h | 71 ---- examples/tools/customtypesending/window.cpp | 79 ----- examples/tools/customtypesending/window.h | 72 ---- examples/tools/doc/contiguouscache.qdoc | 83 ----- examples/tools/doc/src/customtype.qdoc | 143 -------- examples/tools/tools.pro | 7 - src/corelib/doc/qtcore.qdocconf | 7 +- src/corelib/doc/src/custom-types.qdoc | 22 +- 173 files changed, 5577 insertions(+), 5570 deletions(-) create mode 100644 examples/corelib/corelib.pro create mode 100644 examples/corelib/ipc/README create mode 100644 examples/corelib/ipc/doc/images/localfortuneclient-example.png create mode 100644 examples/corelib/ipc/doc/images/localfortuneserver-example.png create mode 100644 examples/corelib/ipc/doc/images/sharedmemory-example_1.png create mode 100644 examples/corelib/ipc/doc/images/sharedmemory-example_2.png create mode 100644 examples/corelib/ipc/doc/src/localfortuneclient.qdoc create mode 100644 examples/corelib/ipc/doc/src/localfortuneserver.qdoc create mode 100644 examples/corelib/ipc/doc/src/sharedmemory.qdoc create mode 100644 examples/corelib/ipc/ipc.pro create mode 100644 examples/corelib/ipc/localfortuneclient/client.cpp create mode 100644 examples/corelib/ipc/localfortuneclient/client.h create mode 100644 examples/corelib/ipc/localfortuneclient/localfortuneclient.pro create mode 100644 examples/corelib/ipc/localfortuneclient/main.cpp create mode 100644 examples/corelib/ipc/localfortuneserver/localfortuneserver.pro create mode 100644 examples/corelib/ipc/localfortuneserver/main.cpp create mode 100644 examples/corelib/ipc/localfortuneserver/server.cpp create mode 100644 examples/corelib/ipc/localfortuneserver/server.h create mode 100644 examples/corelib/ipc/sharedmemory/dialog.cpp create mode 100644 examples/corelib/ipc/sharedmemory/dialog.h create mode 100644 examples/corelib/ipc/sharedmemory/dialog.ui create mode 100644 examples/corelib/ipc/sharedmemory/image.png create mode 100644 examples/corelib/ipc/sharedmemory/main.cpp create mode 100644 examples/corelib/ipc/sharedmemory/qt.png create mode 100644 examples/corelib/ipc/sharedmemory/sharedmemory.pro create mode 100644 examples/corelib/json/json.pro create mode 100644 examples/corelib/json/savegame/character.cpp create mode 100644 examples/corelib/json/savegame/character.h create mode 100644 examples/corelib/json/savegame/doc/src/savegame.qdoc create mode 100644 examples/corelib/json/savegame/game.cpp create mode 100644 examples/corelib/json/savegame/game.h create mode 100644 examples/corelib/json/savegame/level.cpp create mode 100644 examples/corelib/json/savegame/level.h create mode 100644 examples/corelib/json/savegame/main.cpp create mode 100644 examples/corelib/json/savegame/savegame.pro create mode 100644 examples/corelib/threads/README create mode 100644 examples/corelib/threads/doc/images/mandelbrot-example.png create mode 100644 examples/corelib/threads/doc/images/mandelbrot_scroll1.png create mode 100644 examples/corelib/threads/doc/images/mandelbrot_scroll2.png create mode 100644 examples/corelib/threads/doc/images/mandelbrot_scroll3.png create mode 100644 examples/corelib/threads/doc/images/mandelbrot_zoom1.png create mode 100644 examples/corelib/threads/doc/images/mandelbrot_zoom2.png create mode 100644 examples/corelib/threads/doc/images/mandelbrot_zoom3.png create mode 100644 examples/corelib/threads/doc/images/queuedcustomtype-example.png create mode 100644 examples/corelib/threads/doc/src/mandelbrot.qdoc create mode 100644 examples/corelib/threads/doc/src/queuedcustomtype.qdoc create mode 100644 examples/corelib/threads/doc/src/semaphores.qdoc create mode 100644 examples/corelib/threads/doc/src/waitconditions.qdoc create mode 100644 examples/corelib/threads/mandelbrot/main.cpp create mode 100644 examples/corelib/threads/mandelbrot/mandelbrot.pro create mode 100644 examples/corelib/threads/mandelbrot/mandelbrotwidget.cpp create mode 100644 examples/corelib/threads/mandelbrot/mandelbrotwidget.h create mode 100644 examples/corelib/threads/mandelbrot/renderthread.cpp create mode 100644 examples/corelib/threads/mandelbrot/renderthread.h create mode 100644 examples/corelib/threads/queuedcustomtype/block.cpp create mode 100644 examples/corelib/threads/queuedcustomtype/block.h create mode 100644 examples/corelib/threads/queuedcustomtype/main.cpp create mode 100644 examples/corelib/threads/queuedcustomtype/queuedcustomtype.pro create mode 100644 examples/corelib/threads/queuedcustomtype/renderthread.cpp create mode 100644 examples/corelib/threads/queuedcustomtype/renderthread.h create mode 100644 examples/corelib/threads/queuedcustomtype/window.cpp create mode 100644 examples/corelib/threads/queuedcustomtype/window.h create mode 100644 examples/corelib/threads/semaphores/semaphores.cpp create mode 100644 examples/corelib/threads/semaphores/semaphores.pro create mode 100644 examples/corelib/threads/threads.pro create mode 100644 examples/corelib/threads/waitconditions/waitconditions.cpp create mode 100644 examples/corelib/threads/waitconditions/waitconditions.pro create mode 100644 examples/corelib/tools/README create mode 100644 examples/corelib/tools/contiguouscache/contiguouscache.pro create mode 100644 examples/corelib/tools/contiguouscache/main.cpp create mode 100644 examples/corelib/tools/contiguouscache/randomlistmodel.cpp create mode 100644 examples/corelib/tools/contiguouscache/randomlistmodel.h create mode 100644 examples/corelib/tools/customtype/customtype.pro create mode 100644 examples/corelib/tools/customtype/main.cpp create mode 100644 examples/corelib/tools/customtype/message.cpp create mode 100644 examples/corelib/tools/customtype/message.h create mode 100644 examples/corelib/tools/customtypesending/customtypesending.pro create mode 100644 examples/corelib/tools/customtypesending/main.cpp create mode 100644 examples/corelib/tools/customtypesending/message.cpp create mode 100644 examples/corelib/tools/customtypesending/message.h create mode 100644 examples/corelib/tools/customtypesending/window.cpp create mode 100644 examples/corelib/tools/customtypesending/window.h create mode 100644 examples/corelib/tools/doc/src/contiguouscache.qdoc create mode 100644 examples/corelib/tools/doc/src/customtype.qdoc create mode 100644 examples/corelib/tools/tools.pro delete mode 100644 examples/ipc/README delete mode 100644 examples/ipc/doc/images/localfortuneclient-example.png delete mode 100644 examples/ipc/doc/images/localfortuneserver-example.png delete mode 100644 examples/ipc/doc/images/sharedmemory-example_1.png delete mode 100644 examples/ipc/doc/images/sharedmemory-example_2.png delete mode 100644 examples/ipc/doc/src/localfortuneclient.qdoc delete mode 100644 examples/ipc/doc/src/localfortuneserver.qdoc delete mode 100644 examples/ipc/doc/src/sharedmemory.qdoc delete mode 100644 examples/ipc/ipc.pro delete mode 100644 examples/ipc/localfortuneclient/client.cpp delete mode 100644 examples/ipc/localfortuneclient/client.h delete mode 100644 examples/ipc/localfortuneclient/localfortuneclient.pro delete mode 100644 examples/ipc/localfortuneclient/main.cpp delete mode 100644 examples/ipc/localfortuneserver/localfortuneserver.pro delete mode 100644 examples/ipc/localfortuneserver/main.cpp delete mode 100644 examples/ipc/localfortuneserver/server.cpp delete mode 100644 examples/ipc/localfortuneserver/server.h delete mode 100644 examples/ipc/sharedmemory/dialog.cpp delete mode 100644 examples/ipc/sharedmemory/dialog.h delete mode 100644 examples/ipc/sharedmemory/dialog.ui delete mode 100644 examples/ipc/sharedmemory/image.png delete mode 100644 examples/ipc/sharedmemory/main.cpp delete mode 100644 examples/ipc/sharedmemory/qt.png delete mode 100644 examples/ipc/sharedmemory/sharedmemory.pro delete mode 100644 examples/json/json.pro delete mode 100644 examples/json/savegame/character.cpp delete mode 100644 examples/json/savegame/character.h delete mode 100644 examples/json/savegame/doc/src/savegame.qdoc delete mode 100644 examples/json/savegame/game.cpp delete mode 100644 examples/json/savegame/game.h delete mode 100644 examples/json/savegame/level.cpp delete mode 100644 examples/json/savegame/level.h delete mode 100644 examples/json/savegame/main.cpp delete mode 100644 examples/json/savegame/savegame.pro delete mode 100644 examples/threads/README delete mode 100644 examples/threads/doc/images/mandelbrot-example.png delete mode 100644 examples/threads/doc/images/mandelbrot_scroll1.png delete mode 100644 examples/threads/doc/images/mandelbrot_scroll2.png delete mode 100644 examples/threads/doc/images/mandelbrot_scroll3.png delete mode 100644 examples/threads/doc/images/mandelbrot_zoom1.png delete mode 100644 examples/threads/doc/images/mandelbrot_zoom2.png delete mode 100644 examples/threads/doc/images/mandelbrot_zoom3.png delete mode 100644 examples/threads/doc/images/queuedcustomtype-example.png delete mode 100644 examples/threads/doc/src/mandelbrot.qdoc delete mode 100644 examples/threads/doc/src/queuedcustomtype.qdoc delete mode 100644 examples/threads/doc/src/semaphores.qdoc delete mode 100644 examples/threads/doc/src/waitconditions.qdoc delete mode 100644 examples/threads/mandelbrot/main.cpp delete mode 100644 examples/threads/mandelbrot/mandelbrot.pro delete mode 100644 examples/threads/mandelbrot/mandelbrotwidget.cpp delete mode 100644 examples/threads/mandelbrot/mandelbrotwidget.h delete mode 100644 examples/threads/mandelbrot/renderthread.cpp delete mode 100644 examples/threads/mandelbrot/renderthread.h delete mode 100644 examples/threads/queuedcustomtype/block.cpp delete mode 100644 examples/threads/queuedcustomtype/block.h delete mode 100644 examples/threads/queuedcustomtype/main.cpp delete mode 100644 examples/threads/queuedcustomtype/queuedcustomtype.pro delete mode 100644 examples/threads/queuedcustomtype/renderthread.cpp delete mode 100644 examples/threads/queuedcustomtype/renderthread.h delete mode 100644 examples/threads/queuedcustomtype/window.cpp delete mode 100644 examples/threads/queuedcustomtype/window.h delete mode 100644 examples/threads/semaphores/semaphores.cpp delete mode 100644 examples/threads/semaphores/semaphores.pro delete mode 100644 examples/threads/threads.pro delete mode 100644 examples/threads/waitconditions/waitconditions.cpp delete mode 100644 examples/threads/waitconditions/waitconditions.pro delete mode 100644 examples/tools/README delete mode 100644 examples/tools/contiguouscache/contiguouscache.pro delete mode 100644 examples/tools/contiguouscache/main.cpp delete mode 100644 examples/tools/contiguouscache/randomlistmodel.cpp delete mode 100644 examples/tools/contiguouscache/randomlistmodel.h delete mode 100644 examples/tools/customtype/customtype.pro delete mode 100644 examples/tools/customtype/main.cpp delete mode 100644 examples/tools/customtype/message.cpp delete mode 100644 examples/tools/customtype/message.h delete mode 100644 examples/tools/customtypesending/customtypesending.pro delete mode 100644 examples/tools/customtypesending/main.cpp delete mode 100644 examples/tools/customtypesending/message.cpp delete mode 100644 examples/tools/customtypesending/message.h delete mode 100644 examples/tools/customtypesending/window.cpp delete mode 100644 examples/tools/customtypesending/window.h delete mode 100644 examples/tools/doc/contiguouscache.qdoc delete mode 100644 examples/tools/doc/src/customtype.qdoc delete mode 100644 examples/tools/tools.pro diff --git a/doc/global/manifest-meta.qdocconf b/doc/global/manifest-meta.qdocconf index f5a4422601..01950e650c 100644 --- a/doc/global/manifest-meta.qdocconf +++ b/doc/global/manifest-meta.qdocconf @@ -255,7 +255,12 @@ manifestmeta.ios.tags = ios # add a generic thumbnail image to examples that do not have any images in their documentation manifestmeta.thumbnail.attributes = "imageUrl:qthelp\://org.qt-project.qtdoc.$QT_VERSION_TAG/qtdoc/images/qt-codesample.png" -manifestmeta.thumbnail.names = "QtConcurrent/Map Example" \ +manifestmeta.thumbnail.names = "QtCore/Contiguous Cache Example" \ + "QtCore/Custom Type Example" \ + "QtCore/JSON Save Game Example" \ + "QtCore/Semaphores Example" \ + "QtCore/Wait Conditions Example" \ + "QtConcurrent/Map Example" \ "QtConcurrent/QtConcurrent Word Count Example" \ "QtConcurrent/Run Function Example" \ "QtGui/Raster Window Example" \ diff --git a/examples/corelib/corelib.pro b/examples/corelib/corelib.pro new file mode 100644 index 0000000000..ec6e19c2b5 --- /dev/null +++ b/examples/corelib/corelib.pro @@ -0,0 +1,8 @@ +TEMPLATE = subdirs +CONFIG += no_docs_target + +SUBDIRS = \ + ipc \ + json \ + threads \ + tools diff --git a/examples/corelib/ipc/README b/examples/corelib/ipc/README new file mode 100644 index 0000000000..83a157a42e --- /dev/null +++ b/examples/corelib/ipc/README @@ -0,0 +1,5 @@ +These examples demonstrate IPC support in Qt. + + +Documentation for these examples can be found via the Examples +link in the main Qt documentation. diff --git a/examples/corelib/ipc/doc/images/localfortuneclient-example.png b/examples/corelib/ipc/doc/images/localfortuneclient-example.png new file mode 100644 index 0000000000..614784bf0f Binary files /dev/null and b/examples/corelib/ipc/doc/images/localfortuneclient-example.png differ diff --git a/examples/corelib/ipc/doc/images/localfortuneserver-example.png b/examples/corelib/ipc/doc/images/localfortuneserver-example.png new file mode 100644 index 0000000000..2f04c7528e Binary files /dev/null and b/examples/corelib/ipc/doc/images/localfortuneserver-example.png differ diff --git a/examples/corelib/ipc/doc/images/sharedmemory-example_1.png b/examples/corelib/ipc/doc/images/sharedmemory-example_1.png new file mode 100644 index 0000000000..53244d3f52 Binary files /dev/null and b/examples/corelib/ipc/doc/images/sharedmemory-example_1.png differ diff --git a/examples/corelib/ipc/doc/images/sharedmemory-example_2.png b/examples/corelib/ipc/doc/images/sharedmemory-example_2.png new file mode 100644 index 0000000000..fc71aed56e Binary files /dev/null and b/examples/corelib/ipc/doc/images/sharedmemory-example_2.png differ diff --git a/examples/corelib/ipc/doc/src/localfortuneclient.qdoc b/examples/corelib/ipc/doc/src/localfortuneclient.qdoc new file mode 100644 index 0000000000..d7a90fd946 --- /dev/null +++ b/examples/corelib/ipc/doc/src/localfortuneclient.qdoc @@ -0,0 +1,40 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example ipc/localfortuneclient + \title Local Fortune Client Example + \ingroup examples-ipc + \brief Demonstrates using QLocalSocket for a simple local service client. + + The Local Fortune Client example shows how to create a client for a simple + local service using QLocalSocket. It is intended to be run alongside the + \l{Local Fortune Server Example}. + + \image localfortuneclient-example.png Screenshot of the Local Fortune Client example + +*/ diff --git a/examples/corelib/ipc/doc/src/localfortuneserver.qdoc b/examples/corelib/ipc/doc/src/localfortuneserver.qdoc new file mode 100644 index 0000000000..47c28e0eb0 --- /dev/null +++ b/examples/corelib/ipc/doc/src/localfortuneserver.qdoc @@ -0,0 +1,39 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example ipc/localfortuneserver + \title Local Fortune Server Example + \ingroup examples-ipc + \brief Demonstrates using QLocalServer and QLocalSocket for serving a simple local service. + + The Local Fortune Server example shows how to create a server for a simple + local service. It is intended to be run alongside the + \l{Local Fortune Client Example} + + \image localfortuneserver-example.png Screenshot of the Local Fortune Server example + */ diff --git a/examples/corelib/ipc/doc/src/sharedmemory.qdoc b/examples/corelib/ipc/doc/src/sharedmemory.qdoc new file mode 100644 index 0000000000..60b949df2d --- /dev/null +++ b/examples/corelib/ipc/doc/src/sharedmemory.qdoc @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example ipc/sharedmemory + \title Shared Memory Example + \ingroup examples-ipc + \brief Demonstrates doing inter-process communication using shared memory with + the QSharedMemory class. + + The Shared Memory example shows how to use the QSharedMemory class + to implement inter-process communication using shared memory. To + build the example, run make. To run the example, start two instances + of the executable. The main() function creates an \l {QApplication} + {application} and an instance of our example's Dialog class. The + dialog is displayed and then control is passed to the application in + the standard way. + + \snippet ipc/sharedmemory/main.cpp 0 + + Two instances of class Dialog appear. + + \image sharedmemory-example_1.png Screenshot of the Shared Memory example + + Class Dialog inherits QDialog. It encapsulates the user interface + and an instance of QSharedMemory. It also has two public slots, + loadFromFile() and loadFromMemory() that correspond to the two + buttons on the dialog. + + \snippet ipc/sharedmemory/dialog.h 0 + + The constructor builds the user interface widgets and connects the + clicked() signal of each button to the corresponding slot function. + + \snippet ipc/sharedmemory/dialog.cpp 0 + + Note that "QSharedMemoryExample" is passed to the \l {QSharedMemory} + {QSharedMemory()} constructor to be used as the key. This will be + used by the system as the identifier of the underlying shared memory + segment. + + Click the \tt {Load Image From File...} button on one of the + dialogs. The loadFromFile() slot is invoked. First, it tests whether + a shared memory segment is already attached to the process. If so, + that segment is detached from the process, so we can be assured of + starting off the example correctly. + + \snippet ipc/sharedmemory/dialog.cpp 1 + + The user is then asked to select an image file using + QFileDialog::getOpenFileName(). The selected file is loaded into a + QImage. Using a QImage lets us ensure that the selected file is a + valid image, and it also allows us to immediately display the image + in the dialog using setPixmap(). + + Next the image is streamed into a QBuffer using a QDataStream. This + gives us the size, which we then use to \l {QSharedMemory::} + {create()} our shared memory segment. Creating a shared memory + segment automatically \l {QSharedMemory::attach()} {attaches} the + segment to the process. Using a QBuffer here lets us get a pointer + to the image data, which we then use to do a memcopy() from the + QBuffer into the shared memory segment. + + \snippet ipc/sharedmemory/dialog.cpp 2 + + Note that we \l {QSharedMemory::} {lock()} the shared memory segment + before we copy into it, and we \l {QSharedMemory::} {unlock()} it + again immediately after the copy. This ensures we have exclusive + access to the shared memory segment to do our memcopy(). If some + other process has the segment lock, then our process will block + until the lock becomes available. + + Note also that the function does not \l {QSharedMemory::} {detach()} + from the shared memory segment after the memcopy() and + unlock(). Recall that when the last process detaches from a shared + memory segment, the segment is released by the operating + system. Since this process only one that is attached to the shared + memory segment at the moment, if loadFromFile() detached from the + shared memory segment, the segment would be destroyed before we get + to the next step. + + When the function returns, if the file you selected was qt.png, your + first dialog looks like this. + + \image sharedmemory-example_2.png Screenshot of the Shared Memory example + + In the second dialog, click the \tt {Display Image From Shared + Memory} button. The loadFromMemory() slot is invoked. It first \l + {QSharedMemory::attach()} {attaches} the process to the same shared + memory segment created by the first process. Then it \l + {QSharedMemory::lock()} {locks} the segment for exclusive access and + links a QBuffer to the image data in the shared memory segment. It + then streams the data into a QImage and \l {QSharedMemory::unlock()} + {unlocks} the segment. + + \snippet ipc/sharedmemory/dialog.cpp 3 + + In this case, the function does \l {QSharedMemory::} {detach()} from + the segment, because now we are effectively finished using + it. Finally, the QImage is displayed. At this point, both dialogs + should be showing the same image. When you close the first dialog, + the Dialog destructor calls the QSharedMemory destructor, which + detaches from the shared memory segment. Since this is the last + process to be detached from the segment, the operating system will + now release the shared memory. + + */ diff --git a/examples/corelib/ipc/ipc.pro b/examples/corelib/ipc/ipc.pro new file mode 100644 index 0000000000..4b4b3870a4 --- /dev/null +++ b/examples/corelib/ipc/ipc.pro @@ -0,0 +1,6 @@ +requires(qtHaveModule(widgets)) + +TEMPLATE = subdirs +# no QSharedMemory +!vxworks:!qnx:SUBDIRS = sharedmemory +!wince*:qtHaveModule(network): SUBDIRS += localfortuneserver localfortuneclient diff --git a/examples/corelib/ipc/localfortuneclient/client.cpp b/examples/corelib/ipc/localfortuneclient/client.cpp new file mode 100644 index 0000000000..267f5329c8 --- /dev/null +++ b/examples/corelib/ipc/localfortuneclient/client.cpp @@ -0,0 +1,153 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#include "client.h" + +Client::Client(QWidget *parent) + : QDialog(parent) +{ + hostLabel = new QLabel(tr("&Server name:")); + hostLineEdit = new QLineEdit("fortune"); + + hostLabel->setBuddy(hostLineEdit); + + statusLabel = new QLabel(tr("This examples requires that you run the " + "Fortune Server example as well.")); + statusLabel->setWordWrap(true); + + getFortuneButton = new QPushButton(tr("Get Fortune")); + getFortuneButton->setDefault(true); + + quitButton = new QPushButton(tr("Quit")); + + buttonBox = new QDialogButtonBox; + buttonBox->addButton(getFortuneButton, QDialogButtonBox::ActionRole); + buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole); + + socket = new QLocalSocket(this); + + connect(hostLineEdit, SIGNAL(textChanged(QString)), + this, SLOT(enableGetFortuneButton())); + connect(getFortuneButton, SIGNAL(clicked()), + this, SLOT(requestNewFortune())); + connect(quitButton, SIGNAL(clicked()), this, SLOT(close())); + connect(socket, SIGNAL(readyRead()), this, SLOT(readFortune())); + connect(socket, SIGNAL(error(QLocalSocket::LocalSocketError)), + this, SLOT(displayError(QLocalSocket::LocalSocketError))); + + QGridLayout *mainLayout = new QGridLayout; + mainLayout->addWidget(hostLabel, 0, 0); + mainLayout->addWidget(hostLineEdit, 0, 1); + mainLayout->addWidget(statusLabel, 2, 0, 1, 2); + mainLayout->addWidget(buttonBox, 3, 0, 1, 2); + setLayout(mainLayout); + + setWindowTitle(tr("Fortune Client")); + hostLineEdit->setFocus(); +} + +void Client::requestNewFortune() +{ + getFortuneButton->setEnabled(false); + blockSize = 0; + socket->abort(); + socket->connectToServer(hostLineEdit->text()); +} + +void Client::readFortune() +{ + QDataStream in(socket); + in.setVersion(QDataStream::Qt_4_0); + + if (blockSize == 0) { + if (socket->bytesAvailable() < (int)sizeof(quint16)) + return; + in >> blockSize; + } + + if (in.atEnd()) + return; + + QString nextFortune; + in >> nextFortune; + + if (nextFortune == currentFortune) { + QTimer::singleShot(0, this, SLOT(requestNewFortune())); + return; + } + + currentFortune = nextFortune; + statusLabel->setText(currentFortune); + getFortuneButton->setEnabled(true); +} + +void Client::displayError(QLocalSocket::LocalSocketError socketError) +{ + switch (socketError) { + case QLocalSocket::ServerNotFoundError: + QMessageBox::information(this, tr("Fortune Client"), + tr("The host was not found. Please check the " + "host name and port settings.")); + break; + case QLocalSocket::ConnectionRefusedError: + QMessageBox::information(this, tr("Fortune Client"), + tr("The connection was refused by the peer. " + "Make sure the fortune server is running, " + "and check that the host name and port " + "settings are correct.")); + break; + case QLocalSocket::PeerClosedError: + break; + default: + QMessageBox::information(this, tr("Fortune Client"), + tr("The following error occurred: %1.") + .arg(socket->errorString())); + } + + getFortuneButton->setEnabled(true); +} + +void Client::enableGetFortuneButton() +{ + getFortuneButton->setEnabled(!hostLineEdit->text().isEmpty()); +} diff --git a/examples/corelib/ipc/localfortuneclient/client.h b/examples/corelib/ipc/localfortuneclient/client.h new file mode 100644 index 0000000000..61b1cd26a4 --- /dev/null +++ b/examples/corelib/ipc/localfortuneclient/client.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CLIENT_H +#define CLIENT_H + +#include + +#include + +QT_BEGIN_NAMESPACE +class QDialogButtonBox; +class QLabel; +class QLineEdit; +class QPushButton; +class QLocalSocket; +QT_END_NAMESPACE + +class Client : public QDialog +{ + Q_OBJECT + +public: + Client(QWidget *parent = 0); + +private slots: + void requestNewFortune(); + void readFortune(); + void displayError(QLocalSocket::LocalSocketError socketError); + void enableGetFortuneButton(); + +private: + QLabel *hostLabel; + QLineEdit *hostLineEdit; + QLabel *statusLabel; + QPushButton *getFortuneButton; + QPushButton *quitButton; + QDialogButtonBox *buttonBox; + + QLocalSocket *socket; + QString currentFortune; + quint16 blockSize; +}; + +#endif diff --git a/examples/corelib/ipc/localfortuneclient/localfortuneclient.pro b/examples/corelib/ipc/localfortuneclient/localfortuneclient.pro new file mode 100644 index 0000000000..912c0f3b8e --- /dev/null +++ b/examples/corelib/ipc/localfortuneclient/localfortuneclient.pro @@ -0,0 +1,8 @@ +HEADERS = client.h +SOURCES = client.cpp \ + main.cpp +QT += network widgets + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/corelib/ipc/localfortuneclient +INSTALLS += target diff --git a/examples/corelib/ipc/localfortuneclient/main.cpp b/examples/corelib/ipc/localfortuneclient/main.cpp new file mode 100644 index 0000000000..f197d7f6cb --- /dev/null +++ b/examples/corelib/ipc/localfortuneclient/main.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "client.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + Client client; + client.show(); + return app.exec(); +} diff --git a/examples/corelib/ipc/localfortuneserver/localfortuneserver.pro b/examples/corelib/ipc/localfortuneserver/localfortuneserver.pro new file mode 100644 index 0000000000..88190c45bd --- /dev/null +++ b/examples/corelib/ipc/localfortuneserver/localfortuneserver.pro @@ -0,0 +1,8 @@ +HEADERS = server.h +SOURCES = server.cpp \ + main.cpp +QT += network widgets + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/corelib/ipc/localfortuneserver +INSTALLS += target diff --git a/examples/corelib/ipc/localfortuneserver/main.cpp b/examples/corelib/ipc/localfortuneserver/main.cpp new file mode 100644 index 0000000000..0ae70e14ef --- /dev/null +++ b/examples/corelib/ipc/localfortuneserver/main.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#include + +#include "server.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + Server server; + server.show(); + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + return app.exec(); +} diff --git a/examples/corelib/ipc/localfortuneserver/server.cpp b/examples/corelib/ipc/localfortuneserver/server.cpp new file mode 100644 index 0000000000..6130aaa1c3 --- /dev/null +++ b/examples/corelib/ipc/localfortuneserver/server.cpp @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#include + +#include "server.h" +#include +#include + +Server::Server(QWidget *parent) + : QDialog(parent) +{ + statusLabel = new QLabel; + statusLabel->setWordWrap(true); + quitButton = new QPushButton(tr("Quit")); + quitButton->setAutoDefault(false); + + server = new QLocalServer(this); + if (!server->listen("fortune")) { + QMessageBox::critical(this, tr("Fortune Server"), + tr("Unable to start the server: %1.") + .arg(server->errorString())); + close(); + return; + } + + statusLabel->setText(tr("The server is running.\n" + "Run the Fortune Client example now.")); + + fortunes << tr("You've been leading a dog's life. Stay off the furniture.") + << tr("You've got to think about tomorrow.") + << tr("You will be surprised by a loud noise.") + << tr("You will feel hungry again in another hour.") + << tr("You might have mail.") + << tr("You cannot kill time without injuring eternity.") + << tr("Computers are not intelligent. They only think they are."); + + connect(quitButton, SIGNAL(clicked()), this, SLOT(close())); + connect(server, SIGNAL(newConnection()), this, SLOT(sendFortune())); + + QHBoxLayout *buttonLayout = new QHBoxLayout; + buttonLayout->addStretch(1); + buttonLayout->addWidget(quitButton); + buttonLayout->addStretch(1); + + QVBoxLayout *mainLayout = new QVBoxLayout; + mainLayout->addWidget(statusLabel); + mainLayout->addLayout(buttonLayout); + setLayout(mainLayout); + + setWindowTitle(tr("Fortune Server")); +} + +void Server::sendFortune() +{ + QByteArray block; + QDataStream out(&block, QIODevice::WriteOnly); + out.setVersion(QDataStream::Qt_4_0); + out << (quint16)0; + out << fortunes.at(qrand() % fortunes.size()); + out.device()->seek(0); + out << (quint16)(block.size() - sizeof(quint16)); + + QLocalSocket *clientConnection = server->nextPendingConnection(); + connect(clientConnection, SIGNAL(disconnected()), + clientConnection, SLOT(deleteLater())); + + clientConnection->write(block); + clientConnection->flush(); + clientConnection->disconnectFromServer(); +} diff --git a/examples/corelib/ipc/localfortuneserver/server.h b/examples/corelib/ipc/localfortuneserver/server.h new file mode 100644 index 0000000000..4ec7f9b8ef --- /dev/null +++ b/examples/corelib/ipc/localfortuneserver/server.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SERVER_H +#define SERVER_H + +#include + +QT_BEGIN_NAMESPACE +class QLabel; +class QPushButton; +class QLocalServer; +QT_END_NAMESPACE + +class Server : public QDialog +{ + Q_OBJECT + +public: + Server(QWidget *parent = 0); + +private slots: + void sendFortune(); + +private: + QLabel *statusLabel; + QPushButton *quitButton; + QLocalServer *server; + QStringList fortunes; +}; + +#endif diff --git a/examples/corelib/ipc/sharedmemory/dialog.cpp b/examples/corelib/ipc/sharedmemory/dialog.cpp new file mode 100644 index 0000000000..c504f3a202 --- /dev/null +++ b/examples/corelib/ipc/sharedmemory/dialog.cpp @@ -0,0 +1,188 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "dialog.h" +#include +#include +#include + +/*! + \class Dialog + + \brief This class is a simple example of how to use QSharedMemory. + + It is a simple dialog that presents a few buttons. To compile the + example, run make in qt/examples/ipc. Then run the executable twice + to create two processes running the dialog. In one of the processes, + press the button to load an image into a shared memory segment, and + then select an image file to load. Once the first process has loaded + and displayed the image, in the second process, press the button to + read the same image from shared memory. The second process displays + the same image loaded from its new loaction in shared memory. +*/ + +/*! + The class contains a data member \l {QSharedMemory} {sharedMemory}, + which is initialized with the key "QSharedMemoryExample" to force + all instances of Dialog to access the same shared memory segment. + The constructor also connects the clicked() signal from each of the + three dialog buttons to the slot function appropriate for handling + each button. +*/ +//! [0] +Dialog::Dialog(QWidget *parent) + : QDialog(parent), sharedMemory("QSharedMemoryExample") +{ + ui.setupUi(this); + connect(ui.loadFromFileButton, SIGNAL(clicked()), SLOT(loadFromFile())); + connect(ui.loadFromSharedMemoryButton, + SIGNAL(clicked()), + SLOT(loadFromMemory())); + setWindowTitle(tr("SharedMemory Example")); +} +//! [0] + +/*! + This slot function is called when the \tt {Load Image From File...} + button is pressed on the firs Dialog process. First, it tests + whether the process is already connected to a shared memory segment + and, if so, detaches from that segment. This ensures that we always + start the example from the beginning if we run it multiple times + with the same two Dialog processes. After detaching from an existing + shared memory segment, the user is prompted to select an image file. + The selected file is loaded into a QImage. The QImage is displayed + in the Dialog and streamed into a QBuffer with a QDataStream. + + Next, it gets a new shared memory segment from the system big enough + to hold the image data in the QBuffer, and it locks the segment to + prevent the second Dialog process from accessing it. Then it copies + the image from the QBuffer into the shared memory segment. Finally, + it unlocks the shared memory segment so the second Dialog process + can access it. + + After this function runs, the user is expected to press the \tt + {Load Image from Shared Memory} button on the second Dialog process. + + \sa loadFromMemory() + */ +//! [1] +void Dialog::loadFromFile() +{ + if (sharedMemory.isAttached()) + detach(); + + ui.label->setText(tr("Select an image file")); + QString fileName = QFileDialog::getOpenFileName(0, QString(), QString(), + tr("Images (*.png *.xpm *.jpg)")); + QImage image; + if (!image.load(fileName)) { + ui.label->setText(tr("Selected file is not an image, please select another.")); + return; + } + ui.label->setPixmap(QPixmap::fromImage(image)); +//! [1] //! [2] + + // load into shared memory + QBuffer buffer; + buffer.open(QBuffer::ReadWrite); + QDataStream out(&buffer); + out << image; + int size = buffer.size(); + + if (!sharedMemory.create(size)) { + ui.label->setText(tr("Unable to create shared memory segment.")); + return; + } + sharedMemory.lock(); + char *to = (char*)sharedMemory.data(); + const char *from = buffer.data().data(); + memcpy(to, from, qMin(sharedMemory.size(), size)); + sharedMemory.unlock(); +} +//! [2] + +/*! + This slot function is called in the second Dialog process, when the + user presses the \tt {Load Image from Shared Memory} button. First, + it attaches the process to the shared memory segment created by the + first Dialog process. Then it locks the segment for exclusive + access, copies the image data from the segment into a QBuffer, and + streams the QBuffer into a QImage. Then it unlocks the shared memory + segment, detaches from it, and finally displays the QImage in the + Dialog. + + \sa loadFromFile() + */ +//! [3] +void Dialog::loadFromMemory() +{ + if (!sharedMemory.attach()) { + ui.label->setText(tr("Unable to attach to shared memory segment.\n" \ + "Load an image first.")); + return; + } + + QBuffer buffer; + QDataStream in(&buffer); + QImage image; + + sharedMemory.lock(); + buffer.setData((char*)sharedMemory.constData(), sharedMemory.size()); + buffer.open(QBuffer::ReadOnly); + in >> image; + sharedMemory.unlock(); + + sharedMemory.detach(); + ui.label->setPixmap(QPixmap::fromImage(image)); +} +//! [3] + +/*! + This private function is called by the destructor to detach the + process from its shared memory segment. When the last process + detaches from a shared memory segment, the system releases the + shared memory. + */ +void Dialog::detach() +{ + if (!sharedMemory.detach()) + ui.label->setText(tr("Unable to detach from shared memory.")); +} + diff --git a/examples/corelib/ipc/sharedmemory/dialog.h b/examples/corelib/ipc/sharedmemory/dialog.h new file mode 100644 index 0000000000..fbc39ed4c0 --- /dev/null +++ b/examples/corelib/ipc/sharedmemory/dialog.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIALOG_H +#define DIALOG_H + +#include +#include +#include "ui_dialog.h" + +//! [0] +class Dialog : public QDialog +{ + Q_OBJECT + + public: + Dialog(QWidget *parent = 0); + + public slots: + void loadFromFile(); + void loadFromMemory(); + + private: + void detach(); + + private: + Ui::Dialog ui; + QSharedMemory sharedMemory; +}; +//! [0] + +#endif + diff --git a/examples/corelib/ipc/sharedmemory/dialog.ui b/examples/corelib/ipc/sharedmemory/dialog.ui new file mode 100644 index 0000000000..e99d6fb3c4 --- /dev/null +++ b/examples/corelib/ipc/sharedmemory/dialog.ui @@ -0,0 +1,47 @@ + + Dialog + + + + 0 + 0 + 451 + 322 + + + + Dialog + + + + + + Load Image From File... + + + + + + + Launch two of these dialogs. In the first, press the top button and load an image from a file. In the second, press the bottom button and display the loaded image from shared memory. + + + Qt::AlignCenter + + + true + + + + + + + Display Image From Shared Memory + + + + + + + + diff --git a/examples/corelib/ipc/sharedmemory/image.png b/examples/corelib/ipc/sharedmemory/image.png new file mode 100644 index 0000000000..dd93453063 Binary files /dev/null and b/examples/corelib/ipc/sharedmemory/image.png differ diff --git a/examples/corelib/ipc/sharedmemory/main.cpp b/examples/corelib/ipc/sharedmemory/main.cpp new file mode 100644 index 0000000000..0e9f84f3e3 --- /dev/null +++ b/examples/corelib/ipc/sharedmemory/main.cpp @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include "dialog.h" + +//! [0] +int main(int argc, char *argv[]) +{ + QApplication application(argc, argv); + Dialog dialog; + dialog.show(); + return application.exec(); +} +//! [0] + diff --git a/examples/corelib/ipc/sharedmemory/qt.png b/examples/corelib/ipc/sharedmemory/qt.png new file mode 100644 index 0000000000..60ef558efe Binary files /dev/null and b/examples/corelib/ipc/sharedmemory/qt.png differ diff --git a/examples/corelib/ipc/sharedmemory/sharedmemory.pro b/examples/corelib/ipc/sharedmemory/sharedmemory.pro new file mode 100644 index 0000000000..c1b634732e --- /dev/null +++ b/examples/corelib/ipc/sharedmemory/sharedmemory.pro @@ -0,0 +1,15 @@ +QT += widgets + +SOURCES += main.cpp \ + dialog.cpp + +HEADERS += dialog.h + +# Forms and resources +FORMS += dialog.ui + +EXAMPLE_FILES = *.png + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/corelib/ipc/sharedmemory +INSTALLS += target diff --git a/examples/corelib/json/json.pro b/examples/corelib/json/json.pro new file mode 100644 index 0000000000..af4d3e6f0f --- /dev/null +++ b/examples/corelib/json/json.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = savegame diff --git a/examples/corelib/json/savegame/character.cpp b/examples/corelib/json/savegame/character.cpp new file mode 100644 index 0000000000..ef30f0eaf4 --- /dev/null +++ b/examples/corelib/json/savegame/character.cpp @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "character.h" + +Character::Character() : + mLevel(0), + mClassType(Warrior) { +} + +Character::Character(const QString &name, int level, Character::ClassType classType) : + mName(name), + mLevel(level), + mClassType(classType) +{ +} + +QString Character::name() const +{ + return mName; +} + +void Character::setName(const QString &name) +{ + mName = name; +} + +int Character::level() const +{ + return mLevel; +} + +void Character::setLevel(int level) +{ + mLevel = level; +} + +Character::ClassType Character::classType() const +{ + return mClassType; +} + +void Character::setClassType(Character::ClassType classType) +{ + mClassType = classType; +} + +//! [0] +void Character::read(const QJsonObject &json) +{ + mName = json["name"].toString(); + mLevel = json["level"].toDouble(); + mClassType = ClassType(qRound(json["classType"].toDouble())); +} +//! [0] + +//! [1] +void Character::write(QJsonObject &json) const +{ + json["name"] = mName; + json["level"] = mLevel; + json["classType"] = mClassType; +} +//! [1] diff --git a/examples/corelib/json/savegame/character.h b/examples/corelib/json/savegame/character.h new file mode 100644 index 0000000000..32369820f4 --- /dev/null +++ b/examples/corelib/json/savegame/character.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CHARACTER_H +#define CHARACTER_H + +#include +#include + +//! [0] +class Character +{ +public: + enum ClassType { + Warrior, Mage, Archer + }; + + Character(); + Character(const QString &name, int level, ClassType classType); + + QString name() const; + void setName(const QString &name); + + int level() const; + void setLevel(int level); + + ClassType classType() const; + void setClassType(ClassType classType); + + void read(const QJsonObject &json); + void write(QJsonObject &json) const; +private: + QString mName; + int mLevel; + ClassType mClassType; +}; +//! [0] + +#endif // CHARACTER_H diff --git a/examples/corelib/json/savegame/doc/src/savegame.qdoc b/examples/corelib/json/savegame/doc/src/savegame.qdoc new file mode 100644 index 0000000000..1de12c38b9 --- /dev/null +++ b/examples/corelib/json/savegame/doc/src/savegame.qdoc @@ -0,0 +1,184 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example json/savegame + \title JSON Save Game Example + + \brief The JSON Save Game example demonstrates how to save and load a + small game using QJsonDocument, QJsonObject and QJsonArray. + + Many games provide save functionality, so that the player's progress through + the game can be saved and loaded at a later time. The process of saving a + game generally involves serializing each game object's member variables + to a file. Many formats can be used for this purpose, one of which is JSON. + With QJsonDocument, you also have the ability to serialize a document in a + binary format, which is great if you don't want the save file to be + readable, or if you need to keep the file size down. + + In this example, we'll demonstrate how to save and load a simple game to + and from JSON and binary formats. + + \section1 The Character Class + + The Character class represents a non-player character (NPC) in our game, and + stores the player's name, level, and class type. + + It provides read() and write() functions to serialise its member variables. + + \snippet json/savegame/character.h 0 + + Of particular interest to us are the read and write function + implementations: + + \snippet json/savegame/character.cpp 0 + + In the read() function, we assign Character's members values from the + QJsonObject argument. You can use either \l QJsonObject::operator[]() or + QJsonObject::value() to access values within the JSON object; both are + const functions and return QJsonValue::Undefined if the key is invalid. We + could check if the keys are valid before attempting to read them with + QJsonObject::contains(), but we assume that they are. + + \snippet json/savegame/character.cpp 1 + + In the write() function, we do the reverse of the read() function; assign + values from the Character object to the JSON object. As with accessing + values, there are two ways to set values on a QJsonObject: + \l QJsonObject::operator[]() and QJsonObject::insert(). Both will override + any existing value at the given key. + + Next up is the Level class: + + \snippet json/savegame/level.h 0 + + We want to have several levels in our game, each with several NPCs, so we + keep a QList of Character objects. We also provide the familiar read() and + write() functions. + + \snippet json/savegame/level.cpp 0 + + Containers can be written and read to and from JSON using QJsonArray. In our + case, we construct a QJsonArray from the value associated with the key + \c "npcs". Then, for each QJsonValue element in the array, we call + toObject() to get the Character's JSON object. The Character object can then + read their JSON and be appended to our NPC list. + + \note \l{Container Classes}{Associate containers} can be written by storing + the key in each value object (if it's not already). With this approach, the + container is stored as a regular array of objects, but the index of each + element is used as the key to construct the container when reading it back + in. + + \snippet json/savegame/level.cpp 1 + + Again, the write() function is similar to the read() function, except + reversed. + + Having established the Character and Level classes, we can move on to + the Game class: + + \snippet json/savegame/game.h 0 + + First of all, we define the \c SaveFormat enum. This will allow us to + specify the format in which the game should be saved: \c Json or \c Binary. + + Next, we provide accessors for the player and levels. We then expose three + functions: newGame(), saveGame() and loadGame(). + + The read() and write() functions are used by saveGame() and loadGame(). + + \snippet json/savegame/game.cpp 0 + + To setup a new game, we create the player and populate the levels and their + NPCs. + + \snippet json/savegame/game.cpp 1 + + The first thing we do in the read() function is tell the player to read + itself. We then clear the levels list so that calling loadGame() on the same + Game object twice doesn't result in old levels hanging around. + + We then populate the level list by reading each Level from a QJsonArray. + + \snippet json/savegame/game.cpp 2 + + We write the game to JSON similarly to how we write Level. + + \snippet json/savegame/game.cpp 3 + + When loading a saved game in loadGame(), the first thing we do is open the + save file based on which format it was saved to; \c "save.json" for JSON, + and \c "save.dat" for binary. We print a warning and return \c false if the + file couldn't be opened. + + Since QJsonDocument's \l{QJsonDocument::fromJson()}{fromJson()} and + \l{QJsonDocument::fromBinaryData()}{fromBinaryData()} functions both take a + QByteArray, we can read the entire contents of the save file into one, + regardless of the save format. + + After constructing the QJsonDocument, we instruct the Game object to read + itself and then return \c true to indicate success. + + \snippet json/savegame/game.cpp 4 + + Not surprisingly, saveGame() looks very much like loadGame(). We determine + the file extension based on the format, print a warning and return \c false + if the opening of the file fails. We then write the Game object to a + QJsonDocument, and call either QJsonDocument::toJson() or to + QJsonDocument::toBinaryData() to save the game, depending on which format + was specified. + + We are now ready to enter main(): + + \snippet json/savegame/main.cpp 0 + + Since we're only interested in demonstrating \e serialization of a game with + JSON, our game is not actually playable. Therefore, we only need + QCoreApplication and have no event loop. We create our game and assume that + the player had a great time and made lots of progress, altering the internal + state of our Character, Level and Game objects. + + \snippet json/savegame/main.cpp 1 + + When the player has finished, we save their game. For demonstration + purposes, we serialize to both JSON and binary. You can examine the contents + of the files in the same directory as the executable, although the binary + save file will contain some garbage characters (which is normal). + + To show that the saved files can be loaded again, we call loadGame() for + each format, returning \c 1 on failure. Assuming everything went well, we + return \c 0 to indicate success. + + That concludes our example. As you can see, serialization with Qt's JSON + classes is very simple and convenient. The advantages of using QJsonDocument + and friends over QDataStream, for example, is that you not only get + human-readable JSON files, but you also have the option to use a binary + format if it's required, \e without rewriting any code. + + \sa {JSON Support in Qt}, {Data Storage} +*/ diff --git a/examples/corelib/json/savegame/game.cpp b/examples/corelib/json/savegame/game.cpp new file mode 100644 index 0000000000..a08071b208 --- /dev/null +++ b/examples/corelib/json/savegame/game.cpp @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "game.h" + +#include +#include +#include + +Game::Game() +{ +} + +const Character &Game::player() const +{ + return mPlayer; +} + +const QList &Game::levels() const { + return mLevels; +} + +//! [0] +void Game::newGame() { + mPlayer = Character(); + mPlayer.setName(QStringLiteral("Hero")); + mPlayer.setClassType(Character::Archer); + mPlayer.setLevel(15); + + mLevels.clear(); + + Level village; + QList villageNpcs; + villageNpcs.append(Character(QStringLiteral("Barry the Blacksmith"), 10, Character::Warrior)); + villageNpcs.append(Character(QStringLiteral("Terry the Trader"), 10, Character::Warrior)); + village.setNpcs(villageNpcs); + mLevels.append(village); + + Level dungeon; + QList dungeonNpcs; + dungeonNpcs.append(Character(QStringLiteral("Eric the Evil"), 20, Character::Mage)); + dungeonNpcs.append(Character(QStringLiteral("Eric's Sidekick #1"), 5, Character::Warrior)); + dungeonNpcs.append(Character(QStringLiteral("Eric's Sidekick #2"), 5, Character::Warrior)); + dungeon.setNpcs(dungeonNpcs); + mLevels.append(dungeon); +} +//! [0] + +//! [3] +bool Game::loadGame(Game::SaveFormat saveFormat) +{ + QFile loadFile(saveFormat == Json + ? QStringLiteral("save.json") + : QStringLiteral("save.dat")); + + if (!loadFile.open(QIODevice::ReadOnly)) { + qWarning("Couldn't open save file."); + return false; + } + + QByteArray saveData = loadFile.readAll(); + + QJsonDocument loadDoc(saveFormat == Json + ? QJsonDocument::fromJson(saveData) + : QJsonDocument::fromBinaryData(saveData)); + + read(loadDoc.object()); + + return true; +} +//! [3] + +//! [4] +bool Game::saveGame(Game::SaveFormat saveFormat) const +{ + QFile saveFile(saveFormat == Json + ? QStringLiteral("save.json") + : QStringLiteral("save.dat")); + + if (!saveFile.open(QIODevice::WriteOnly)) { + qWarning("Couldn't open save file."); + return false; + } + + QJsonObject gameObject; + write(gameObject); + QJsonDocument saveDoc(gameObject); + saveFile.write(saveFormat == Json + ? saveDoc.toJson() + : saveDoc.toBinaryData()); + + return true; +} +//! [4] + +//! [1] +void Game::read(const QJsonObject &json) +{ + mPlayer.read(json["player"].toObject()); + + mLevels.clear(); + QJsonArray levelArray = json["levels"].toArray(); + for (int levelIndex = 0; levelIndex < levelArray.size(); ++levelIndex) { + QJsonObject levelObject = levelArray[levelIndex].toObject(); + Level level; + level.read(levelObject); + mLevels.append(level); + } +} +//! [1] + +//! [2] +void Game::write(QJsonObject &json) const +{ + QJsonObject playerObject; + mPlayer.write(playerObject); + json["player"] = playerObject; + + QJsonArray levelArray; + foreach (const Level level, mLevels) { + QJsonObject levelObject; + level.write(levelObject); + levelArray.append(levelObject); + } + json["levels"] = levelArray; +} +//! [2] diff --git a/examples/corelib/json/savegame/game.h b/examples/corelib/json/savegame/game.h new file mode 100644 index 0000000000..9216a373d1 --- /dev/null +++ b/examples/corelib/json/savegame/game.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef GAME_H +#define GAME_H + +#include +#include + +#include "character.h" +#include "level.h" + +//! [0] +class Game +{ +public: + Game(); + + enum SaveFormat { + Json, Binary + }; + + const Character &player() const; + const QList &levels() const; + + void newGame(); + bool loadGame(SaveFormat saveFormat); + bool saveGame(SaveFormat saveFormat) const; + + void read(const QJsonObject &json); + void write(QJsonObject &json) const; +private: + Character mPlayer; + QList mLevels; +}; +//! [0] + +#endif // GAME_H diff --git a/examples/corelib/json/savegame/level.cpp b/examples/corelib/json/savegame/level.cpp new file mode 100644 index 0000000000..afbd3e0fa0 --- /dev/null +++ b/examples/corelib/json/savegame/level.cpp @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "level.h" + +#include + +Level::Level() { +} + +const QList &Level::npcs() const +{ + return mNpcs; +} + +void Level::setNpcs(const QList &npcs) +{ + mNpcs = npcs; +} + +//! [0] +void Level::read(const QJsonObject &json) +{ + mNpcs.clear(); + QJsonArray npcArray = json["npcs"].toArray(); + for (int npcIndex = 0; npcIndex < npcArray.size(); ++npcIndex) { + QJsonObject npcObject = npcArray[npcIndex].toObject(); + Character npc; + npc.read(npcObject); + mNpcs.append(npc); + } +} +//! [0] + +//! [1] +void Level::write(QJsonObject &json) const +{ + QJsonArray npcArray; + foreach (const Character npc, mNpcs) { + QJsonObject npcObject; + npc.write(npcObject); + npcArray.append(npcObject); + } + json["npcs"] = npcArray; +} +//! [1] diff --git a/examples/corelib/json/savegame/level.h b/examples/corelib/json/savegame/level.h new file mode 100644 index 0000000000..6cdf508c87 --- /dev/null +++ b/examples/corelib/json/savegame/level.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef LEVEL_H +#define LEVEL_H + +#include +#include + +#include "character.h" + +//! [0] +class Level +{ +public: + Level(); + + const QList &npcs() const; + void setNpcs(const QList &npcs); + + void read(const QJsonObject &json); + void write(QJsonObject &json) const; +private: + QList mNpcs; +}; +//! [0] + +#endif // LEVEL_H diff --git a/examples/corelib/json/savegame/main.cpp b/examples/corelib/json/savegame/main.cpp new file mode 100644 index 0000000000..1b44306bb0 --- /dev/null +++ b/examples/corelib/json/savegame/main.cpp @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "game.h" +//! [0] +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + + Game game; + game.newGame(); + // Game is played; changes are made... +//! [0] +//! [1] + if (!game.saveGame(Game::Json)) + return 1; + + if (!game.saveGame(Game::Binary)) + return 1; + + Game fromJsonGame; + if (!fromJsonGame.loadGame(Game::Json)) + return 1; + + Game fromBinaryGame; + if (!fromBinaryGame.loadGame(Game::Binary)) + return 1; + + return 0; +} +//! [1] diff --git a/examples/corelib/json/savegame/savegame.pro b/examples/corelib/json/savegame/savegame.pro new file mode 100644 index 0000000000..6706444506 --- /dev/null +++ b/examples/corelib/json/savegame/savegame.pro @@ -0,0 +1,22 @@ +QT += core +QT -= gui + +TARGET = savegame +CONFIG += console +CONFIG -= app_bundle + +TEMPLATE = app + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/corelib/json/savegame +INSTALLS += target + +SOURCES += main.cpp \ + character.cpp \ + game.cpp \ + level.cpp + +HEADERS += \ + character.h \ + game.h \ + level.h diff --git a/examples/corelib/threads/README b/examples/corelib/threads/README new file mode 100644 index 0000000000..6c20844564 --- /dev/null +++ b/examples/corelib/threads/README @@ -0,0 +1,7 @@ +This folder contains examples for the use of the threading-related classes +in Qt Core. For examples using the higher-level Qt Concurrent module, +check out the "qtconcurrent" folder instead. + +Documentation for examples can be found via the Examples and Tutorials link +in the main Qt documentation. The examples and their documentation can also +be opened from the Examples tab of Qt Creator's Welcome mode. diff --git a/examples/corelib/threads/doc/images/mandelbrot-example.png b/examples/corelib/threads/doc/images/mandelbrot-example.png new file mode 100644 index 0000000000..f5817834e1 Binary files /dev/null and b/examples/corelib/threads/doc/images/mandelbrot-example.png differ diff --git a/examples/corelib/threads/doc/images/mandelbrot_scroll1.png b/examples/corelib/threads/doc/images/mandelbrot_scroll1.png new file mode 100644 index 0000000000..b800455821 Binary files /dev/null and b/examples/corelib/threads/doc/images/mandelbrot_scroll1.png differ diff --git a/examples/corelib/threads/doc/images/mandelbrot_scroll2.png b/examples/corelib/threads/doc/images/mandelbrot_scroll2.png new file mode 100644 index 0000000000..704ea0a7c1 Binary files /dev/null and b/examples/corelib/threads/doc/images/mandelbrot_scroll2.png differ diff --git a/examples/corelib/threads/doc/images/mandelbrot_scroll3.png b/examples/corelib/threads/doc/images/mandelbrot_scroll3.png new file mode 100644 index 0000000000..8b48211444 Binary files /dev/null and b/examples/corelib/threads/doc/images/mandelbrot_scroll3.png differ diff --git a/examples/corelib/threads/doc/images/mandelbrot_zoom1.png b/examples/corelib/threads/doc/images/mandelbrot_zoom1.png new file mode 100644 index 0000000000..30190e44eb Binary files /dev/null and b/examples/corelib/threads/doc/images/mandelbrot_zoom1.png differ diff --git a/examples/corelib/threads/doc/images/mandelbrot_zoom2.png b/examples/corelib/threads/doc/images/mandelbrot_zoom2.png new file mode 100644 index 0000000000..148ac777b8 Binary files /dev/null and b/examples/corelib/threads/doc/images/mandelbrot_zoom2.png differ diff --git a/examples/corelib/threads/doc/images/mandelbrot_zoom3.png b/examples/corelib/threads/doc/images/mandelbrot_zoom3.png new file mode 100644 index 0000000000..a669f4b5fe Binary files /dev/null and b/examples/corelib/threads/doc/images/mandelbrot_zoom3.png differ diff --git a/examples/corelib/threads/doc/images/queuedcustomtype-example.png b/examples/corelib/threads/doc/images/queuedcustomtype-example.png new file mode 100644 index 0000000000..4399b631d7 Binary files /dev/null and b/examples/corelib/threads/doc/images/queuedcustomtype-example.png differ diff --git a/examples/corelib/threads/doc/src/mandelbrot.qdoc b/examples/corelib/threads/doc/src/mandelbrot.qdoc new file mode 100644 index 0000000000..75d424e6a4 --- /dev/null +++ b/examples/corelib/threads/doc/src/mandelbrot.qdoc @@ -0,0 +1,370 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example threads/mandelbrot + \title Mandelbrot Example + \ingroup qtconcurrent-mtexamples + + \brief The Mandelbrot example demonstrates multi-thread programming + using Qt. It shows how to use a worker thread to + perform heavy computations without blocking the main thread's + event loop. + + \image mandelbrot-example.png Screenshot of the Mandelbrot example + + The heavy computation here is the Mandelbrot set, probably the + world's most famous fractal. These days, while sophisticated + programs such as \l{http://xaos.sourceforge.net/}{XaoS} that provide real-time zooming in the + Mandelbrot set, the standard Mandelbrot algorithm is just slow + enough for our purposes. + + In real life, the approach described here is applicable to a + large set of problems, including synchronous network I/O and + database access, where the user interface must remain responsive + while some heavy operation is taking place. The \l + {Blocking Fortune Client Example} shows the same principle at + work in a TCP client. + + The Mandelbrot application supports zooming and scrolling using + the mouse or the keyboard. To avoid freezing the main thread's + event loop (and, as a consequence, the application's user + interface), we put all the fractal computation in a separate + worker thread. The thread emits a signal when it is done + rendering the fractal. + + During the time where the worker thread is recomputing the + fractal to reflect the new zoom factor position, the main thread + simply scales the previously rendered pixmap to provide immediate + feedback. The result doesn't look as good as what the worker + thread eventually ends up providing, but at least it makes the + application more responsive. The sequence of screenshots below + shows the original image, the scaled image, and the rerendered + image. + + \table + \row + \li \inlineimage mandelbrot_zoom1.png + \li \inlineimage mandelbrot_zoom2.png + \li \inlineimage mandelbrot_zoom3.png + \endtable + + Similarly, when the user scrolls, the previous pixmap is scrolled + immediately, revealing unpainted areas beyond the edge of the + pixmap, while the image is rendered by the worker thread. + + \table + \row + \li \inlineimage mandelbrot_scroll1.png + \li \inlineimage mandelbrot_scroll2.png + \li \inlineimage mandelbrot_scroll3.png + \endtable + + The application consists of two classes: + + \list + \li \c RenderThread is a QThread subclass that renders + the Mandelbrot set. + \li \c MandelbrotWidget is a QWidget subclass that shows the + Mandelbrot set on screen and lets the user zoom and scroll. + \endlist + + If you are not already familiar with Qt's thread support, we + recommend that you start by reading the \l{Thread Support in Qt} + overview. + + \section1 RenderThread Class Definition + + We'll start with the definition of the \c RenderThread class: + + \snippet threads/mandelbrot/renderthread.h 0 + + The class inherits QThread so that it gains the ability to run in + a separate thread. Apart from the constructor and destructor, \c + render() is the only public function. Whenever the thread is done + rendering an image, it emits the \c renderedImage() signal. + + The protected \c run() function is reimplemented from QThread. It + is automatically called when the thread is started. + + In the \c private section, we have a QMutex, a QWaitCondition, + and a few other data members. The mutex protects the other data + member. + + \section1 RenderThread Class Implementation + + \snippet threads/mandelbrot/renderthread.cpp 0 + + In the constructor, we initialize the \c restart and \c abort + variables to \c false. These variables control the flow of the \c + run() function. + + We also initialize the \c colormap array, which contains a series + of RGB colors. + + \snippet threads/mandelbrot/renderthread.cpp 1 + + The destructor can be called at any point while the thread is + active. We set \c abort to \c true to tell \c run() to stop + running as soon as possible. We also call + QWaitCondition::wakeOne() to wake up the thread if it's sleeping. + (As we will see when we review \c run(), the thread is put to + sleep when it has nothing to do.) + + The important thing to notice here is that \c run() is executed + in its own thread (the worker thread), whereas the \c + RenderThread constructor and destructor (as well as the \c + render() function) are called by the thread that created the + worker thread. Therefore, we need a mutex to protect accesses to + the \c abort and \c condition variables, which might be accessed + at any time by \c run(). + + At the end of the destructor, we call QThread::wait() to wait + until \c run() has exited before the base class destructor is + invoked. + + \snippet threads/mandelbrot/renderthread.cpp 2 + + The \c render() function is called by the \c MandelbrotWidget + whenever it needs to generate a new image of the Mandelbrot set. + The \c centerX, \c centerY, and \c scaleFactor parameters specify + the portion of the fractal to render; \c resultSize specifies the + size of the resulting QImage. + + The function stores the parameters in member variables. If the + thread isn't already running, it starts it; otherwise, it sets \c + restart to \c true (telling \c run() to stop any unfinished + computation and start again with the new parameters) and wakes up + the thread, which might be sleeping. + + \snippet threads/mandelbrot/renderthread.cpp 3 + + \c run() is quite a big function, so we'll break it down into + parts. + + The function body is an infinite loop which starts by storing the + rendering parameters in local variables. As usual, we protect + accesses to the member variables using the class's mutex. Storing + the member variables in local variables allows us to minimize the + amout of code that needs to be protected by a mutex. This ensures + that the main thread will never have to block for too long when + it needs to access \c{RenderThread}'s member variables (e.g., in + \c render()). + + The \c forever keyword is, like \c foreach, a Qt pseudo-keyword. + + \snippet threads/mandelbrot/renderthread.cpp 4 + \snippet threads/mandelbrot/renderthread.cpp 5 + \snippet threads/mandelbrot/renderthread.cpp 6 + \snippet threads/mandelbrot/renderthread.cpp 7 + + Then comes the core of the algorithm. Instead of trying to create + a perfect Mandelbrot set image, we do multiple passes and + generate more and more precise (and computationally expensive) + approximations of the fractal. + + If we discover inside the loop that \c restart has been set to \c + true (by \c render()), we break out of the loop immediately, so + that the control quickly returns to the very top of the outer + loop (the \c forever loop) and we fetch the new rendering + parameters. Similarly, if we discover that \c abort has been set + to \c true (by the \c RenderThread destructor), we return from + the function immediately, terminating the thread. + + The core algorithm is beyond the scope of this tutorial. + + \snippet threads/mandelbrot/renderthread.cpp 8 + \snippet threads/mandelbrot/renderthread.cpp 9 + + Once we're done with all the iterations, we call + QWaitCondition::wait() to put the thread to sleep by calling, + unless \c restart is \c true. There's no use in keeping a worker + thread looping indefinitely while there's nothing to do. + + \snippet threads/mandelbrot/renderthread.cpp 10 + + The \c rgbFromWaveLength() function is a helper function that + converts a wave length to a RGB value compatible with 32-bit + \l{QImage}s. It is called from the constructor to initialize the + \c colormap array with pleasing colors. + + \section1 MandelbrotWidget Class Definition + + The \c MandelbrotWidget class uses \c RenderThread to draw the + Mandelbrot set on screen. Here's the class definition: + + \snippet threads/mandelbrot/mandelbrotwidget.h 0 + + The widget reimplements many event handlers from QWidget. In + addition, it has an \c updatePixmap() slot that we'll connect to + the worker thread's \c renderedImage() signal to update the + display whenever we receive new data from the thread. + + Among the private variables, we have \c thread of type \c + RenderThread and \c pixmap, which contains the last rendered + image. + + \section1 MandelbrotWidget Class Implementation + + \snippet threads/mandelbrot/mandelbrotwidget.cpp 0 + + The implementation starts with a few contants that we'll need + later on. + + \snippet threads/mandelbrot/mandelbrotwidget.cpp 1 + + The interesting part of the constructor is the + qRegisterMetaType() and QObject::connect() calls. Let's start + with the \l{QObject::connect()}{connect()} call. + + Although it looks like a standard signal-slot connection between + two \l{QObject}s, because the signal is emitted in a different + thread than the receiver lives in, the connection is effectively a + \l{Qt::QueuedConnection}{queued connection}. These connections are + asynchronous (i.e., non-blocking), meaning that the slot will be + called at some point after the \c emit statement. What's more, the + slot will be invoked in the thread in which the receiver lives. + Here, the signal is emitted in the worker thread, and the slot is + executed in the GUI thread when control returns to the event loop. + + With queued connections, Qt must store a copy of the arguments + that were passed to the signal so that it can pass them to the + slot later on. Qt knows how to take of copy of many C++ and Qt + types, but QImage isn't one of them. We must therefore call the + template function qRegisterMetaType() before we can use QImage + as parameter in queued connections. + + \snippet threads/mandelbrot/mandelbrotwidget.cpp 2 + \snippet threads/mandelbrot/mandelbrotwidget.cpp 3 + \snippet threads/mandelbrot/mandelbrotwidget.cpp 4 + + In \l{QWidget::paintEvent()}{paintEvent()}, we start by filling + the background with black. If we have nothing yet to paint (\c + pixmap is null), we print a message on the widget asking the user + to be patient and return from the function immediately. + + \snippet threads/mandelbrot/mandelbrotwidget.cpp 5 + \snippet threads/mandelbrot/mandelbrotwidget.cpp 6 + \snippet threads/mandelbrot/mandelbrotwidget.cpp 7 + \snippet threads/mandelbrot/mandelbrotwidget.cpp 8 + + If the pixmap has the right scale factor, we draw the pixmap directly onto + the widget. Otherwise, we scale and translate the \l{Coordinate + System}{coordinate system} before we draw the pixmap. By reverse mapping + the widget's rectangle using the scaled painter matrix, we also make sure + that only the exposed areas of the pixmap are drawn. The calls to + QPainter::save() and QPainter::restore() make sure that any painting + performed afterwards uses the standard coordinate system. + + \snippet threads/mandelbrot/mandelbrotwidget.cpp 9 + + At the end of the paint event handler, we draw a text string and + a semi-transparent rectangle on top of the fractal. + + \snippet threads/mandelbrot/mandelbrotwidget.cpp 10 + + Whenever the user resizes the widget, we call \c render() to + start generating a new image, with the same \c centerX, \c + centerY, and \c curScale parameters but with the new widget size. + + Notice that we rely on \c resizeEvent() being automatically + called by Qt when the widget is shown the first time to generate + the image the very first time. + + \snippet threads/mandelbrot/mandelbrotwidget.cpp 11 + + The key press event handler provides a few keyboard bindings for + the benefit of users who don't have a mouse. The \c zoom() and \c + scroll() functions will be covered later. + + \snippet threads/mandelbrot/mandelbrotwidget.cpp 12 + + The wheel event handler is reimplemented to make the mouse wheel + control the zoom level. QWheelEvent::delta() returns the angle of + the wheel mouse movement, in eights of a degree. For most mice, + one wheel step corresponds to 15 degrees. We find out how many + mouse steps we have and determine the zoom factor in consequence. + For example, if we have two wheel steps in the positive direction + (i.e., +30 degrees), the zoom factor becomes \c ZoomInFactor + to the second power, i.e. 0.8 * 0.8 = 0.64. + + \snippet threads/mandelbrot/mandelbrotwidget.cpp 13 + + When the user presses the left mouse button, we store the mouse + pointer position in \c lastDragPos. + + \snippet threads/mandelbrot/mandelbrotwidget.cpp 14 + + When the user moves the mouse pointer while the left mouse button + is pressed, we adjust \c pixmapOffset to paint the pixmap at a + shifted position and call QWidget::update() to force a repaint. + + \snippet threads/mandelbrot/mandelbrotwidget.cpp 15 + + When the left mouse button is released, we update \c pixmapOffset + just like we did on a mouse move and we reset \c lastDragPos to a + default value. Then, we call \c scroll() to render a new image + for the new position. (Adjusting \c pixmapOffset isn't sufficient + because areas revealed when dragging the pixmap are drawn in + black.) + + \snippet threads/mandelbrot/mandelbrotwidget.cpp 16 + + The \c updatePixmap() slot is invoked when the worker thread has + finished rendering an image. We start by checking whether a drag + is in effect and do nothing in that case. In the normal case, we + store the image in \c pixmap and reinitialize some of the other + members. At the end, we call QWidget::update() to refresh the + display. + + At this point, you might wonder why we use a QImage for the + parameter and a QPixmap for the data member. Why not stick to one + type? The reason is that QImage is the only class that supports + direct pixel manipulation, which we need in the worker thread. On + the other hand, before an image can be drawn on screen, it must + be converted into a pixmap. It's better to do the conversion once + and for all here, rather than in \c paintEvent(). + + \snippet threads/mandelbrot/mandelbrotwidget.cpp 17 + + In \c zoom(), we recompute \c curScale. Then we call + QWidget::update() to draw a scaled pixmap, and we ask the worker + thread to render a new image corresponding to the new \c curScale + value. + + \snippet threads/mandelbrot/mandelbrotwidget.cpp 18 + + \c scroll() is similar to \c zoom(), except that the affected + parameters are \c centerX and \c centerY. + + \section1 The main() Function + + The application's multithreaded nature has no impact on its \c + main() function, which is as simple as usual: + + \snippet threads/mandelbrot/main.cpp 0 +*/ diff --git a/examples/corelib/threads/doc/src/queuedcustomtype.qdoc b/examples/corelib/threads/doc/src/queuedcustomtype.qdoc new file mode 100644 index 0000000000..cca68b4513 --- /dev/null +++ b/examples/corelib/threads/doc/src/queuedcustomtype.qdoc @@ -0,0 +1,166 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example threads/queuedcustomtype + \title Queued Custom Type Example + \brief Demonstrates multi-thread programming using Qt + \ingroup qtconcurrent-mtexamples + + \brief The Queued Custom Type example shows how to send custom types between + threads with queued signals and slots. + + \image queuedcustomtype-example.png + + Contents: + + \tableofcontents + + \section1 Overview + + In the \l{Custom Type Example}, we showed how to integrate custom types with + the meta-object system, enabling them to be stored in QVariant objects, written + out in debugging information and used in signal-slot communication. + + In this example, we create a new value class, \c Block, and register it + with the meta-object system to enable us to send instances of it between + threads using queued signals and slots. + + \section1 The Block Class + + The \c Block class is similar to the \c Message class described in the + \l{Custom Type Example}. It provides the default constructor, copy + constructor and destructor in the public section of the class that the + meta-object system requires. It describes a colored rectangle. + + \snippet threads/queuedcustomtype/block.h custom type definition and meta-type declaration + + We will still need to register it with the meta-object system at + run-time by calling the qRegisterMetaType() template function before + we make any signal-slot connections that use this type. + Even though we do not intend to use the type with QVariant in this example, + it is good practice to also declare the new type with Q_DECLARE_METATYPE(). + + The implementation of the \c Block class is trivial, so we avoid quoting + it here. + + \section1 The Window Class + + We define a simple \c Window class with a public slot that accepts a + \c Block object. The rest of the class is concerned with managing the + user interface and handling images. + + \snippet threads/queuedcustomtype/window.h Window class definition + + The \c Window class also contains a worker thread, provided by a + \c RenderThread object. This will emit signals to send \c Block objects + to the window's \c addBlock(Block) slot. + + The parts of the \c Window class that are most relevant are the constructor + and the \c addBlock(Block) slot. + + The constructor creates a thread for rendering images, sets up a user + interface containing a label and two push buttons that are connected to + slots in the same class. + + \snippet threads/queuedcustomtype/window.cpp Window constructor start + \snippet threads/queuedcustomtype/window.cpp set up widgets and connections + \snippet threads/queuedcustomtype/window.cpp connecting signal with custom type + + In the last of these connections, we connect a signal in the + \c RenderThread object to the \c addBlock(Block) slot in the window. + + \dots + \snippet threads/queuedcustomtype/window.cpp Window constructor finish + + The rest of the constructor simply sets up the layout of the window. + + The \c addBlock(Block) slot receives blocks from the rendering thread via + the signal-slot connection set up in the constructor: + + \snippet threads/queuedcustomtype/window.cpp Adding blocks to the display + + We simply paint these onto the label as they arrive. + + \section1 The RenderThread Class + + The \c RenderThread class processes an image, creating \c Block objects + and using the \c sendBlock(Block) signal to send them to other components + in the example. + + \snippet threads/queuedcustomtype/renderthread.h RenderThread class definition + + The constructor and destructor are not quoted here. These take care of + setting up the thread's internal state and cleaning up when it is destroyed. + + Processing is started with the \c processImage() function, which calls the + \c RenderThread class's reimplementation of the QThread::run() function: + + \snippet threads/queuedcustomtype/renderthread.cpp processing the image (start) + + Ignoring the details of the way the image is processed, we see that the + signal containing a block is emitted in the usual way: + + \dots + \snippet threads/queuedcustomtype/renderthread.cpp processing the image (finish) + + Each signal that is emitted will be queued and delivered later to the + window's \c addBlock(Block) slot. + + \section1 Registering the Type + + In the example's \c{main()} function, we perform the registration of the + \c Block class as a custom type with the meta-object system by calling the + qRegisterMetaType() template function: + + \snippet threads/queuedcustomtype/main.cpp main function + + This call is placed here to ensure that the type is registered before any + signal-slot connections are made that use it. + + The rest of the \c{main()} function is concerned with setting a seed for + the pseudo-random number generator, creating and showing the window, and + setting a default image. See the source code for the implementation of the + \c createImage() function. + + \section1 Further Reading + + This example showed how a custom type can be registered with the + meta-object system so that it can be used with signal-slot connections + between threads. For ordinary communication involving direct signals and + slots, it is enough to simply declare the type in the way described in the + \l{Custom Type Example}. + + In practice, both the Q_DECLARE_METATYPE() macro and the qRegisterMetaType() + template function can be used to register custom types, but + qRegisterMetaType() is only required if you need to perform signal-slot + communication or need to create and destroy objects of the custom type + at run-time. + + More information on using custom types with Qt can be found in the + \l{Creating Custom Qt Types} document. +*/ diff --git a/examples/corelib/threads/doc/src/semaphores.qdoc b/examples/corelib/threads/doc/src/semaphores.qdoc new file mode 100644 index 0000000000..0b1a2e852e --- /dev/null +++ b/examples/corelib/threads/doc/src/semaphores.qdoc @@ -0,0 +1,147 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example threads/semaphores + \title Semaphores Example + \brief Demonstrates multi-thread programming using Qt + \ingroup qtconcurrent-mtexamples + + \brief The Semaphores example shows how to use QSemaphore to control + access to a circular buffer shared by a producer thread and a + consumer thread. + + The producer writes data to the buffer until it reaches the end + of the buffer, at which point it restarts from the beginning, + overwriting existing data. The consumer thread reads the data as + it is produced and writes it to standard error. + + Semaphores make it possible to have a higher level of concurrency + than mutexes. If accesses to the buffer were guarded by a QMutex, + the consumer thread couldn't access the buffer at the same time + as the producer thread. Yet, there is no harm in having both + threads working on \e{different parts} of the buffer at the same + time. + + The example comprises two classes: \c Producer and \c Consumer. + Both inherit from QThread. The circular buffer used for + communicating between these two classes and the semaphores that + protect it are global variables. + + An alternative to using QSemaphore to solve the producer-consumer + problem is to use QWaitCondition and QMutex. This is what the + \l{Wait Conditions Example} does. + + \section1 Global Variables + + Let's start by reviewing the circular buffer and the associated + semaphores: + + \snippet threads/semaphores/semaphores.cpp 0 + + \c DataSize is the amout of data that the producer will generate. + To keep the example as simple as possible, we make it a constant. + \c BufferSize is the size of the circular buffer. It is less than + \c DataSize, meaning that at some point the producer will reach + the end of the buffer and restart from the beginning. + + To synchronize the producer and the consumer, we need two + semaphores. The \c freeBytes semaphore controls the "free" area + of the buffer (the area that the producer hasn't filled with data + yet or that the consumer has already read). The \c usedBytes + semaphore controls the "used" area of the buffer (the area that + the producer has filled but that the consumer hasn't read yet). + + Together, the semaphores ensure that the producer is never more + than \c BufferSize bytes ahead of the consumer, and that the + consumer never reads data that the producer hasn't generated yet. + + The \c freeBytes semaphore is initialized with \c BufferSize, + because initially the entire buffer is empty. The \c usedBytes + semaphore is initialized to 0 (the default value if none is + specified). + + \section1 Producer Class + + Let's review the code for the \c Producer class: + + \snippet threads/semaphores/semaphores.cpp 1 + \snippet threads/semaphores/semaphores.cpp 2 + + The producer generates \c DataSize bytes of data. Before it + writes a byte to the circular buffer, it must acquire a "free" + byte using the \c freeBytes semaphore. The QSemaphore::acquire() + call might block if the consumer hasn't kept up the pace with the + producer. + + At the end, the producer releases a byte using the \c usedBytes + semaphore. The "free" byte has successfully been transformed into + a "used" byte, ready to be read by the consumer. + + \section1 Consumer Class + + Let's now turn to the \c Consumer class: + + \snippet threads/semaphores/semaphores.cpp 3 + \snippet threads/semaphores/semaphores.cpp 4 + + The code is very similar to the producer, except that this time + we acquire a "used" byte and release a "free" byte, instead of + the opposite. + + \section1 The main() Function + + In \c main(), we create the two threads and call QThread::wait() + to ensure that both threads get time to finish before we exit: + + \snippet threads/semaphores/semaphores.cpp 5 + \snippet threads/semaphores/semaphores.cpp 6 + + So what happens when we run the program? Initially, the producer + thread is the only one that can do anything; the consumer is + blocked waiting for the \c usedBytes semaphore to be released (its + initial \l{QSemaphore::available()}{available()} count is 0). + Once the producer has put one byte in the buffer, + \c{freeBytes.available()} is \c BufferSize - 1 and + \c{usedBytes.available()} is 1. At that point, two things can + happen: Either the consumer thread takes over and reads that + byte, or the consumer gets to produce a second byte. + + The producer-consumer model presented in this example makes it + possible to write highly concurrent multithreaded applications. + On a multiprocessor machine, the program is potentially up to + twice as fast as the equivalent mutex-based program, since the + two threads can be active at the same time on different parts of + the buffer. + + Be aware though that these benefits aren't always realized. + Acquiring and releasing a QSemaphore has a cost. In practice, it + would probably be worthwhile to divide the buffer into chunks and + to operate on chunks instead of individual bytes. The buffer size + is also a parameter that must be selected carefully, based on + experimentation. +*/ diff --git a/examples/corelib/threads/doc/src/waitconditions.qdoc b/examples/corelib/threads/doc/src/waitconditions.qdoc new file mode 100644 index 0000000000..aff6997b55 --- /dev/null +++ b/examples/corelib/threads/doc/src/waitconditions.qdoc @@ -0,0 +1,154 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example threads/waitconditions + \title Wait Conditions Example + \brief Demonstrates multi-thread programming using Qt + \ingroup qtconcurrent-mtexamples + + \brief The Wait Conditions example shows how to use QWaitCondition and + QMutex to control access to a circular buffer shared by a + producer thread and a consumer thread. + + The producer writes data to the buffer until it reaches the end + of the buffer, at which point it restarts from the beginning, + overwriting existing data. The consumer thread reads the data as + it is produced and writes it to standard error. + + Wait conditions make it possible to have a higher level of + concurrency than what is possible with mutexes alone. If accesses + to the buffer were simply guarded by a QMutex, the consumer + thread couldn't access the buffer at the same time as the + producer thread. Yet, there is no harm in having both threads + working on \e{different parts} of the buffer at the same time. + + The example comprises two classes: \c Producer and \c Consumer. + Both inherit from QThread. The circular buffer used for + communicating between these two classes and the synchronization + tools that protect it are global variables. + + An alternative to using QWaitCondition and QMutex to solve the + producer-consumer problem is to use QSemaphore. This is what the + \l{Semaphores Example} does. + + \section1 Global Variables + + Let's start by reviewing the circular buffer and the associated + synchronization tools: + + \snippet threads/waitconditions/waitconditions.cpp 0 + + \c DataSize is the amount of data that the producer will generate. + To keep the example as simple as possible, we make it a constant. + \c BufferSize is the size of the circular buffer. It is less than + \c DataSize, meaning that at some point the producer will reach + the end of the buffer and restart from the beginning. + + To synchronize the producer and the consumer, we need two wait + conditions and one mutex. The \c bufferNotEmpty condition is + signalled when the producer has generated some data, telling the + consumer that it can start reading it. The \c bufferNotFull + condition is signalled when the consumer has read some data, + telling the producer that it can generate more. The \c numUsedBytes + is the number of bytes in the buffer that contain data. + + Together, the wait conditions, the mutex, and the \c numUsedBytes + counter ensure that the producer is never more than \c BufferSize + bytes ahead of the consumer, and that the consumer never reads + data that the producer hasn't generated yet. + + \section1 Producer Class + + Let's review the code for the \c Producer class: + + \snippet threads/waitconditions/waitconditions.cpp 1 + \snippet threads/waitconditions/waitconditions.cpp 2 + + The producer generates \c DataSize bytes of data. Before it + writes a byte to the circular buffer, it must first check whether + the buffer is full (i.e., \c numUsedBytes equals \c BufferSize). + If the buffer is full, the thread waits on the \c bufferNotFull + condition. + + At the end, the producer increments \c numUsedBytes and signalls + that the condition \c bufferNotEmpty is true, since \c + numUsedBytes is necessarily greater than 0. + + We guard all accesses to the \c numUsedBytes variable with a + mutex. In addition, the QWaitCondition::wait() function accepts a + mutex as its argument. This mutex is unlocked before the thread + is put to sleep and locked when the thread wakes up. Furthermore, + the transition from the locked state to the wait state is atomic, + to prevent race conditions from occurring. + + \section1 Consumer Class + + Let's turn to the \c Consumer class: + + \snippet threads/waitconditions/waitconditions.cpp 3 + \snippet threads/waitconditions/waitconditions.cpp 4 + + The code is very similar to the producer. Before we read the + byte, we check whether the buffer is empty (\c numUsedBytes is 0) + instead of whether it's full and wait on the \c bufferNotEmpty + condition if it's empty. After we've read the byte, we decrement + \c numUsedBytes (instead of incrementing it), and we signal the + \c bufferNotFull condition (instead of the \c bufferNotEmpty + condition). + + \section1 The main() Function + + In \c main(), we create the two threads and call QThread::wait() + to ensure that both threads get time to finish before we exit: + + \snippet threads/waitconditions/waitconditions.cpp 5 + \snippet threads/waitconditions/waitconditions.cpp 6 + + So what happens when we run the program? Initially, the producer + thread is the only one that can do anything; the consumer is + blocked waiting for the \c bufferNotEmpty condition to be + signalled (\c numUsedBytes is 0). Once the producer has put one + byte in the buffer, \c numUsedBytes is \c BufferSize - 1 and the + \c bufferNotEmpty condition is signalled. At that point, two + things can happen: Either the consumer thread takes over and + reads that byte, or the consumer gets to produce a second byte. + + The producer-consumer model presented in this example makes it + possible to write highly concurrent multithreaded applications. + On a multiprocessor machine, the program is potentially up to + twice as fast as the equivalent mutex-based program, since the + two threads can be active at the same time on different parts of + the buffer. + + Be aware though that these benefits aren't always realized. + Locking and unlocking a QMutex has a cost. In practice, it would + probably be worthwhile to divide the buffer into chunks and to + operate on chunks instead of individual bytes. The buffer size is + also a parameter that must be selected carefully, based on + experimentation. +*/ diff --git a/examples/corelib/threads/mandelbrot/main.cpp b/examples/corelib/threads/mandelbrot/main.cpp new file mode 100644 index 0000000000..8334d94f9c --- /dev/null +++ b/examples/corelib/threads/mandelbrot/main.cpp @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mandelbrotwidget.h" + +#include + +//! [0] +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + MandelbrotWidget widget; + widget.show(); + return app.exec(); +} +//! [0] diff --git a/examples/corelib/threads/mandelbrot/mandelbrot.pro b/examples/corelib/threads/mandelbrot/mandelbrot.pro new file mode 100644 index 0000000000..5a01a405f2 --- /dev/null +++ b/examples/corelib/threads/mandelbrot/mandelbrot.pro @@ -0,0 +1,13 @@ +QT += widgets + +HEADERS = mandelbrotwidget.h \ + renderthread.h +SOURCES = main.cpp \ + mandelbrotwidget.cpp \ + renderthread.cpp + +unix:!mac:!vxworks:!integrity:LIBS += -lm + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/corelib/threads/mandelbrot +INSTALLS += target diff --git a/examples/corelib/threads/mandelbrot/mandelbrotwidget.cpp b/examples/corelib/threads/mandelbrot/mandelbrotwidget.cpp new file mode 100644 index 0000000000..633d4a1ec5 --- /dev/null +++ b/examples/corelib/threads/mandelbrot/mandelbrotwidget.cpp @@ -0,0 +1,239 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#include + +#include "mandelbrotwidget.h" + + +//! [0] +const double DefaultCenterX = -0.637011f; +const double DefaultCenterY = -0.0395159f; +const double DefaultScale = 0.00403897f; + +const double ZoomInFactor = 0.8f; +const double ZoomOutFactor = 1 / ZoomInFactor; +const int ScrollStep = 20; +//! [0] + +//! [1] +MandelbrotWidget::MandelbrotWidget(QWidget *parent) + : QWidget(parent) +{ + centerX = DefaultCenterX; + centerY = DefaultCenterY; + pixmapScale = DefaultScale; + curScale = DefaultScale; + + connect(&thread, SIGNAL(renderedImage(QImage,double)), this, SLOT(updatePixmap(QImage,double))); + + setWindowTitle(tr("Mandelbrot")); +#ifndef QT_NO_CURSOR + setCursor(Qt::CrossCursor); +#endif + resize(550, 400); + +} +//! [1] + +//! [2] +void MandelbrotWidget::paintEvent(QPaintEvent * /* event */) +{ + QPainter painter(this); + painter.fillRect(rect(), Qt::black); + + if (pixmap.isNull()) { + painter.setPen(Qt::white); + painter.drawText(rect(), Qt::AlignCenter, tr("Rendering initial image, please wait...")); +//! [2] //! [3] + return; +//! [3] //! [4] + } +//! [4] + +//! [5] + if (curScale == pixmapScale) { +//! [5] //! [6] + painter.drawPixmap(pixmapOffset, pixmap); +//! [6] //! [7] + } else { +//! [7] //! [8] + double scaleFactor = pixmapScale / curScale; + int newWidth = int(pixmap.width() * scaleFactor); + int newHeight = int(pixmap.height() * scaleFactor); + int newX = pixmapOffset.x() + (pixmap.width() - newWidth) / 2; + int newY = pixmapOffset.y() + (pixmap.height() - newHeight) / 2; + + painter.save(); + painter.translate(newX, newY); + painter.scale(scaleFactor, scaleFactor); + QRectF exposed = painter.matrix().inverted().mapRect(rect()).adjusted(-1, -1, 1, 1); + painter.drawPixmap(exposed, pixmap, exposed); + painter.restore(); + } +//! [8] //! [9] + + QString text = tr("Use mouse wheel or the '+' and '-' keys to zoom. " + "Press and hold left mouse button to scroll."); + QFontMetrics metrics = painter.fontMetrics(); + int textWidth = metrics.width(text); + + painter.setPen(Qt::NoPen); + painter.setBrush(QColor(0, 0, 0, 127)); + painter.drawRect((width() - textWidth) / 2 - 5, 0, textWidth + 10, metrics.lineSpacing() + 5); + painter.setPen(Qt::white); + painter.drawText((width() - textWidth) / 2, metrics.leading() + metrics.ascent(), text); +} +//! [9] + +//! [10] +void MandelbrotWidget::resizeEvent(QResizeEvent * /* event */) +{ + thread.render(centerX, centerY, curScale, size()); +} +//! [10] + +//! [11] +void MandelbrotWidget::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Plus: + zoom(ZoomInFactor); + break; + case Qt::Key_Minus: + zoom(ZoomOutFactor); + break; + case Qt::Key_Left: + scroll(-ScrollStep, 0); + break; + case Qt::Key_Right: + scroll(+ScrollStep, 0); + break; + case Qt::Key_Down: + scroll(0, -ScrollStep); + break; + case Qt::Key_Up: + scroll(0, +ScrollStep); + break; + default: + QWidget::keyPressEvent(event); + } +} +//! [11] + +#ifndef QT_NO_WHEELEVENT +//! [12] +void MandelbrotWidget::wheelEvent(QWheelEvent *event) +{ + int numDegrees = event->delta() / 8; + double numSteps = numDegrees / 15.0f; + zoom(pow(ZoomInFactor, numSteps)); +} +//! [12] +#endif + +//! [13] +void MandelbrotWidget::mousePressEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) + lastDragPos = event->pos(); +} +//! [13] + +//! [14] +void MandelbrotWidget::mouseMoveEvent(QMouseEvent *event) +{ + if (event->buttons() & Qt::LeftButton) { + pixmapOffset += event->pos() - lastDragPos; + lastDragPos = event->pos(); + update(); + } +} +//! [14] + +//! [15] +void MandelbrotWidget::mouseReleaseEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) { + pixmapOffset += event->pos() - lastDragPos; + lastDragPos = QPoint(); + + int deltaX = (width() - pixmap.width()) / 2 - pixmapOffset.x(); + int deltaY = (height() - pixmap.height()) / 2 - pixmapOffset.y(); + scroll(deltaX, deltaY); + } +} +//! [15] + +//! [16] +void MandelbrotWidget::updatePixmap(const QImage &image, double scaleFactor) +{ + if (!lastDragPos.isNull()) + return; + + pixmap = QPixmap::fromImage(image); + pixmapOffset = QPoint(); + lastDragPos = QPoint(); + pixmapScale = scaleFactor; + update(); +} +//! [16] + +//! [17] +void MandelbrotWidget::zoom(double zoomFactor) +{ + curScale *= zoomFactor; + update(); + thread.render(centerX, centerY, curScale, size()); +} +//! [17] + +//! [18] +void MandelbrotWidget::scroll(int deltaX, int deltaY) +{ + centerX += deltaX * curScale; + centerY += deltaY * curScale; + update(); + thread.render(centerX, centerY, curScale, size()); +} +//! [18] diff --git a/examples/corelib/threads/mandelbrot/mandelbrotwidget.h b/examples/corelib/threads/mandelbrot/mandelbrotwidget.h new file mode 100644 index 0000000000..183edf2e26 --- /dev/null +++ b/examples/corelib/threads/mandelbrot/mandelbrotwidget.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MANDELBROTWIDGET_H +#define MANDELBROTWIDGET_H + +#include +#include +#include "renderthread.h" + + +//! [0] +class MandelbrotWidget : public QWidget +{ + Q_OBJECT + +public: + MandelbrotWidget(QWidget *parent = 0); + +protected: + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; + void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; +#ifndef QT_NO_WHEELEVENT + void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; +#endif + void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + +private slots: + void updatePixmap(const QImage &image, double scaleFactor); + void zoom(double zoomFactor); + +private: + void scroll(int deltaX, int deltaY); + + RenderThread thread; + QPixmap pixmap; + QPoint pixmapOffset; + QPoint lastDragPos; + double centerX; + double centerY; + double pixmapScale; + double curScale; +}; +//! [0] + +#endif // MANDELBROTWIDGET_H diff --git a/examples/corelib/threads/mandelbrot/renderthread.cpp b/examples/corelib/threads/mandelbrot/renderthread.cpp new file mode 100644 index 0000000000..5779c65c9c --- /dev/null +++ b/examples/corelib/threads/mandelbrot/renderthread.cpp @@ -0,0 +1,215 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "renderthread.h" + +#include + +#include + +//! [0] +RenderThread::RenderThread(QObject *parent) + : QThread(parent) +{ + restart = false; + abort = false; + + for (int i = 0; i < ColormapSize; ++i) + colormap[i] = rgbFromWaveLength(380.0 + (i * 400.0 / ColormapSize)); +} +//! [0] + +//! [1] +RenderThread::~RenderThread() +{ + mutex.lock(); + abort = true; + condition.wakeOne(); + mutex.unlock(); + + wait(); +} +//! [1] + +//! [2] +void RenderThread::render(double centerX, double centerY, double scaleFactor, + QSize resultSize) +{ + QMutexLocker locker(&mutex); + + this->centerX = centerX; + this->centerY = centerY; + this->scaleFactor = scaleFactor; + this->resultSize = resultSize; + + if (!isRunning()) { + start(LowPriority); + } else { + restart = true; + condition.wakeOne(); + } +} +//! [2] + +//! [3] +void RenderThread::run() +{ + forever { + mutex.lock(); + QSize resultSize = this->resultSize; + double scaleFactor = this->scaleFactor; + double centerX = this->centerX; + double centerY = this->centerY; + mutex.unlock(); +//! [3] + +//! [4] + int halfWidth = resultSize.width() / 2; +//! [4] //! [5] + int halfHeight = resultSize.height() / 2; + QImage image(resultSize, QImage::Format_RGB32); + + const int NumPasses = 8; + int pass = 0; + while (pass < NumPasses) { + const int MaxIterations = (1 << (2 * pass + 6)) + 32; + const int Limit = 4; + bool allBlack = true; + + for (int y = -halfHeight; y < halfHeight; ++y) { + if (restart) + break; + if (abort) + return; + + uint *scanLine = + reinterpret_cast(image.scanLine(y + halfHeight)); + double ay = centerY + (y * scaleFactor); + + for (int x = -halfWidth; x < halfWidth; ++x) { + double ax = centerX + (x * scaleFactor); + double a1 = ax; + double b1 = ay; + int numIterations = 0; + + do { + ++numIterations; + double a2 = (a1 * a1) - (b1 * b1) + ax; + double b2 = (2 * a1 * b1) + ay; + if ((a2 * a2) + (b2 * b2) > Limit) + break; + + ++numIterations; + a1 = (a2 * a2) - (b2 * b2) + ax; + b1 = (2 * a2 * b2) + ay; + if ((a1 * a1) + (b1 * b1) > Limit) + break; + } while (numIterations < MaxIterations); + + if (numIterations < MaxIterations) { + *scanLine++ = colormap[numIterations % ColormapSize]; + allBlack = false; + } else { + *scanLine++ = qRgb(0, 0, 0); + } + } + } + + if (allBlack && pass == 0) { + pass = 4; + } else { + if (!restart) + emit renderedImage(image, scaleFactor); +//! [5] //! [6] + ++pass; + } +//! [6] //! [7] + } +//! [7] + +//! [8] + mutex.lock(); +//! [8] //! [9] + if (!restart) + condition.wait(&mutex); + restart = false; + mutex.unlock(); + } +} +//! [9] + +//! [10] +uint RenderThread::rgbFromWaveLength(double wave) +{ + double r = 0.0; + double g = 0.0; + double b = 0.0; + + if (wave >= 380.0 && wave <= 440.0) { + r = -1.0 * (wave - 440.0) / (440.0 - 380.0); + b = 1.0; + } else if (wave >= 440.0 && wave <= 490.0) { + g = (wave - 440.0) / (490.0 - 440.0); + b = 1.0; + } else if (wave >= 490.0 && wave <= 510.0) { + g = 1.0; + b = -1.0 * (wave - 510.0) / (510.0 - 490.0); + } else if (wave >= 510.0 && wave <= 580.0) { + r = (wave - 510.0) / (580.0 - 510.0); + g = 1.0; + } else if (wave >= 580.0 && wave <= 645.0) { + r = 1.0; + g = -1.0 * (wave - 645.0) / (645.0 - 580.0); + } else if (wave >= 645.0 && wave <= 780.0) { + r = 1.0; + } + + double s = 1.0; + if (wave > 700.0) + s = 0.3 + 0.7 * (780.0 - wave) / (780.0 - 700.0); + else if (wave < 420.0) + s = 0.3 + 0.7 * (wave - 380.0) / (420.0 - 380.0); + + r = pow(r * s, 0.8); + g = pow(g * s, 0.8); + b = pow(b * s, 0.8); + return qRgb(int(r * 255), int(g * 255), int(b * 255)); +} +//! [10] diff --git a/examples/corelib/threads/mandelbrot/renderthread.h b/examples/corelib/threads/mandelbrot/renderthread.h new file mode 100644 index 0000000000..881870665f --- /dev/null +++ b/examples/corelib/threads/mandelbrot/renderthread.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef RENDERTHREAD_H +#define RENDERTHREAD_H + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE +class QImage; +QT_END_NAMESPACE + +//! [0] +class RenderThread : public QThread +{ + Q_OBJECT + +public: + RenderThread(QObject *parent = 0); + ~RenderThread(); + + void render(double centerX, double centerY, double scaleFactor, QSize resultSize); + +signals: + void renderedImage(const QImage &image, double scaleFactor); + +protected: + void run() Q_DECL_OVERRIDE; + +private: + uint rgbFromWaveLength(double wave); + + QMutex mutex; + QWaitCondition condition; + double centerX; + double centerY; + double scaleFactor; + QSize resultSize; + bool restart; + bool abort; + + enum { ColormapSize = 512 }; + uint colormap[ColormapSize]; +}; +//! [0] + +#endif // RENDERTHREAD_H diff --git a/examples/corelib/threads/queuedcustomtype/block.cpp b/examples/corelib/threads/queuedcustomtype/block.cpp new file mode 100644 index 0000000000..07bd58cd97 --- /dev/null +++ b/examples/corelib/threads/queuedcustomtype/block.cpp @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include "block.h" + +Block::Block() +{ +} + +Block::Block(const Block &other) +{ + m_rect = other.m_rect; + m_color = other.m_color; +} + +Block::~Block() +{ +} + +Block::Block(const QRect &rect, const QColor &color) +{ + m_rect = rect; + m_color = color; +} + +QColor Block::color() const +{ + return m_color; +} + +QRect Block::rect() const +{ + return m_rect; +} diff --git a/examples/corelib/threads/queuedcustomtype/block.h b/examples/corelib/threads/queuedcustomtype/block.h new file mode 100644 index 0000000000..f9930340e2 --- /dev/null +++ b/examples/corelib/threads/queuedcustomtype/block.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef BLOCK_H +#define BLOCK_H + +#include +#include +#include +#include + +//! [custom type definition and meta-type declaration] +class Block +{ +public: + Block(); + Block(const Block &other); + ~Block(); + + Block(const QRect &rect, const QColor &color); + + QColor color() const; + QRect rect() const; + +private: + QRect m_rect; + QColor m_color; +}; + +Q_DECLARE_METATYPE(Block); +//! [custom type definition and meta-type declaration] + +#endif diff --git a/examples/corelib/threads/queuedcustomtype/main.cpp b/examples/corelib/threads/queuedcustomtype/main.cpp new file mode 100644 index 0000000000..98933c66f3 --- /dev/null +++ b/examples/corelib/threads/queuedcustomtype/main.cpp @@ -0,0 +1,128 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include "block.h" +#include "window.h" + +QImage createImage(int width, int height) +{ + QImage image(width, height, QImage::Format_RGB16); + QPainter painter; + QPen pen; + pen.setStyle(Qt::NoPen); + QBrush brush(Qt::blue); + + painter.begin(&image); + painter.fillRect(image.rect(), brush); + brush.setColor(Qt::white); + painter.setPen(pen); + painter.setBrush(brush); + + static const QPointF points1[3] = { + QPointF(4, 4), + QPointF(7, 4), + QPointF(5.5, 1) + }; + + static const QPointF points2[3] = { + QPointF(1, 4), + QPointF(7, 4), + QPointF(10, 10) + }; + + static const QPointF points3[3] = { + QPointF(4, 4), + QPointF(10, 4), + QPointF(1, 10) + }; + + painter.setWindow(0, 0, 10, 10); + + int x = 0; + int y = 0; + int starWidth = image.width()/3; + int starHeight = image.height()/3; + + QRect rect(x, y, starWidth, starHeight); + + for (int i = 0; i < 9; ++i) { + + painter.setViewport(rect); + painter.drawPolygon(points1, 3); + painter.drawPolygon(points2, 3); + painter.drawPolygon(points3, 3); + + if (i % 3 == 2) { + y = y + starHeight; + rect.moveTop(y); + + x = 0; + rect.moveLeft(x); + + } else { + x = x + starWidth; + rect.moveLeft(x); + } + } + + painter.end(); + return image; +} + +//! [main function] //! [main start] +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); +//! [main start] //! [register meta-type for queued communications] + qRegisterMetaType(); +//! [register meta-type for queued communications] + qsrand(QTime::currentTime().elapsed()); + + Window window; + window.show(); + + window.loadImage(createImage(256, 256)); +//! [main finish] + return app.exec(); +} +//! [main finish] //! [main function] diff --git a/examples/corelib/threads/queuedcustomtype/queuedcustomtype.pro b/examples/corelib/threads/queuedcustomtype/queuedcustomtype.pro new file mode 100644 index 0000000000..77421eb638 --- /dev/null +++ b/examples/corelib/threads/queuedcustomtype/queuedcustomtype.pro @@ -0,0 +1,14 @@ +HEADERS = block.h \ + renderthread.h \ + window.h +SOURCES = main.cpp \ + block.cpp \ + renderthread.cpp \ + window.cpp +QT += widgets + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/corelib/threads/mandelbrot +INSTALLS += target + + diff --git a/examples/corelib/threads/queuedcustomtype/renderthread.cpp b/examples/corelib/threads/queuedcustomtype/renderthread.cpp new file mode 100644 index 0000000000..50a638987f --- /dev/null +++ b/examples/corelib/threads/queuedcustomtype/renderthread.cpp @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "renderthread.h" + +RenderThread::RenderThread(QObject *parent) + : QThread(parent) +{ + m_abort = false; +} + +RenderThread::~RenderThread() +{ + mutex.lock(); + m_abort = true; + mutex.unlock(); + + wait(); +} + +//![processing the image (start)] +void RenderThread::processImage(const QImage &image) +{ + if (image.isNull()) + return; + + m_image = image; + m_abort = false; + start(); +} + +void RenderThread::run() +{ + int size = qMax(m_image.width()/20, m_image.height()/20); + for (int s = size; s > 0; --s) { + for (int c = 0; c < 400; ++c) { +//![processing the image (start)] + int x1 = qMax(0, (qrand() % m_image.width()) - s/2); + int x2 = qMin(x1 + s/2 + 1, m_image.width()); + int y1 = qMax(0, (qrand() % m_image.height()) - s/2); + int y2 = qMin(y1 + s/2 + 1, m_image.height()); + int n = 0; + int red = 0; + int green = 0; + int blue = 0; + for (int i = y1; i < y2; ++i) { + for (int j = x1; j < x2; ++j) { + QRgb pixel = m_image.pixel(j, i); + red += qRed(pixel); + green += qGreen(pixel); + blue += qBlue(pixel); + n += 1; + } + } +//![processing the image (finish)] + Block block(QRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1), + QColor(red/n, green/n, blue/n)); + emit sendBlock(block); + if (m_abort) + return; + msleep(10); + } + } +} +//![processing the image (finish)] + +void RenderThread::stopProcess() +{ + mutex.lock(); + m_abort = true; + mutex.unlock(); +} diff --git a/examples/corelib/threads/queuedcustomtype/renderthread.h b/examples/corelib/threads/queuedcustomtype/renderthread.h new file mode 100644 index 0000000000..5630926d41 --- /dev/null +++ b/examples/corelib/threads/queuedcustomtype/renderthread.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef RENDERTHREAD_H +#define RENDERTHREAD_H + +#include +#include +#include +#include "block.h" + +//! [RenderThread class definition] +class RenderThread : public QThread +{ + Q_OBJECT + +public: + RenderThread(QObject *parent = 0); + ~RenderThread(); + + void processImage(const QImage &image); + +signals: + void sendBlock(const Block &block); + +public slots: + void stopProcess(); + +protected: + void run(); + +private: + bool m_abort; + QImage m_image; + QMutex mutex; +}; +//! [RenderThread class definition] + +#endif diff --git a/examples/corelib/threads/queuedcustomtype/window.cpp b/examples/corelib/threads/queuedcustomtype/window.cpp new file mode 100644 index 0000000000..8afb8b6782 --- /dev/null +++ b/examples/corelib/threads/queuedcustomtype/window.cpp @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include "window.h" + +//! [Window constructor start] +Window::Window() +{ + thread = new RenderThread(); +//! [Window constructor start] //! [set up widgets and connections] + + label = new QLabel(); + label->setAlignment(Qt::AlignCenter); + + loadButton = new QPushButton(tr("&Load image...")); + resetButton = new QPushButton(tr("&Stop")); + resetButton->setEnabled(false); + + connect(loadButton, SIGNAL(clicked()), this, SLOT(loadImage())); + connect(resetButton, SIGNAL(clicked()), thread, SLOT(stopProcess())); + connect(thread, SIGNAL(finished()), this, SLOT(resetUi())); +//! [set up widgets and connections] //! [connecting signal with custom type] + connect(thread, SIGNAL(sendBlock(Block)), this, SLOT(addBlock(Block))); +//! [connecting signal with custom type] + + QHBoxLayout *buttonLayout = new QHBoxLayout(); + buttonLayout->addStretch(); + buttonLayout->addWidget(loadButton); + buttonLayout->addWidget(resetButton); + buttonLayout->addStretch(); + + QVBoxLayout *layout = new QVBoxLayout(this); + layout->addWidget(label); + layout->addLayout(buttonLayout); + +//! [Window constructor finish] + setWindowTitle(tr("Queued Custom Type")); +} +//! [Window constructor finish] + +void Window::loadImage() +{ + QStringList formats; + foreach (QByteArray format, QImageReader::supportedImageFormats()) + if (format.toLower() == format) + formats.append("*." + format); + + QString newPath = QFileDialog::getOpenFileName(this, tr("Open Image"), + path, tr("Image files (%1)").arg(formats.join(' '))); + + if (newPath.isEmpty()) + return; + + QImage image(newPath); + if (!image.isNull()) { + loadImage(image); + path = newPath; + } +} + +void Window::loadImage(const QImage &image) +{ + QDesktopWidget desktop; + QImage useImage; + QRect space = desktop.availableGeometry(); + if (image.width() > 0.75*space.width() || image.height() > 0.75*space.height()) + useImage = image.scaled(0.75*space.width(), 0.75*space.height(), + Qt::KeepAspectRatio, Qt::SmoothTransformation); + else + useImage = image; + + pixmap = QPixmap(useImage.width(), useImage.height()); + pixmap.fill(qRgb(255, 255, 255)); + label->setPixmap(pixmap); + loadButton->setEnabled(false); + resetButton->setEnabled(true); + thread->processImage(useImage); +} + +//! [Adding blocks to the display] +void Window::addBlock(const Block &block) +{ + QColor color = block.color(); + color.setAlpha(64); + + QPainter painter; + painter.begin(&pixmap); + painter.fillRect(block.rect(), color); + painter.end(); + label->setPixmap(pixmap); +} +//! [Adding blocks to the display] + +void Window::resetUi() +{ + loadButton->setEnabled(true); + resetButton->setEnabled(false); +} diff --git a/examples/corelib/threads/queuedcustomtype/window.h b/examples/corelib/threads/queuedcustomtype/window.h new file mode 100644 index 0000000000..cb648f1be2 --- /dev/null +++ b/examples/corelib/threads/queuedcustomtype/window.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include +#include "renderthread.h" + +class QLabel; +class QPushButton; + +//! [Window class definition] +class Window : public QWidget +{ + Q_OBJECT + +public: + Window(); + void loadImage(const QImage &image); + +public slots: + void addBlock(const Block &block); + +private slots: + void loadImage(); + void resetUi(); + +private: + QLabel *label; + QPixmap pixmap; + QPushButton *loadButton; + QPushButton *resetButton; + QString path; + RenderThread *thread; +}; +//! [Window class definition] + +#endif diff --git a/examples/corelib/threads/semaphores/semaphores.cpp b/examples/corelib/threads/semaphores/semaphores.cpp new file mode 100644 index 0000000000..f519e5f323 --- /dev/null +++ b/examples/corelib/threads/semaphores/semaphores.cpp @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include +#include + +//! [0] +const int DataSize = 100000; + +const int BufferSize = 8192; +char buffer[BufferSize]; + +QSemaphore freeBytes(BufferSize); +QSemaphore usedBytes; +//! [0] + +//! [1] +class Producer : public QThread +//! [1] //! [2] +{ +public: + void run() Q_DECL_OVERRIDE + { + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + for (int i = 0; i < DataSize; ++i) { + freeBytes.acquire(); + buffer[i % BufferSize] = "ACGT"[(int)qrand() % 4]; + usedBytes.release(); + } + } +}; +//! [2] + +//! [3] +class Consumer : public QThread +//! [3] //! [4] +{ + Q_OBJECT +public: + void run() Q_DECL_OVERRIDE + { + for (int i = 0; i < DataSize; ++i) { + usedBytes.acquire(); + fprintf(stderr, "%c", buffer[i % BufferSize]); + freeBytes.release(); + } + fprintf(stderr, "\n"); + } + +signals: + void stringConsumed(const QString &text); + +protected: + bool finish; +}; +//! [4] + +//! [5] +int main(int argc, char *argv[]) +//! [5] //! [6] +{ + QCoreApplication app(argc, argv); + Producer producer; + Consumer consumer; + producer.start(); + consumer.start(); + producer.wait(); + consumer.wait(); + return 0; +} +//! [6] + +#include "semaphores.moc" diff --git a/examples/corelib/threads/semaphores/semaphores.pro b/examples/corelib/threads/semaphores/semaphores.pro new file mode 100644 index 0000000000..69154e57eb --- /dev/null +++ b/examples/corelib/threads/semaphores/semaphores.pro @@ -0,0 +1,9 @@ +SOURCES += semaphores.cpp +QT = core + +CONFIG -= app_bundle +CONFIG += console + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/corelib/threads/semaphores +INSTALLS += target diff --git a/examples/corelib/threads/threads.pro b/examples/corelib/threads/threads.pro new file mode 100644 index 0000000000..e47da84a06 --- /dev/null +++ b/examples/corelib/threads/threads.pro @@ -0,0 +1,7 @@ +TEMPLATE = subdirs +CONFIG += no_docs_target + +SUBDIRS = semaphores \ + waitconditions + +qtHaveModule(widgets): SUBDIRS += mandelbrot diff --git a/examples/corelib/threads/waitconditions/waitconditions.cpp b/examples/corelib/threads/waitconditions/waitconditions.cpp new file mode 100644 index 0000000000..b0336f4c2b --- /dev/null +++ b/examples/corelib/threads/waitconditions/waitconditions.cpp @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include +#include + +//! [0] +const int DataSize = 100000; + +const int BufferSize = 8192; +char buffer[BufferSize]; + +QWaitCondition bufferNotEmpty; +QWaitCondition bufferNotFull; +QMutex mutex; +int numUsedBytes = 0; +//! [0] + +//! [1] +class Producer : public QThread +//! [1] //! [2] +{ +public: + Producer(QObject *parent = NULL) : QThread(parent) + { + } + + void run() Q_DECL_OVERRIDE + { + qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); + + for (int i = 0; i < DataSize; ++i) { + mutex.lock(); + if (numUsedBytes == BufferSize) + bufferNotFull.wait(&mutex); + mutex.unlock(); + + buffer[i % BufferSize] = "ACGT"[(int)qrand() % 4]; + + mutex.lock(); + ++numUsedBytes; + bufferNotEmpty.wakeAll(); + mutex.unlock(); + } + } +}; +//! [2] + +//! [3] +class Consumer : public QThread +//! [3] //! [4] +{ + Q_OBJECT +public: + Consumer(QObject *parent = NULL) : QThread(parent) + { + } + + void run() Q_DECL_OVERRIDE + { + for (int i = 0; i < DataSize; ++i) { + mutex.lock(); + if (numUsedBytes == 0) + bufferNotEmpty.wait(&mutex); + mutex.unlock(); + + fprintf(stderr, "%c", buffer[i % BufferSize]); + + mutex.lock(); + --numUsedBytes; + bufferNotFull.wakeAll(); + mutex.unlock(); + } + fprintf(stderr, "\n"); + } + +signals: + void stringConsumed(const QString &text); +}; +//! [4] + + +//! [5] +int main(int argc, char *argv[]) +//! [5] //! [6] +{ + QCoreApplication app(argc, argv); + Producer producer; + Consumer consumer; + producer.start(); + consumer.start(); + producer.wait(); + consumer.wait(); + return 0; +} +//! [6] + +#include "waitconditions.moc" diff --git a/examples/corelib/threads/waitconditions/waitconditions.pro b/examples/corelib/threads/waitconditions/waitconditions.pro new file mode 100644 index 0000000000..2dbe7df68a --- /dev/null +++ b/examples/corelib/threads/waitconditions/waitconditions.pro @@ -0,0 +1,9 @@ +QT = core +CONFIG -= moc app_bundle +CONFIG += console + +SOURCES += waitconditions.cpp + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/corelib/threads/waitconditions +INSTALLS += target diff --git a/examples/corelib/tools/README b/examples/corelib/tools/README new file mode 100644 index 0000000000..db5c107c82 --- /dev/null +++ b/examples/corelib/tools/README @@ -0,0 +1,9 @@ +Qt is equipped with a range of capable tool classes, from containers and +iterators to classes for string handling and manipulation. + +Other classes provide application infrastructure support, handling plugin +loading and managing configuration files. + + +Documentation for these examples can be found via the Examples +link in the main Qt documentation. diff --git a/examples/corelib/tools/contiguouscache/contiguouscache.pro b/examples/corelib/tools/contiguouscache/contiguouscache.pro new file mode 100644 index 0000000000..fb2267fc64 --- /dev/null +++ b/examples/corelib/tools/contiguouscache/contiguouscache.pro @@ -0,0 +1,9 @@ +QT += widgets + +HEADERS = randomlistmodel.h +SOURCES = randomlistmodel.cpp \ + main.cpp + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/corelib/tools/contiguouscache +INSTALLS += target diff --git a/examples/corelib/tools/contiguouscache/main.cpp b/examples/corelib/tools/contiguouscache/main.cpp new file mode 100644 index 0000000000..62fa8dcf42 --- /dev/null +++ b/examples/corelib/tools/contiguouscache/main.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "randomlistmodel.h" +#include +#include + +int main(int c, char **v) +{ + QApplication a(c, v); + + QListView view; + view.setUniformItemSizes(true); + view.setModel(new RandomListModel(&view)); + view.show(); + + return a.exec(); +} diff --git a/examples/corelib/tools/contiguouscache/randomlistmodel.cpp b/examples/corelib/tools/contiguouscache/randomlistmodel.cpp new file mode 100644 index 0000000000..cd1a301dc7 --- /dev/null +++ b/examples/corelib/tools/contiguouscache/randomlistmodel.cpp @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "randomlistmodel.h" +#include + +static const int bufferSize(500); +static const int lookAhead(100); +static const int halfLookAhead(lookAhead/2); + +RandomListModel::RandomListModel(QObject *parent) +: QAbstractListModel(parent), m_rows(bufferSize), m_count(10000) +{ +} + +RandomListModel::~RandomListModel() +{ +} + +int RandomListModel::rowCount(const QModelIndex &) const +{ + return m_count; +} + +//! [0] +QVariant RandomListModel::data(const QModelIndex &index, int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + int row = index.row(); + + if (row > m_rows.lastIndex()) { + if (row - m_rows.lastIndex() > lookAhead) + cacheRows(row-halfLookAhead, qMin(m_count, row+halfLookAhead)); + else while (row > m_rows.lastIndex()) + m_rows.append(fetchRow(m_rows.lastIndex()+1)); + } else if (row < m_rows.firstIndex()) { + if (m_rows.firstIndex() - row > lookAhead) + cacheRows(qMax(0, row-halfLookAhead), row+halfLookAhead); + else while (row < m_rows.firstIndex()) + m_rows.prepend(fetchRow(m_rows.firstIndex()-1)); + } + + return m_rows.at(row); +} + +void RandomListModel::cacheRows(int from, int to) const +{ + for (int i = from; i <= to; ++i) + m_rows.insert(i, fetchRow(i)); +} +//![0] + +//![1] +QString RandomListModel::fetchRow(int position) const +{ + return QString::number(rand() % ++position); +} +//![1] diff --git a/examples/corelib/tools/contiguouscache/randomlistmodel.h b/examples/corelib/tools/contiguouscache/randomlistmodel.h new file mode 100644 index 0000000000..3acafc23ff --- /dev/null +++ b/examples/corelib/tools/contiguouscache/randomlistmodel.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef RANDOMLISTMODEL_H +#define RANDOMLISTMODEL_H + +#include +#include + +QT_FORWARD_DECLARE_CLASS(QTimer) + +class RandomListModel : public QAbstractListModel +{ + Q_OBJECT +public: + RandomListModel(QObject *parent = 0); + ~RandomListModel(); + + int rowCount(const QModelIndex & = QModelIndex()) const Q_DECL_OVERRIDE; + QVariant data(const QModelIndex &, int) const Q_DECL_OVERRIDE; + +private: + void cacheRows(int, int) const; + QString fetchRow(int) const; + + mutable QContiguousCache m_rows; + const int m_count; +}; + +#endif diff --git a/examples/corelib/tools/customtype/customtype.pro b/examples/corelib/tools/customtype/customtype.pro new file mode 100644 index 0000000000..1bd792db85 --- /dev/null +++ b/examples/corelib/tools/customtype/customtype.pro @@ -0,0 +1,8 @@ +HEADERS = message.h +SOURCES = main.cpp \ + message.cpp +QT += widgets + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/corelib/tools/customcompleter +INSTALLS += target diff --git a/examples/corelib/tools/customtype/main.cpp b/examples/corelib/tools/customtype/main.cpp new file mode 100644 index 0000000000..8e97d3db96 --- /dev/null +++ b/examples/corelib/tools/customtype/main.cpp @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include "message.h" + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + QStringList headers; + headers << "Subject: Hello World" + << "From: address@example.com"; + QString body = "This is a test.\r\n"; + +//! [printing a custom type] + Message message(body, headers); + qDebug() << "Original:" << message; +//! [printing a custom type] + +//! [storing a custom value] + QVariant stored; + stored.setValue(message); +//! [storing a custom value] + + qDebug() << "Stored:" << stored; + +//! [retrieving a custom value] + Message retrieved = stored.value(); + qDebug() << "Retrieved:" << retrieved; + retrieved = qvariant_cast(stored); + qDebug() << "Retrieved:" << retrieved; +//! [retrieving a custom value] + + return 0; +} diff --git a/examples/corelib/tools/customtype/message.cpp b/examples/corelib/tools/customtype/message.cpp new file mode 100644 index 0000000000..c470ab116e --- /dev/null +++ b/examples/corelib/tools/customtype/message.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "message.h" + +//! [Message class implementation] +Message::Message() +{ +} + +Message::Message(const Message &other) +{ + m_body = other.m_body; + m_headers = other.m_headers; +} + +Message::~Message() +{ +} +//! [Message class implementation] + +Message::Message(const QString &body, const QStringList &headers) +{ + m_body = body; + m_headers = headers; +} + +//! [custom type streaming operator] +QDebug operator<<(QDebug dbg, const Message &message) +{ + QStringList pieces = message.body().split("\r\n", QString::SkipEmptyParts); + if (pieces.isEmpty()) + dbg.nospace() << "Message()"; + else if (pieces.size() == 1) + dbg.nospace() << "Message(" << pieces.first() << ")"; + else + dbg.nospace() << "Message(" << pieces.first() << " ...)"; + return dbg.maybeSpace(); +} +//! [custom type streaming operator] + +//! [getter functions] +QString Message::body() const +{ + return m_body; +} + +QStringList Message::headers() const +{ + return m_headers; +} +//! [getter functions] diff --git a/examples/corelib/tools/customtype/message.h b/examples/corelib/tools/customtype/message.h new file mode 100644 index 0000000000..cdc4e39caf --- /dev/null +++ b/examples/corelib/tools/customtype/message.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MESSAGE_H +#define MESSAGE_H + +#include +#include +#include + +//! [custom type definition] +class Message +{ +public: + Message(); + Message(const Message &other); + ~Message(); + + Message(const QString &body, const QStringList &headers); + + QString body() const; + QStringList headers() const; + +private: + QString m_body; + QStringList m_headers; +}; +//! [custom type definition] + +//! [custom type meta-type declaration] +Q_DECLARE_METATYPE(Message); +//! [custom type meta-type declaration] + +//! [custom type streaming operator] +QDebug operator<<(QDebug dbg, const Message &message); +//! [custom type streaming operator] + +#endif diff --git a/examples/corelib/tools/customtypesending/customtypesending.pro b/examples/corelib/tools/customtypesending/customtypesending.pro new file mode 100644 index 0000000000..672f6569c2 --- /dev/null +++ b/examples/corelib/tools/customtypesending/customtypesending.pro @@ -0,0 +1,10 @@ +HEADERS = message.h \ + window.h +SOURCES = main.cpp \ + message.cpp \ + window.cpp +QT += widgets + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/corelib/tools/customcompleter +INSTALLS += target diff --git a/examples/corelib/tools/customtypesending/main.cpp b/examples/corelib/tools/customtypesending/main.cpp new file mode 100644 index 0000000000..5f01e2a154 --- /dev/null +++ b/examples/corelib/tools/customtypesending/main.cpp @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include "message.h" +#include "window.h" + +//! [main function] +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + Window window1; + QStringList headers; + headers << "Subject: Hello World" + << "From: address@example.com"; + QString body = "This is a test.\r\n"; + Message message(body, headers); + window1.setMessage(message); + + Window window2; + QObject::connect(&window1, SIGNAL(messageSent(Message)), + &window2, SLOT(setMessage(Message))); + QObject::connect(&window2, SIGNAL(messageSent(Message)), + &window1, SLOT(setMessage(Message))); + window1.show(); + window2.show(); + return app.exec(); +} +//! [main function] diff --git a/examples/corelib/tools/customtypesending/message.cpp b/examples/corelib/tools/customtypesending/message.cpp new file mode 100644 index 0000000000..9b53b8757d --- /dev/null +++ b/examples/corelib/tools/customtypesending/message.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "message.h" + +Message::Message() +{ +} + +Message::Message(const Message &other) +{ + m_body = other.m_body; + m_headers = other.m_headers; +} + +Message::~Message() +{ +} + +Message::Message(const QString &body, const QStringList &headers) +{ + m_body = body; + m_headers = headers; +} + +QString Message::body() const +{ + return m_body; +} + +QStringList Message::headers() const +{ + return m_headers; +} diff --git a/examples/corelib/tools/customtypesending/message.h b/examples/corelib/tools/customtypesending/message.h new file mode 100644 index 0000000000..3e5f17db2b --- /dev/null +++ b/examples/corelib/tools/customtypesending/message.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MESSAGE_H +#define MESSAGE_H + +#include +#include +#include + +//! [custom type definition] +class Message +{ +public: + Message(); + Message(const Message &other); + ~Message(); + + Message(const QString &body, const QStringList &headers); + + QString body() const; + QStringList headers() const; + +private: + QString m_body; + QStringList m_headers; +}; +//! [custom type definition] + +//! [custom type meta-type declaration] +Q_DECLARE_METATYPE(Message); +//! [custom type meta-type declaration] + +#endif diff --git a/examples/corelib/tools/customtypesending/window.cpp b/examples/corelib/tools/customtypesending/window.cpp new file mode 100644 index 0000000000..aa4a7eab3c --- /dev/null +++ b/examples/corelib/tools/customtypesending/window.cpp @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include "window.h" + +//! [Window constructor] +Window::Window() +{ + editor = new QTextEdit(); + QPushButton *sendButton = new QPushButton(tr("&Send message")); + + connect(sendButton, SIGNAL(clicked()), this, SLOT(sendMessage())); + + QHBoxLayout *buttonLayout = new QHBoxLayout(); + buttonLayout->addStretch(); + buttonLayout->addWidget(sendButton); + buttonLayout->addStretch(); + + QVBoxLayout *layout = new QVBoxLayout(this); + layout->addWidget(editor); + layout->addLayout(buttonLayout); + + setWindowTitle(tr("Custom Type Sending")); +} +//! [Window constructor] + +//! [sending a message] +void Window::sendMessage() +{ + thisMessage = Message(editor->toPlainText(), thisMessage.headers()); + emit messageSent(thisMessage); +} +//! [sending a message] + +//! [receiving a message] +void Window::setMessage(const Message &message) +{ + thisMessage = message; + editor->setPlainText(thisMessage.body()); +} +//! [receiving a message] diff --git a/examples/corelib/tools/customtypesending/window.h b/examples/corelib/tools/customtypesending/window.h new file mode 100644 index 0000000000..0889800064 --- /dev/null +++ b/examples/corelib/tools/customtypesending/window.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include +#include "message.h" + +QT_FORWARD_DECLARE_CLASS(QTextEdit) + +//! [Window class definition] +class Window : public QWidget +{ + Q_OBJECT + +public: + Window(); + +signals: + void messageSent(const Message &message); + +public slots: + void setMessage(const Message &message); + +private slots: + void sendMessage(); + +private: + Message thisMessage; + QTextEdit *editor; +}; +//! [Window class definition] + +#endif diff --git a/examples/corelib/tools/doc/src/contiguouscache.qdoc b/examples/corelib/tools/doc/src/contiguouscache.qdoc new file mode 100644 index 0000000000..e88b2629b8 --- /dev/null +++ b/examples/corelib/tools/doc/src/contiguouscache.qdoc @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example tools/contiguouscache + \title Contiguous Cache Example + + \brief The Contiguous Cache example shows how to use QContiguousCache to manage memory usage for + very large models. In some environments memory is limited and, even when it + isn't, users still dislike an application using excessive memory. + Using QContiguousCache to manage a list, rather than loading + the entire list into memory, allows the application to limit the amount + of memory it uses, regardless of the size of the data set it accesses + + The simplest way to use QContiguousCache is to cache as items are requested. When + a view requests an item at row N it is also likely to ask for items at rows near + to N. + + \snippet tools/contiguouscache/randomlistmodel.cpp 0 + + After getting the row, the class determines if the row is in the bounds + of the contiguous cache's current range. It would have been equally valid to + simply have the following code instead. + + \code + while (row > m_rows.lastIndex()) + m_rows.append(fetchWord(m_rows.lastIndex()+1); + while (row < m_rows.firstIndex()) + m_rows.prepend(fetchWord(m_rows.firstIndex()-1); + \endcode + + However a list will often jump rows if the scroll bar is used directly, resulting in + the code above causing every row between the old and new rows to be fetched. + + Using QContiguousCache::lastIndex() and QContiguousCache::firstIndex() allows + the example to determine what part of the list the cache is currently caching. + These values don't represent the indexes into the cache's own memory, but rather + a virtual infinite array that the cache represents. + + By using QContiguousCache::append() and QContiguousCache::prepend() the code ensures + that items that may be still on the screen are not lost when the requested row + has not moved far from the current cache range. QContiguousCache::insert() can + potentially remove more than one item from the cache as QContiguousCache does not + allow for gaps. If your cache needs to quickly jump back and forth between + rows with significant gaps between them consider using QCache instead. + + And thats it. A perfectly reasonable cache, using minimal memory for a very large + list. In this case the accessor for getting the words into the cache + generates random information rather than fixed information. This allows you + to see how the cache range is kept for a local number of rows when running the + example. + + \snippet tools/contiguouscache/randomlistmodel.cpp 1 + + It is also worth considering pre-fetching items into the cache outside of the + application's paint routine. This can be done either with a separate thread + or using a QTimer to incrementally expand the range of the cache prior to + rows being requested out of the current cache range. +*/ diff --git a/examples/corelib/tools/doc/src/customtype.qdoc b/examples/corelib/tools/doc/src/customtype.qdoc new file mode 100644 index 0000000000..f03fafec30 --- /dev/null +++ b/examples/corelib/tools/doc/src/customtype.qdoc @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example tools/customtype + \title Custom Type Example + + \brief The Custom Type example shows how to integrate a custom type into Qt's + meta-object system. + + Contents: + + \tableofcontents + + \section1 Overview + + Qt provides a range of standard value types that are used to provide + rich and meaningful APIs. These types are integrated with the meta-object + system, enabling them to be stored in QVariant objects, written out in + debugging information and sent between components in signal-slot + communication. + + Custom types can also be integrated with the meta-object system as long as + they are written to conform to some simple guidelines. In this example, we + introduce a simple \c Message class, we describe how we make it work with + QVariant, and we show how it can be extended to generate a printable + representation of itself for use in debugging output. + + \section1 The Message Class Definition + + The \c Message class is a simple value class that contains two pieces + of information (a QString and a QStringList), each of which can be read + using trivial getter functions: + + \snippet tools/customtype/message.h custom type definition + + The default constructor, copy constructor and destructor are + all required, and must be public, if the type is to be integrated into the + meta-object system. Other than this, we are free to implement whatever we + need to make the type do what we want, so we also include a constructor + that lets us set the type's data members. + + To enable the type to be used with QVariant, we declare it using the + Q_DECLARE_METATYPE() macro: + + \snippet tools/customtype/message.h custom type meta-type declaration + + We do not need to write any additional code to accompany this macro. + + To allow us to see a readable description of each \c Message object when it + is sent to the debug output stream, we define a streaming operator: + + \snippet tools/customtype/message.h custom type streaming operator + + This facility is useful if you need to insert tracing statements in your + code for debugging purposes. + + \section1 The Message Class Implementation + + The implementation of the default constructor, copy constructor and destructor + are straightforward for the \c Message class: + + \snippet tools/customtype/message.cpp Message class implementation + + The streaming operator is implemented in the following way: + + \snippet tools/customtype/message.cpp custom type streaming operator + + Here, we want to represent each value depending on how many lines are stored + in the message body. We stream text to the QDebug object passed to the + operator and return the QDebug object obtained from its maybeSpace() member + function; this is described in more detail in the + \l{Creating Custom Qt Types#Making the Type Printable}{Creating Custom Qt Types} + document. + + We include the code for the getter functions for completeness: + + \snippet tools/customtype/message.cpp getter functions + + With the type fully defined, implemented, and integrated with the + meta-object system, we can now use it. + + \section1 Using the Message + + In the example's \c{main()} function, we show how a \c Message object can + be printed to the console by sending it to the debug stream: + + \snippet tools/customtype/main.cpp printing a custom type + + You can use the type with QVariant in exactly the same way as you would + use standard Qt value types. Here's how to store a value using the + QVariant::setValue() function: + + \snippet tools/customtype/main.cpp storing a custom value + + Alternatively, the QVariant::fromValue() and qVariantSetValue() functions + can be used if you are using a compiler without support for member template + functions. + + The value can be retrieved using the QVariant::value() member template + function: + + \snippet tools/customtype/main.cpp retrieving a custom value + + Alternatively, the qVariantValue() template function can be used if + you are using a compiler without support for member template functions. + + \section1 Further Reading + + The custom \c Message type can also be used with direct signal-slot + connections. + + To register a custom type for use with queued signals and slots, such as + those used in cross-thread communication, see the + \l{Queued Custom Type Example}. + + More information on using custom types with Qt can be found in the + \l{Creating Custom Qt Types} document. +*/ diff --git a/examples/corelib/tools/tools.pro b/examples/corelib/tools/tools.pro new file mode 100644 index 0000000000..36fa776980 --- /dev/null +++ b/examples/corelib/tools/tools.pro @@ -0,0 +1,7 @@ +requires(qtHaveModule(widgets)) + +TEMPLATE = subdirs +CONFIG += ordered +SUBDIRS = contiguouscache \ + customtype \ + customtypesending diff --git a/examples/examples.pro b/examples/examples.pro index 052802b803..bcc13704dc 100644 --- a/examples/examples.pro +++ b/examples/examples.pro @@ -2,18 +2,15 @@ TEMPLATE = subdirs CONFIG += no_docs_target SUBDIRS = \ + corelib \ dbus \ embedded \ gui \ - ipc \ - json \ network \ qpa \ qtconcurrent \ qtestlib \ sql \ - threads \ - tools \ touch \ widgets \ xml diff --git a/examples/ipc/README b/examples/ipc/README deleted file mode 100644 index 83a157a42e..0000000000 --- a/examples/ipc/README +++ /dev/null @@ -1,5 +0,0 @@ -These examples demonstrate IPC support in Qt. - - -Documentation for these examples can be found via the Examples -link in the main Qt documentation. diff --git a/examples/ipc/doc/images/localfortuneclient-example.png b/examples/ipc/doc/images/localfortuneclient-example.png deleted file mode 100644 index 614784bf0f..0000000000 Binary files a/examples/ipc/doc/images/localfortuneclient-example.png and /dev/null differ diff --git a/examples/ipc/doc/images/localfortuneserver-example.png b/examples/ipc/doc/images/localfortuneserver-example.png deleted file mode 100644 index 2f04c7528e..0000000000 Binary files a/examples/ipc/doc/images/localfortuneserver-example.png and /dev/null differ diff --git a/examples/ipc/doc/images/sharedmemory-example_1.png b/examples/ipc/doc/images/sharedmemory-example_1.png deleted file mode 100644 index 53244d3f52..0000000000 Binary files a/examples/ipc/doc/images/sharedmemory-example_1.png and /dev/null differ diff --git a/examples/ipc/doc/images/sharedmemory-example_2.png b/examples/ipc/doc/images/sharedmemory-example_2.png deleted file mode 100644 index fc71aed56e..0000000000 Binary files a/examples/ipc/doc/images/sharedmemory-example_2.png and /dev/null differ diff --git a/examples/ipc/doc/src/localfortuneclient.qdoc b/examples/ipc/doc/src/localfortuneclient.qdoc deleted file mode 100644 index a68f4bad0c..0000000000 --- a/examples/ipc/doc/src/localfortuneclient.qdoc +++ /dev/null @@ -1,40 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: http://www.gnu.org/copyleft/fdl.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \example localfortuneclient - \title Local Fortune Client Example - \ingroup examples-ipc - \brief Demonstrates using QLocalSocket for a simple local service client. - - The Local Fortune Client example shows how to create a client for a simple - local service using QLocalSocket. It is intended to be run alongside the - \l{Local Fortune Server Example}. - - \image localfortuneclient-example.png Screenshot of the Local Fortune Client example - -*/ diff --git a/examples/ipc/doc/src/localfortuneserver.qdoc b/examples/ipc/doc/src/localfortuneserver.qdoc deleted file mode 100644 index 13f7f3ca74..0000000000 --- a/examples/ipc/doc/src/localfortuneserver.qdoc +++ /dev/null @@ -1,39 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: http://www.gnu.org/copyleft/fdl.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \example localfortuneserver - \title Local Fortune Server Example - \ingroup examples-ipc - \brief Demonstrates using QLocalServer and QLocalSocket for serving a simple local service. - - The Local Fortune Server example shows how to create a server for a simple - local service. It is intended to be run alongside the - \l{Local Fortune Client Example} - - \image localfortuneserver-example.png Screenshot of the Local Fortune Server example - */ diff --git a/examples/ipc/doc/src/sharedmemory.qdoc b/examples/ipc/doc/src/sharedmemory.qdoc deleted file mode 100644 index b9f0c86d44..0000000000 --- a/examples/ipc/doc/src/sharedmemory.qdoc +++ /dev/null @@ -1,131 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: http://www.gnu.org/copyleft/fdl.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \example sharedmemory - \title Shared Memory Example - \ingroup examples-ipc - \brief Demonstrates doing inter-process communication using shared memory with - the QSharedMemory class. - - The Shared Memory example shows how to use the QSharedMemory class - to implement inter-process communication using shared memory. To - build the example, run make. To run the example, start two instances - of the executable. The main() function creates an \l {QApplication} - {application} and an instance of our example's Dialog class. The - dialog is displayed and then control is passed to the application in - the standard way. - - \snippet sharedmemory/main.cpp 0 - - Two instances of class Dialog appear. - - \image sharedmemory-example_1.png Screenshot of the Shared Memory example - - Class Dialog inherits QDialog. It encapsulates the user interface - and an instance of QSharedMemory. It also has two public slots, - loadFromFile() and loadFromMemory() that correspond to the two - buttons on the dialog. - - \snippet sharedmemory/dialog.h 0 - - The constructor builds the user interface widgets and connects the - clicked() signal of each button to the corresponding slot function. - - \snippet sharedmemory/dialog.cpp 0 - - Note that "QSharedMemoryExample" is passed to the \l {QSharedMemory} - {QSharedMemory()} constructor to be used as the key. This will be - used by the system as the identifier of the underlying shared memory - segment. - - Click the \tt {Load Image From File...} button on one of the - dialogs. The loadFromFile() slot is invoked. First, it tests whether - a shared memory segment is already attached to the process. If so, - that segment is detached from the process, so we can be assured of - starting off the example correctly. - - \snippet sharedmemory/dialog.cpp 1 - - The user is then asked to select an image file using - QFileDialog::getOpenFileName(). The selected file is loaded into a - QImage. Using a QImage lets us ensure that the selected file is a - valid image, and it also allows us to immediately display the image - in the dialog using setPixmap(). - - Next the image is streamed into a QBuffer using a QDataStream. This - gives us the size, which we then use to \l {QSharedMemory::} - {create()} our shared memory segment. Creating a shared memory - segment automatically \l {QSharedMemory::attach()} {attaches} the - segment to the process. Using a QBuffer here lets us get a pointer - to the image data, which we then use to do a memcopy() from the - QBuffer into the shared memory segment. - - \snippet sharedmemory/dialog.cpp 2 - - Note that we \l {QSharedMemory::} {lock()} the shared memory segment - before we copy into it, and we \l {QSharedMemory::} {unlock()} it - again immediately after the copy. This ensures we have exclusive - access to the shared memory segment to do our memcopy(). If some - other process has the segment lock, then our process will block - until the lock becomes available. - - Note also that the function does not \l {QSharedMemory::} {detach()} - from the shared memory segment after the memcopy() and - unlock(). Recall that when the last process detaches from a shared - memory segment, the segment is released by the operating - system. Since this process only one that is attached to the shared - memory segment at the moment, if loadFromFile() detached from the - shared memory segment, the segment would be destroyed before we get - to the next step. - - When the function returns, if the file you selected was qt.png, your - first dialog looks like this. - - \image sharedmemory-example_2.png Screenshot of the Shared Memory example - - In the second dialog, click the \tt {Display Image From Shared - Memory} button. The loadFromMemory() slot is invoked. It first \l - {QSharedMemory::attach()} {attaches} the process to the same shared - memory segment created by the first process. Then it \l - {QSharedMemory::lock()} {locks} the segment for exclusive access and - links a QBuffer to the image data in the shared memory segment. It - then streams the data into a QImage and \l {QSharedMemory::unlock()} - {unlocks} the segment. - - \snippet sharedmemory/dialog.cpp 3 - - In this case, the function does \l {QSharedMemory::} {detach()} from - the segment, because now we are effectively finished using - it. Finally, the QImage is displayed. At this point, both dialogs - should be showing the same image. When you close the first dialog, - the Dialog destructor calls the QSharedMemory destructor, which - detaches from the shared memory segment. Since this is the last - process to be detached from the segment, the operating system will - now release the shared memory. - - */ diff --git a/examples/ipc/ipc.pro b/examples/ipc/ipc.pro deleted file mode 100644 index 4b4b3870a4..0000000000 --- a/examples/ipc/ipc.pro +++ /dev/null @@ -1,6 +0,0 @@ -requires(qtHaveModule(widgets)) - -TEMPLATE = subdirs -# no QSharedMemory -!vxworks:!qnx:SUBDIRS = sharedmemory -!wince*:qtHaveModule(network): SUBDIRS += localfortuneserver localfortuneclient diff --git a/examples/ipc/localfortuneclient/client.cpp b/examples/ipc/localfortuneclient/client.cpp deleted file mode 100644 index 267f5329c8..0000000000 --- a/examples/ipc/localfortuneclient/client.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -#include "client.h" - -Client::Client(QWidget *parent) - : QDialog(parent) -{ - hostLabel = new QLabel(tr("&Server name:")); - hostLineEdit = new QLineEdit("fortune"); - - hostLabel->setBuddy(hostLineEdit); - - statusLabel = new QLabel(tr("This examples requires that you run the " - "Fortune Server example as well.")); - statusLabel->setWordWrap(true); - - getFortuneButton = new QPushButton(tr("Get Fortune")); - getFortuneButton->setDefault(true); - - quitButton = new QPushButton(tr("Quit")); - - buttonBox = new QDialogButtonBox; - buttonBox->addButton(getFortuneButton, QDialogButtonBox::ActionRole); - buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole); - - socket = new QLocalSocket(this); - - connect(hostLineEdit, SIGNAL(textChanged(QString)), - this, SLOT(enableGetFortuneButton())); - connect(getFortuneButton, SIGNAL(clicked()), - this, SLOT(requestNewFortune())); - connect(quitButton, SIGNAL(clicked()), this, SLOT(close())); - connect(socket, SIGNAL(readyRead()), this, SLOT(readFortune())); - connect(socket, SIGNAL(error(QLocalSocket::LocalSocketError)), - this, SLOT(displayError(QLocalSocket::LocalSocketError))); - - QGridLayout *mainLayout = new QGridLayout; - mainLayout->addWidget(hostLabel, 0, 0); - mainLayout->addWidget(hostLineEdit, 0, 1); - mainLayout->addWidget(statusLabel, 2, 0, 1, 2); - mainLayout->addWidget(buttonBox, 3, 0, 1, 2); - setLayout(mainLayout); - - setWindowTitle(tr("Fortune Client")); - hostLineEdit->setFocus(); -} - -void Client::requestNewFortune() -{ - getFortuneButton->setEnabled(false); - blockSize = 0; - socket->abort(); - socket->connectToServer(hostLineEdit->text()); -} - -void Client::readFortune() -{ - QDataStream in(socket); - in.setVersion(QDataStream::Qt_4_0); - - if (blockSize == 0) { - if (socket->bytesAvailable() < (int)sizeof(quint16)) - return; - in >> blockSize; - } - - if (in.atEnd()) - return; - - QString nextFortune; - in >> nextFortune; - - if (nextFortune == currentFortune) { - QTimer::singleShot(0, this, SLOT(requestNewFortune())); - return; - } - - currentFortune = nextFortune; - statusLabel->setText(currentFortune); - getFortuneButton->setEnabled(true); -} - -void Client::displayError(QLocalSocket::LocalSocketError socketError) -{ - switch (socketError) { - case QLocalSocket::ServerNotFoundError: - QMessageBox::information(this, tr("Fortune Client"), - tr("The host was not found. Please check the " - "host name and port settings.")); - break; - case QLocalSocket::ConnectionRefusedError: - QMessageBox::information(this, tr("Fortune Client"), - tr("The connection was refused by the peer. " - "Make sure the fortune server is running, " - "and check that the host name and port " - "settings are correct.")); - break; - case QLocalSocket::PeerClosedError: - break; - default: - QMessageBox::information(this, tr("Fortune Client"), - tr("The following error occurred: %1.") - .arg(socket->errorString())); - } - - getFortuneButton->setEnabled(true); -} - -void Client::enableGetFortuneButton() -{ - getFortuneButton->setEnabled(!hostLineEdit->text().isEmpty()); -} diff --git a/examples/ipc/localfortuneclient/client.h b/examples/ipc/localfortuneclient/client.h deleted file mode 100644 index 61b1cd26a4..0000000000 --- a/examples/ipc/localfortuneclient/client.h +++ /dev/null @@ -1,82 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CLIENT_H -#define CLIENT_H - -#include - -#include - -QT_BEGIN_NAMESPACE -class QDialogButtonBox; -class QLabel; -class QLineEdit; -class QPushButton; -class QLocalSocket; -QT_END_NAMESPACE - -class Client : public QDialog -{ - Q_OBJECT - -public: - Client(QWidget *parent = 0); - -private slots: - void requestNewFortune(); - void readFortune(); - void displayError(QLocalSocket::LocalSocketError socketError); - void enableGetFortuneButton(); - -private: - QLabel *hostLabel; - QLineEdit *hostLineEdit; - QLabel *statusLabel; - QPushButton *getFortuneButton; - QPushButton *quitButton; - QDialogButtonBox *buttonBox; - - QLocalSocket *socket; - QString currentFortune; - quint16 blockSize; -}; - -#endif diff --git a/examples/ipc/localfortuneclient/localfortuneclient.pro b/examples/ipc/localfortuneclient/localfortuneclient.pro deleted file mode 100644 index c52a173ed5..0000000000 --- a/examples/ipc/localfortuneclient/localfortuneclient.pro +++ /dev/null @@ -1,8 +0,0 @@ -HEADERS = client.h -SOURCES = client.cpp \ - main.cpp -QT += network widgets - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/ipc/localfortuneclient -INSTALLS += target diff --git a/examples/ipc/localfortuneclient/main.cpp b/examples/ipc/localfortuneclient/main.cpp deleted file mode 100644 index f197d7f6cb..0000000000 --- a/examples/ipc/localfortuneclient/main.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include "client.h" - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - Client client; - client.show(); - return app.exec(); -} diff --git a/examples/ipc/localfortuneserver/localfortuneserver.pro b/examples/ipc/localfortuneserver/localfortuneserver.pro deleted file mode 100644 index 9eed28ef74..0000000000 --- a/examples/ipc/localfortuneserver/localfortuneserver.pro +++ /dev/null @@ -1,8 +0,0 @@ -HEADERS = server.h -SOURCES = server.cpp \ - main.cpp -QT += network widgets - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/ipc/localfortuneserver -INSTALLS += target diff --git a/examples/ipc/localfortuneserver/main.cpp b/examples/ipc/localfortuneserver/main.cpp deleted file mode 100644 index 0ae70e14ef..0000000000 --- a/examples/ipc/localfortuneserver/main.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -#include - -#include "server.h" - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - Server server; - server.show(); - qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); - return app.exec(); -} diff --git a/examples/ipc/localfortuneserver/server.cpp b/examples/ipc/localfortuneserver/server.cpp deleted file mode 100644 index 6130aaa1c3..0000000000 --- a/examples/ipc/localfortuneserver/server.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -#include - -#include "server.h" -#include -#include - -Server::Server(QWidget *parent) - : QDialog(parent) -{ - statusLabel = new QLabel; - statusLabel->setWordWrap(true); - quitButton = new QPushButton(tr("Quit")); - quitButton->setAutoDefault(false); - - server = new QLocalServer(this); - if (!server->listen("fortune")) { - QMessageBox::critical(this, tr("Fortune Server"), - tr("Unable to start the server: %1.") - .arg(server->errorString())); - close(); - return; - } - - statusLabel->setText(tr("The server is running.\n" - "Run the Fortune Client example now.")); - - fortunes << tr("You've been leading a dog's life. Stay off the furniture.") - << tr("You've got to think about tomorrow.") - << tr("You will be surprised by a loud noise.") - << tr("You will feel hungry again in another hour.") - << tr("You might have mail.") - << tr("You cannot kill time without injuring eternity.") - << tr("Computers are not intelligent. They only think they are."); - - connect(quitButton, SIGNAL(clicked()), this, SLOT(close())); - connect(server, SIGNAL(newConnection()), this, SLOT(sendFortune())); - - QHBoxLayout *buttonLayout = new QHBoxLayout; - buttonLayout->addStretch(1); - buttonLayout->addWidget(quitButton); - buttonLayout->addStretch(1); - - QVBoxLayout *mainLayout = new QVBoxLayout; - mainLayout->addWidget(statusLabel); - mainLayout->addLayout(buttonLayout); - setLayout(mainLayout); - - setWindowTitle(tr("Fortune Server")); -} - -void Server::sendFortune() -{ - QByteArray block; - QDataStream out(&block, QIODevice::WriteOnly); - out.setVersion(QDataStream::Qt_4_0); - out << (quint16)0; - out << fortunes.at(qrand() % fortunes.size()); - out.device()->seek(0); - out << (quint16)(block.size() - sizeof(quint16)); - - QLocalSocket *clientConnection = server->nextPendingConnection(); - connect(clientConnection, SIGNAL(disconnected()), - clientConnection, SLOT(deleteLater())); - - clientConnection->write(block); - clientConnection->flush(); - clientConnection->disconnectFromServer(); -} diff --git a/examples/ipc/localfortuneserver/server.h b/examples/ipc/localfortuneserver/server.h deleted file mode 100644 index 4ec7f9b8ef..0000000000 --- a/examples/ipc/localfortuneserver/server.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SERVER_H -#define SERVER_H - -#include - -QT_BEGIN_NAMESPACE -class QLabel; -class QPushButton; -class QLocalServer; -QT_END_NAMESPACE - -class Server : public QDialog -{ - Q_OBJECT - -public: - Server(QWidget *parent = 0); - -private slots: - void sendFortune(); - -private: - QLabel *statusLabel; - QPushButton *quitButton; - QLocalServer *server; - QStringList fortunes; -}; - -#endif diff --git a/examples/ipc/sharedmemory/dialog.cpp b/examples/ipc/sharedmemory/dialog.cpp deleted file mode 100644 index c504f3a202..0000000000 --- a/examples/ipc/sharedmemory/dialog.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "dialog.h" -#include -#include -#include - -/*! - \class Dialog - - \brief This class is a simple example of how to use QSharedMemory. - - It is a simple dialog that presents a few buttons. To compile the - example, run make in qt/examples/ipc. Then run the executable twice - to create two processes running the dialog. In one of the processes, - press the button to load an image into a shared memory segment, and - then select an image file to load. Once the first process has loaded - and displayed the image, in the second process, press the button to - read the same image from shared memory. The second process displays - the same image loaded from its new loaction in shared memory. -*/ - -/*! - The class contains a data member \l {QSharedMemory} {sharedMemory}, - which is initialized with the key "QSharedMemoryExample" to force - all instances of Dialog to access the same shared memory segment. - The constructor also connects the clicked() signal from each of the - three dialog buttons to the slot function appropriate for handling - each button. -*/ -//! [0] -Dialog::Dialog(QWidget *parent) - : QDialog(parent), sharedMemory("QSharedMemoryExample") -{ - ui.setupUi(this); - connect(ui.loadFromFileButton, SIGNAL(clicked()), SLOT(loadFromFile())); - connect(ui.loadFromSharedMemoryButton, - SIGNAL(clicked()), - SLOT(loadFromMemory())); - setWindowTitle(tr("SharedMemory Example")); -} -//! [0] - -/*! - This slot function is called when the \tt {Load Image From File...} - button is pressed on the firs Dialog process. First, it tests - whether the process is already connected to a shared memory segment - and, if so, detaches from that segment. This ensures that we always - start the example from the beginning if we run it multiple times - with the same two Dialog processes. After detaching from an existing - shared memory segment, the user is prompted to select an image file. - The selected file is loaded into a QImage. The QImage is displayed - in the Dialog and streamed into a QBuffer with a QDataStream. - - Next, it gets a new shared memory segment from the system big enough - to hold the image data in the QBuffer, and it locks the segment to - prevent the second Dialog process from accessing it. Then it copies - the image from the QBuffer into the shared memory segment. Finally, - it unlocks the shared memory segment so the second Dialog process - can access it. - - After this function runs, the user is expected to press the \tt - {Load Image from Shared Memory} button on the second Dialog process. - - \sa loadFromMemory() - */ -//! [1] -void Dialog::loadFromFile() -{ - if (sharedMemory.isAttached()) - detach(); - - ui.label->setText(tr("Select an image file")); - QString fileName = QFileDialog::getOpenFileName(0, QString(), QString(), - tr("Images (*.png *.xpm *.jpg)")); - QImage image; - if (!image.load(fileName)) { - ui.label->setText(tr("Selected file is not an image, please select another.")); - return; - } - ui.label->setPixmap(QPixmap::fromImage(image)); -//! [1] //! [2] - - // load into shared memory - QBuffer buffer; - buffer.open(QBuffer::ReadWrite); - QDataStream out(&buffer); - out << image; - int size = buffer.size(); - - if (!sharedMemory.create(size)) { - ui.label->setText(tr("Unable to create shared memory segment.")); - return; - } - sharedMemory.lock(); - char *to = (char*)sharedMemory.data(); - const char *from = buffer.data().data(); - memcpy(to, from, qMin(sharedMemory.size(), size)); - sharedMemory.unlock(); -} -//! [2] - -/*! - This slot function is called in the second Dialog process, when the - user presses the \tt {Load Image from Shared Memory} button. First, - it attaches the process to the shared memory segment created by the - first Dialog process. Then it locks the segment for exclusive - access, copies the image data from the segment into a QBuffer, and - streams the QBuffer into a QImage. Then it unlocks the shared memory - segment, detaches from it, and finally displays the QImage in the - Dialog. - - \sa loadFromFile() - */ -//! [3] -void Dialog::loadFromMemory() -{ - if (!sharedMemory.attach()) { - ui.label->setText(tr("Unable to attach to shared memory segment.\n" \ - "Load an image first.")); - return; - } - - QBuffer buffer; - QDataStream in(&buffer); - QImage image; - - sharedMemory.lock(); - buffer.setData((char*)sharedMemory.constData(), sharedMemory.size()); - buffer.open(QBuffer::ReadOnly); - in >> image; - sharedMemory.unlock(); - - sharedMemory.detach(); - ui.label->setPixmap(QPixmap::fromImage(image)); -} -//! [3] - -/*! - This private function is called by the destructor to detach the - process from its shared memory segment. When the last process - detaches from a shared memory segment, the system releases the - shared memory. - */ -void Dialog::detach() -{ - if (!sharedMemory.detach()) - ui.label->setText(tr("Unable to detach from shared memory.")); -} - diff --git a/examples/ipc/sharedmemory/dialog.h b/examples/ipc/sharedmemory/dialog.h deleted file mode 100644 index fbc39ed4c0..0000000000 --- a/examples/ipc/sharedmemory/dialog.h +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIALOG_H -#define DIALOG_H - -#include -#include -#include "ui_dialog.h" - -//! [0] -class Dialog : public QDialog -{ - Q_OBJECT - - public: - Dialog(QWidget *parent = 0); - - public slots: - void loadFromFile(); - void loadFromMemory(); - - private: - void detach(); - - private: - Ui::Dialog ui; - QSharedMemory sharedMemory; -}; -//! [0] - -#endif - diff --git a/examples/ipc/sharedmemory/dialog.ui b/examples/ipc/sharedmemory/dialog.ui deleted file mode 100644 index e99d6fb3c4..0000000000 --- a/examples/ipc/sharedmemory/dialog.ui +++ /dev/null @@ -1,47 +0,0 @@ - - Dialog - - - - 0 - 0 - 451 - 322 - - - - Dialog - - - - - - Load Image From File... - - - - - - - Launch two of these dialogs. In the first, press the top button and load an image from a file. In the second, press the bottom button and display the loaded image from shared memory. - - - Qt::AlignCenter - - - true - - - - - - - Display Image From Shared Memory - - - - - - - - diff --git a/examples/ipc/sharedmemory/image.png b/examples/ipc/sharedmemory/image.png deleted file mode 100644 index dd93453063..0000000000 Binary files a/examples/ipc/sharedmemory/image.png and /dev/null differ diff --git a/examples/ipc/sharedmemory/main.cpp b/examples/ipc/sharedmemory/main.cpp deleted file mode 100644 index 0e9f84f3e3..0000000000 --- a/examples/ipc/sharedmemory/main.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include "dialog.h" - -//! [0] -int main(int argc, char *argv[]) -{ - QApplication application(argc, argv); - Dialog dialog; - dialog.show(); - return application.exec(); -} -//! [0] - diff --git a/examples/ipc/sharedmemory/qt.png b/examples/ipc/sharedmemory/qt.png deleted file mode 100644 index 60ef558efe..0000000000 Binary files a/examples/ipc/sharedmemory/qt.png and /dev/null differ diff --git a/examples/ipc/sharedmemory/sharedmemory.pro b/examples/ipc/sharedmemory/sharedmemory.pro deleted file mode 100644 index a392f9542d..0000000000 --- a/examples/ipc/sharedmemory/sharedmemory.pro +++ /dev/null @@ -1,15 +0,0 @@ -QT += widgets - -SOURCES += main.cpp \ - dialog.cpp - -HEADERS += dialog.h - -# Forms and resources -FORMS += dialog.ui - -EXAMPLE_FILES = *.png - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/ipc/sharedmemory -INSTALLS += target diff --git a/examples/json/json.pro b/examples/json/json.pro deleted file mode 100644 index af4d3e6f0f..0000000000 --- a/examples/json/json.pro +++ /dev/null @@ -1,2 +0,0 @@ -TEMPLATE = subdirs -SUBDIRS = savegame diff --git a/examples/json/savegame/character.cpp b/examples/json/savegame/character.cpp deleted file mode 100644 index ef30f0eaf4..0000000000 --- a/examples/json/savegame/character.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "character.h" - -Character::Character() : - mLevel(0), - mClassType(Warrior) { -} - -Character::Character(const QString &name, int level, Character::ClassType classType) : - mName(name), - mLevel(level), - mClassType(classType) -{ -} - -QString Character::name() const -{ - return mName; -} - -void Character::setName(const QString &name) -{ - mName = name; -} - -int Character::level() const -{ - return mLevel; -} - -void Character::setLevel(int level) -{ - mLevel = level; -} - -Character::ClassType Character::classType() const -{ - return mClassType; -} - -void Character::setClassType(Character::ClassType classType) -{ - mClassType = classType; -} - -//! [0] -void Character::read(const QJsonObject &json) -{ - mName = json["name"].toString(); - mLevel = json["level"].toDouble(); - mClassType = ClassType(qRound(json["classType"].toDouble())); -} -//! [0] - -//! [1] -void Character::write(QJsonObject &json) const -{ - json["name"] = mName; - json["level"] = mLevel; - json["classType"] = mClassType; -} -//! [1] diff --git a/examples/json/savegame/character.h b/examples/json/savegame/character.h deleted file mode 100644 index 32369820f4..0000000000 --- a/examples/json/savegame/character.h +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef CHARACTER_H -#define CHARACTER_H - -#include -#include - -//! [0] -class Character -{ -public: - enum ClassType { - Warrior, Mage, Archer - }; - - Character(); - Character(const QString &name, int level, ClassType classType); - - QString name() const; - void setName(const QString &name); - - int level() const; - void setLevel(int level); - - ClassType classType() const; - void setClassType(ClassType classType); - - void read(const QJsonObject &json); - void write(QJsonObject &json) const; -private: - QString mName; - int mLevel; - ClassType mClassType; -}; -//! [0] - -#endif // CHARACTER_H diff --git a/examples/json/savegame/doc/src/savegame.qdoc b/examples/json/savegame/doc/src/savegame.qdoc deleted file mode 100644 index 872f2faf42..0000000000 --- a/examples/json/savegame/doc/src/savegame.qdoc +++ /dev/null @@ -1,184 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: http://www.gnu.org/copyleft/fdl.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \example savegame - \title JSON Save Game Example - - \brief The JSON Save Game example demonstrates how to save and load a - small game using QJsonDocument, QJsonObject and QJsonArray. - - Many games provide save functionality, so that the player's progress through - the game can be saved and loaded at a later time. The process of saving a - game generally involves serializing each game object's member variables - to a file. Many formats can be used for this purpose, one of which is JSON. - With QJsonDocument, you also have the ability to serialize a document in a - binary format, which is great if you don't want the save file to be - readable, or if you need to keep the file size down. - - In this example, we'll demonstrate how to save and load a simple game to - and from JSON and binary formats. - - \section1 The Character Class - - The Character class represents a non-player character (NPC) in our game, and - stores the player's name, level, and class type. - - It provides read() and write() functions to serialise its member variables. - - \snippet savegame/character.h 0 - - Of particular interest to us are the read and write function - implementations: - - \snippet savegame/character.cpp 0 - - In the read() function, we assign Character's members values from the - QJsonObject argument. You can use either \l QJsonObject::operator[]() or - QJsonObject::value() to access values within the JSON object; both are - const functions and return QJsonValue::Undefined if the key is invalid. We - could check if the keys are valid before attempting to read them with - QJsonObject::contains(), but we assume that they are. - - \snippet savegame/character.cpp 1 - - In the write() function, we do the reverse of the read() function; assign - values from the Character object to the JSON object. As with accessing - values, there are two ways to set values on a QJsonObject: - \l QJsonObject::operator[]() and QJsonObject::insert(). Both will override - any existing value at the given key. - - Next up is the Level class: - - \snippet savegame/level.h 0 - - We want to have several levels in our game, each with several NPCs, so we - keep a QList of Character objects. We also provide the familiar read() and - write() functions. - - \snippet savegame/level.cpp 0 - - Containers can be written and read to and from JSON using QJsonArray. In our - case, we construct a QJsonArray from the value associated with the key - \c "npcs". Then, for each QJsonValue element in the array, we call - toObject() to get the Character's JSON object. The Character object can then - read their JSON and be appended to our NPC list. - - \note \l{Container Classes}{Associate containers} can be written by storing - the key in each value object (if it's not already). With this approach, the - container is stored as a regular array of objects, but the index of each - element is used as the key to construct the container when reading it back - in. - - \snippet savegame/level.cpp 1 - - Again, the write() function is similar to the read() function, except - reversed. - - Having established the Character and Level classes, we can move on to - the Game class: - - \snippet savegame/game.h 0 - - First of all, we define the \c SaveFormat enum. This will allow us to - specify the format in which the game should be saved: \c Json or \c Binary. - - Next, we provide accessors for the player and levels. We then expose three - functions: newGame(), saveGame() and loadGame(). - - The read() and write() functions are used by saveGame() and loadGame(). - - \snippet savegame/game.cpp 0 - - To setup a new game, we create the player and populate the levels and their - NPCs. - - \snippet savegame/game.cpp 1 - - The first thing we do in the read() function is tell the player to read - itself. We then clear the levels list so that calling loadGame() on the same - Game object twice doesn't result in old levels hanging around. - - We then populate the level list by reading each Level from a QJsonArray. - - \snippet savegame/game.cpp 2 - - We write the game to JSON similarly to how we write Level. - - \snippet savegame/game.cpp 3 - - When loading a saved game in loadGame(), the first thing we do is open the - save file based on which format it was saved to; \c "save.json" for JSON, - and \c "save.dat" for binary. We print a warning and return \c false if the - file couldn't be opened. - - Since QJsonDocument's \l{QJsonDocument::fromJson()}{fromJson()} and - \l{QJsonDocument::fromBinaryData()}{fromBinaryData()} functions both take a - QByteArray, we can read the entire contents of the save file into one, - regardless of the save format. - - After constructing the QJsonDocument, we instruct the Game object to read - itself and then return \c true to indicate success. - - \snippet savegame/game.cpp 4 - - Not surprisingly, saveGame() looks very much like loadGame(). We determine - the file extension based on the format, print a warning and return \c false - if the opening of the file fails. We then write the Game object to a - QJsonDocument, and call either QJsonDocument::toJson() or to - QJsonDocument::toBinaryData() to save the game, depending on which format - was specified. - - We are now ready to enter main(): - - \snippet savegame/main.cpp 0 - - Since we're only interested in demonstrating \e serialization of a game with - JSON, our game is not actually playable. Therefore, we only need - QCoreApplication and have no event loop. We create our game and assume that - the player had a great time and made lots of progress, altering the internal - state of our Character, Level and Game objects. - - \snippet savegame/main.cpp 1 - - When the player has finished, we save their game. For demonstration - purposes, we serialize to both JSON and binary. You can examine the contents - of the files in the same directory as the executable, although the binary - save file will contain some garbage characters (which is normal). - - To show that the saved files can be loaded again, we call loadGame() for - each format, returning \c 1 on failure. Assuming everything went well, we - return \c 0 to indicate success. - - That concludes our example. As you can see, serialization with Qt's JSON - classes is very simple and convenient. The advantages of using QJsonDocument - and friends over QDataStream, for example, is that you not only get - human-readable JSON files, but you also have the option to use a binary - format if it's required, \e without rewriting any code. - - \sa {JSON Support in Qt}, {Data Storage} -*/ diff --git a/examples/json/savegame/game.cpp b/examples/json/savegame/game.cpp deleted file mode 100644 index a08071b208..0000000000 --- a/examples/json/savegame/game.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "game.h" - -#include -#include -#include - -Game::Game() -{ -} - -const Character &Game::player() const -{ - return mPlayer; -} - -const QList &Game::levels() const { - return mLevels; -} - -//! [0] -void Game::newGame() { - mPlayer = Character(); - mPlayer.setName(QStringLiteral("Hero")); - mPlayer.setClassType(Character::Archer); - mPlayer.setLevel(15); - - mLevels.clear(); - - Level village; - QList villageNpcs; - villageNpcs.append(Character(QStringLiteral("Barry the Blacksmith"), 10, Character::Warrior)); - villageNpcs.append(Character(QStringLiteral("Terry the Trader"), 10, Character::Warrior)); - village.setNpcs(villageNpcs); - mLevels.append(village); - - Level dungeon; - QList dungeonNpcs; - dungeonNpcs.append(Character(QStringLiteral("Eric the Evil"), 20, Character::Mage)); - dungeonNpcs.append(Character(QStringLiteral("Eric's Sidekick #1"), 5, Character::Warrior)); - dungeonNpcs.append(Character(QStringLiteral("Eric's Sidekick #2"), 5, Character::Warrior)); - dungeon.setNpcs(dungeonNpcs); - mLevels.append(dungeon); -} -//! [0] - -//! [3] -bool Game::loadGame(Game::SaveFormat saveFormat) -{ - QFile loadFile(saveFormat == Json - ? QStringLiteral("save.json") - : QStringLiteral("save.dat")); - - if (!loadFile.open(QIODevice::ReadOnly)) { - qWarning("Couldn't open save file."); - return false; - } - - QByteArray saveData = loadFile.readAll(); - - QJsonDocument loadDoc(saveFormat == Json - ? QJsonDocument::fromJson(saveData) - : QJsonDocument::fromBinaryData(saveData)); - - read(loadDoc.object()); - - return true; -} -//! [3] - -//! [4] -bool Game::saveGame(Game::SaveFormat saveFormat) const -{ - QFile saveFile(saveFormat == Json - ? QStringLiteral("save.json") - : QStringLiteral("save.dat")); - - if (!saveFile.open(QIODevice::WriteOnly)) { - qWarning("Couldn't open save file."); - return false; - } - - QJsonObject gameObject; - write(gameObject); - QJsonDocument saveDoc(gameObject); - saveFile.write(saveFormat == Json - ? saveDoc.toJson() - : saveDoc.toBinaryData()); - - return true; -} -//! [4] - -//! [1] -void Game::read(const QJsonObject &json) -{ - mPlayer.read(json["player"].toObject()); - - mLevels.clear(); - QJsonArray levelArray = json["levels"].toArray(); - for (int levelIndex = 0; levelIndex < levelArray.size(); ++levelIndex) { - QJsonObject levelObject = levelArray[levelIndex].toObject(); - Level level; - level.read(levelObject); - mLevels.append(level); - } -} -//! [1] - -//! [2] -void Game::write(QJsonObject &json) const -{ - QJsonObject playerObject; - mPlayer.write(playerObject); - json["player"] = playerObject; - - QJsonArray levelArray; - foreach (const Level level, mLevels) { - QJsonObject levelObject; - level.write(levelObject); - levelArray.append(levelObject); - } - json["levels"] = levelArray; -} -//! [2] diff --git a/examples/json/savegame/game.h b/examples/json/savegame/game.h deleted file mode 100644 index 9216a373d1..0000000000 --- a/examples/json/savegame/game.h +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef GAME_H -#define GAME_H - -#include -#include - -#include "character.h" -#include "level.h" - -//! [0] -class Game -{ -public: - Game(); - - enum SaveFormat { - Json, Binary - }; - - const Character &player() const; - const QList &levels() const; - - void newGame(); - bool loadGame(SaveFormat saveFormat); - bool saveGame(SaveFormat saveFormat) const; - - void read(const QJsonObject &json); - void write(QJsonObject &json) const; -private: - Character mPlayer; - QList mLevels; -}; -//! [0] - -#endif // GAME_H diff --git a/examples/json/savegame/level.cpp b/examples/json/savegame/level.cpp deleted file mode 100644 index afbd3e0fa0..0000000000 --- a/examples/json/savegame/level.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "level.h" - -#include - -Level::Level() { -} - -const QList &Level::npcs() const -{ - return mNpcs; -} - -void Level::setNpcs(const QList &npcs) -{ - mNpcs = npcs; -} - -//! [0] -void Level::read(const QJsonObject &json) -{ - mNpcs.clear(); - QJsonArray npcArray = json["npcs"].toArray(); - for (int npcIndex = 0; npcIndex < npcArray.size(); ++npcIndex) { - QJsonObject npcObject = npcArray[npcIndex].toObject(); - Character npc; - npc.read(npcObject); - mNpcs.append(npc); - } -} -//! [0] - -//! [1] -void Level::write(QJsonObject &json) const -{ - QJsonArray npcArray; - foreach (const Character npc, mNpcs) { - QJsonObject npcObject; - npc.write(npcObject); - npcArray.append(npcObject); - } - json["npcs"] = npcArray; -} -//! [1] diff --git a/examples/json/savegame/level.h b/examples/json/savegame/level.h deleted file mode 100644 index 6cdf508c87..0000000000 --- a/examples/json/savegame/level.h +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef LEVEL_H -#define LEVEL_H - -#include -#include - -#include "character.h" - -//! [0] -class Level -{ -public: - Level(); - - const QList &npcs() const; - void setNpcs(const QList &npcs); - - void read(const QJsonObject &json); - void write(QJsonObject &json) const; -private: - QList mNpcs; -}; -//! [0] - -#endif // LEVEL_H diff --git a/examples/json/savegame/main.cpp b/examples/json/savegame/main.cpp deleted file mode 100644 index 1b44306bb0..0000000000 --- a/examples/json/savegame/main.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include "game.h" -//! [0] -int main(int argc, char *argv[]) -{ - QCoreApplication app(argc, argv); - - Game game; - game.newGame(); - // Game is played; changes are made... -//! [0] -//! [1] - if (!game.saveGame(Game::Json)) - return 1; - - if (!game.saveGame(Game::Binary)) - return 1; - - Game fromJsonGame; - if (!fromJsonGame.loadGame(Game::Json)) - return 1; - - Game fromBinaryGame; - if (!fromBinaryGame.loadGame(Game::Binary)) - return 1; - - return 0; -} -//! [1] diff --git a/examples/json/savegame/savegame.pro b/examples/json/savegame/savegame.pro deleted file mode 100644 index fd754ace80..0000000000 --- a/examples/json/savegame/savegame.pro +++ /dev/null @@ -1,22 +0,0 @@ -QT += core -QT -= gui - -TARGET = savegame -CONFIG += console -CONFIG -= app_bundle - -TEMPLATE = app - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/json/savegame -INSTALLS += target - -SOURCES += main.cpp \ - character.cpp \ - game.cpp \ - level.cpp - -HEADERS += \ - character.h \ - game.h \ - level.h diff --git a/examples/threads/README b/examples/threads/README deleted file mode 100644 index 6c20844564..0000000000 --- a/examples/threads/README +++ /dev/null @@ -1,7 +0,0 @@ -This folder contains examples for the use of the threading-related classes -in Qt Core. For examples using the higher-level Qt Concurrent module, -check out the "qtconcurrent" folder instead. - -Documentation for examples can be found via the Examples and Tutorials link -in the main Qt documentation. The examples and their documentation can also -be opened from the Examples tab of Qt Creator's Welcome mode. diff --git a/examples/threads/doc/images/mandelbrot-example.png b/examples/threads/doc/images/mandelbrot-example.png deleted file mode 100644 index f5817834e1..0000000000 Binary files a/examples/threads/doc/images/mandelbrot-example.png and /dev/null differ diff --git a/examples/threads/doc/images/mandelbrot_scroll1.png b/examples/threads/doc/images/mandelbrot_scroll1.png deleted file mode 100644 index b800455821..0000000000 Binary files a/examples/threads/doc/images/mandelbrot_scroll1.png and /dev/null differ diff --git a/examples/threads/doc/images/mandelbrot_scroll2.png b/examples/threads/doc/images/mandelbrot_scroll2.png deleted file mode 100644 index 704ea0a7c1..0000000000 Binary files a/examples/threads/doc/images/mandelbrot_scroll2.png and /dev/null differ diff --git a/examples/threads/doc/images/mandelbrot_scroll3.png b/examples/threads/doc/images/mandelbrot_scroll3.png deleted file mode 100644 index 8b48211444..0000000000 Binary files a/examples/threads/doc/images/mandelbrot_scroll3.png and /dev/null differ diff --git a/examples/threads/doc/images/mandelbrot_zoom1.png b/examples/threads/doc/images/mandelbrot_zoom1.png deleted file mode 100644 index 30190e44eb..0000000000 Binary files a/examples/threads/doc/images/mandelbrot_zoom1.png and /dev/null differ diff --git a/examples/threads/doc/images/mandelbrot_zoom2.png b/examples/threads/doc/images/mandelbrot_zoom2.png deleted file mode 100644 index 148ac777b8..0000000000 Binary files a/examples/threads/doc/images/mandelbrot_zoom2.png and /dev/null differ diff --git a/examples/threads/doc/images/mandelbrot_zoom3.png b/examples/threads/doc/images/mandelbrot_zoom3.png deleted file mode 100644 index a669f4b5fe..0000000000 Binary files a/examples/threads/doc/images/mandelbrot_zoom3.png and /dev/null differ diff --git a/examples/threads/doc/images/queuedcustomtype-example.png b/examples/threads/doc/images/queuedcustomtype-example.png deleted file mode 100644 index 4399b631d7..0000000000 Binary files a/examples/threads/doc/images/queuedcustomtype-example.png and /dev/null differ diff --git a/examples/threads/doc/src/mandelbrot.qdoc b/examples/threads/doc/src/mandelbrot.qdoc deleted file mode 100644 index c1393769f1..0000000000 --- a/examples/threads/doc/src/mandelbrot.qdoc +++ /dev/null @@ -1,370 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: http://www.gnu.org/copyleft/fdl.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \example mandelbrot - \title Mandelbrot Example - \ingroup qtconcurrent-mtexamples - - \brief The Mandelbrot example demonstrates multi-thread programming - using Qt. It shows how to use a worker thread to - perform heavy computations without blocking the main thread's - event loop. - - \image mandelbrot-example.png Screenshot of the Mandelbrot example - - The heavy computation here is the Mandelbrot set, probably the - world's most famous fractal. These days, while sophisticated - programs such as \l{http://xaos.sourceforge.net/}{XaoS} that provide real-time zooming in the - Mandelbrot set, the standard Mandelbrot algorithm is just slow - enough for our purposes. - - In real life, the approach described here is applicable to a - large set of problems, including synchronous network I/O and - database access, where the user interface must remain responsive - while some heavy operation is taking place. The \l - {Blocking Fortune Client Example} shows the same principle at - work in a TCP client. - - The Mandelbrot application supports zooming and scrolling using - the mouse or the keyboard. To avoid freezing the main thread's - event loop (and, as a consequence, the application's user - interface), we put all the fractal computation in a separate - worker thread. The thread emits a signal when it is done - rendering the fractal. - - During the time where the worker thread is recomputing the - fractal to reflect the new zoom factor position, the main thread - simply scales the previously rendered pixmap to provide immediate - feedback. The result doesn't look as good as what the worker - thread eventually ends up providing, but at least it makes the - application more responsive. The sequence of screenshots below - shows the original image, the scaled image, and the rerendered - image. - - \table - \row - \li \inlineimage mandelbrot_zoom1.png - \li \inlineimage mandelbrot_zoom2.png - \li \inlineimage mandelbrot_zoom3.png - \endtable - - Similarly, when the user scrolls, the previous pixmap is scrolled - immediately, revealing unpainted areas beyond the edge of the - pixmap, while the image is rendered by the worker thread. - - \table - \row - \li \inlineimage mandelbrot_scroll1.png - \li \inlineimage mandelbrot_scroll2.png - \li \inlineimage mandelbrot_scroll3.png - \endtable - - The application consists of two classes: - - \list - \li \c RenderThread is a QThread subclass that renders - the Mandelbrot set. - \li \c MandelbrotWidget is a QWidget subclass that shows the - Mandelbrot set on screen and lets the user zoom and scroll. - \endlist - - If you are not already familiar with Qt's thread support, we - recommend that you start by reading the \l{Thread Support in Qt} - overview. - - \section1 RenderThread Class Definition - - We'll start with the definition of the \c RenderThread class: - - \snippet mandelbrot/renderthread.h 0 - - The class inherits QThread so that it gains the ability to run in - a separate thread. Apart from the constructor and destructor, \c - render() is the only public function. Whenever the thread is done - rendering an image, it emits the \c renderedImage() signal. - - The protected \c run() function is reimplemented from QThread. It - is automatically called when the thread is started. - - In the \c private section, we have a QMutex, a QWaitCondition, - and a few other data members. The mutex protects the other data - member. - - \section1 RenderThread Class Implementation - - \snippet mandelbrot/renderthread.cpp 0 - - In the constructor, we initialize the \c restart and \c abort - variables to \c false. These variables control the flow of the \c - run() function. - - We also initialize the \c colormap array, which contains a series - of RGB colors. - - \snippet mandelbrot/renderthread.cpp 1 - - The destructor can be called at any point while the thread is - active. We set \c abort to \c true to tell \c run() to stop - running as soon as possible. We also call - QWaitCondition::wakeOne() to wake up the thread if it's sleeping. - (As we will see when we review \c run(), the thread is put to - sleep when it has nothing to do.) - - The important thing to notice here is that \c run() is executed - in its own thread (the worker thread), whereas the \c - RenderThread constructor and destructor (as well as the \c - render() function) are called by the thread that created the - worker thread. Therefore, we need a mutex to protect accesses to - the \c abort and \c condition variables, which might be accessed - at any time by \c run(). - - At the end of the destructor, we call QThread::wait() to wait - until \c run() has exited before the base class destructor is - invoked. - - \snippet mandelbrot/renderthread.cpp 2 - - The \c render() function is called by the \c MandelbrotWidget - whenever it needs to generate a new image of the Mandelbrot set. - The \c centerX, \c centerY, and \c scaleFactor parameters specify - the portion of the fractal to render; \c resultSize specifies the - size of the resulting QImage. - - The function stores the parameters in member variables. If the - thread isn't already running, it starts it; otherwise, it sets \c - restart to \c true (telling \c run() to stop any unfinished - computation and start again with the new parameters) and wakes up - the thread, which might be sleeping. - - \snippet mandelbrot/renderthread.cpp 3 - - \c run() is quite a big function, so we'll break it down into - parts. - - The function body is an infinite loop which starts by storing the - rendering parameters in local variables. As usual, we protect - accesses to the member variables using the class's mutex. Storing - the member variables in local variables allows us to minimize the - amout of code that needs to be protected by a mutex. This ensures - that the main thread will never have to block for too long when - it needs to access \c{RenderThread}'s member variables (e.g., in - \c render()). - - The \c forever keyword is, like \c foreach, a Qt pseudo-keyword. - - \snippet mandelbrot/renderthread.cpp 4 - \snippet mandelbrot/renderthread.cpp 5 - \snippet mandelbrot/renderthread.cpp 6 - \snippet mandelbrot/renderthread.cpp 7 - - Then comes the core of the algorithm. Instead of trying to create - a perfect Mandelbrot set image, we do multiple passes and - generate more and more precise (and computationally expensive) - approximations of the fractal. - - If we discover inside the loop that \c restart has been set to \c - true (by \c render()), we break out of the loop immediately, so - that the control quickly returns to the very top of the outer - loop (the \c forever loop) and we fetch the new rendering - parameters. Similarly, if we discover that \c abort has been set - to \c true (by the \c RenderThread destructor), we return from - the function immediately, terminating the thread. - - The core algorithm is beyond the scope of this tutorial. - - \snippet mandelbrot/renderthread.cpp 8 - \snippet mandelbrot/renderthread.cpp 9 - - Once we're done with all the iterations, we call - QWaitCondition::wait() to put the thread to sleep by calling, - unless \c restart is \c true. There's no use in keeping a worker - thread looping indefinitely while there's nothing to do. - - \snippet mandelbrot/renderthread.cpp 10 - - The \c rgbFromWaveLength() function is a helper function that - converts a wave length to a RGB value compatible with 32-bit - \l{QImage}s. It is called from the constructor to initialize the - \c colormap array with pleasing colors. - - \section1 MandelbrotWidget Class Definition - - The \c MandelbrotWidget class uses \c RenderThread to draw the - Mandelbrot set on screen. Here's the class definition: - - \snippet mandelbrot/mandelbrotwidget.h 0 - - The widget reimplements many event handlers from QWidget. In - addition, it has an \c updatePixmap() slot that we'll connect to - the worker thread's \c renderedImage() signal to update the - display whenever we receive new data from the thread. - - Among the private variables, we have \c thread of type \c - RenderThread and \c pixmap, which contains the last rendered - image. - - \section1 MandelbrotWidget Class Implementation - - \snippet mandelbrot/mandelbrotwidget.cpp 0 - - The implementation starts with a few contants that we'll need - later on. - - \snippet mandelbrot/mandelbrotwidget.cpp 1 - - The interesting part of the constructor is the - qRegisterMetaType() and QObject::connect() calls. Let's start - with the \l{QObject::connect()}{connect()} call. - - Although it looks like a standard signal-slot connection between - two \l{QObject}s, because the signal is emitted in a different - thread than the receiver lives in, the connection is effectively a - \l{Qt::QueuedConnection}{queued connection}. These connections are - asynchronous (i.e., non-blocking), meaning that the slot will be - called at some point after the \c emit statement. What's more, the - slot will be invoked in the thread in which the receiver lives. - Here, the signal is emitted in the worker thread, and the slot is - executed in the GUI thread when control returns to the event loop. - - With queued connections, Qt must store a copy of the arguments - that were passed to the signal so that it can pass them to the - slot later on. Qt knows how to take of copy of many C++ and Qt - types, but QImage isn't one of them. We must therefore call the - template function qRegisterMetaType() before we can use QImage - as parameter in queued connections. - - \snippet mandelbrot/mandelbrotwidget.cpp 2 - \snippet mandelbrot/mandelbrotwidget.cpp 3 - \snippet mandelbrot/mandelbrotwidget.cpp 4 - - In \l{QWidget::paintEvent()}{paintEvent()}, we start by filling - the background with black. If we have nothing yet to paint (\c - pixmap is null), we print a message on the widget asking the user - to be patient and return from the function immediately. - - \snippet mandelbrot/mandelbrotwidget.cpp 5 - \snippet mandelbrot/mandelbrotwidget.cpp 6 - \snippet mandelbrot/mandelbrotwidget.cpp 7 - \snippet mandelbrot/mandelbrotwidget.cpp 8 - - If the pixmap has the right scale factor, we draw the pixmap directly onto - the widget. Otherwise, we scale and translate the \l{Coordinate - System}{coordinate system} before we draw the pixmap. By reverse mapping - the widget's rectangle using the scaled painter matrix, we also make sure - that only the exposed areas of the pixmap are drawn. The calls to - QPainter::save() and QPainter::restore() make sure that any painting - performed afterwards uses the standard coordinate system. - - \snippet mandelbrot/mandelbrotwidget.cpp 9 - - At the end of the paint event handler, we draw a text string and - a semi-transparent rectangle on top of the fractal. - - \snippet mandelbrot/mandelbrotwidget.cpp 10 - - Whenever the user resizes the widget, we call \c render() to - start generating a new image, with the same \c centerX, \c - centerY, and \c curScale parameters but with the new widget size. - - Notice that we rely on \c resizeEvent() being automatically - called by Qt when the widget is shown the first time to generate - the image the very first time. - - \snippet mandelbrot/mandelbrotwidget.cpp 11 - - The key press event handler provides a few keyboard bindings for - the benefit of users who don't have a mouse. The \c zoom() and \c - scroll() functions will be covered later. - - \snippet mandelbrot/mandelbrotwidget.cpp 12 - - The wheel event handler is reimplemented to make the mouse wheel - control the zoom level. QWheelEvent::delta() returns the angle of - the wheel mouse movement, in eights of a degree. For most mice, - one wheel step corresponds to 15 degrees. We find out how many - mouse steps we have and determine the zoom factor in consequence. - For example, if we have two wheel steps in the positive direction - (i.e., +30 degrees), the zoom factor becomes \c ZoomInFactor - to the second power, i.e. 0.8 * 0.8 = 0.64. - - \snippet mandelbrot/mandelbrotwidget.cpp 13 - - When the user presses the left mouse button, we store the mouse - pointer position in \c lastDragPos. - - \snippet mandelbrot/mandelbrotwidget.cpp 14 - - When the user moves the mouse pointer while the left mouse button - is pressed, we adjust \c pixmapOffset to paint the pixmap at a - shifted position and call QWidget::update() to force a repaint. - - \snippet mandelbrot/mandelbrotwidget.cpp 15 - - When the left mouse button is released, we update \c pixmapOffset - just like we did on a mouse move and we reset \c lastDragPos to a - default value. Then, we call \c scroll() to render a new image - for the new position. (Adjusting \c pixmapOffset isn't sufficient - because areas revealed when dragging the pixmap are drawn in - black.) - - \snippet mandelbrot/mandelbrotwidget.cpp 16 - - The \c updatePixmap() slot is invoked when the worker thread has - finished rendering an image. We start by checking whether a drag - is in effect and do nothing in that case. In the normal case, we - store the image in \c pixmap and reinitialize some of the other - members. At the end, we call QWidget::update() to refresh the - display. - - At this point, you might wonder why we use a QImage for the - parameter and a QPixmap for the data member. Why not stick to one - type? The reason is that QImage is the only class that supports - direct pixel manipulation, which we need in the worker thread. On - the other hand, before an image can be drawn on screen, it must - be converted into a pixmap. It's better to do the conversion once - and for all here, rather than in \c paintEvent(). - - \snippet mandelbrot/mandelbrotwidget.cpp 17 - - In \c zoom(), we recompute \c curScale. Then we call - QWidget::update() to draw a scaled pixmap, and we ask the worker - thread to render a new image corresponding to the new \c curScale - value. - - \snippet mandelbrot/mandelbrotwidget.cpp 18 - - \c scroll() is similar to \c zoom(), except that the affected - parameters are \c centerX and \c centerY. - - \section1 The main() Function - - The application's multithreaded nature has no impact on its \c - main() function, which is as simple as usual: - - \snippet mandelbrot/main.cpp 0 -*/ diff --git a/examples/threads/doc/src/queuedcustomtype.qdoc b/examples/threads/doc/src/queuedcustomtype.qdoc deleted file mode 100644 index 40ec2668de..0000000000 --- a/examples/threads/doc/src/queuedcustomtype.qdoc +++ /dev/null @@ -1,166 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: http://www.gnu.org/copyleft/fdl.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \example queuedcustomtype - \title Queued Custom Type Example - \brief Demonstrates multi-thread programming using Qt - \ingroup qtconcurrent-mtexamples - - \brief The Queued Custom Type example shows how to send custom types between - threads with queued signals and slots. - - \image queuedcustomtype-example.png - - Contents: - - \tableofcontents - - \section1 Overview - - In the \l{Custom Type Example}, we showed how to integrate custom types with - the meta-object system, enabling them to be stored in QVariant objects, written - out in debugging information and used in signal-slot communication. - - In this example, we create a new value class, \c Block, and register it - with the meta-object system to enable us to send instances of it between - threads using queued signals and slots. - - \section1 The Block Class - - The \c Block class is similar to the \c Message class described in the - \l{Custom Type Example}. It provides the default constructor, copy - constructor and destructor in the public section of the class that the - meta-object system requires. It describes a colored rectangle. - - \snippet queuedcustomtype/block.h custom type definition and meta-type declaration - - We will still need to register it with the meta-object system at - run-time by calling the qRegisterMetaType() template function before - we make any signal-slot connections that use this type. - Even though we do not intend to use the type with QVariant in this example, - it is good practice to also declare the new type with Q_DECLARE_METATYPE(). - - The implementation of the \c Block class is trivial, so we avoid quoting - it here. - - \section1 The Window Class - - We define a simple \c Window class with a public slot that accepts a - \c Block object. The rest of the class is concerned with managing the - user interface and handling images. - - \snippet queuedcustomtype/window.h Window class definition - - The \c Window class also contains a worker thread, provided by a - \c RenderThread object. This will emit signals to send \c Block objects - to the window's \c addBlock(Block) slot. - - The parts of the \c Window class that are most relevant are the constructor - and the \c addBlock(Block) slot. - - The constructor creates a thread for rendering images, sets up a user - interface containing a label and two push buttons that are connected to - slots in the same class. - - \snippet queuedcustomtype/window.cpp Window constructor start - \snippet queuedcustomtype/window.cpp set up widgets and connections - \snippet queuedcustomtype/window.cpp connecting signal with custom type - - In the last of these connections, we connect a signal in the - \c RenderThread object to the \c addBlock(Block) slot in the window. - - \dots - \snippet queuedcustomtype/window.cpp Window constructor finish - - The rest of the constructor simply sets up the layout of the window. - - The \c addBlock(Block) slot receives blocks from the rendering thread via - the signal-slot connection set up in the constructor: - - \snippet queuedcustomtype/window.cpp Adding blocks to the display - - We simply paint these onto the label as they arrive. - - \section1 The RenderThread Class - - The \c RenderThread class processes an image, creating \c Block objects - and using the \c sendBlock(Block) signal to send them to other components - in the example. - - \snippet queuedcustomtype/renderthread.h RenderThread class definition - - The constructor and destructor are not quoted here. These take care of - setting up the thread's internal state and cleaning up when it is destroyed. - - Processing is started with the \c processImage() function, which calls the - \c RenderThread class's reimplementation of the QThread::run() function: - - \snippet queuedcustomtype/renderthread.cpp processing the image (start) - - Ignoring the details of the way the image is processed, we see that the - signal containing a block is emitted in the usual way: - - \dots - \snippet queuedcustomtype/renderthread.cpp processing the image (finish) - - Each signal that is emitted will be queued and delivered later to the - window's \c addBlock(Block) slot. - - \section1 Registering the Type - - In the example's \c{main()} function, we perform the registration of the - \c Block class as a custom type with the meta-object system by calling the - qRegisterMetaType() template function: - - \snippet queuedcustomtype/main.cpp main function - - This call is placed here to ensure that the type is registered before any - signal-slot connections are made that use it. - - The rest of the \c{main()} function is concerned with setting a seed for - the pseudo-random number generator, creating and showing the window, and - setting a default image. See the source code for the implementation of the - \c createImage() function. - - \section1 Further Reading - - This example showed how a custom type can be registered with the - meta-object system so that it can be used with signal-slot connections - between threads. For ordinary communication involving direct signals and - slots, it is enough to simply declare the type in the way described in the - \l{Custom Type Example}. - - In practice, both the Q_DECLARE_METATYPE() macro and the qRegisterMetaType() - template function can be used to register custom types, but - qRegisterMetaType() is only required if you need to perform signal-slot - communication or need to create and destroy objects of the custom type - at run-time. - - More information on using custom types with Qt can be found in the - \l{Creating Custom Qt Types} document. -*/ diff --git a/examples/threads/doc/src/semaphores.qdoc b/examples/threads/doc/src/semaphores.qdoc deleted file mode 100644 index e90045f824..0000000000 --- a/examples/threads/doc/src/semaphores.qdoc +++ /dev/null @@ -1,147 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: http://www.gnu.org/copyleft/fdl.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \example semaphores - \title Semaphores Example - \brief Demonstrates multi-thread programming using Qt - \ingroup qtconcurrent-mtexamples - - \brief The Semaphores example shows how to use QSemaphore to control - access to a circular buffer shared by a producer thread and a - consumer thread. - - The producer writes data to the buffer until it reaches the end - of the buffer, at which point it restarts from the beginning, - overwriting existing data. The consumer thread reads the data as - it is produced and writes it to standard error. - - Semaphores make it possible to have a higher level of concurrency - than mutexes. If accesses to the buffer were guarded by a QMutex, - the consumer thread couldn't access the buffer at the same time - as the producer thread. Yet, there is no harm in having both - threads working on \e{different parts} of the buffer at the same - time. - - The example comprises two classes: \c Producer and \c Consumer. - Both inherit from QThread. The circular buffer used for - communicating between these two classes and the semaphores that - protect it are global variables. - - An alternative to using QSemaphore to solve the producer-consumer - problem is to use QWaitCondition and QMutex. This is what the - \l{Wait Conditions Example} does. - - \section1 Global Variables - - Let's start by reviewing the circular buffer and the associated - semaphores: - - \snippet semaphores/semaphores.cpp 0 - - \c DataSize is the amout of data that the producer will generate. - To keep the example as simple as possible, we make it a constant. - \c BufferSize is the size of the circular buffer. It is less than - \c DataSize, meaning that at some point the producer will reach - the end of the buffer and restart from the beginning. - - To synchronize the producer and the consumer, we need two - semaphores. The \c freeBytes semaphore controls the "free" area - of the buffer (the area that the producer hasn't filled with data - yet or that the consumer has already read). The \c usedBytes - semaphore controls the "used" area of the buffer (the area that - the producer has filled but that the consumer hasn't read yet). - - Together, the semaphores ensure that the producer is never more - than \c BufferSize bytes ahead of the consumer, and that the - consumer never reads data that the producer hasn't generated yet. - - The \c freeBytes semaphore is initialized with \c BufferSize, - because initially the entire buffer is empty. The \c usedBytes - semaphore is initialized to 0 (the default value if none is - specified). - - \section1 Producer Class - - Let's review the code for the \c Producer class: - - \snippet semaphores/semaphores.cpp 1 - \snippet semaphores/semaphores.cpp 2 - - The producer generates \c DataSize bytes of data. Before it - writes a byte to the circular buffer, it must acquire a "free" - byte using the \c freeBytes semaphore. The QSemaphore::acquire() - call might block if the consumer hasn't kept up the pace with the - producer. - - At the end, the producer releases a byte using the \c usedBytes - semaphore. The "free" byte has successfully been transformed into - a "used" byte, ready to be read by the consumer. - - \section1 Consumer Class - - Let's now turn to the \c Consumer class: - - \snippet semaphores/semaphores.cpp 3 - \snippet semaphores/semaphores.cpp 4 - - The code is very similar to the producer, except that this time - we acquire a "used" byte and release a "free" byte, instead of - the opposite. - - \section1 The main() Function - - In \c main(), we create the two threads and call QThread::wait() - to ensure that both threads get time to finish before we exit: - - \snippet semaphores/semaphores.cpp 5 - \snippet semaphores/semaphores.cpp 6 - - So what happens when we run the program? Initially, the producer - thread is the only one that can do anything; the consumer is - blocked waiting for the \c usedBytes semaphore to be released (its - initial \l{QSemaphore::available()}{available()} count is 0). - Once the producer has put one byte in the buffer, - \c{freeBytes.available()} is \c BufferSize - 1 and - \c{usedBytes.available()} is 1. At that point, two things can - happen: Either the consumer thread takes over and reads that - byte, or the consumer gets to produce a second byte. - - The producer-consumer model presented in this example makes it - possible to write highly concurrent multithreaded applications. - On a multiprocessor machine, the program is potentially up to - twice as fast as the equivalent mutex-based program, since the - two threads can be active at the same time on different parts of - the buffer. - - Be aware though that these benefits aren't always realized. - Acquiring and releasing a QSemaphore has a cost. In practice, it - would probably be worthwhile to divide the buffer into chunks and - to operate on chunks instead of individual bytes. The buffer size - is also a parameter that must be selected carefully, based on - experimentation. -*/ diff --git a/examples/threads/doc/src/waitconditions.qdoc b/examples/threads/doc/src/waitconditions.qdoc deleted file mode 100644 index 25c9ce88fb..0000000000 --- a/examples/threads/doc/src/waitconditions.qdoc +++ /dev/null @@ -1,154 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: http://www.gnu.org/copyleft/fdl.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \example waitconditions - \title Wait Conditions Example - \brief Demonstrates multi-thread programming using Qt - \ingroup qtconcurrent-mtexamples - - \brief The Wait Conditions example shows how to use QWaitCondition and - QMutex to control access to a circular buffer shared by a - producer thread and a consumer thread. - - The producer writes data to the buffer until it reaches the end - of the buffer, at which point it restarts from the beginning, - overwriting existing data. The consumer thread reads the data as - it is produced and writes it to standard error. - - Wait conditions make it possible to have a higher level of - concurrency than what is possible with mutexes alone. If accesses - to the buffer were simply guarded by a QMutex, the consumer - thread couldn't access the buffer at the same time as the - producer thread. Yet, there is no harm in having both threads - working on \e{different parts} of the buffer at the same time. - - The example comprises two classes: \c Producer and \c Consumer. - Both inherit from QThread. The circular buffer used for - communicating between these two classes and the synchronization - tools that protect it are global variables. - - An alternative to using QWaitCondition and QMutex to solve the - producer-consumer problem is to use QSemaphore. This is what the - \l{Semaphores Example} does. - - \section1 Global Variables - - Let's start by reviewing the circular buffer and the associated - synchronization tools: - - \snippet waitconditions/waitconditions.cpp 0 - - \c DataSize is the amount of data that the producer will generate. - To keep the example as simple as possible, we make it a constant. - \c BufferSize is the size of the circular buffer. It is less than - \c DataSize, meaning that at some point the producer will reach - the end of the buffer and restart from the beginning. - - To synchronize the producer and the consumer, we need two wait - conditions and one mutex. The \c bufferNotEmpty condition is - signalled when the producer has generated some data, telling the - consumer that it can start reading it. The \c bufferNotFull - condition is signalled when the consumer has read some data, - telling the producer that it can generate more. The \c numUsedBytes - is the number of bytes in the buffer that contain data. - - Together, the wait conditions, the mutex, and the \c numUsedBytes - counter ensure that the producer is never more than \c BufferSize - bytes ahead of the consumer, and that the consumer never reads - data that the producer hasn't generated yet. - - \section1 Producer Class - - Let's review the code for the \c Producer class: - - \snippet waitconditions/waitconditions.cpp 1 - \snippet waitconditions/waitconditions.cpp 2 - - The producer generates \c DataSize bytes of data. Before it - writes a byte to the circular buffer, it must first check whether - the buffer is full (i.e., \c numUsedBytes equals \c BufferSize). - If the buffer is full, the thread waits on the \c bufferNotFull - condition. - - At the end, the producer increments \c numUsedBytes and signalls - that the condition \c bufferNotEmpty is true, since \c - numUsedBytes is necessarily greater than 0. - - We guard all accesses to the \c numUsedBytes variable with a - mutex. In addition, the QWaitCondition::wait() function accepts a - mutex as its argument. This mutex is unlocked before the thread - is put to sleep and locked when the thread wakes up. Furthermore, - the transition from the locked state to the wait state is atomic, - to prevent race conditions from occurring. - - \section1 Consumer Class - - Let's turn to the \c Consumer class: - - \snippet waitconditions/waitconditions.cpp 3 - \snippet waitconditions/waitconditions.cpp 4 - - The code is very similar to the producer. Before we read the - byte, we check whether the buffer is empty (\c numUsedBytes is 0) - instead of whether it's full and wait on the \c bufferNotEmpty - condition if it's empty. After we've read the byte, we decrement - \c numUsedBytes (instead of incrementing it), and we signal the - \c bufferNotFull condition (instead of the \c bufferNotEmpty - condition). - - \section1 The main() Function - - In \c main(), we create the two threads and call QThread::wait() - to ensure that both threads get time to finish before we exit: - - \snippet waitconditions/waitconditions.cpp 5 - \snippet waitconditions/waitconditions.cpp 6 - - So what happens when we run the program? Initially, the producer - thread is the only one that can do anything; the consumer is - blocked waiting for the \c bufferNotEmpty condition to be - signalled (\c numUsedBytes is 0). Once the producer has put one - byte in the buffer, \c numUsedBytes is \c BufferSize - 1 and the - \c bufferNotEmpty condition is signalled. At that point, two - things can happen: Either the consumer thread takes over and - reads that byte, or the consumer gets to produce a second byte. - - The producer-consumer model presented in this example makes it - possible to write highly concurrent multithreaded applications. - On a multiprocessor machine, the program is potentially up to - twice as fast as the equivalent mutex-based program, since the - two threads can be active at the same time on different parts of - the buffer. - - Be aware though that these benefits aren't always realized. - Locking and unlocking a QMutex has a cost. In practice, it would - probably be worthwhile to divide the buffer into chunks and to - operate on chunks instead of individual bytes. The buffer size is - also a parameter that must be selected carefully, based on - experimentation. -*/ diff --git a/examples/threads/mandelbrot/main.cpp b/examples/threads/mandelbrot/main.cpp deleted file mode 100644 index 8334d94f9c..0000000000 --- a/examples/threads/mandelbrot/main.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mandelbrotwidget.h" - -#include - -//! [0] -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - MandelbrotWidget widget; - widget.show(); - return app.exec(); -} -//! [0] diff --git a/examples/threads/mandelbrot/mandelbrot.pro b/examples/threads/mandelbrot/mandelbrot.pro deleted file mode 100644 index 45f21baf08..0000000000 --- a/examples/threads/mandelbrot/mandelbrot.pro +++ /dev/null @@ -1,13 +0,0 @@ -QT += widgets - -HEADERS = mandelbrotwidget.h \ - renderthread.h -SOURCES = main.cpp \ - mandelbrotwidget.cpp \ - renderthread.cpp - -unix:!mac:!vxworks:!integrity:LIBS += -lm - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/threads/mandelbrot -INSTALLS += target diff --git a/examples/threads/mandelbrot/mandelbrotwidget.cpp b/examples/threads/mandelbrot/mandelbrotwidget.cpp deleted file mode 100644 index 633d4a1ec5..0000000000 --- a/examples/threads/mandelbrot/mandelbrotwidget.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -#include - -#include "mandelbrotwidget.h" - - -//! [0] -const double DefaultCenterX = -0.637011f; -const double DefaultCenterY = -0.0395159f; -const double DefaultScale = 0.00403897f; - -const double ZoomInFactor = 0.8f; -const double ZoomOutFactor = 1 / ZoomInFactor; -const int ScrollStep = 20; -//! [0] - -//! [1] -MandelbrotWidget::MandelbrotWidget(QWidget *parent) - : QWidget(parent) -{ - centerX = DefaultCenterX; - centerY = DefaultCenterY; - pixmapScale = DefaultScale; - curScale = DefaultScale; - - connect(&thread, SIGNAL(renderedImage(QImage,double)), this, SLOT(updatePixmap(QImage,double))); - - setWindowTitle(tr("Mandelbrot")); -#ifndef QT_NO_CURSOR - setCursor(Qt::CrossCursor); -#endif - resize(550, 400); - -} -//! [1] - -//! [2] -void MandelbrotWidget::paintEvent(QPaintEvent * /* event */) -{ - QPainter painter(this); - painter.fillRect(rect(), Qt::black); - - if (pixmap.isNull()) { - painter.setPen(Qt::white); - painter.drawText(rect(), Qt::AlignCenter, tr("Rendering initial image, please wait...")); -//! [2] //! [3] - return; -//! [3] //! [4] - } -//! [4] - -//! [5] - if (curScale == pixmapScale) { -//! [5] //! [6] - painter.drawPixmap(pixmapOffset, pixmap); -//! [6] //! [7] - } else { -//! [7] //! [8] - double scaleFactor = pixmapScale / curScale; - int newWidth = int(pixmap.width() * scaleFactor); - int newHeight = int(pixmap.height() * scaleFactor); - int newX = pixmapOffset.x() + (pixmap.width() - newWidth) / 2; - int newY = pixmapOffset.y() + (pixmap.height() - newHeight) / 2; - - painter.save(); - painter.translate(newX, newY); - painter.scale(scaleFactor, scaleFactor); - QRectF exposed = painter.matrix().inverted().mapRect(rect()).adjusted(-1, -1, 1, 1); - painter.drawPixmap(exposed, pixmap, exposed); - painter.restore(); - } -//! [8] //! [9] - - QString text = tr("Use mouse wheel or the '+' and '-' keys to zoom. " - "Press and hold left mouse button to scroll."); - QFontMetrics metrics = painter.fontMetrics(); - int textWidth = metrics.width(text); - - painter.setPen(Qt::NoPen); - painter.setBrush(QColor(0, 0, 0, 127)); - painter.drawRect((width() - textWidth) / 2 - 5, 0, textWidth + 10, metrics.lineSpacing() + 5); - painter.setPen(Qt::white); - painter.drawText((width() - textWidth) / 2, metrics.leading() + metrics.ascent(), text); -} -//! [9] - -//! [10] -void MandelbrotWidget::resizeEvent(QResizeEvent * /* event */) -{ - thread.render(centerX, centerY, curScale, size()); -} -//! [10] - -//! [11] -void MandelbrotWidget::keyPressEvent(QKeyEvent *event) -{ - switch (event->key()) { - case Qt::Key_Plus: - zoom(ZoomInFactor); - break; - case Qt::Key_Minus: - zoom(ZoomOutFactor); - break; - case Qt::Key_Left: - scroll(-ScrollStep, 0); - break; - case Qt::Key_Right: - scroll(+ScrollStep, 0); - break; - case Qt::Key_Down: - scroll(0, -ScrollStep); - break; - case Qt::Key_Up: - scroll(0, +ScrollStep); - break; - default: - QWidget::keyPressEvent(event); - } -} -//! [11] - -#ifndef QT_NO_WHEELEVENT -//! [12] -void MandelbrotWidget::wheelEvent(QWheelEvent *event) -{ - int numDegrees = event->delta() / 8; - double numSteps = numDegrees / 15.0f; - zoom(pow(ZoomInFactor, numSteps)); -} -//! [12] -#endif - -//! [13] -void MandelbrotWidget::mousePressEvent(QMouseEvent *event) -{ - if (event->button() == Qt::LeftButton) - lastDragPos = event->pos(); -} -//! [13] - -//! [14] -void MandelbrotWidget::mouseMoveEvent(QMouseEvent *event) -{ - if (event->buttons() & Qt::LeftButton) { - pixmapOffset += event->pos() - lastDragPos; - lastDragPos = event->pos(); - update(); - } -} -//! [14] - -//! [15] -void MandelbrotWidget::mouseReleaseEvent(QMouseEvent *event) -{ - if (event->button() == Qt::LeftButton) { - pixmapOffset += event->pos() - lastDragPos; - lastDragPos = QPoint(); - - int deltaX = (width() - pixmap.width()) / 2 - pixmapOffset.x(); - int deltaY = (height() - pixmap.height()) / 2 - pixmapOffset.y(); - scroll(deltaX, deltaY); - } -} -//! [15] - -//! [16] -void MandelbrotWidget::updatePixmap(const QImage &image, double scaleFactor) -{ - if (!lastDragPos.isNull()) - return; - - pixmap = QPixmap::fromImage(image); - pixmapOffset = QPoint(); - lastDragPos = QPoint(); - pixmapScale = scaleFactor; - update(); -} -//! [16] - -//! [17] -void MandelbrotWidget::zoom(double zoomFactor) -{ - curScale *= zoomFactor; - update(); - thread.render(centerX, centerY, curScale, size()); -} -//! [17] - -//! [18] -void MandelbrotWidget::scroll(int deltaX, int deltaY) -{ - centerX += deltaX * curScale; - centerY += deltaY * curScale; - update(); - thread.render(centerX, centerY, curScale, size()); -} -//! [18] diff --git a/examples/threads/mandelbrot/mandelbrotwidget.h b/examples/threads/mandelbrot/mandelbrotwidget.h deleted file mode 100644 index 183edf2e26..0000000000 --- a/examples/threads/mandelbrot/mandelbrotwidget.h +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MANDELBROTWIDGET_H -#define MANDELBROTWIDGET_H - -#include -#include -#include "renderthread.h" - - -//! [0] -class MandelbrotWidget : public QWidget -{ - Q_OBJECT - -public: - MandelbrotWidget(QWidget *parent = 0); - -protected: - void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; - void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; - void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; -#ifndef QT_NO_WHEELEVENT - void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; -#endif - void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - -private slots: - void updatePixmap(const QImage &image, double scaleFactor); - void zoom(double zoomFactor); - -private: - void scroll(int deltaX, int deltaY); - - RenderThread thread; - QPixmap pixmap; - QPoint pixmapOffset; - QPoint lastDragPos; - double centerX; - double centerY; - double pixmapScale; - double curScale; -}; -//! [0] - -#endif // MANDELBROTWIDGET_H diff --git a/examples/threads/mandelbrot/renderthread.cpp b/examples/threads/mandelbrot/renderthread.cpp deleted file mode 100644 index 5779c65c9c..0000000000 --- a/examples/threads/mandelbrot/renderthread.cpp +++ /dev/null @@ -1,215 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "renderthread.h" - -#include - -#include - -//! [0] -RenderThread::RenderThread(QObject *parent) - : QThread(parent) -{ - restart = false; - abort = false; - - for (int i = 0; i < ColormapSize; ++i) - colormap[i] = rgbFromWaveLength(380.0 + (i * 400.0 / ColormapSize)); -} -//! [0] - -//! [1] -RenderThread::~RenderThread() -{ - mutex.lock(); - abort = true; - condition.wakeOne(); - mutex.unlock(); - - wait(); -} -//! [1] - -//! [2] -void RenderThread::render(double centerX, double centerY, double scaleFactor, - QSize resultSize) -{ - QMutexLocker locker(&mutex); - - this->centerX = centerX; - this->centerY = centerY; - this->scaleFactor = scaleFactor; - this->resultSize = resultSize; - - if (!isRunning()) { - start(LowPriority); - } else { - restart = true; - condition.wakeOne(); - } -} -//! [2] - -//! [3] -void RenderThread::run() -{ - forever { - mutex.lock(); - QSize resultSize = this->resultSize; - double scaleFactor = this->scaleFactor; - double centerX = this->centerX; - double centerY = this->centerY; - mutex.unlock(); -//! [3] - -//! [4] - int halfWidth = resultSize.width() / 2; -//! [4] //! [5] - int halfHeight = resultSize.height() / 2; - QImage image(resultSize, QImage::Format_RGB32); - - const int NumPasses = 8; - int pass = 0; - while (pass < NumPasses) { - const int MaxIterations = (1 << (2 * pass + 6)) + 32; - const int Limit = 4; - bool allBlack = true; - - for (int y = -halfHeight; y < halfHeight; ++y) { - if (restart) - break; - if (abort) - return; - - uint *scanLine = - reinterpret_cast(image.scanLine(y + halfHeight)); - double ay = centerY + (y * scaleFactor); - - for (int x = -halfWidth; x < halfWidth; ++x) { - double ax = centerX + (x * scaleFactor); - double a1 = ax; - double b1 = ay; - int numIterations = 0; - - do { - ++numIterations; - double a2 = (a1 * a1) - (b1 * b1) + ax; - double b2 = (2 * a1 * b1) + ay; - if ((a2 * a2) + (b2 * b2) > Limit) - break; - - ++numIterations; - a1 = (a2 * a2) - (b2 * b2) + ax; - b1 = (2 * a2 * b2) + ay; - if ((a1 * a1) + (b1 * b1) > Limit) - break; - } while (numIterations < MaxIterations); - - if (numIterations < MaxIterations) { - *scanLine++ = colormap[numIterations % ColormapSize]; - allBlack = false; - } else { - *scanLine++ = qRgb(0, 0, 0); - } - } - } - - if (allBlack && pass == 0) { - pass = 4; - } else { - if (!restart) - emit renderedImage(image, scaleFactor); -//! [5] //! [6] - ++pass; - } -//! [6] //! [7] - } -//! [7] - -//! [8] - mutex.lock(); -//! [8] //! [9] - if (!restart) - condition.wait(&mutex); - restart = false; - mutex.unlock(); - } -} -//! [9] - -//! [10] -uint RenderThread::rgbFromWaveLength(double wave) -{ - double r = 0.0; - double g = 0.0; - double b = 0.0; - - if (wave >= 380.0 && wave <= 440.0) { - r = -1.0 * (wave - 440.0) / (440.0 - 380.0); - b = 1.0; - } else if (wave >= 440.0 && wave <= 490.0) { - g = (wave - 440.0) / (490.0 - 440.0); - b = 1.0; - } else if (wave >= 490.0 && wave <= 510.0) { - g = 1.0; - b = -1.0 * (wave - 510.0) / (510.0 - 490.0); - } else if (wave >= 510.0 && wave <= 580.0) { - r = (wave - 510.0) / (580.0 - 510.0); - g = 1.0; - } else if (wave >= 580.0 && wave <= 645.0) { - r = 1.0; - g = -1.0 * (wave - 645.0) / (645.0 - 580.0); - } else if (wave >= 645.0 && wave <= 780.0) { - r = 1.0; - } - - double s = 1.0; - if (wave > 700.0) - s = 0.3 + 0.7 * (780.0 - wave) / (780.0 - 700.0); - else if (wave < 420.0) - s = 0.3 + 0.7 * (wave - 380.0) / (420.0 - 380.0); - - r = pow(r * s, 0.8); - g = pow(g * s, 0.8); - b = pow(b * s, 0.8); - return qRgb(int(r * 255), int(g * 255), int(b * 255)); -} -//! [10] diff --git a/examples/threads/mandelbrot/renderthread.h b/examples/threads/mandelbrot/renderthread.h deleted file mode 100644 index 881870665f..0000000000 --- a/examples/threads/mandelbrot/renderthread.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef RENDERTHREAD_H -#define RENDERTHREAD_H - -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE -class QImage; -QT_END_NAMESPACE - -//! [0] -class RenderThread : public QThread -{ - Q_OBJECT - -public: - RenderThread(QObject *parent = 0); - ~RenderThread(); - - void render(double centerX, double centerY, double scaleFactor, QSize resultSize); - -signals: - void renderedImage(const QImage &image, double scaleFactor); - -protected: - void run() Q_DECL_OVERRIDE; - -private: - uint rgbFromWaveLength(double wave); - - QMutex mutex; - QWaitCondition condition; - double centerX; - double centerY; - double scaleFactor; - QSize resultSize; - bool restart; - bool abort; - - enum { ColormapSize = 512 }; - uint colormap[ColormapSize]; -}; -//! [0] - -#endif // RENDERTHREAD_H diff --git a/examples/threads/queuedcustomtype/block.cpp b/examples/threads/queuedcustomtype/block.cpp deleted file mode 100644 index 07bd58cd97..0000000000 --- a/examples/threads/queuedcustomtype/block.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include "block.h" - -Block::Block() -{ -} - -Block::Block(const Block &other) -{ - m_rect = other.m_rect; - m_color = other.m_color; -} - -Block::~Block() -{ -} - -Block::Block(const QRect &rect, const QColor &color) -{ - m_rect = rect; - m_color = color; -} - -QColor Block::color() const -{ - return m_color; -} - -QRect Block::rect() const -{ - return m_rect; -} diff --git a/examples/threads/queuedcustomtype/block.h b/examples/threads/queuedcustomtype/block.h deleted file mode 100644 index f9930340e2..0000000000 --- a/examples/threads/queuedcustomtype/block.h +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef BLOCK_H -#define BLOCK_H - -#include -#include -#include -#include - -//! [custom type definition and meta-type declaration] -class Block -{ -public: - Block(); - Block(const Block &other); - ~Block(); - - Block(const QRect &rect, const QColor &color); - - QColor color() const; - QRect rect() const; - -private: - QRect m_rect; - QColor m_color; -}; - -Q_DECLARE_METATYPE(Block); -//! [custom type definition and meta-type declaration] - -#endif diff --git a/examples/threads/queuedcustomtype/main.cpp b/examples/threads/queuedcustomtype/main.cpp deleted file mode 100644 index 98933c66f3..0000000000 --- a/examples/threads/queuedcustomtype/main.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include "block.h" -#include "window.h" - -QImage createImage(int width, int height) -{ - QImage image(width, height, QImage::Format_RGB16); - QPainter painter; - QPen pen; - pen.setStyle(Qt::NoPen); - QBrush brush(Qt::blue); - - painter.begin(&image); - painter.fillRect(image.rect(), brush); - brush.setColor(Qt::white); - painter.setPen(pen); - painter.setBrush(brush); - - static const QPointF points1[3] = { - QPointF(4, 4), - QPointF(7, 4), - QPointF(5.5, 1) - }; - - static const QPointF points2[3] = { - QPointF(1, 4), - QPointF(7, 4), - QPointF(10, 10) - }; - - static const QPointF points3[3] = { - QPointF(4, 4), - QPointF(10, 4), - QPointF(1, 10) - }; - - painter.setWindow(0, 0, 10, 10); - - int x = 0; - int y = 0; - int starWidth = image.width()/3; - int starHeight = image.height()/3; - - QRect rect(x, y, starWidth, starHeight); - - for (int i = 0; i < 9; ++i) { - - painter.setViewport(rect); - painter.drawPolygon(points1, 3); - painter.drawPolygon(points2, 3); - painter.drawPolygon(points3, 3); - - if (i % 3 == 2) { - y = y + starHeight; - rect.moveTop(y); - - x = 0; - rect.moveLeft(x); - - } else { - x = x + starWidth; - rect.moveLeft(x); - } - } - - painter.end(); - return image; -} - -//! [main function] //! [main start] -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); -//! [main start] //! [register meta-type for queued communications] - qRegisterMetaType(); -//! [register meta-type for queued communications] - qsrand(QTime::currentTime().elapsed()); - - Window window; - window.show(); - - window.loadImage(createImage(256, 256)); -//! [main finish] - return app.exec(); -} -//! [main finish] //! [main function] diff --git a/examples/threads/queuedcustomtype/queuedcustomtype.pro b/examples/threads/queuedcustomtype/queuedcustomtype.pro deleted file mode 100644 index 8b18b13ba6..0000000000 --- a/examples/threads/queuedcustomtype/queuedcustomtype.pro +++ /dev/null @@ -1,14 +0,0 @@ -HEADERS = block.h \ - renderthread.h \ - window.h -SOURCES = main.cpp \ - block.cpp \ - renderthread.cpp \ - window.cpp -QT += widgets - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/threads/mandelbrot -INSTALLS += target - - diff --git a/examples/threads/queuedcustomtype/renderthread.cpp b/examples/threads/queuedcustomtype/renderthread.cpp deleted file mode 100644 index 50a638987f..0000000000 --- a/examples/threads/queuedcustomtype/renderthread.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "renderthread.h" - -RenderThread::RenderThread(QObject *parent) - : QThread(parent) -{ - m_abort = false; -} - -RenderThread::~RenderThread() -{ - mutex.lock(); - m_abort = true; - mutex.unlock(); - - wait(); -} - -//![processing the image (start)] -void RenderThread::processImage(const QImage &image) -{ - if (image.isNull()) - return; - - m_image = image; - m_abort = false; - start(); -} - -void RenderThread::run() -{ - int size = qMax(m_image.width()/20, m_image.height()/20); - for (int s = size; s > 0; --s) { - for (int c = 0; c < 400; ++c) { -//![processing the image (start)] - int x1 = qMax(0, (qrand() % m_image.width()) - s/2); - int x2 = qMin(x1 + s/2 + 1, m_image.width()); - int y1 = qMax(0, (qrand() % m_image.height()) - s/2); - int y2 = qMin(y1 + s/2 + 1, m_image.height()); - int n = 0; - int red = 0; - int green = 0; - int blue = 0; - for (int i = y1; i < y2; ++i) { - for (int j = x1; j < x2; ++j) { - QRgb pixel = m_image.pixel(j, i); - red += qRed(pixel); - green += qGreen(pixel); - blue += qBlue(pixel); - n += 1; - } - } -//![processing the image (finish)] - Block block(QRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1), - QColor(red/n, green/n, blue/n)); - emit sendBlock(block); - if (m_abort) - return; - msleep(10); - } - } -} -//![processing the image (finish)] - -void RenderThread::stopProcess() -{ - mutex.lock(); - m_abort = true; - mutex.unlock(); -} diff --git a/examples/threads/queuedcustomtype/renderthread.h b/examples/threads/queuedcustomtype/renderthread.h deleted file mode 100644 index 5630926d41..0000000000 --- a/examples/threads/queuedcustomtype/renderthread.h +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef RENDERTHREAD_H -#define RENDERTHREAD_H - -#include -#include -#include -#include "block.h" - -//! [RenderThread class definition] -class RenderThread : public QThread -{ - Q_OBJECT - -public: - RenderThread(QObject *parent = 0); - ~RenderThread(); - - void processImage(const QImage &image); - -signals: - void sendBlock(const Block &block); - -public slots: - void stopProcess(); - -protected: - void run(); - -private: - bool m_abort; - QImage m_image; - QMutex mutex; -}; -//! [RenderThread class definition] - -#endif diff --git a/examples/threads/queuedcustomtype/window.cpp b/examples/threads/queuedcustomtype/window.cpp deleted file mode 100644 index 8afb8b6782..0000000000 --- a/examples/threads/queuedcustomtype/window.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include "window.h" - -//! [Window constructor start] -Window::Window() -{ - thread = new RenderThread(); -//! [Window constructor start] //! [set up widgets and connections] - - label = new QLabel(); - label->setAlignment(Qt::AlignCenter); - - loadButton = new QPushButton(tr("&Load image...")); - resetButton = new QPushButton(tr("&Stop")); - resetButton->setEnabled(false); - - connect(loadButton, SIGNAL(clicked()), this, SLOT(loadImage())); - connect(resetButton, SIGNAL(clicked()), thread, SLOT(stopProcess())); - connect(thread, SIGNAL(finished()), this, SLOT(resetUi())); -//! [set up widgets and connections] //! [connecting signal with custom type] - connect(thread, SIGNAL(sendBlock(Block)), this, SLOT(addBlock(Block))); -//! [connecting signal with custom type] - - QHBoxLayout *buttonLayout = new QHBoxLayout(); - buttonLayout->addStretch(); - buttonLayout->addWidget(loadButton); - buttonLayout->addWidget(resetButton); - buttonLayout->addStretch(); - - QVBoxLayout *layout = new QVBoxLayout(this); - layout->addWidget(label); - layout->addLayout(buttonLayout); - -//! [Window constructor finish] - setWindowTitle(tr("Queued Custom Type")); -} -//! [Window constructor finish] - -void Window::loadImage() -{ - QStringList formats; - foreach (QByteArray format, QImageReader::supportedImageFormats()) - if (format.toLower() == format) - formats.append("*." + format); - - QString newPath = QFileDialog::getOpenFileName(this, tr("Open Image"), - path, tr("Image files (%1)").arg(formats.join(' '))); - - if (newPath.isEmpty()) - return; - - QImage image(newPath); - if (!image.isNull()) { - loadImage(image); - path = newPath; - } -} - -void Window::loadImage(const QImage &image) -{ - QDesktopWidget desktop; - QImage useImage; - QRect space = desktop.availableGeometry(); - if (image.width() > 0.75*space.width() || image.height() > 0.75*space.height()) - useImage = image.scaled(0.75*space.width(), 0.75*space.height(), - Qt::KeepAspectRatio, Qt::SmoothTransformation); - else - useImage = image; - - pixmap = QPixmap(useImage.width(), useImage.height()); - pixmap.fill(qRgb(255, 255, 255)); - label->setPixmap(pixmap); - loadButton->setEnabled(false); - resetButton->setEnabled(true); - thread->processImage(useImage); -} - -//! [Adding blocks to the display] -void Window::addBlock(const Block &block) -{ - QColor color = block.color(); - color.setAlpha(64); - - QPainter painter; - painter.begin(&pixmap); - painter.fillRect(block.rect(), color); - painter.end(); - label->setPixmap(pixmap); -} -//! [Adding blocks to the display] - -void Window::resetUi() -{ - loadButton->setEnabled(true); - resetButton->setEnabled(false); -} diff --git a/examples/threads/queuedcustomtype/window.h b/examples/threads/queuedcustomtype/window.h deleted file mode 100644 index cb648f1be2..0000000000 --- a/examples/threads/queuedcustomtype/window.h +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef WINDOW_H -#define WINDOW_H - -#include -#include "renderthread.h" - -class QLabel; -class QPushButton; - -//! [Window class definition] -class Window : public QWidget -{ - Q_OBJECT - -public: - Window(); - void loadImage(const QImage &image); - -public slots: - void addBlock(const Block &block); - -private slots: - void loadImage(); - void resetUi(); - -private: - QLabel *label; - QPixmap pixmap; - QPushButton *loadButton; - QPushButton *resetButton; - QString path; - RenderThread *thread; -}; -//! [Window class definition] - -#endif diff --git a/examples/threads/semaphores/semaphores.cpp b/examples/threads/semaphores/semaphores.cpp deleted file mode 100644 index f519e5f323..0000000000 --- a/examples/threads/semaphores/semaphores.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include -#include - -//! [0] -const int DataSize = 100000; - -const int BufferSize = 8192; -char buffer[BufferSize]; - -QSemaphore freeBytes(BufferSize); -QSemaphore usedBytes; -//! [0] - -//! [1] -class Producer : public QThread -//! [1] //! [2] -{ -public: - void run() Q_DECL_OVERRIDE - { - qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); - for (int i = 0; i < DataSize; ++i) { - freeBytes.acquire(); - buffer[i % BufferSize] = "ACGT"[(int)qrand() % 4]; - usedBytes.release(); - } - } -}; -//! [2] - -//! [3] -class Consumer : public QThread -//! [3] //! [4] -{ - Q_OBJECT -public: - void run() Q_DECL_OVERRIDE - { - for (int i = 0; i < DataSize; ++i) { - usedBytes.acquire(); - fprintf(stderr, "%c", buffer[i % BufferSize]); - freeBytes.release(); - } - fprintf(stderr, "\n"); - } - -signals: - void stringConsumed(const QString &text); - -protected: - bool finish; -}; -//! [4] - -//! [5] -int main(int argc, char *argv[]) -//! [5] //! [6] -{ - QCoreApplication app(argc, argv); - Producer producer; - Consumer consumer; - producer.start(); - consumer.start(); - producer.wait(); - consumer.wait(); - return 0; -} -//! [6] - -#include "semaphores.moc" diff --git a/examples/threads/semaphores/semaphores.pro b/examples/threads/semaphores/semaphores.pro deleted file mode 100644 index 7dfe7c3ba0..0000000000 --- a/examples/threads/semaphores/semaphores.pro +++ /dev/null @@ -1,9 +0,0 @@ -SOURCES += semaphores.cpp -QT = core - -CONFIG -= app_bundle -CONFIG += console - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/threads/semaphores -INSTALLS += target diff --git a/examples/threads/threads.pro b/examples/threads/threads.pro deleted file mode 100644 index e47da84a06..0000000000 --- a/examples/threads/threads.pro +++ /dev/null @@ -1,7 +0,0 @@ -TEMPLATE = subdirs -CONFIG += no_docs_target - -SUBDIRS = semaphores \ - waitconditions - -qtHaveModule(widgets): SUBDIRS += mandelbrot diff --git a/examples/threads/waitconditions/waitconditions.cpp b/examples/threads/waitconditions/waitconditions.cpp deleted file mode 100644 index b0336f4c2b..0000000000 --- a/examples/threads/waitconditions/waitconditions.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include -#include - -//! [0] -const int DataSize = 100000; - -const int BufferSize = 8192; -char buffer[BufferSize]; - -QWaitCondition bufferNotEmpty; -QWaitCondition bufferNotFull; -QMutex mutex; -int numUsedBytes = 0; -//! [0] - -//! [1] -class Producer : public QThread -//! [1] //! [2] -{ -public: - Producer(QObject *parent = NULL) : QThread(parent) - { - } - - void run() Q_DECL_OVERRIDE - { - qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); - - for (int i = 0; i < DataSize; ++i) { - mutex.lock(); - if (numUsedBytes == BufferSize) - bufferNotFull.wait(&mutex); - mutex.unlock(); - - buffer[i % BufferSize] = "ACGT"[(int)qrand() % 4]; - - mutex.lock(); - ++numUsedBytes; - bufferNotEmpty.wakeAll(); - mutex.unlock(); - } - } -}; -//! [2] - -//! [3] -class Consumer : public QThread -//! [3] //! [4] -{ - Q_OBJECT -public: - Consumer(QObject *parent = NULL) : QThread(parent) - { - } - - void run() Q_DECL_OVERRIDE - { - for (int i = 0; i < DataSize; ++i) { - mutex.lock(); - if (numUsedBytes == 0) - bufferNotEmpty.wait(&mutex); - mutex.unlock(); - - fprintf(stderr, "%c", buffer[i % BufferSize]); - - mutex.lock(); - --numUsedBytes; - bufferNotFull.wakeAll(); - mutex.unlock(); - } - fprintf(stderr, "\n"); - } - -signals: - void stringConsumed(const QString &text); -}; -//! [4] - - -//! [5] -int main(int argc, char *argv[]) -//! [5] //! [6] -{ - QCoreApplication app(argc, argv); - Producer producer; - Consumer consumer; - producer.start(); - consumer.start(); - producer.wait(); - consumer.wait(); - return 0; -} -//! [6] - -#include "waitconditions.moc" diff --git a/examples/threads/waitconditions/waitconditions.pro b/examples/threads/waitconditions/waitconditions.pro deleted file mode 100644 index 7f9491a0b1..0000000000 --- a/examples/threads/waitconditions/waitconditions.pro +++ /dev/null @@ -1,9 +0,0 @@ -QT = core -CONFIG -= moc app_bundle -CONFIG += console - -SOURCES += waitconditions.cpp - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/threads/waitconditions -INSTALLS += target diff --git a/examples/tools/README b/examples/tools/README deleted file mode 100644 index db5c107c82..0000000000 --- a/examples/tools/README +++ /dev/null @@ -1,9 +0,0 @@ -Qt is equipped with a range of capable tool classes, from containers and -iterators to classes for string handling and manipulation. - -Other classes provide application infrastructure support, handling plugin -loading and managing configuration files. - - -Documentation for these examples can be found via the Examples -link in the main Qt documentation. diff --git a/examples/tools/contiguouscache/contiguouscache.pro b/examples/tools/contiguouscache/contiguouscache.pro deleted file mode 100644 index d384a1845a..0000000000 --- a/examples/tools/contiguouscache/contiguouscache.pro +++ /dev/null @@ -1,9 +0,0 @@ -QT += widgets - -HEADERS = randomlistmodel.h -SOURCES = randomlistmodel.cpp \ - main.cpp - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/tools/contiguouscache -INSTALLS += target diff --git a/examples/tools/contiguouscache/main.cpp b/examples/tools/contiguouscache/main.cpp deleted file mode 100644 index 62fa8dcf42..0000000000 --- a/examples/tools/contiguouscache/main.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "randomlistmodel.h" -#include -#include - -int main(int c, char **v) -{ - QApplication a(c, v); - - QListView view; - view.setUniformItemSizes(true); - view.setModel(new RandomListModel(&view)); - view.show(); - - return a.exec(); -} diff --git a/examples/tools/contiguouscache/randomlistmodel.cpp b/examples/tools/contiguouscache/randomlistmodel.cpp deleted file mode 100644 index cd1a301dc7..0000000000 --- a/examples/tools/contiguouscache/randomlistmodel.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "randomlistmodel.h" -#include - -static const int bufferSize(500); -static const int lookAhead(100); -static const int halfLookAhead(lookAhead/2); - -RandomListModel::RandomListModel(QObject *parent) -: QAbstractListModel(parent), m_rows(bufferSize), m_count(10000) -{ -} - -RandomListModel::~RandomListModel() -{ -} - -int RandomListModel::rowCount(const QModelIndex &) const -{ - return m_count; -} - -//! [0] -QVariant RandomListModel::data(const QModelIndex &index, int role) const -{ - if (role != Qt::DisplayRole) - return QVariant(); - - int row = index.row(); - - if (row > m_rows.lastIndex()) { - if (row - m_rows.lastIndex() > lookAhead) - cacheRows(row-halfLookAhead, qMin(m_count, row+halfLookAhead)); - else while (row > m_rows.lastIndex()) - m_rows.append(fetchRow(m_rows.lastIndex()+1)); - } else if (row < m_rows.firstIndex()) { - if (m_rows.firstIndex() - row > lookAhead) - cacheRows(qMax(0, row-halfLookAhead), row+halfLookAhead); - else while (row < m_rows.firstIndex()) - m_rows.prepend(fetchRow(m_rows.firstIndex()-1)); - } - - return m_rows.at(row); -} - -void RandomListModel::cacheRows(int from, int to) const -{ - for (int i = from; i <= to; ++i) - m_rows.insert(i, fetchRow(i)); -} -//![0] - -//![1] -QString RandomListModel::fetchRow(int position) const -{ - return QString::number(rand() % ++position); -} -//![1] diff --git a/examples/tools/contiguouscache/randomlistmodel.h b/examples/tools/contiguouscache/randomlistmodel.h deleted file mode 100644 index 3acafc23ff..0000000000 --- a/examples/tools/contiguouscache/randomlistmodel.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef RANDOMLISTMODEL_H -#define RANDOMLISTMODEL_H - -#include -#include - -QT_FORWARD_DECLARE_CLASS(QTimer) - -class RandomListModel : public QAbstractListModel -{ - Q_OBJECT -public: - RandomListModel(QObject *parent = 0); - ~RandomListModel(); - - int rowCount(const QModelIndex & = QModelIndex()) const Q_DECL_OVERRIDE; - QVariant data(const QModelIndex &, int) const Q_DECL_OVERRIDE; - -private: - void cacheRows(int, int) const; - QString fetchRow(int) const; - - mutable QContiguousCache m_rows; - const int m_count; -}; - -#endif diff --git a/examples/tools/customtype/customtype.pro b/examples/tools/customtype/customtype.pro deleted file mode 100644 index d05540f403..0000000000 --- a/examples/tools/customtype/customtype.pro +++ /dev/null @@ -1,8 +0,0 @@ -HEADERS = message.h -SOURCES = main.cpp \ - message.cpp -QT += widgets - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/tools/customcompleter -INSTALLS += target diff --git a/examples/tools/customtype/main.cpp b/examples/tools/customtype/main.cpp deleted file mode 100644 index 8e97d3db96..0000000000 --- a/examples/tools/customtype/main.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include "message.h" - -int main(int argc, char *argv[]) -{ - QCoreApplication app(argc, argv); - QStringList headers; - headers << "Subject: Hello World" - << "From: address@example.com"; - QString body = "This is a test.\r\n"; - -//! [printing a custom type] - Message message(body, headers); - qDebug() << "Original:" << message; -//! [printing a custom type] - -//! [storing a custom value] - QVariant stored; - stored.setValue(message); -//! [storing a custom value] - - qDebug() << "Stored:" << stored; - -//! [retrieving a custom value] - Message retrieved = stored.value(); - qDebug() << "Retrieved:" << retrieved; - retrieved = qvariant_cast(stored); - qDebug() << "Retrieved:" << retrieved; -//! [retrieving a custom value] - - return 0; -} diff --git a/examples/tools/customtype/message.cpp b/examples/tools/customtype/message.cpp deleted file mode 100644 index c470ab116e..0000000000 --- a/examples/tools/customtype/message.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "message.h" - -//! [Message class implementation] -Message::Message() -{ -} - -Message::Message(const Message &other) -{ - m_body = other.m_body; - m_headers = other.m_headers; -} - -Message::~Message() -{ -} -//! [Message class implementation] - -Message::Message(const QString &body, const QStringList &headers) -{ - m_body = body; - m_headers = headers; -} - -//! [custom type streaming operator] -QDebug operator<<(QDebug dbg, const Message &message) -{ - QStringList pieces = message.body().split("\r\n", QString::SkipEmptyParts); - if (pieces.isEmpty()) - dbg.nospace() << "Message()"; - else if (pieces.size() == 1) - dbg.nospace() << "Message(" << pieces.first() << ")"; - else - dbg.nospace() << "Message(" << pieces.first() << " ...)"; - return dbg.maybeSpace(); -} -//! [custom type streaming operator] - -//! [getter functions] -QString Message::body() const -{ - return m_body; -} - -QStringList Message::headers() const -{ - return m_headers; -} -//! [getter functions] diff --git a/examples/tools/customtype/message.h b/examples/tools/customtype/message.h deleted file mode 100644 index cdc4e39caf..0000000000 --- a/examples/tools/customtype/message.h +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MESSAGE_H -#define MESSAGE_H - -#include -#include -#include - -//! [custom type definition] -class Message -{ -public: - Message(); - Message(const Message &other); - ~Message(); - - Message(const QString &body, const QStringList &headers); - - QString body() const; - QStringList headers() const; - -private: - QString m_body; - QStringList m_headers; -}; -//! [custom type definition] - -//! [custom type meta-type declaration] -Q_DECLARE_METATYPE(Message); -//! [custom type meta-type declaration] - -//! [custom type streaming operator] -QDebug operator<<(QDebug dbg, const Message &message); -//! [custom type streaming operator] - -#endif diff --git a/examples/tools/customtypesending/customtypesending.pro b/examples/tools/customtypesending/customtypesending.pro deleted file mode 100644 index faa07bf339..0000000000 --- a/examples/tools/customtypesending/customtypesending.pro +++ /dev/null @@ -1,10 +0,0 @@ -HEADERS = message.h \ - window.h -SOURCES = main.cpp \ - message.cpp \ - window.cpp -QT += widgets - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/tools/customcompleter -INSTALLS += target diff --git a/examples/tools/customtypesending/main.cpp b/examples/tools/customtypesending/main.cpp deleted file mode 100644 index 5f01e2a154..0000000000 --- a/examples/tools/customtypesending/main.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include "message.h" -#include "window.h" - -//! [main function] -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - - Window window1; - QStringList headers; - headers << "Subject: Hello World" - << "From: address@example.com"; - QString body = "This is a test.\r\n"; - Message message(body, headers); - window1.setMessage(message); - - Window window2; - QObject::connect(&window1, SIGNAL(messageSent(Message)), - &window2, SLOT(setMessage(Message))); - QObject::connect(&window2, SIGNAL(messageSent(Message)), - &window1, SLOT(setMessage(Message))); - window1.show(); - window2.show(); - return app.exec(); -} -//! [main function] diff --git a/examples/tools/customtypesending/message.cpp b/examples/tools/customtypesending/message.cpp deleted file mode 100644 index 9b53b8757d..0000000000 --- a/examples/tools/customtypesending/message.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "message.h" - -Message::Message() -{ -} - -Message::Message(const Message &other) -{ - m_body = other.m_body; - m_headers = other.m_headers; -} - -Message::~Message() -{ -} - -Message::Message(const QString &body, const QStringList &headers) -{ - m_body = body; - m_headers = headers; -} - -QString Message::body() const -{ - return m_body; -} - -QStringList Message::headers() const -{ - return m_headers; -} diff --git a/examples/tools/customtypesending/message.h b/examples/tools/customtypesending/message.h deleted file mode 100644 index 3e5f17db2b..0000000000 --- a/examples/tools/customtypesending/message.h +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MESSAGE_H -#define MESSAGE_H - -#include -#include -#include - -//! [custom type definition] -class Message -{ -public: - Message(); - Message(const Message &other); - ~Message(); - - Message(const QString &body, const QStringList &headers); - - QString body() const; - QStringList headers() const; - -private: - QString m_body; - QStringList m_headers; -}; -//! [custom type definition] - -//! [custom type meta-type declaration] -Q_DECLARE_METATYPE(Message); -//! [custom type meta-type declaration] - -#endif diff --git a/examples/tools/customtypesending/window.cpp b/examples/tools/customtypesending/window.cpp deleted file mode 100644 index aa4a7eab3c..0000000000 --- a/examples/tools/customtypesending/window.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include "window.h" - -//! [Window constructor] -Window::Window() -{ - editor = new QTextEdit(); - QPushButton *sendButton = new QPushButton(tr("&Send message")); - - connect(sendButton, SIGNAL(clicked()), this, SLOT(sendMessage())); - - QHBoxLayout *buttonLayout = new QHBoxLayout(); - buttonLayout->addStretch(); - buttonLayout->addWidget(sendButton); - buttonLayout->addStretch(); - - QVBoxLayout *layout = new QVBoxLayout(this); - layout->addWidget(editor); - layout->addLayout(buttonLayout); - - setWindowTitle(tr("Custom Type Sending")); -} -//! [Window constructor] - -//! [sending a message] -void Window::sendMessage() -{ - thisMessage = Message(editor->toPlainText(), thisMessage.headers()); - emit messageSent(thisMessage); -} -//! [sending a message] - -//! [receiving a message] -void Window::setMessage(const Message &message) -{ - thisMessage = message; - editor->setPlainText(thisMessage.body()); -} -//! [receiving a message] diff --git a/examples/tools/customtypesending/window.h b/examples/tools/customtypesending/window.h deleted file mode 100644 index 0889800064..0000000000 --- a/examples/tools/customtypesending/window.h +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names -** of its contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef WINDOW_H -#define WINDOW_H - -#include -#include "message.h" - -QT_FORWARD_DECLARE_CLASS(QTextEdit) - -//! [Window class definition] -class Window : public QWidget -{ - Q_OBJECT - -public: - Window(); - -signals: - void messageSent(const Message &message); - -public slots: - void setMessage(const Message &message); - -private slots: - void sendMessage(); - -private: - Message thisMessage; - QTextEdit *editor; -}; -//! [Window class definition] - -#endif diff --git a/examples/tools/doc/contiguouscache.qdoc b/examples/tools/doc/contiguouscache.qdoc deleted file mode 100644 index 2f7ea716e6..0000000000 --- a/examples/tools/doc/contiguouscache.qdoc +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: http://www.gnu.org/copyleft/fdl.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \example contiguouscache - \title Contiguous Cache Example - - \brief The Contiguous Cache example shows how to use QContiguousCache to manage memory usage for - very large models. In some environments memory is limited and, even when it - isn't, users still dislike an application using excessive memory. - Using QContiguousCache to manage a list, rather than loading - the entire list into memory, allows the application to limit the amount - of memory it uses, regardless of the size of the data set it accesses - - The simplest way to use QContiguousCache is to cache as items are requested. When - a view requests an item at row N it is also likely to ask for items at rows near - to N. - - \snippet contiguouscache/randomlistmodel.cpp 0 - - After getting the row, the class determines if the row is in the bounds - of the contiguous cache's current range. It would have been equally valid to - simply have the following code instead. - - \code - while (row > m_rows.lastIndex()) - m_rows.append(fetchWord(m_rows.lastIndex()+1); - while (row < m_rows.firstIndex()) - m_rows.prepend(fetchWord(m_rows.firstIndex()-1); - \endcode - - However a list will often jump rows if the scroll bar is used directly, resulting in - the code above causing every row between the old and new rows to be fetched. - - Using QContiguousCache::lastIndex() and QContiguousCache::firstIndex() allows - the example to determine what part of the list the cache is currently caching. - These values don't represent the indexes into the cache's own memory, but rather - a virtual infinite array that the cache represents. - - By using QContiguousCache::append() and QContiguousCache::prepend() the code ensures - that items that may be still on the screen are not lost when the requested row - has not moved far from the current cache range. QContiguousCache::insert() can - potentially remove more than one item from the cache as QContiguousCache does not - allow for gaps. If your cache needs to quickly jump back and forth between - rows with significant gaps between them consider using QCache instead. - - And thats it. A perfectly reasonable cache, using minimal memory for a very large - list. In this case the accessor for getting the words into the cache - generates random information rather than fixed information. This allows you - to see how the cache range is kept for a local number of rows when running the - example. - - \snippet contiguouscache/randomlistmodel.cpp 1 - - It is also worth considering pre-fetching items into the cache outside of the - application's paint routine. This can be done either with a separate thread - or using a QTimer to incrementally expand the range of the cache prior to - rows being requested out of the current cache range. -*/ diff --git a/examples/tools/doc/src/customtype.qdoc b/examples/tools/doc/src/customtype.qdoc deleted file mode 100644 index e016933e04..0000000000 --- a/examples/tools/doc/src/customtype.qdoc +++ /dev/null @@ -1,143 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: http://www.gnu.org/copyleft/fdl.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \example customtype - \title Custom Type Example - - \brief The Custom Type example shows how to integrate a custom type into Qt's - meta-object system. - - Contents: - - \tableofcontents - - \section1 Overview - - Qt provides a range of standard value types that are used to provide - rich and meaningful APIs. These types are integrated with the meta-object - system, enabling them to be stored in QVariant objects, written out in - debugging information and sent between components in signal-slot - communication. - - Custom types can also be integrated with the meta-object system as long as - they are written to conform to some simple guidelines. In this example, we - introduce a simple \c Message class, we describe how we make it work with - QVariant, and we show how it can be extended to generate a printable - representation of itself for use in debugging output. - - \section1 The Message Class Definition - - The \c Message class is a simple value class that contains two pieces - of information (a QString and a QStringList), each of which can be read - using trivial getter functions: - - \snippet customtype/message.h custom type definition - - The default constructor, copy constructor and destructor are - all required, and must be public, if the type is to be integrated into the - meta-object system. Other than this, we are free to implement whatever we - need to make the type do what we want, so we also include a constructor - that lets us set the type's data members. - - To enable the type to be used with QVariant, we declare it using the - Q_DECLARE_METATYPE() macro: - - \snippet customtype/message.h custom type meta-type declaration - - We do not need to write any additional code to accompany this macro. - - To allow us to see a readable description of each \c Message object when it - is sent to the debug output stream, we define a streaming operator: - - \snippet customtype/message.h custom type streaming operator - - This facility is useful if you need to insert tracing statements in your - code for debugging purposes. - - \section1 The Message Class Implementation - - The implementation of the default constructor, copy constructor and destructor - are straightforward for the \c Message class: - - \snippet customtype/message.cpp Message class implementation - - The streaming operator is implemented in the following way: - - \snippet customtype/message.cpp custom type streaming operator - - Here, we want to represent each value depending on how many lines are stored - in the message body. We stream text to the QDebug object passed to the - operator and return the QDebug object obtained from its maybeSpace() member - function; this is described in more detail in the - \l{Creating Custom Qt Types#Making the Type Printable}{Creating Custom Qt Types} - document. - - We include the code for the getter functions for completeness: - - \snippet customtype/message.cpp getter functions - - With the type fully defined, implemented, and integrated with the - meta-object system, we can now use it. - - \section1 Using the Message - - In the example's \c{main()} function, we show how a \c Message object can - be printed to the console by sending it to the debug stream: - - \snippet customtype/main.cpp printing a custom type - - You can use the type with QVariant in exactly the same way as you would - use standard Qt value types. Here's how to store a value using the - QVariant::setValue() function: - - \snippet customtype/main.cpp storing a custom value - - Alternatively, the QVariant::fromValue() and qVariantSetValue() functions - can be used if you are using a compiler without support for member template - functions. - - The value can be retrieved using the QVariant::value() member template - function: - - \snippet customtype/main.cpp retrieving a custom value - - Alternatively, the qVariantValue() template function can be used if - you are using a compiler without support for member template functions. - - \section1 Further Reading - - The custom \c Message type can also be used with direct signal-slot - connections. - - To register a custom type for use with queued signals and slots, such as - those used in cross-thread communication, see the - \l{Queued Custom Type Example}. - - More information on using custom types with Qt can be found in the - \l{Creating Custom Qt Types} document. -*/ diff --git a/examples/tools/tools.pro b/examples/tools/tools.pro deleted file mode 100644 index 36fa776980..0000000000 --- a/examples/tools/tools.pro +++ /dev/null @@ -1,7 +0,0 @@ -requires(qtHaveModule(widgets)) - -TEMPLATE = subdirs -CONFIG += ordered -SUBDIRS = contiguouscache \ - customtype \ - customtypesending diff --git a/src/corelib/doc/qtcore.qdocconf b/src/corelib/doc/qtcore.qdocconf index 7c879cbbfd..5a14ba9088 100644 --- a/src/corelib/doc/qtcore.qdocconf +++ b/src/corelib/doc/qtcore.qdocconf @@ -4,7 +4,7 @@ project = QtCore description = Qt Core Reference Documentation version = $QT_VERSION -examplesinstallpath = core +examplesinstallpath = corelib qhp.projects = QtCore @@ -35,10 +35,7 @@ sourcedirs += .. exampledirs += \ ../ \ snippets \ - ../../../examples/threads/ \ - ../../../examples/tools/ \ - ../../../examples/ipc/ \ - ../../../examples/json/ \ + ../../../examples/corelib \ ../../../examples/network/dnslookup imagedirs += images diff --git a/src/corelib/doc/src/custom-types.qdoc b/src/corelib/doc/src/custom-types.qdoc index bac4a90829..81ce698735 100644 --- a/src/corelib/doc/src/custom-types.qdoc +++ b/src/corelib/doc/src/custom-types.qdoc @@ -61,7 +61,7 @@ The following \c Message class definition includes these members: - \snippet customtype/message.h custom type definition + \snippet tools/customtype/message.h custom type definition The class also provides a constructor for normal use and two public member functions that are used to obtain the private data. @@ -77,7 +77,7 @@ to this class, we invoke the Q_DECLARE_METATYPE() macro on the class in the header file where it is defined: - \snippet customtype/message.h custom type meta-type declaration + \snippet tools/customtype/message.h custom type meta-type declaration This now makes it possible for \c Message values to be stored in QVariant objects and retrieved later. See the \l{Custom Type Example} for code that demonstrates @@ -104,19 +104,19 @@ The \l{Queued Custom Type Example} declares a \c Block class which is registered in the \c{main.cpp} file: - \snippet queuedcustomtype/main.cpp main start + \snippet threads/queuedcustomtype/main.cpp main start \dots - \snippet queuedcustomtype/main.cpp register meta-type for queued communications + \snippet threads/queuedcustomtype/main.cpp register meta-type for queued communications \dots - \snippet queuedcustomtype/main.cpp main finish + \snippet threads/queuedcustomtype/main.cpp main finish This type is later used in a signal-slot connection in the \c{window.cpp} file: - \snippet queuedcustomtype/window.cpp Window constructor start + \snippet threads/queuedcustomtype/window.cpp Window constructor start \dots - \snippet queuedcustomtype/window.cpp connecting signal with custom type + \snippet threads/queuedcustomtype/window.cpp connecting signal with custom type \dots - \snippet queuedcustomtype/window.cpp Window constructor finish + \snippet threads/queuedcustomtype/window.cpp Window constructor finish If a type is used in a queued connection without being registered, a warning will be printed at the console; for example: @@ -131,18 +131,18 @@ It is often quite useful to make a custom type printable for debugging purposes, as in the following code: - \snippet customtype/main.cpp printing a custom type + \snippet tools/customtype/main.cpp printing a custom type This is achieved by creating a streaming operator for the type, which is often defined in the header file for that type: - \snippet customtype/message.h custom type streaming operator + \snippet tools/customtype/message.h custom type streaming operator The implementation for the \c Message type in the \l{Custom Type Example} goes to some effort to make the printable representation as readable as possible: - \snippet customtype/message.cpp custom type streaming operator + \snippet tools/customtype/message.cpp custom type streaming operator The output sent to the debug stream can, of course, be made as simple or as complicated as you like. Note that the value returned by this function is -- cgit v1.2.3 From 3d94a564f4c439ca0d1c2a0af807b9edeeb39299 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Mon, 29 Sep 2014 14:16:28 +0200 Subject: Android: Improve cache logic in findClass() This change adds guards to ensure that we only do a class look-up once when calling QJNIEnvironmentPrivate::findClass(). IF someone calls findClass() with an environment that does not contain a "valid" class loader, we should fallback to loadClass(), but only once. Change-Id: If5fc82956db889f3269bb33c98a16c49cae55def Reviewed-by: Yoann Lopes --- src/corelib/kernel/qjni.cpp | 65 ++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/src/corelib/kernel/qjni.cpp b/src/corelib/kernel/qjni.cpp index 173127b063..452e3464d6 100644 --- a/src/corelib/kernel/qjni.cpp +++ b/src/corelib/kernel/qjni.cpp @@ -80,38 +80,22 @@ static QString toDotEncodedClassName(const char *className) return QString::fromLatin1(className).replace(QLatin1Char('/'), QLatin1Char('.')); } -static jclass getCachedClass(const QString &classDotEnc) +static jclass getCachedClass(const QString &classDotEnc, bool *isCached = 0) { QHash::iterator it = cachedClasses->find(classDotEnc); + const bool found = (it != cachedClasses->end()); - if (it == cachedClasses->end()) - return 0; - - return it.value(); -} - -static jclass findClass(const char *className, JNIEnv *env) -{ - const QString &classDotEnc = toDotEncodedClassName(className); - jclass clazz = getCachedClass(classDotEnc); - if (clazz != 0) - return clazz; - - jclass fclazz = env->FindClass(className); - if (!exceptionCheckAndClear(env)) { - clazz = static_cast(env->NewGlobalRef(fclazz)); - env->DeleteLocalRef(fclazz); - } + if (isCached != 0) + *isCached = found; - cachedClasses->insert(classDotEnc, clazz); - return clazz; + return found ? it.value() : 0; } -static jclass loadClass(const char *className, JNIEnv *env) +static jclass loadClassDotEnc(const QString &classDotEnc, JNIEnv *env) { - const QString &classDotEnc = toDotEncodedClassName(className); - jclass clazz = getCachedClass(classDotEnc); - if (clazz != 0) + bool isCached = false; + jclass clazz = getCachedClass(classDotEnc, &isCached); + if (clazz != 0 || isCached) return clazz; QJNIObjectPrivate classLoader = QtAndroidPrivate::classLoader(); @@ -130,6 +114,11 @@ static jclass loadClass(const char *className, JNIEnv *env) return clazz; } +inline static jclass loadClass(const char *className, JNIEnv *env) +{ + return loadClassDotEnc(toDotEncodedClassName(className), env); +} + typedef QHash JMethodIDHash; Q_GLOBAL_STATIC(JMethodIDHash, cachedMethodID) @@ -224,12 +213,28 @@ JNIEnv *QJNIEnvironmentPrivate::operator->() jclass QJNIEnvironmentPrivate::findClass(const char *className, JNIEnv *env) { - jclass clazz = 0; - if (env != 0) - clazz = ::findClass(className, env); + const QString &classDotEnc = toDotEncodedClassName(className); + bool isCached = false; + jclass clazz = getCachedClass(classDotEnc, &isCached); + + const bool found = (clazz != 0) || (clazz == 0 && isCached); + + if (found) + return clazz; + + if (env != 0) { // We got an env. pointer (We expect this to be the right env. and call FindClass()) + jclass fclazz = env->FindClass(className); + if (!exceptionCheckAndClear(env)) { + clazz = static_cast(env->NewGlobalRef(fclazz)); + env->DeleteLocalRef(fclazz); + } + + if (clazz != 0) + cachedClasses->insert(classDotEnc, clazz); + } - if (clazz == 0) - clazz = loadClass(className, QJNIEnvironmentPrivate()); + if (clazz == 0) // We didn't get an env. pointer or we got one with the WRONG class loader... + clazz = loadClassDotEnc(classDotEnc, QJNIEnvironmentPrivate()); return clazz; } -- cgit v1.2.3 From 06e706bdbb826b521389409b53079483fda5584a Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Thu, 16 Oct 2014 20:25:00 +0200 Subject: Fix QAbstractListModel's detailed description. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I3f3e6b9d4e021620505c03458e78856326dcd859 Reviewed-by: Topi Reiniö --- src/corelib/itemmodels/qabstractitemmodel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp index 68ab03976f..74a7ea1988 100644 --- a/src/corelib/itemmodels/qabstractitemmodel.cpp +++ b/src/corelib/itemmodels/qabstractitemmodel.cpp @@ -3375,7 +3375,7 @@ Qt::ItemFlags QAbstractTableModel::flags(const QModelIndex &index) const QAbstractItemModel, it is not suitable for use with tree views; you will need to subclass QAbstractItemModel if you want to provide a model for that purpose. If you need to use a number of list models to manage data, - it may be more appropriate to subclass QAbstractTableModel class instead. + it may be more appropriate to subclass QAbstractTableModel instead. Simple models can be created by subclassing this class and implementing the minimum number of required functions. For example, we could implement @@ -3399,7 +3399,7 @@ Qt::ItemFlags QAbstractTableModel::flags(const QModelIndex &index) const default ones provided by the roleNames() function, you must override it. For editable list models, you must also provide an implementation of - setData(), implement the flags() function so that it returns a value + setData(), and implement the flags() function so that it returns a value containing \l{Qt::ItemFlags}{Qt::ItemIsEditable}. Note that QAbstractListModel provides a default implementation of -- cgit v1.2.3 From 4de382f4a222e3f589e9fd554610f920c1957d10 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Thu, 2 Oct 2014 17:57:42 +0400 Subject: Make font hinting and antialiasing size dependent when using FontConfig Add the pixel size of the font to the search pattern to get size dependent font settings. This patch allows to take into account KDE settings for font sizes which should be excluded from antialiasing. Change-Id: I8bd8b7b3d585009d0a39db631cd02b7970537f5c Reviewed-by: Allan Sandfeld Jensen --- src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp index 1aac0791cd..2b9883eb36 100644 --- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp +++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp @@ -845,6 +845,9 @@ void QFontconfigDatabase::setupFontEngine(QFontEngineFT *engine, const QFontDef FcPatternAdd(pattern,FC_INDEX,value,true); } + if (fontDef.pixelSize > 0.1) + FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fontDef.pixelSize); + FcResult result; FcConfigSubstitute(0, pattern, FcMatchPattern); -- cgit v1.2.3 From 239b71d07d8a129ed445c7553c738934c7828711 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 17 Oct 2014 16:19:16 +0200 Subject: Fix use-after-delete bug in tst_QWidget::taskQTBUG_27643_enterEvents() ASAN report: READ of size 8 at 0x606000011990 thread T0 #0 0x505e3b in EnterTestMainDialog::eventFilter(QObject*, QEvent*) tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp:10294 [...] 0x606000011990 is located 48 bytes inside of 56-byte region [0x606000011960,0x606000011998) freed by thread T0 here: #0 0x2b8df3551c79 in operator delete(void*) ../../../../gcc/libsanitizer/asan/asan_new_delete.cc:92 #1 0x418ab5 in EnterTestMainDialog::buttonPressed() tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp:10276 previously allocated by thread T0 here: #0 0x2b8df3551739 in operator new(unsigned long) ../../../../gcc/libsanitizer/asan/asan_new_delete.cc:60 #1 0x4188cf in EnterTestMainDialog::buttonPressed() tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp:10272 EnterTestMainDialog::eventFilter() checks for nullness of 'modal' before accessing it, but buttonPressed() did not reset 'modal' to nullptr after deletion. Change-Id: I65562a29f8264a6996d7d615e06de1d1afb5af53 Reviewed-by: Friedemann Kleint --- tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 34bb4cfdf6..ec3e8ece6a 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -10274,6 +10274,7 @@ public slots: QTimer::singleShot(100, this, SLOT(doMouseMoves())); modal->exec(); delete modal; + modal = Q_NULLPTR; } void doMouseMoves() -- cgit v1.2.3 From 8dd15fd9554e096a71443d3e370473978ef96e49 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 3 Oct 2014 14:14:09 +0200 Subject: QMacStyle: Add optional block parameter to drawNSViewInRect() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In some cases we want to do something different than just calling - [NSView drawRect:]. Change-Id: I7db704daa39611f33f270b0192c4301de62ec1bf Reviewed-by: Morten Johan Sørvig --- src/widgets/styles/qmacstyle_mac.mm | 7 +++++-- src/widgets/styles/qmacstyle_mac_p_p.h | 4 +++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index 9347a6ea90..6990cb6fe8 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -1888,7 +1888,7 @@ NSView *QMacStylePrivate::cocoaControl(QCocoaWidget widget, QPoint *offset) cons return bv; } -void QMacStylePrivate::drawNSViewInRect(NSView *view, const QRect &qtRect, QPainter *p) const +void QMacStylePrivate::drawNSViewInRect(NSView *view, const QRect &qtRect, QPainter *p, QCocoaDrawRectBlock drawRectBlock) const { QMacCGContext ctx(p); CGContextSaveGState(ctx); @@ -1901,7 +1901,10 @@ void QMacStylePrivate::drawNSViewInRect(NSView *view, const QRect &qtRect, QPain [backingStoreNSView addSubview:view]; view.frame = rect; - [view drawRect:rect]; + if (drawRectBlock) + drawRectBlock(rect, (CGContextRef)ctx); + else + [view drawRect:rect]; [view removeFromSuperviewWithoutNeedingDisplay]; [NSGraphicsContext restoreGraphicsState]; diff --git a/src/widgets/styles/qmacstyle_mac_p_p.h b/src/widgets/styles/qmacstyle_mac_p_p.h index b6267c43e6..1c5e7b5c45 100644 --- a/src/widgets/styles/qmacstyle_mac_p_p.h +++ b/src/widgets/styles/qmacstyle_mac_p_p.h @@ -132,6 +132,8 @@ enum QCocoaWidgetKind { typedef QPair QCocoaWidget; +typedef void (^QCocoaDrawRectBlock)(NSRect, CGContextRef); + #define SIZE(large, small, mini) \ (controlSize == QAquaSizeLarge ? (large) : controlSize == QAquaSizeSmall ? (small) : (mini)) @@ -201,7 +203,7 @@ public: NSView *cocoaControl(QCocoaWidget widget, QPoint *offset) const; - void drawNSViewInRect(NSView *view, const QRect &rect, QPainter *p) const; + void drawNSViewInRect(NSView *view, const QRect &rect, QPainter *p, QCocoaDrawRectBlock drawRectBlock = nil) const; void resolveCurrentNSView(QWindow *window); public: -- cgit v1.2.3 From cb2e65eea29ce0928cd1d93c005f015fb8225560 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Wed, 15 Oct 2014 17:53:15 +0200 Subject: QMacStyle: Fix QSlider appearance on Yosemite MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit First, we adjust the min and max positions, which HITheme has been unable to render properly for years. This involves separating the knob and track rendering. Also, on Yosemite, the tickmarks-less slider shows a blue progress fill in the track, on the knob's left side. Finaly, and this is valid for all versions, the tickmarks are being drawn before the knob (or the whole slider for OS X versions before 10.10) Change-Id: I6fce2e298a80858a18fd9fe1e799b65265a8aefd Reviewed-by: Morten Johan Sørvig --- src/widgets/styles/qmacstyle_mac.mm | 148 +++++++++++++++++++++++++++++++-- src/widgets/styles/qmacstyle_mac_p_p.h | 4 +- 2 files changed, 142 insertions(+), 10 deletions(-) diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index 6990cb6fe8..2b2f729972 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -1661,10 +1661,34 @@ void QMacStylePrivate::getSliderInfo(QStyle::ComplexControl cc, const QStyleOpti tdi->kind = kThemeSmallSlider; break; } + + bool usePlainKnob = slider->tickPosition == QSlider::NoTicks + || slider->tickPosition == QSlider::TicksBothSides; + tdi->bounds = qt_hirectForQRect(slider->rect); - tdi->min = slider->minimum; - tdi->max = slider->maximum; - tdi->value = slider->sliderPosition; + if (isScrollbar || QSysInfo::MacintoshVersion <= QSysInfo::MV_10_9) { + tdi->min = slider->minimum; + tdi->max = slider->maximum; + tdi->value = slider->sliderPosition; + } else { + // Fix min and max positions. HITheme seems confused when it comes to rendering + // a slider at those positions. We give it a hand by extending and offsetting + // the slider range accordingly. See also comment for CC_Slider in drawComplexControl() + tdi->min = 0; + if (slider->orientation == Qt::Horizontal) + tdi->max = 10 * slider->rect.width(); + else + tdi->max = 10 * slider->rect.height(); + + if (usePlainKnob || slider->orientation == Qt::Horizontal) { + int endsCorrection = usePlainKnob ? 25 : 10; + tdi->value = (tdi->max + 2 * endsCorrection) * (slider->sliderPosition - slider->minimum) + / (slider->maximum - slider->minimum) - endsCorrection; + } else { + tdi->value = (tdi->max + 30) * (slider->sliderPosition - slider->minimum) + / (slider->maximum - slider->minimum) - 20; + } + } tdi->attributes = kThemeTrackShowThumb; if (slider->upsideDown) tdi->attributes |= kThemeTrackRightToLeft; @@ -1681,7 +1705,7 @@ void QMacStylePrivate::getSliderInfo(QStyle::ComplexControl cc, const QStyleOpti // Tiger broke reverse scroll bars so put them back and "fake it" if (isScrollbar && (tdi->attributes & kThemeTrackRightToLeft)) { tdi->attributes &= ~kThemeTrackRightToLeft; - tdi->value = tdi->max - slider->sliderPosition; + tdi->value = tdi->max - tdi->value; } tdi->enableState = (slider->state & QStyle::State_Enabled) ? kThemeTrackActive @@ -1689,7 +1713,7 @@ void QMacStylePrivate::getSliderInfo(QStyle::ComplexControl cc, const QStyleOpti if (!isScrollbar) { if (slider->state & QStyle::QStyle::State_HasFocus) tdi->attributes |= kThemeTrackHasFocus; - if (slider->tickPosition == QSlider::NoTicks || slider->tickPosition == QSlider::TicksBothSides) + if (usePlainKnob) tdi->trackInfo.slider.thumbDir = kThemeThumbPlain; else if (slider->tickPosition == QSlider::TicksAbove) tdi->trackInfo.slider.thumbDir = kThemeThumbUpward; @@ -1815,6 +1839,12 @@ NSView *QMacStylePrivate::cocoaControl(QCocoaWidget widget, QPoint *offset) cons bv = [[NSPopUpButton alloc] init]; else if (widget.first == QCocoaComboBox) bv = [[NSComboBox alloc] init]; + else if (widget.first == QCocoaHorizontalSlider) + bv = [[NSSlider alloc] init]; + else if (widget.first == QCocoaVerticalSlider) + // Cocoa sets the orientation from the view's frame + // at construction time, and it cannot be changed later. + bv = [[NSSlider alloc] initWithFrame:NSMakeRect(0, 0, 10, 100)]; else bv = [[NSButton alloc] init]; @@ -5315,6 +5345,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex // because on Tiger I only "fake" the reverse stuff. bool reverseHorizontal = (slider->direction == Qt::RightToLeft && slider->orientation == Qt::Horizontal); + if ((reverseHorizontal && slider->activeSubControls == SC_ScrollBarAddLine) || (!reverseHorizontal @@ -5365,6 +5396,9 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex tdi.attributes |= kThemeTrackHideTrack; } + const bool usingYosemiteOrLater = QSysInfo::MacintoshVersion > QSysInfo::MV_10_9; + const bool isHorizontal = slider->orientation == Qt::Horizontal; + #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 if (cc == CC_ScrollBar && proxy()->styleHint(SH_ScrollBar_Transient, opt, widget)) { bool wasActive = false; @@ -5449,8 +5483,6 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex } } - const bool isHorizontal = slider->orientation == Qt::Horizontal; - CGContextSaveGState(cg); [NSGraphicsContext saveGraphicsState]; @@ -5535,9 +5567,86 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex { d->stopAnimation(opt->styleObject); - HIThemeDrawTrack(&tdi, tracking ? 0 : &macRect, cg, - kHIThemeOrientationNormal); + if (usingYosemiteOrLater && cc == CC_Slider) { + // Fix min and max positions. (See also getSliderInfo() + // for the slider values adjustments.) + // HITheme seems to have forgotten how to render + // a slide at those positions, leaving a gap between + // the knob and the ends of the track. + // We fix this by rendering the track first, and then + // the knob on top. However, in order to not clip the + // knob, we reduce the the drawing rect for the track. + HIRect bounds = tdi.bounds; + if (isHorizontal) { + tdi.bounds.size.width -= 2; + tdi.bounds.origin.x += 1; + if (tdi.trackInfo.slider.thumbDir == kThemeThumbDownward) + tdi.bounds.origin.y -= 2; + else if (tdi.trackInfo.slider.thumbDir == kThemeThumbUpward) + tdi.bounds.origin.y += 3; + } else { + tdi.bounds.size.height -= 2; + tdi.bounds.origin.y += 1; + if (tdi.trackInfo.slider.thumbDir == kThemeThumbDownward) // pointing right + tdi.bounds.origin.x -= 4; + else if (tdi.trackInfo.slider.thumbDir == kThemeThumbUpward) // pointing left + tdi.bounds.origin.x += 2; + } + + // Yosemite demands its blue progress track when no tickmarks are present + if (!(slider->subControls & SC_SliderTickmarks)) { + QCocoaWidgetKind sliderKind = slider->orientation == Qt::Horizontal ? QCocoaHorizontalSlider : QCocoaVerticalSlider; + NSSlider *sl = (NSSlider *)d->cocoaControl(QCocoaWidget(sliderKind, QAquaSizeLarge), 0); + sl.minValue = slider->minimum; + sl.maxValue = slider->maximum; + sl.intValue = slider->sliderValue; + sl.enabled = slider->state & QStyle::State_Enabled; + d->drawNSViewInRect(sl, opt->rect, p, ^(NSRect rect, CGContextRef ctx) { + if (slider->upsideDown) { + if (isHorizontal) { + CGContextTranslateCTM(ctx, rect.size.width, 0); + CGContextScaleCTM(ctx, -1, 1); + } + } else if (!isHorizontal) { + CGContextTranslateCTM(ctx, 0, rect.size.height); + CGContextScaleCTM(ctx, 1, -1); + } + [sl.cell drawBarInside:tdi.bounds flipped:NO]; + // No need to restore the CTM later, the context has been saved + // and will be restored at the end of drawNSViewInRect() + }); + tdi.attributes |= kThemeTrackHideTrack; + } else { + tdi.attributes &= ~(kThemeTrackShowThumb | kThemeTrackHasFocus); + HIThemeDrawTrack(&tdi, tracking ? 0 : &macRect, cg, + kHIThemeOrientationNormal); + tdi.attributes |= kThemeTrackHideTrack | kThemeTrackShowThumb; + } + + tdi.bounds = bounds; + } + if (cc == CC_Slider && slider->subControls & SC_SliderTickmarks) { + + HIRect bounds; + if (usingYosemiteOrLater) { + // As part of fixing the min and max positions, + // we need to adjust the tickmarks as well + bounds = tdi.bounds; + if (slider->orientation == Qt::Horizontal) { + tdi.bounds.size.width += 2; + tdi.bounds.origin.x -= 1; + if (tdi.trackInfo.slider.thumbDir == kThemeThumbUpward) + tdi.bounds.origin.y -= 2; + } else { + tdi.bounds.size.height += 3; + tdi.bounds.origin.y -= 3; + tdi.bounds.origin.y += 1; + if (tdi.trackInfo.slider.thumbDir == kThemeThumbUpward) // pointing left + tdi.bounds.origin.x -= 2; + } + } + if (qt_mac_is_metal(widget)) { if (tdi.enableState == kThemeTrackInactive) tdi.enableState = kThemeTrackActive; // Looks more Cocoa-like @@ -5559,16 +5668,37 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex cg, kHIThemeOrientationNormal); tdi.trackInfo.slider.thumbDir = kThemeThumbUpward; + if (usingYosemiteOrLater) { + if (slider->orientation == Qt::Vertical) + tdi.bounds.origin.x -= 2; + } HIThemeDrawTrackTickMarks(&tdi, numMarks, cg, kHIThemeOrientationNormal); + // Reset to plain thumb to be drawn further down + tdi.trackInfo.slider.thumbDir = kThemeThumbPlain; } else { HIThemeDrawTrackTickMarks(&tdi, numMarks, cg, kHIThemeOrientationNormal); + } + + if (usingYosemiteOrLater) + tdi.bounds = bounds; + } + if (usingYosemiteOrLater && cc == CC_Slider) { + // Still as part of fixing the min and max positions, + // we also adjust the knob position. We can do this + // because it's rendered separately from the track. + if (slider->orientation == Qt::Vertical) { + if (tdi.trackInfo.slider.thumbDir == kThemeThumbDownward) // pointing right + tdi.bounds.origin.x -= 2; } } + + HIThemeDrawTrack(&tdi, tracking ? 0 : &macRect, cg, + kHIThemeOrientationNormal); } } break; diff --git a/src/widgets/styles/qmacstyle_mac_p_p.h b/src/widgets/styles/qmacstyle_mac_p_p.h index 1c5e7b5c45..f36ba2c190 100644 --- a/src/widgets/styles/qmacstyle_mac_p_p.h +++ b/src/widgets/styles/qmacstyle_mac_p_p.h @@ -127,7 +127,9 @@ enum QCocoaWidgetKind { QCocoaComboBox, // Editable QComboBox QCocoaPopupButton, // Non-editable QComboBox QCocoaPushButton, - QCocoaRadioButton + QCocoaRadioButton, + QCocoaHorizontalSlider, + QCocoaVerticalSlider }; typedef QPair QCocoaWidget; -- cgit v1.2.3 From cd512cbcab25a96519c540de062959961877fbc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Mon, 6 Oct 2014 11:04:55 +0200 Subject: Bump default deployment target to 10.7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 10.6 is no longer supported. Change-Id: I4c799ba2a9622aa1dd8a79ff70608b50b2bbd26a Reviewed-by: Gabriel de Dietrich Reviewed-by: Tor Arne Vestbø --- mkspecs/macx-clang-32/qmake.conf | 2 +- mkspecs/macx-clang/qmake.conf | 2 +- mkspecs/macx-g++-32/qmake.conf | 2 +- mkspecs/macx-g++/qmake.conf | 2 +- mkspecs/macx-g++40/qmake.conf | 2 +- mkspecs/macx-g++42/qmake.conf | 2 +- mkspecs/macx-icc/qmake.conf | 2 +- mkspecs/macx-llvm/qmake.conf | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/mkspecs/macx-clang-32/qmake.conf b/mkspecs/macx-clang-32/qmake.conf index e0c4bd57b7..87c601ee74 100644 --- a/mkspecs/macx-clang-32/qmake.conf +++ b/mkspecs/macx-clang-32/qmake.conf @@ -11,7 +11,7 @@ include(../common/gcc-base-mac.conf) include(../common/clang.conf) include(../common/clang-mac.conf) -QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6 +QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7 QMAKE_CFLAGS += -arch i386 QMAKE_OBJECTIVE_CFLAGS += -arch i386 diff --git a/mkspecs/macx-clang/qmake.conf b/mkspecs/macx-clang/qmake.conf index f28b728bd9..d14b11179a 100644 --- a/mkspecs/macx-clang/qmake.conf +++ b/mkspecs/macx-clang/qmake.conf @@ -11,6 +11,6 @@ include(../common/gcc-base-mac.conf) include(../common/clang.conf) include(../common/clang-mac.conf) -QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6 +QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7 load(qt_config) diff --git a/mkspecs/macx-g++-32/qmake.conf b/mkspecs/macx-g++-32/qmake.conf index 6ef78aacbf..2a8197ebbd 100644 --- a/mkspecs/macx-g++-32/qmake.conf +++ b/mkspecs/macx-g++-32/qmake.conf @@ -14,7 +14,7 @@ include(../common/macx.conf) include(../common/gcc-base-mac.conf) include(../common/g++-macx.conf) -QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6 +QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7 QMAKE_CFLAGS += -arch i386 QMAKE_OBJECTIVE_CFLAGS += -arch i386 diff --git a/mkspecs/macx-g++/qmake.conf b/mkspecs/macx-g++/qmake.conf index a6c075a2ce..9c44f278e9 100644 --- a/mkspecs/macx-g++/qmake.conf +++ b/mkspecs/macx-g++/qmake.conf @@ -14,6 +14,6 @@ include(../common/macx.conf) include(../common/gcc-base-mac.conf) include(../common/g++-macx.conf) -QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6 +QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7 load(qt_config) diff --git a/mkspecs/macx-g++40/qmake.conf b/mkspecs/macx-g++40/qmake.conf index f40315a602..0f2dd6bb71 100644 --- a/mkspecs/macx-g++40/qmake.conf +++ b/mkspecs/macx-g++40/qmake.conf @@ -14,7 +14,7 @@ include(../common/macx.conf) include(../common/gcc-base-mac.conf) include(../common/g++-macx.conf) -QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6 +QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7 QMAKE_CC = gcc-4.0 QMAKE_CXX = g++-4.0 diff --git a/mkspecs/macx-g++42/qmake.conf b/mkspecs/macx-g++42/qmake.conf index 25383e9cb6..e003193e1b 100644 --- a/mkspecs/macx-g++42/qmake.conf +++ b/mkspecs/macx-g++42/qmake.conf @@ -14,7 +14,7 @@ include(../common/macx.conf) include(../common/gcc-base-mac.conf) include(../common/g++-macx.conf) -QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6 +QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7 QMAKE_CC = gcc-4.2 QMAKE_CXX = g++-4.2 diff --git a/mkspecs/macx-icc/qmake.conf b/mkspecs/macx-icc/qmake.conf index 521e64e364..a1783c97ad 100644 --- a/mkspecs/macx-icc/qmake.conf +++ b/mkspecs/macx-icc/qmake.conf @@ -85,7 +85,7 @@ QMAKE_CXXFLAGS_PRECOMPILE = -c -pch-create ${QMAKE_PCH_OUTPUT} -include ${QMAKE_ QMAKE_CFLAGS_HIDESYMS += -fvisibility=hidden QMAKE_CXXFLAGS_HIDESYMS += $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden -QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6 +QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7 include(../common/macx.conf) diff --git a/mkspecs/macx-llvm/qmake.conf b/mkspecs/macx-llvm/qmake.conf index 7bdef70943..cf4e00cd61 100644 --- a/mkspecs/macx-llvm/qmake.conf +++ b/mkspecs/macx-llvm/qmake.conf @@ -14,7 +14,7 @@ include(../common/macx.conf) include(../common/gcc-base-mac.conf) include(../common/llvm.conf) -QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.6 +QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7 QMAKE_XCODE_GCC_VERSION = com.apple.compilers.llvmgcc42 -- cgit v1.2.3 From 1cfd45782638b8266d46af289de5abdd0371fc27 Mon Sep 17 00:00:00 2001 From: Dyami Caliri Date: Mon, 15 Sep 2014 15:25:33 -0700 Subject: OS X: Emit QClipboard::dataChanged when activating application MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The QClipboard documentation states that on OS X it will emit dataChanged() when activating the application, if the system clipboard had changed. It wasn't doing this in Qt5. Task-number: QTBUG-34941 Change-Id: I7f34e757876757691f0a6c94dd2ae76a60146291 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoaclipboard.h | 8 +++++++- src/plugins/platforms/cocoa/qcocoaclipboard.mm | 16 ++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoaclipboard.h b/src/plugins/platforms/cocoa/qcocoaclipboard.h index 5ebdad79f1..2c34ef9278 100644 --- a/src/plugins/platforms/cocoa/qcocoaclipboard.h +++ b/src/plugins/platforms/cocoa/qcocoaclipboard.h @@ -40,8 +40,10 @@ QT_BEGIN_NAMESPACE -class QCocoaClipboard : public QPlatformClipboard +class QCocoaClipboard : public QObject, public QPlatformClipboard { + Q_OBJECT + public: QCocoaClipboard(); @@ -49,6 +51,10 @@ public: void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard); bool supportsMode(QClipboard::Mode mode) const; bool ownsMode(QClipboard::Mode mode) const; + +private Q_SLOTS: + void handleApplicationStateChanged(Qt::ApplicationState state); + protected: QMacPasteboard *pasteboardForMode(QClipboard::Mode mode) const; diff --git a/src/plugins/platforms/cocoa/qcocoaclipboard.mm b/src/plugins/platforms/cocoa/qcocoaclipboard.mm index f6c424d4fd..1a23da8a8e 100644 --- a/src/plugins/platforms/cocoa/qcocoaclipboard.mm +++ b/src/plugins/platforms/cocoa/qcocoaclipboard.mm @@ -40,7 +40,6 @@ ****************************************************************************/ #include "qcocoaclipboard.h" -#include "qmacclipboard.h" QT_BEGIN_NAMESPACE @@ -48,7 +47,7 @@ QCocoaClipboard::QCocoaClipboard() :m_clipboard(new QMacPasteboard(kPasteboardClipboard, QMacInternalPasteboardMime::MIME_CLIP)) ,m_find(new QMacPasteboard(kPasteboardFind, QMacInternalPasteboardMime::MIME_CLIP)) { - + connect(qGuiApp, &QGuiApplication::applicationStateChanged, this, &QCocoaClipboard::handleApplicationStateChanged); } QMimeData *QCocoaClipboard::mimeData(QClipboard::Mode mode) @@ -94,4 +93,17 @@ QMacPasteboard *QCocoaClipboard::pasteboardForMode(QClipboard::Mode mode) const return 0; } +void QCocoaClipboard::handleApplicationStateChanged(Qt::ApplicationState state) +{ + if (state != Qt::ApplicationActive) + return; + + if (m_clipboard->sync()) + emitChanged(QClipboard::Clipboard); + if (m_find->sync()) + emitChanged(QClipboard::FindBuffer); +} + +#include "moc_qcocoaclipboard.cpp" + QT_END_NAMESPACE -- cgit v1.2.3 From fc567acefb9eddb4d52d7cbe6510364fa865f330 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 14 Oct 2014 14:04:59 +0200 Subject: iOS: ensure edit menu works on iOS6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Method "- (id)targetForAction:(SEL)action withSender:(id)sender" is only available from iOS7. So change implementation to use whats available on iOS 6. Change-Id: I4e21495073364e83ef396dfab47a7ea2a23bbead Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/quiview.mm | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm index 200b07b5fc..81f82ba97d 100644 --- a/src/plugins/platforms/ios/quiview.mm +++ b/src/plugins/platforms/ios/quiview.mm @@ -340,11 +340,16 @@ QWindowSystemInterface::flushWindowSystemEvents(); } -- (id)targetForAction:(SEL)action withSender:(id)sender +- (BOOL)canPerformAction:(SEL)action withSender:(id)sender { // Check first if QIOSMenu should handle the action before continuing up the responder chain - id target = [QIOSMenu::menuActionTarget() targetForAction:action withSender:sender]; - return target ? target : [super targetForAction:action withSender:sender]; + return [QIOSMenu::menuActionTarget() targetForAction:action withSender:sender] != 0; +} + +- (id)forwardingTargetForSelector:(SEL)selector +{ + Q_UNUSED(selector) + return QIOSMenu::menuActionTarget(); } @end -- cgit v1.2.3 From 3797ee7747988c721740871f3a601d885d91d881 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 15 Oct 2014 16:02:06 +0200 Subject: CoreText font database: Use dynamic type on iOS to resolve theme fonts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use Dynamic Type to resolve theme fonts, so that we get the correct font sizes and styling based on user preferences in Settings app. Change-Id: I2222199a5ba21badb2e3696993eee503e720c476 Reviewed-by: Tor Arne Vestbø --- .../fontdatabases/mac/qcoretextfontdatabase.mm | 50 +++++++++++++++++++--- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index 52cb928615..fc289579ea 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -759,6 +759,50 @@ static CTFontUIFontType fontTypeFromTheme(QPlatformTheme::Font f) } } +static CTFontDescriptorRef fontDescriptorFromTheme(QPlatformTheme::Font f) +{ +#ifdef Q_OS_IOS + if (QSysInfo::MacintoshVersion >= QSysInfo::MV_IOS_7_0) { + // Use Dynamic Type to resolve theme fonts if possible, to get + // correct font sizes and style based on user configuration. + NSString *textStyle = 0; + switch (f) { + case QPlatformTheme::TitleBarFont: + case QPlatformTheme::HeaderViewFont: + textStyle = UIFontTextStyleHeadline; + break; + case QPlatformTheme::MdiSubWindowTitleFont: + textStyle = UIFontTextStyleSubheadline; + break; + case QPlatformTheme::TipLabelFont: + case QPlatformTheme::SmallFont: + textStyle = UIFontTextStyleFootnote; + break; + case QPlatformTheme::MiniFont: + textStyle = UIFontTextStyleCaption2; + break; + case QPlatformTheme::FixedFont: + // Fall back to regular code path, as iOS doesn't provide + // an appropriate text style for this theme font. + break; + default: + textStyle = UIFontTextStyleBody; + break; + } + + if (textStyle) { + UIFontDescriptor *desc = [UIFontDescriptor preferredFontDescriptorWithTextStyle:textStyle]; + return static_cast(CFBridgingRetain(desc)); + } + } +#endif // Q_OS_IOS + + // OSX default case and iOS fallback case + CTFontUIFontType fontType = fontTypeFromTheme(f); + QCFType ctFont = CTFontCreateUIFontForLanguage(fontType, 0.0, NULL); + return CTFontCopyFontDescriptor(ctFont); +} + const QHash &QCoreTextFontDatabase::themeFonts() const { if (m_themeFonts.isEmpty()) { @@ -773,11 +817,7 @@ const QHash &QCoreTextFontDatabase::themeFonts() QFont *QCoreTextFontDatabase::themeFont(QPlatformTheme::Font f) const { - CTFontUIFontType fontType = fontTypeFromTheme(f); - - QCFType ctFont = CTFontCreateUIFontForLanguage(fontType, 0.0, NULL); - CTFontDescriptorRef fontDesc = CTFontCopyFontDescriptor(ctFont); - + CTFontDescriptorRef fontDesc = fontDescriptorFromTheme(f); FontDescription fd; getFontDescription(fontDesc, &fd); m_systemFontDescriptors.insert(fontDesc); -- cgit v1.2.3 From 0ed65a651307007fc0e61ad69b33783ba9c3a736 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 14 Oct 2014 16:26:17 +0200 Subject: iOS: ignore sender of actions for edit menu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The reason is that the sender is sometimes 'NULL', so we cannot rely on it. But the current test with our prefix should suffice. Change-Id: Ie58bf062cbade08feda622bda753d63e1d811a8d Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosmenu.mm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/qiosmenu.mm b/src/plugins/platforms/ios/qiosmenu.mm index c247c16514..005b06547e 100644 --- a/src/plugins/platforms/ios/qiosmenu.mm +++ b/src/plugins/platforms/ios/qiosmenu.mm @@ -88,8 +88,9 @@ static NSString *const kSelectorPrefix = @"_qtMenuItem_"; - (id)targetForAction:(SEL)action withSender:(id)sender { + Q_UNUSED(sender); BOOL containsPrefix = ([NSStringFromSelector(action) rangeOfString:kSelectorPrefix].location != NSNotFound); - return (containsPrefix && [sender isKindOfClass:[UIMenuController class]]) ? self : 0; + return containsPrefix ? self : 0; } - (NSMethodSignature *)methodSignatureForSelector:(SEL)selector -- cgit v1.2.3 From e57153b0821acd876f1938a192f21843c3f70679 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 17 Oct 2014 10:59:44 +0200 Subject: iOS: ensure we have a valid focusObject before sending it IM events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Should not really happen, but since we don't store the focus object given to us, we should do a check. A crash was seen from this when running the "Application" example for widgets. Change-Id: I9c4121766d7028a4eceede7d7b15c8c53d34e16e Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosinputcontext.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index 13e91889a2..ac6e339633 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -322,7 +322,7 @@ bool QIOSInputContext::isInputPanelVisible() const void QIOSInputContext::cursorRectangleChanged() { - if (!m_keyboardListener->m_keyboardVisibleAndDocked) + if (!m_keyboardListener->m_keyboardVisibleAndDocked || !qApp->focusObject()) return; // Check if the cursor has changed position inside the input item. Since -- cgit v1.2.3 From adadb5e870c1b805aa3dabe12ae29005c8f1a406 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 4 Oct 2014 01:21:18 +0200 Subject: QSizePolicy: remind to mark as Q_PRIMITIVE_TYPE in Qt 6 Change-Id: I1f18b4cd99f37aadf199e70d3acade9c8f5f9799 Reviewed-by: Thiago Macieira --- src/widgets/kernel/qsizepolicy.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/widgets/kernel/qsizepolicy.h b/src/widgets/kernel/qsizepolicy.h index 9730ec1206..41adf5c58a 100644 --- a/src/widgets/kernel/qsizepolicy.h +++ b/src/widgets/kernel/qsizepolicy.h @@ -150,6 +150,10 @@ private: quint32 data; }; }; +#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) +// Can't add in Qt 5, as QList would be BiC: +Q_DECLARE_TYPEINFO(QSizePolicy, Q_PRIMITIVE_TYPE); +#endif Q_DECLARE_OPERATORS_FOR_FLAGS(QSizePolicy::ControlTypes) -- cgit v1.2.3 From e8bdc949fc3646ff323a4fb4b83835e089a86b77 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 25 Sep 2014 15:55:35 +0200 Subject: Add qHash(QSslCertificate) overload qsslsocket_winrt.cpp defined it locally, which runs the risk of clashes with a potential user-defined qHash(QSslCertificate), so make it public. Also, the implementation in qsslsocket_winrt.cpp simply hashed the handle(), which violates the principle that equal instances must hash to the same value. Also, for some platforms, the implementation returns nullptr unconditionally, which, while not violating the above-mentioned principle, will make all users of the hash have worst-case complexity. To calculate a meaningful hash, therefore, the certificate needs to be inspected deeper than just the handle. For OpenSSL, we use X509::sha1_hash, which also X509_cmp uses internally to determine inequality (it checks more stuff, but if X059::sha1_hash is different, X509_cmp() returns non-zero, which is sufficient for the purposes of qHash()). sha1_hash may not be up-to-date, though, so we call X509_cmp to make it valid. Ugh. For WinRT/Qt, we use the DER encoding, as that is the native storage format used in QSslCertificate. This is not equivalent to the implementation used in qsslsocket_winrt.cpp before, but since handle() == handle() => toDer() == toDer(), it should not be a problem. [ChangeLog][QtNetwork][QSslCertificate] Can now be used as a key in QSet/QHash. Change-Id: I10858fe648c70fc9535af6913dd3b7f3b2cf0eba Reviewed-by: Oliver Wolff --- src/network/ssl/qsslcertificate.cpp | 6 ++++++ src/network/ssl/qsslcertificate.h | 6 ++++++ src/network/ssl/qsslcertificate_openssl.cpp | 11 +++++++++++ src/network/ssl/qsslcertificate_qt.cpp | 6 ++++++ src/network/ssl/qsslsocket_winrt.cpp | 5 ----- .../auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp | 9 +++++++++ 6 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index 8d38a5fd54..13bddcb3ea 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -662,7 +662,13 @@ QByteArray QSslCertificatePrivate::subjectInfoToString(QSslCertificate::SubjectI return str; } +/*! + \fn uint qHash(const QSslCertificate &key, uint seed) + Returns the hash value for the \a key, using \a seed to seed the calculation. + \since 5.4 + \relates QHash +*/ #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug debug, const QSslCertificate &certificate) diff --git a/src/network/ssl/qsslcertificate.h b/src/network/ssl/qsslcertificate.h index d1290b1d42..e34ea97fc4 100644 --- a/src/network/ssl/qsslcertificate.h +++ b/src/network/ssl/qsslcertificate.h @@ -59,6 +59,10 @@ class QSslKey; class QSslCertificateExtension; class QStringList; +class QSslCertificate; +// qHash is a friend, but we can't use default arguments for friends (§8.3.6.4) +Q_NETWORK_EXPORT uint qHash(const QSslCertificate &key, uint seed = 0) Q_DECL_NOTHROW; + class QSslCertificatePrivate; class Q_NETWORK_EXPORT QSslCertificate { @@ -145,6 +149,8 @@ private: QExplicitlySharedDataPointer d; friend class QSslCertificatePrivate; friend class QSslSocketBackendPrivate; + + friend Q_NETWORK_EXPORT uint qHash(const QSslCertificate &key, uint seed) Q_DECL_NOTHROW; }; Q_DECLARE_SHARED(QSslCertificate) diff --git a/src/network/ssl/qsslcertificate_openssl.cpp b/src/network/ssl/qsslcertificate_openssl.cpp index 850654835d..1906c72ff8 100644 --- a/src/network/ssl/qsslcertificate_openssl.cpp +++ b/src/network/ssl/qsslcertificate_openssl.cpp @@ -62,6 +62,17 @@ bool QSslCertificate::operator==(const QSslCertificate &other) const return false; } +uint qHash(const QSslCertificate &key, uint seed) Q_DECL_NOTHROW +{ + if (X509 * const x509 = key.d->x509) { + (void)q_X509_cmp(x509, x509); // populate x509->sha1_hash + // (if someone knows a better way...) + return qHashBits(x509->sha1_hash, SHA_DIGEST_LENGTH, seed); + } else { + return seed; + } +} + bool QSslCertificate::isNull() const { return d->null; diff --git a/src/network/ssl/qsslcertificate_qt.cpp b/src/network/ssl/qsslcertificate_qt.cpp index 16df4a8f73..d74042a95f 100644 --- a/src/network/ssl/qsslcertificate_qt.cpp +++ b/src/network/ssl/qsslcertificate_qt.cpp @@ -67,6 +67,12 @@ bool QSslCertificate::operator==(const QSslCertificate &other) const return d->derData == other.d->derData; } +uint qHash(const QSslCertificate &key, uint seed) Q_DECL_NOTHROW +{ + // DER is the native encoding here, so toDer() is just "return d->derData": + return qHash(key.toDer(), seed); +} + bool QSslCertificate::isNull() const { return d->null; diff --git a/src/network/ssl/qsslsocket_winrt.cpp b/src/network/ssl/qsslsocket_winrt.cpp index c9ddd9ec1b..69f8b6d68a 100644 --- a/src/network/ssl/qsslsocket_winrt.cpp +++ b/src/network/ssl/qsslsocket_winrt.cpp @@ -70,11 +70,6 @@ inline uint qHash(const QSslError &error, uint seed) Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(error))) { return (qHash(error.error()) ^ seed); } -// For QSet -inline uint qHash(const QSslCertificate &certificate, uint seed) - Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(certificate))) -{ return (qHash(certificate.handle()) ^ seed); } - bool QSslSocketPrivate::s_libraryLoaded = true; bool QSslSocketPrivate::s_loadRootCertsOnDemand = true; bool QSslSocketPrivate::s_loadedCiphersAndCerts = false; diff --git a/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp b/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp index 67cbd5059f..49ff1b48fe 100644 --- a/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp +++ b/tests/auto/network/ssl/qsslcertificate/tst_qsslcertificate.cpp @@ -70,6 +70,7 @@ public slots: #ifndef QT_NO_SSL private slots: + void hash(); void emptyConstructor(); void constructor_data(); void constructor(); @@ -164,6 +165,14 @@ void tst_QSslCertificate::cleanupTestCase() #ifndef QT_NO_SSL +void tst_QSslCertificate::hash() +{ + // mostly a compile-only test, to check that qHash(QSslCertificate) is found. + QSet certs; + certs << QSslCertificate(); + QCOMPARE(certs.size(), 1); +} + static QByteArray readFile(const QString &absFilePath) { QFile file(absFilePath); -- cgit v1.2.3 From 32dfbd6dbf8393dcd4e4eaa557902108a2714326 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 25 Sep 2014 16:01:09 +0200 Subject: Add qHash(QSslError) overload qsslsocket_winrt.cpp defined it locally, which runs the risk of clashes with a potential user-defined qHash(QSslError), so make it public. Also included both .error() and .certificate() in the hash, as both of these are used to determine equality (the WinRT version only used .error()). [ChangeLog][QtNetwork][QSslError] Can now be used in QSet/QHash. Change-Id: Ieb7995bed491ff011d4be9dad544248b56fd4f73 Reviewed-by: Oliver Wolff Reviewed-by: Andrew Knight --- src/network/ssl/qsslerror.cpp | 13 +++++++++++++ src/network/ssl/qsslerror.h | 2 ++ src/network/ssl/qsslsocket_winrt.cpp | 5 ----- tests/auto/network/ssl/qsslerror/tst_qsslerror.cpp | 9 +++++++++ 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/network/ssl/qsslerror.cpp b/src/network/ssl/qsslerror.cpp index ff30098347..5004e561a8 100644 --- a/src/network/ssl/qsslerror.cpp +++ b/src/network/ssl/qsslerror.cpp @@ -305,6 +305,19 @@ QSslCertificate QSslError::certificate() const return d->certificate; } +/*! + Returns the hash value for the \a key, using \a seed to seed the calculation. + \since 5.4 + \relates QHash +*/ +uint qHash(const QSslError &key, uint seed) Q_DECL_NOTHROW +{ + // 2x boost::hash_combine inlined: + seed ^= qHash(key.error()) + 0x9e3779b9 + (seed << 6) + (seed >> 2); + seed ^= qHash(key.certificate()) + 0x9e3779b9 + (seed << 6) + (seed >> 2); + return seed; +} + #ifndef QT_NO_DEBUG_STREAM //class QDebug; QDebug operator<<(QDebug debug, const QSslError &error) diff --git a/src/network/ssl/qsslerror.h b/src/network/ssl/qsslerror.h index d25546b68b..c00532e294 100644 --- a/src/network/ssl/qsslerror.h +++ b/src/network/ssl/qsslerror.h @@ -102,6 +102,8 @@ private: }; Q_DECLARE_SHARED(QSslError) +Q_NETWORK_EXPORT uint qHash(const QSslError &key, uint seed = 0) Q_DECL_NOTHROW; + #ifndef QT_NO_DEBUG_STREAM class QDebug; Q_NETWORK_EXPORT QDebug operator<<(QDebug debug, const QSslError &error); diff --git a/src/network/ssl/qsslsocket_winrt.cpp b/src/network/ssl/qsslsocket_winrt.cpp index 69f8b6d68a..da4c72be01 100644 --- a/src/network/ssl/qsslsocket_winrt.cpp +++ b/src/network/ssl/qsslsocket_winrt.cpp @@ -65,11 +65,6 @@ using namespace ABI::Windows::Storage::Streams; QT_BEGIN_NAMESPACE -// For QSet -inline uint qHash(const QSslError &error, uint seed) - Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(error))) -{ return (qHash(error.error()) ^ seed); } - bool QSslSocketPrivate::s_libraryLoaded = true; bool QSslSocketPrivate::s_loadRootCertsOnDemand = true; bool QSslSocketPrivate::s_loadedCiphersAndCerts = false; diff --git a/tests/auto/network/ssl/qsslerror/tst_qsslerror.cpp b/tests/auto/network/ssl/qsslerror/tst_qsslerror.cpp index 58136f9a68..7fd6dc8233 100644 --- a/tests/auto/network/ssl/qsslerror/tst_qsslerror.cpp +++ b/tests/auto/network/ssl/qsslerror/tst_qsslerror.cpp @@ -64,6 +64,7 @@ public: #ifndef QT_NO_SSL private slots: void constructing(); + void hash(); #endif private: @@ -79,6 +80,14 @@ void tst_QSslError::constructing() QSslError error; } +void tst_QSslError::hash() +{ + // mostly a compile-only test, to check that qHash(QSslError) is found + QSet errors; + errors << QSslError(); + QCOMPARE(errors.size(), 1); +} + #endif // QT_NO_SSL QTEST_MAIN(tst_QSslError) -- cgit v1.2.3 From e5f48c63d2c6f9a6c4f8a21bcf634111e002ae5b Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Fri, 17 Oct 2014 12:33:06 +0200 Subject: Widgets: only update IM if the widget is the current focus object MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QInputMethod works on focusObject, not focusWidget. These two are not always the same, and sometimes the focusObject is also NULL. In either case, we should not tell QInputMethod to commit, reset or otherwise emit signals based on the internal state of widgets that are not the focus object. This led to a crash on iOS, since we got a call to cursorRectangleChanged when focus object was NULL, which the code didn't (and shouldn't need to) take into account. Change-Id: I54e40d7ec35210ba6599a78c5a8c7f982a1c3dbb Reviewed-by: Tor Arne Vestbø --- src/widgets/kernel/qwidget.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index de64755e4f..e7d33d3bd8 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -9688,7 +9688,8 @@ void QWidget::setInputMethodHints(Qt::InputMethodHints hints) if (d->imHints == hints) return; d->imHints = hints; - qApp->inputMethod()->update(Qt::ImHints); + if (this == qApp->focusObject()) + qApp->inputMethod()->update(Qt::ImHints); #endif //QT_NO_IM } @@ -11031,7 +11032,7 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) d->createTLSysExtra(); #ifndef QT_NO_IM QWidget *focusWidget = d->effectiveFocusWidget(); - if (on && !internalWinId() && hasFocus() + if (on && !internalWinId() && this == qApp->focusObject() && focusWidget->testAttribute(Qt::WA_InputMethodEnabled)) { qApp->inputMethod()->commit(); qApp->inputMethod()->update(Qt::ImEnabled); @@ -11040,7 +11041,7 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on) parentWidget()->d_func()->enforceNativeChildren(); if (on && !internalWinId() && testAttribute(Qt::WA_WState_Created)) d->createWinId(); - if (isEnabled() && focusWidget->isEnabled() + if (isEnabled() && focusWidget->isEnabled() && this == qApp->focusObject() && focusWidget->testAttribute(Qt::WA_InputMethodEnabled)) { qApp->inputMethod()->update(Qt::ImEnabled); } @@ -11566,7 +11567,8 @@ void QWidget::setShortcutAutoRepeat(int id, bool enable) void QWidget::updateMicroFocus() { // updating everything since this is currently called for any kind of state change - qApp->inputMethod()->update(Qt::ImQueryAll); + if (this == qApp->focusObject()) + qApp->inputMethod()->update(Qt::ImQueryAll); } /*! -- cgit v1.2.3 From c5b0308dc562880cdcf55d8f86cad11769e65155 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Thu, 16 Oct 2014 11:02:08 +0300 Subject: Android: Update Ministro's requirements. Task-number: QTBUG-41968 Change-Id: Ia0c204dd87b9de3cbb7bb388099c435b855ad4d5 Reviewed-by: Paul Olav Tvete --- src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java | 2 +- src/android/templates/res/values/libs.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java index e526c0a210..0c52bc7530 100644 --- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java +++ b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java @@ -99,7 +99,7 @@ import android.view.ActionMode.Callback; public class QtActivity extends Activity { private final static int MINISTRO_INSTALL_REQUEST_CODE = 0xf3ee; // request code used to know when Ministro instalation is finished - private static final int MINISTRO_API_LEVEL = 4; // Ministro api level (check IMinistro.aidl file) + private static final int MINISTRO_API_LEVEL = 5; // Ministro api level (check IMinistro.aidl file) private static final int NECESSITAS_API_LEVEL = 2; // Necessitas api level used by platform plugin private static final int QT_VERSION = 0x050100; // This app requires at least Qt version 5.1.0 diff --git a/src/android/templates/res/values/libs.xml b/src/android/templates/res/values/libs.xml index 664ab0abec..4d68673cb0 100644 --- a/src/android/templates/res/values/libs.xml +++ b/src/android/templates/res/values/libs.xml @@ -1,7 +1,7 @@ - https://download.qt-project.org/ministro/android/qt5/qt-5.3 + https://download.qt-project.org/ministro/android/qt5/qt-5.4