diff --git a/ci/accelbubble.7z b/ci/accelbubble.7z
deleted file mode 100644
index 0cdb0a6f..00000000
Binary files a/ci/accelbubble.7z and /dev/null differ
diff --git a/ci/accelbubble/Bluebubble.svg b/ci/accelbubble/Bluebubble.svg
new file mode 100644
index 00000000..d9c406c4
--- /dev/null
+++ b/ci/accelbubble/Bluebubble.svg
@@ -0,0 +1,10 @@
+
+
diff --git a/ci/accelbubble/Bubble.qml b/ci/accelbubble/Bubble.qml
new file mode 100644
index 00000000..67e1c592
--- /dev/null
+++ b/ci/accelbubble/Bubble.qml
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, 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 The Qt Company Ltd 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$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+import QtQuick.Controls 2.2
+
+Image {
+ source: "Bluebubble.svg"
+ smooth: true
+ property real centerX
+ property real centerY
+ property real bubbleCenter
+}
diff --git a/ci/accelbubble/Info.plist b/ci/accelbubble/Info.plist
new file mode 100644
index 00000000..90725455
--- /dev/null
+++ b/ci/accelbubble/Info.plist
@@ -0,0 +1,34 @@
+
+
+
+
+ CFBundleDisplayName
+ accelbubble
+ CFBundleExecutable
+ accelbubble
+ CFBundleGetInfoString
+ Created by Qt/QMake
+ CFBundleIdentifier
+ com.digia.accelbubble
+ CFBundleName
+ accelbubble
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1.0
+ LSRequiresIPhoneOS
+
+ NOTE
+ This file was generated by Qt/QMake.
+ UILaunchStoryboardName
+ LaunchScreen
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+
+
+
diff --git a/ci/accelbubble/Page1Form.ui.qml b/ci/accelbubble/Page1Form.ui.qml
new file mode 100644
index 00000000..0ab08fc4
--- /dev/null
+++ b/ci/accelbubble/Page1Form.ui.qml
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, 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 The Qt Company Ltd 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$
+**
+****************************************************************************/
+import QtQuick 2.9
+import QtQuick.Controls 2.2
+
+Page {
+ width: 600
+ height: 400
+ property alias bubble: bubble
+ property alias mainWindow: mainWindow
+
+ header: Label {
+ text: qsTr("Page 1")
+ font.pixelSize: Qt.application.font.pixelSize * 2
+ padding: 10
+ }
+
+ Rectangle {
+ id: mainWindow
+ color: "#ffffff"
+ anchors.fill: parent
+
+ Bubble {
+ id: bubble
+ }
+ }
+}
diff --git a/ci/accelbubble/Page2Form.ui.qml b/ci/accelbubble/Page2Form.ui.qml
new file mode 100644
index 00000000..11a8abff
--- /dev/null
+++ b/ci/accelbubble/Page2Form.ui.qml
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, 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 The Qt Company Ltd 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$
+**
+****************************************************************************/
+import QtQuick 2.9
+import QtQuick.Controls 2.2
+
+Page {
+ width: 600
+ height: 400
+
+ header: Label {
+ text: qsTr("Page 2")
+ font.pixelSize: Qt.application.font.pixelSize * 2
+ padding: 10
+ }
+
+ Label {
+ text: qsTr("You are on Page 2.")
+ anchors.centerIn: parent
+ }
+}
diff --git a/ci/accelbubble/accelbubble.pro b/ci/accelbubble/accelbubble.pro
new file mode 100644
index 00000000..2ad69426
--- /dev/null
+++ b/ci/accelbubble/accelbubble.pro
@@ -0,0 +1,37 @@
+QT += quick svg xml
+
+CONFIG += c++11
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which as been marked deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += main.cpp
+
+RESOURCES += qml.qrc
+
+# Additional import path used to resolve QML modules in Qt Creator's code model
+QML_IMPORT_PATH =
+
+# Additional import path used to resolve QML modules just for Qt Quick Designer
+QML_DESIGNER_IMPORT_PATH =
+
+# Default rules for deployment.
+qnx: target.path = /tmp/$${TARGET}/bin
+else: unix:!android: target.path = /opt/$${TARGET}/bin
+!isEmpty(target.path): INSTALLS += target
+
+ ios {
+ QTPLUGIN += qsvg qsvgicon qtsensors_ios
+ QMAKE_INFO_PLIST = Info.plist
+ }
+
+DISTFILES += \
+ Bluebubble.svg
diff --git a/ci/accelbubble/main.cpp b/ci/accelbubble/main.cpp
new file mode 100644
index 00000000..4e002b28
--- /dev/null
+++ b/ci/accelbubble/main.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, 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 The Qt Company Ltd 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
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+
+ QGuiApplication app(argc, argv);
+
+ QQmlApplicationEngine engine;
+ engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
+ if (engine.rootObjects().isEmpty())
+ return -1;
+
+ return app.exec();
+}
diff --git a/ci/accelbubble/main.qml b/ci/accelbubble/main.qml
new file mode 100644
index 00000000..26fe2598
--- /dev/null
+++ b/ci/accelbubble/main.qml
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, 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 The Qt Company Ltd 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$
+**
+****************************************************************************/
+
+import QtQuick 2.9
+import QtQuick.Controls 2.2
+import QtSensors 5.9
+
+ApplicationWindow {
+ visible: true
+ width: 640
+ height: 480
+ title: qsTr("Accelerate Bubble")
+
+ SwipeView {
+ id: swipeView
+ anchors.fill: parent
+ currentIndex: tabBar.currentIndex
+
+ Page1Form {
+ bubble {
+ id: bubble
+ centerX: mainWindow.width / 2
+ centerY: mainWindow.height / 2
+ bubbleCenter: bubble.width / 2
+ x: bubble.centerX - bubble.bubbleCenter
+ y: bubble.centerY - bubble.bubbleCenter
+
+ Behavior on y {
+ SmoothedAnimation {
+ easing.type: Easing.Linear
+ duration: 100
+ }
+ }
+ Behavior on x {
+ SmoothedAnimation {
+ easing.type: Easing.Linear
+ duration: 100
+ }
+ }
+ }
+ }
+
+ Page2Form {
+ }
+ }
+
+ footer: TabBar {
+ id: tabBar
+ currentIndex: swipeView.currentIndex
+
+ TabButton {
+ text: qsTr("Page 1")
+ }
+ TabButton {
+ text: qsTr("Page 2")
+ }
+ }
+
+ Accelerometer {
+ id: accel
+ dataRate: 100
+ active: true
+
+ onReadingChanged: {
+ var newX = (bubble.x + calcRoll(accel.reading.x, accel.reading.y, accel.reading.z) * 0.1)
+ var newY = (bubble.y - calcPitch(accel.reading.x, accel.reading.y, accel.reading.z) * 0.1)
+
+ if (isNaN(newX) || isNaN(newY))
+ return;
+
+ if (newX < 0)
+ newX = 0
+
+ if (newX > mainWindow.width - bubble.width)
+ newX = mainWindow.width - bubble.width
+
+ if (newY < 18)
+ newY = 18
+
+ if (newY > mainWindow.height - bubble.height)
+ newY = mainWindow.height - bubble.height
+
+ bubble.x = newX
+ bubble.y = newY
+ }
+ }
+
+ function calcPitch(x, y, z) {
+ return -(Math.atan(y / Math.sqrt(x * x + z * z)) * 57.2957795);
+ }
+ function calcRoll(x, y, z) {
+ return -(Math.atan(x / Math.sqrt(y * y + z * z)) * 57.2957795);
+ }
+}
diff --git a/ci/accelbubble/qml.qrc b/ci/accelbubble/qml.qrc
new file mode 100644
index 00000000..7d7777ac
--- /dev/null
+++ b/ci/accelbubble/qml.qrc
@@ -0,0 +1,10 @@
+
+
+ Page1Form.ui.qml
+ Page2Form.ui.qml
+ qtquickcontrols2.conf
+ Bubble.qml
+ Bluebubble.svg
+ main.qml
+
+
diff --git a/ci/accelbubble/qtquickcontrols2.conf b/ci/accelbubble/qtquickcontrols2.conf
new file mode 100644
index 00000000..75b2cb8f
--- /dev/null
+++ b/ci/accelbubble/qtquickcontrols2.conf
@@ -0,0 +1,6 @@
+; This file can be edited to change the style of the application
+; Read "Qt Quick Controls 2 Configuration File" for details:
+; http://doc.qt.io/qt-5/qtquickcontrols2-configuration.html
+
+[Controls]
+Style=Default
diff --git a/ci/helloworld.7z b/ci/helloworld.7z
deleted file mode 100644
index ffbf45d2..00000000
Binary files a/ci/helloworld.7z and /dev/null differ
diff --git a/ci/helloworld/hello.pro b/ci/helloworld/hello.pro
new file mode 100644
index 00000000..57f727a2
--- /dev/null
+++ b/ci/helloworld/hello.pro
@@ -0,0 +1,9 @@
+QT += core gui
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+TARGET = Hello
+TEMPLATE = app
+
+SOURCES += main.cpp
+
diff --git a/ci/helloworld/main.cpp b/ci/helloworld/main.cpp
new file mode 100644
index 00000000..cd61fcbc
--- /dev/null
+++ b/ci/helloworld/main.cpp
@@ -0,0 +1,12 @@
+#include
+#include
+
+int main(int argc, char **argv)
+{
+ QApplication app (argc, argv);
+
+ QPushButton button ("Hello world !");
+ button.show();
+
+ return app.exec();
+}
\ No newline at end of file
diff --git a/ci/helloworld_qttools.7z b/ci/helloworld_qttools.7z
deleted file mode 100644
index cd17b1de..00000000
Binary files a/ci/helloworld_qttools.7z and /dev/null differ
diff --git a/ci/helloworld_qttools/hello.pro b/ci/helloworld_qttools/hello.pro
new file mode 100644
index 00000000..03a8fe60
--- /dev/null
+++ b/ci/helloworld_qttools/hello.pro
@@ -0,0 +1,7 @@
+QT += uitools
+
+TARGET = Hello
+TEMPLATE = app
+
+SOURCES += main.cpp
+
diff --git a/ci/helloworld_qttools/main.cpp b/ci/helloworld_qttools/main.cpp
new file mode 100644
index 00000000..7d6d1924
--- /dev/null
+++ b/ci/helloworld_qttools/main.cpp
@@ -0,0 +1,13 @@
+#include
+#include
+#include
+
+int main(int argc, char **argv)
+{
+ QApplication app (argc, argv);
+ QUiLoader loader;
+ QPushButton button ("Hello world !");
+ button.show();
+
+ return app.exec();
+}
diff --git a/ci/jom-md5sums.txt b/ci/jom-md5sums.txt
new file mode 100644
index 00000000..65318eb4
--- /dev/null
+++ b/ci/jom-md5sums.txt
@@ -0,0 +1 @@
+4cd0e6fb721e063b24232bc9ecb6d130 jom.zip
diff --git a/ci/jom_1_1_3.zip b/ci/jom_1_1_3.zip
deleted file mode 100644
index ac05c15d..00000000
Binary files a/ci/jom_1_1_3.zip and /dev/null differ
diff --git a/ci/openglwindow.7z b/ci/openglwindow.7z
deleted file mode 100644
index c43192df..00000000
Binary files a/ci/openglwindow.7z and /dev/null differ
diff --git a/ci/openglwindow/CMakeLists.txt b/ci/openglwindow/CMakeLists.txt
new file mode 100644
index 00000000..3d5511ef
--- /dev/null
+++ b/ci/openglwindow/CMakeLists.txt
@@ -0,0 +1,34 @@
+cmake_minimum_required(VERSION 3.16)
+project(openglwindow LANGUAGES CXX)
+
+set(CMAKE_AUTOMOC ON)
+
+if(NOT DEFINED INSTALL_EXAMPLESDIR)
+ set(INSTALL_EXAMPLESDIR "examples")
+endif()
+
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/opengl/openglwindow")
+
+find_package(Qt6 REQUIRED COMPONENTS Core Gui OpenGL)
+
+qt_add_executable(openglwindow
+ main.cpp
+ openglwindow.cpp openglwindow.h
+)
+
+set_target_properties(openglwindow PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+target_link_libraries(openglwindow PUBLIC
+ Qt::Core
+ Qt::Gui
+ Qt::OpenGL
+)
+
+install(TARGETS openglwindow
+ RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
+ LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+)
diff --git a/ci/openglwindow/main.cpp b/ci/openglwindow/main.cpp
new file mode 100644
index 00000000..6813dc9e
--- /dev/null
+++ b/ci/openglwindow/main.cpp
@@ -0,0 +1,130 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "openglwindow.h"
+
+#include
+#include
+#include
+#include
+#include
+
+
+//! [1]
+class TriangleWindow : public OpenGLWindow
+{
+public:
+ using OpenGLWindow::OpenGLWindow;
+
+ void initialize() override;
+ void render() override;
+
+private:
+ GLint m_posAttr = 0;
+ GLint m_colAttr = 0;
+ GLint m_matrixUniform = 0;
+
+ QOpenGLShaderProgram *m_program = nullptr;
+ int m_frame = 0;
+};
+//! [1]
+
+//! [2]
+int main(int argc, char **argv)
+{
+ QGuiApplication app(argc, argv);
+
+ QSurfaceFormat format;
+ format.setSamples(16);
+
+ TriangleWindow window;
+ window.setFormat(format);
+ window.resize(640, 480);
+ window.show();
+
+ window.setAnimating(true);
+
+ return app.exec();
+}
+//! [2]
+
+
+//! [3]
+static const char *vertexShaderSource =
+ "attribute highp vec4 posAttr;\n"
+ "attribute lowp vec4 colAttr;\n"
+ "varying lowp vec4 col;\n"
+ "uniform highp mat4 matrix;\n"
+ "void main() {\n"
+ " col = colAttr;\n"
+ " gl_Position = matrix * posAttr;\n"
+ "}\n";
+
+static const char *fragmentShaderSource =
+ "varying lowp vec4 col;\n"
+ "void main() {\n"
+ " gl_FragColor = col;\n"
+ "}\n";
+//! [3]
+
+//! [4]
+void TriangleWindow::initialize()
+{
+ m_program = new QOpenGLShaderProgram(this);
+ m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
+ m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
+ m_program->link();
+ m_posAttr = m_program->attributeLocation("posAttr");
+ Q_ASSERT(m_posAttr != -1);
+ m_colAttr = m_program->attributeLocation("colAttr");
+ Q_ASSERT(m_colAttr != -1);
+ m_matrixUniform = m_program->uniformLocation("matrix");
+ Q_ASSERT(m_matrixUniform != -1);
+}
+//! [4]
+
+//! [5]
+void TriangleWindow::render()
+{
+ const qreal retinaScale = devicePixelRatio();
+ glViewport(0, 0, width() * retinaScale, height() * retinaScale);
+
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ m_program->bind();
+
+ QMatrix4x4 matrix;
+ matrix.perspective(60.0f, 4.0f / 3.0f, 0.1f, 100.0f);
+ matrix.translate(0, 0, -2);
+ matrix.rotate(100.0f * m_frame / screen()->refreshRate(), 0, 1, 0);
+
+ m_program->setUniformValue(m_matrixUniform, matrix);
+
+ static const GLfloat vertices[] = {
+ 0.0f, 0.707f,
+ -0.5f, -0.5f,
+ 0.5f, -0.5f
+ };
+
+ static const GLfloat colors[] = {
+ 1.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f
+ };
+
+ glVertexAttribPointer(m_posAttr, 2, GL_FLOAT, GL_FALSE, 0, vertices);
+ glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, 0, colors);
+
+ glEnableVertexAttribArray(m_posAttr);
+ glEnableVertexAttribArray(m_colAttr);
+
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+
+ glDisableVertexAttribArray(m_colAttr);
+ glDisableVertexAttribArray(m_posAttr);
+
+ m_program->release();
+
+ ++m_frame;
+}
+//! [5]
diff --git a/ci/openglwindow/openglwindow.cpp b/ci/openglwindow/openglwindow.cpp
new file mode 100644
index 00000000..4869f45e
--- /dev/null
+++ b/ci/openglwindow/openglwindow.cpp
@@ -0,0 +1,114 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "openglwindow.h"
+
+#include
+#include
+#include
+
+//! [1]
+OpenGLWindow::OpenGLWindow(QWindow *parent)
+ : QWindow(parent)
+{
+ setSurfaceType(QWindow::OpenGLSurface);
+}
+//! [1]
+
+OpenGLWindow::~OpenGLWindow()
+{
+ delete m_device;
+}
+//! [2]
+void OpenGLWindow::render(QPainter *painter)
+{
+ Q_UNUSED(painter);
+}
+
+void OpenGLWindow::initialize()
+{
+}
+
+void OpenGLWindow::render()
+{
+ if (!m_device)
+ m_device = new QOpenGLPaintDevice;
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+ m_device->setSize(size() * devicePixelRatio());
+ m_device->setDevicePixelRatio(devicePixelRatio());
+
+ QPainter painter(m_device);
+ render(&painter);
+}
+//! [2]
+
+//! [3]
+void OpenGLWindow::renderLater()
+{
+ requestUpdate();
+}
+
+bool OpenGLWindow::event(QEvent *event)
+{
+ switch (event->type()) {
+ case QEvent::UpdateRequest:
+ renderNow();
+ return true;
+ default:
+ return QWindow::event(event);
+ }
+}
+
+void OpenGLWindow::exposeEvent(QExposeEvent *event)
+{
+ Q_UNUSED(event);
+
+ if (isExposed())
+ renderNow();
+}
+//! [3]
+
+//! [4]
+void OpenGLWindow::renderNow()
+{
+ if (!isExposed())
+ return;
+
+ bool needsInitialize = false;
+
+ if (!m_context) {
+ m_context = new QOpenGLContext(this);
+ m_context->setFormat(requestedFormat());
+ m_context->create();
+
+ needsInitialize = true;
+ }
+
+ m_context->makeCurrent(this);
+
+ if (needsInitialize) {
+ initializeOpenGLFunctions();
+ initialize();
+ }
+
+ render();
+
+ m_context->swapBuffers(this);
+
+ if (m_animating)
+ renderLater();
+}
+//! [4]
+
+//! [5]
+void OpenGLWindow::setAnimating(bool animating)
+{
+ m_animating = animating;
+
+ if (animating)
+ renderLater();
+}
+//! [5]
+
diff --git a/ci/openglwindow/openglwindow.h b/ci/openglwindow/openglwindow.h
new file mode 100644
index 00000000..7206fc57
--- /dev/null
+++ b/ci/openglwindow/openglwindow.h
@@ -0,0 +1,44 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include
+#include
+
+QT_BEGIN_NAMESPACE
+class QPainter;
+class QOpenGLContext;
+class QOpenGLPaintDevice;
+QT_END_NAMESPACE
+
+//! [1]
+class OpenGLWindow : public QWindow, protected QOpenGLFunctions
+{
+ Q_OBJECT
+public:
+ explicit OpenGLWindow(QWindow *parent = nullptr);
+ ~OpenGLWindow();
+
+ virtual void render(QPainter *painter);
+ virtual void render();
+
+ virtual void initialize();
+
+ void setAnimating(bool animating);
+
+public slots:
+ void renderLater();
+ void renderNow();
+
+protected:
+ bool event(QEvent *event) override;
+
+ void exposeEvent(QExposeEvent *event) override;
+
+private:
+ bool m_animating = false;
+
+ QOpenGLContext *m_context = nullptr;
+ QOpenGLPaintDevice *m_device = nullptr;
+};
+//! [1]
+
diff --git a/ci/openglwindow/openglwindow.pri b/ci/openglwindow/openglwindow.pri
new file mode 100644
index 00000000..30320df3
--- /dev/null
+++ b/ci/openglwindow/openglwindow.pri
@@ -0,0 +1,4 @@
+QT += opengl
+INCLUDEPATH += $$PWD
+SOURCES += $$PWD/openglwindow.cpp
+HEADERS += $$PWD/openglwindow.h
diff --git a/ci/openglwindow/openglwindow.pro b/ci/openglwindow/openglwindow.pro
new file mode 100644
index 00000000..8b1ae71c
--- /dev/null
+++ b/ci/openglwindow/openglwindow.pro
@@ -0,0 +1,7 @@
+include(openglwindow.pri)
+
+SOURCES += \
+ main.cpp
+
+target.path = $$[QT_INSTALL_EXAMPLES]/opengl/openglwindow
+INSTALLS += target
diff --git a/ci/openglwindow_qt5/main.cpp b/ci/openglwindow_qt5/main.cpp
new file mode 100644
index 00000000..90c93f0d
--- /dev/null
+++ b/ci/openglwindow_qt5/main.cpp
@@ -0,0 +1,180 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, 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 The Qt Company Ltd 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 "openglwindow.h"
+
+#include
+#include
+#include
+#include
+
+#include
+
+//! [1]
+class TriangleWindow : public OpenGLWindow
+{
+public:
+ TriangleWindow();
+
+ void initialize() override;
+ void render() override;
+
+private:
+ GLuint m_posAttr;
+ GLuint m_colAttr;
+ GLuint m_matrixUniform;
+
+ QOpenGLShaderProgram *m_program;
+ int m_frame;
+};
+
+TriangleWindow::TriangleWindow()
+ : m_program(0)
+ , m_frame(0)
+{
+}
+//! [1]
+
+//! [2]
+int main(int argc, char **argv)
+{
+ QGuiApplication app(argc, argv);
+
+ QSurfaceFormat format;
+ format.setSamples(16);
+
+ TriangleWindow window;
+ window.setFormat(format);
+ window.resize(640, 480);
+ window.show();
+
+ window.setAnimating(true);
+
+ return app.exec();
+}
+//! [2]
+
+
+//! [3]
+static const char *vertexShaderSource =
+ "attribute highp vec4 posAttr;\n"
+ "attribute lowp vec4 colAttr;\n"
+ "varying lowp vec4 col;\n"
+ "uniform highp mat4 matrix;\n"
+ "void main() {\n"
+ " col = colAttr;\n"
+ " gl_Position = matrix * posAttr;\n"
+ "}\n";
+
+static const char *fragmentShaderSource =
+ "varying lowp vec4 col;\n"
+ "void main() {\n"
+ " gl_FragColor = col;\n"
+ "}\n";
+//! [3]
+
+//! [4]
+void TriangleWindow::initialize()
+{
+ m_program = new QOpenGLShaderProgram(this);
+ m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
+ m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
+ m_program->link();
+ m_posAttr = m_program->attributeLocation("posAttr");
+ m_colAttr = m_program->attributeLocation("colAttr");
+ m_matrixUniform = m_program->uniformLocation("matrix");
+}
+//! [4]
+
+//! [5]
+void TriangleWindow::render()
+{
+ const qreal retinaScale = devicePixelRatio();
+ glViewport(0, 0, width() * retinaScale, height() * retinaScale);
+
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ m_program->bind();
+
+ QMatrix4x4 matrix;
+ matrix.perspective(60.0f, 4.0f/3.0f, 0.1f, 100.0f);
+ matrix.translate(0, 0, -2);
+ matrix.rotate(100.0f * m_frame / screen()->refreshRate(), 0, 1, 0);
+
+ m_program->setUniformValue(m_matrixUniform, matrix);
+
+ GLfloat vertices[] = {
+ 0.0f, 0.707f,
+ -0.5f, -0.5f,
+ 0.5f, -0.5f
+ };
+
+ GLfloat colors[] = {
+ 1.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f
+ };
+
+ glVertexAttribPointer(m_posAttr, 2, GL_FLOAT, GL_FALSE, 0, vertices);
+ glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, 0, colors);
+
+ glEnableVertexAttribArray(0);
+ glEnableVertexAttribArray(1);
+
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+
+ glDisableVertexAttribArray(1);
+ glDisableVertexAttribArray(0);
+
+ m_program->release();
+
+ ++m_frame;
+}
+//! [5]
diff --git a/ci/openglwindow_qt5/openglwindow.cpp b/ci/openglwindow_qt5/openglwindow.cpp
new file mode 100644
index 00000000..a0c85006
--- /dev/null
+++ b/ci/openglwindow_qt5/openglwindow.cpp
@@ -0,0 +1,166 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, 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 The Qt Company Ltd 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 "openglwindow.h"
+
+#include
+
+#include
+#include
+#include
+
+//! [1]
+OpenGLWindow::OpenGLWindow(QWindow *parent)
+ : QWindow(parent)
+ , m_animating(false)
+ , m_context(0)
+ , m_device(0)
+{
+ setSurfaceType(QWindow::OpenGLSurface);
+}
+//! [1]
+
+OpenGLWindow::~OpenGLWindow()
+{
+ delete m_device;
+}
+//! [2]
+void OpenGLWindow::render(QPainter *painter)
+{
+ Q_UNUSED(painter);
+}
+
+void OpenGLWindow::initialize()
+{
+}
+
+void OpenGLWindow::render()
+{
+ if (!m_device)
+ m_device = new QOpenGLPaintDevice;
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+
+ m_device->setSize(size() * devicePixelRatio());
+ m_device->setDevicePixelRatio(devicePixelRatio());
+
+ QPainter painter(m_device);
+ render(&painter);
+}
+//! [2]
+
+//! [3]
+void OpenGLWindow::renderLater()
+{
+ requestUpdate();
+}
+
+bool OpenGLWindow::event(QEvent *event)
+{
+ switch (event->type()) {
+ case QEvent::UpdateRequest:
+ renderNow();
+ return true;
+ default:
+ return QWindow::event(event);
+ }
+}
+
+void OpenGLWindow::exposeEvent(QExposeEvent *event)
+{
+ Q_UNUSED(event);
+
+ if (isExposed())
+ renderNow();
+}
+//! [3]
+
+//! [4]
+void OpenGLWindow::renderNow()
+{
+ if (!isExposed())
+ return;
+
+ bool needsInitialize = false;
+
+ if (!m_context) {
+ m_context = new QOpenGLContext(this);
+ m_context->setFormat(requestedFormat());
+ m_context->create();
+
+ needsInitialize = true;
+ }
+
+ m_context->makeCurrent(this);
+
+ if (needsInitialize) {
+ initializeOpenGLFunctions();
+ initialize();
+ }
+
+ render();
+
+ m_context->swapBuffers(this);
+
+ if (m_animating)
+ renderLater();
+}
+//! [4]
+
+//! [5]
+void OpenGLWindow::setAnimating(bool animating)
+{
+ m_animating = animating;
+
+ if (animating)
+ renderLater();
+}
+//! [5]
+
diff --git a/ci/openglwindow_qt5/openglwindow.h b/ci/openglwindow_qt5/openglwindow.h
new file mode 100644
index 00000000..6e6c1d74
--- /dev/null
+++ b/ci/openglwindow_qt5/openglwindow.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, 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 The Qt Company Ltd 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
+
+QT_BEGIN_NAMESPACE
+class QPainter;
+class QOpenGLContext;
+class QOpenGLPaintDevice;
+QT_END_NAMESPACE
+
+//! [1]
+class OpenGLWindow : public QWindow, protected QOpenGLFunctions
+{
+ Q_OBJECT
+public:
+ explicit OpenGLWindow(QWindow *parent = 0);
+ ~OpenGLWindow();
+
+ virtual void render(QPainter *painter);
+ virtual void render();
+
+ virtual void initialize();
+
+ void setAnimating(bool animating);
+
+public slots:
+ void renderLater();
+ void renderNow();
+
+protected:
+ bool event(QEvent *event) override;
+
+ void exposeEvent(QExposeEvent *event) override;
+
+private:
+ bool m_animating;
+
+ QOpenGLContext *m_context;
+ QOpenGLPaintDevice *m_device;
+};
+//! [1]
+
diff --git a/ci/openglwindow_qt5/openglwindow.pri b/ci/openglwindow_qt5/openglwindow.pri
new file mode 100644
index 00000000..45b0b0cd
--- /dev/null
+++ b/ci/openglwindow_qt5/openglwindow.pri
@@ -0,0 +1,3 @@
+INCLUDEPATH += $$PWD
+SOURCES += $$PWD/openglwindow.cpp
+HEADERS += $$PWD/openglwindow.h
diff --git a/ci/openglwindow_qt5/openglwindow.pro b/ci/openglwindow_qt5/openglwindow.pro
new file mode 100644
index 00000000..93f18f3d
--- /dev/null
+++ b/ci/openglwindow_qt5/openglwindow.pro
@@ -0,0 +1,7 @@
+include(openglwindow.pri)
+
+SOURCES += \
+ main.cpp
+
+target.path = $$[QT_INSTALL_EXAMPLES]/gui/openglwindow
+INSTALLS += target
diff --git a/ci/openglwindow_qt6.7z b/ci/openglwindow_qt6.7z
deleted file mode 100644
index 332a8f2e..00000000
Binary files a/ci/openglwindow_qt6.7z and /dev/null differ
diff --git a/ci/redditclient.7z b/ci/redditclient.7z
deleted file mode 100644
index 4e346cc2..00000000
Binary files a/ci/redditclient.7z and /dev/null differ
diff --git a/ci/redditclient/main.cpp b/ci/redditclient/main.cpp
new file mode 100644
index 00000000..d451fd1b
--- /dev/null
+++ b/ci/redditclient/main.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Network Auth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, 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 The Qt Company Ltd 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 "redditmodel.h"
+
+#include
+#include
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+ QCommandLineParser parser;
+ const QCommandLineOption clientId(QStringList() << "i" << "client-id",
+ "Specifies the application client id", "client_id");
+
+ parser.addOptions({clientId});
+ parser.process(app);
+
+ if (parser.isSet(clientId)) {
+ QListView view;
+ RedditModel model(parser.value(clientId));
+ view.setModel(&model);
+ view.show();
+ return app.exec();
+ } else {
+ parser.showHelp();
+ }
+ return 0;
+}
diff --git a/ci/redditclient/redditclient.pro b/ci/redditclient/redditclient.pro
new file mode 100644
index 00000000..456fc781
--- /dev/null
+++ b/ci/redditclient/redditclient.pro
@@ -0,0 +1,17 @@
+QT += widgets network networkauth
+requires(qtConfig(listview))
+
+TARGET = redditclient
+
+# Input
+SOURCES += main.cpp \
+ redditmodel.cpp \
+ redditwrapper.cpp
+
+HEADERS += \
+ redditmodel.h \
+ redditwrapper.h
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/oauth/redditclient
+INSTALLS += target
diff --git a/ci/redditclient/redditmodel.cpp b/ci/redditclient/redditmodel.cpp
new file mode 100644
index 00000000..a415e04b
--- /dev/null
+++ b/ci/redditclient/redditmodel.cpp
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Network Auth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, 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 The Qt Company Ltd 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 "redditmodel.h"
+
+#include
+#include
+
+RedditModel::RedditModel(QObject *parent) : QAbstractTableModel(parent) {}
+
+RedditModel::RedditModel(const QString &clientId, QObject *parent) :
+ QAbstractTableModel(parent),
+ redditWrapper(clientId)
+{
+ grant();
+}
+
+int RedditModel::rowCount(const QModelIndex &parent) const
+{
+ Q_UNUSED(parent);
+ return threads.size();
+}
+
+int RedditModel::columnCount(const QModelIndex &parent) const
+{
+ Q_UNUSED(parent);
+ return threads.size() ? 1 : 0;
+}
+
+QVariant RedditModel::data(const QModelIndex &index, int role) const
+{
+ Q_UNUSED(role);
+ if (!index.isValid())
+ return QVariant();
+
+ if (role == Qt::DisplayRole) {
+ const auto childrenObject = threads.at(index.row());
+ Q_ASSERT(childrenObject.value("data").isObject());
+ const auto dataObject = childrenObject.value("data").toObject();
+ return dataObject.value("title").toString();
+ }
+ return QVariant();
+}
+
+void RedditModel::grant()
+{
+ redditWrapper.grant();
+ connect(&redditWrapper, &RedditWrapper::authenticated, this, &RedditModel::update);
+}
+
+void RedditModel::update()
+{
+ auto reply = redditWrapper.requestHotThreads();
+
+ connect(reply, &QNetworkReply::finished, [=]() {
+ reply->deleteLater();
+ if (reply->error() != QNetworkReply::NoError) {
+ emit error(reply->errorString());
+ return;
+ }
+ const auto json = reply->readAll();
+ const auto document = QJsonDocument::fromJson(json);
+ Q_ASSERT(document.isObject());
+ const auto rootObject = document.object();
+ Q_ASSERT(rootObject.value("kind").toString() == "Listing");
+ const auto dataValue = rootObject.value("data");
+ Q_ASSERT(dataValue.isObject());
+ const auto dataObject = dataValue.toObject();
+ const auto childrenValue = dataObject.value("children");
+ Q_ASSERT(childrenValue.isArray());
+ const auto childrenArray = childrenValue.toArray();
+
+ if (childrenArray.isEmpty())
+ return;
+
+ beginInsertRows(QModelIndex(), threads.size(), childrenArray.size() + threads.size() - 1);
+ for (const auto childValue : qAsConst(childrenArray)) {
+ Q_ASSERT(childValue.isObject());
+ threads.append(childValue.toObject());
+ }
+ endInsertRows();
+ });
+}
diff --git a/ci/redditclient/redditmodel.h b/ci/redditclient/redditmodel.h
new file mode 100644
index 00000000..98dbb907
--- /dev/null
+++ b/ci/redditclient/redditmodel.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Network Auth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, 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 The Qt Company Ltd 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 REDDITMODEL_H
+#define REDDITMODEL_H
+
+#include "redditwrapper.h"
+
+#include
+
+QT_FORWARD_DECLARE_CLASS(QNetworkReply)
+
+class RedditModel : public QAbstractTableModel
+{
+ Q_OBJECT
+
+public:
+ RedditModel(QObject *parent = nullptr);
+ RedditModel(const QString &clientId, QObject *parent = nullptr);
+
+ int rowCount(const QModelIndex &parent) const override;
+ int columnCount(const QModelIndex &parent) const override;
+ QVariant data(const QModelIndex &index, int role) const override;
+
+ void grant();
+
+signals:
+ void error(const QString &errorString);
+
+private slots:
+ void update();
+
+private:
+ RedditWrapper redditWrapper;
+ QPointer liveThreadReply;
+ QList threads;
+};
+
+#endif // REDDITMODEL_H
diff --git a/ci/redditclient/redditwrapper.cpp b/ci/redditclient/redditwrapper.cpp
new file mode 100644
index 00000000..c112671c
--- /dev/null
+++ b/ci/redditclient/redditwrapper.cpp
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Network Auth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, 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 The Qt Company Ltd 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 "redditwrapper.h"
+
+#include
+#include
+#include
+
+const QUrl newUrl("https://oauth.reddit.com/new");
+const QUrl hotUrl("https://oauth.reddit.com/hot");
+const QUrl liveThreadsUrl("https://oauth.reddit.com/live/XXXX/about.json");
+
+RedditWrapper::RedditWrapper(QObject *parent) : QObject(parent)
+{
+ auto replyHandler = new QOAuthHttpServerReplyHandler(1337, this);
+ oauth2.setReplyHandler(replyHandler);
+ oauth2.setAuthorizationUrl(QUrl("https://www.reddit.com/api/v1/authorize"));
+ oauth2.setAccessTokenUrl(QUrl("https://www.reddit.com/api/v1/access_token"));
+ oauth2.setScope("identity read");
+
+ connect(&oauth2, &QOAuth2AuthorizationCodeFlow::statusChanged, [=](
+ QAbstractOAuth::Status status) {
+ if (status == QAbstractOAuth::Status::Granted)
+ emit authenticated();
+ });
+ oauth2.setModifyParametersFunction([&](QAbstractOAuth::Stage stage, QMultiMap *parameters) {
+ if (stage == QAbstractOAuth::Stage::RequestingAuthorization && isPermanent())
+ parameters->insert("duration", "permanent");
+ });
+ connect(&oauth2, &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser,
+ &QDesktopServices::openUrl);
+}
+
+RedditWrapper::RedditWrapper(const QString &clientIdentifier, QObject *parent) :
+ RedditWrapper(parent)
+{
+ oauth2.setClientIdentifier(clientIdentifier);
+}
+
+QNetworkReply *RedditWrapper::requestHotThreads()
+{
+ qDebug() << "Getting hot threads...";
+ return oauth2.get(hotUrl);
+}
+
+bool RedditWrapper::isPermanent() const
+{
+ return permanent;
+}
+
+void RedditWrapper::setPermanent(bool value)
+{
+ permanent = value;
+}
+
+void RedditWrapper::grant()
+{
+ oauth2.grant();
+}
+
+void RedditWrapper::subscribeToLiveUpdates()
+{
+ qDebug() << "Susbscribing...";
+ QNetworkReply *reply = oauth2.get(liveThreadsUrl);
+ connect(reply, &QNetworkReply::finished, [=]() {
+ reply->deleteLater();
+ if (reply->error() != QNetworkReply::NoError) {
+ qCritical() << "Reddit error:" << reply->errorString();
+ return;
+ }
+
+ const auto json = reply->readAll();
+
+ const auto document = QJsonDocument::fromJson(json);
+ Q_ASSERT(document.isObject());
+ const auto rootObject = document.object();
+ const auto dataValue = rootObject.value("data");
+ Q_ASSERT(dataValue.isObject());
+ const auto dataObject = dataValue.toObject();
+ const auto websocketUrlValue = dataObject.value("websocket_url");
+ Q_ASSERT(websocketUrlValue.isString() && websocketUrlValue.toString().size());
+ const QUrl websocketUrl(websocketUrlValue.toString());
+ emit subscribed(websocketUrl);
+ });
+}
diff --git a/ci/redditclient/redditwrapper.h b/ci/redditclient/redditwrapper.h
new file mode 100644
index 00000000..4b86ba97
--- /dev/null
+++ b/ci/redditclient/redditwrapper.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Network Auth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, 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 The Qt Company Ltd 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 REDDITWRAPPER_H
+#define REDDITWRAPPER_H
+
+#include
+#include
+
+#include
+
+class RedditWrapper : public QObject
+{
+ Q_OBJECT
+
+public:
+ RedditWrapper(QObject *parent = nullptr);
+ RedditWrapper(const QString &clientIdentifier, QObject *parent = nullptr);
+
+ QNetworkReply *requestHotThreads();
+
+ bool isPermanent() const;
+ void setPermanent(bool value);
+
+public slots:
+ void grant();
+ void subscribeToLiveUpdates();
+
+signals:
+ void authenticated();
+ void subscribed(const QUrl &url);
+
+private:
+ QOAuth2AuthorizationCodeFlow oauth2;
+ bool permanent = false;
+};
+
+#endif // REDDITWRAPPER_H
diff --git a/ci/redditclient_qt5/main.cpp b/ci/redditclient_qt5/main.cpp
new file mode 100644
index 00000000..d451fd1b
--- /dev/null
+++ b/ci/redditclient_qt5/main.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Network Auth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, 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 The Qt Company Ltd 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 "redditmodel.h"
+
+#include
+#include
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+ QCommandLineParser parser;
+ const QCommandLineOption clientId(QStringList() << "i" << "client-id",
+ "Specifies the application client id", "client_id");
+
+ parser.addOptions({clientId});
+ parser.process(app);
+
+ if (parser.isSet(clientId)) {
+ QListView view;
+ RedditModel model(parser.value(clientId));
+ view.setModel(&model);
+ view.show();
+ return app.exec();
+ } else {
+ parser.showHelp();
+ }
+ return 0;
+}
diff --git a/ci/redditclient_qt5/redditclient.pro b/ci/redditclient_qt5/redditclient.pro
new file mode 100644
index 00000000..456fc781
--- /dev/null
+++ b/ci/redditclient_qt5/redditclient.pro
@@ -0,0 +1,17 @@
+QT += widgets network networkauth
+requires(qtConfig(listview))
+
+TARGET = redditclient
+
+# Input
+SOURCES += main.cpp \
+ redditmodel.cpp \
+ redditwrapper.cpp
+
+HEADERS += \
+ redditmodel.h \
+ redditwrapper.h
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/oauth/redditclient
+INSTALLS += target
diff --git a/ci/redditclient_qt5/redditmodel.cpp b/ci/redditclient_qt5/redditmodel.cpp
new file mode 100644
index 00000000..a415e04b
--- /dev/null
+++ b/ci/redditclient_qt5/redditmodel.cpp
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Network Auth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, 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 The Qt Company Ltd 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 "redditmodel.h"
+
+#include
+#include
+
+RedditModel::RedditModel(QObject *parent) : QAbstractTableModel(parent) {}
+
+RedditModel::RedditModel(const QString &clientId, QObject *parent) :
+ QAbstractTableModel(parent),
+ redditWrapper(clientId)
+{
+ grant();
+}
+
+int RedditModel::rowCount(const QModelIndex &parent) const
+{
+ Q_UNUSED(parent);
+ return threads.size();
+}
+
+int RedditModel::columnCount(const QModelIndex &parent) const
+{
+ Q_UNUSED(parent);
+ return threads.size() ? 1 : 0;
+}
+
+QVariant RedditModel::data(const QModelIndex &index, int role) const
+{
+ Q_UNUSED(role);
+ if (!index.isValid())
+ return QVariant();
+
+ if (role == Qt::DisplayRole) {
+ const auto childrenObject = threads.at(index.row());
+ Q_ASSERT(childrenObject.value("data").isObject());
+ const auto dataObject = childrenObject.value("data").toObject();
+ return dataObject.value("title").toString();
+ }
+ return QVariant();
+}
+
+void RedditModel::grant()
+{
+ redditWrapper.grant();
+ connect(&redditWrapper, &RedditWrapper::authenticated, this, &RedditModel::update);
+}
+
+void RedditModel::update()
+{
+ auto reply = redditWrapper.requestHotThreads();
+
+ connect(reply, &QNetworkReply::finished, [=]() {
+ reply->deleteLater();
+ if (reply->error() != QNetworkReply::NoError) {
+ emit error(reply->errorString());
+ return;
+ }
+ const auto json = reply->readAll();
+ const auto document = QJsonDocument::fromJson(json);
+ Q_ASSERT(document.isObject());
+ const auto rootObject = document.object();
+ Q_ASSERT(rootObject.value("kind").toString() == "Listing");
+ const auto dataValue = rootObject.value("data");
+ Q_ASSERT(dataValue.isObject());
+ const auto dataObject = dataValue.toObject();
+ const auto childrenValue = dataObject.value("children");
+ Q_ASSERT(childrenValue.isArray());
+ const auto childrenArray = childrenValue.toArray();
+
+ if (childrenArray.isEmpty())
+ return;
+
+ beginInsertRows(QModelIndex(), threads.size(), childrenArray.size() + threads.size() - 1);
+ for (const auto childValue : qAsConst(childrenArray)) {
+ Q_ASSERT(childValue.isObject());
+ threads.append(childValue.toObject());
+ }
+ endInsertRows();
+ });
+}
diff --git a/ci/redditclient_qt5/redditmodel.h b/ci/redditclient_qt5/redditmodel.h
new file mode 100644
index 00000000..98dbb907
--- /dev/null
+++ b/ci/redditclient_qt5/redditmodel.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Network Auth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, 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 The Qt Company Ltd 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 REDDITMODEL_H
+#define REDDITMODEL_H
+
+#include "redditwrapper.h"
+
+#include
+
+QT_FORWARD_DECLARE_CLASS(QNetworkReply)
+
+class RedditModel : public QAbstractTableModel
+{
+ Q_OBJECT
+
+public:
+ RedditModel(QObject *parent = nullptr);
+ RedditModel(const QString &clientId, QObject *parent = nullptr);
+
+ int rowCount(const QModelIndex &parent) const override;
+ int columnCount(const QModelIndex &parent) const override;
+ QVariant data(const QModelIndex &index, int role) const override;
+
+ void grant();
+
+signals:
+ void error(const QString &errorString);
+
+private slots:
+ void update();
+
+private:
+ RedditWrapper redditWrapper;
+ QPointer liveThreadReply;
+ QList threads;
+};
+
+#endif // REDDITMODEL_H
diff --git a/ci/redditclient_qt5/redditwrapper.cpp b/ci/redditclient_qt5/redditwrapper.cpp
new file mode 100644
index 00000000..105f670b
--- /dev/null
+++ b/ci/redditclient_qt5/redditwrapper.cpp
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Network Auth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, 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 The Qt Company Ltd 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 "redditwrapper.h"
+
+#include
+#include
+#include
+
+const QUrl newUrl("https://oauth.reddit.com/new");
+const QUrl hotUrl("https://oauth.reddit.com/hot");
+const QUrl liveThreadsUrl("https://oauth.reddit.com/live/XXXX/about.json");
+
+RedditWrapper::RedditWrapper(QObject *parent) : QObject(parent)
+{
+ auto replyHandler = new QOAuthHttpServerReplyHandler(1337, this);
+ oauth2.setReplyHandler(replyHandler);
+ oauth2.setAuthorizationUrl(QUrl("https://www.reddit.com/api/v1/authorize"));
+ oauth2.setAccessTokenUrl(QUrl("https://www.reddit.com/api/v1/access_token"));
+ oauth2.setScope("identity read");
+
+ connect(&oauth2, &QOAuth2AuthorizationCodeFlow::statusChanged, [=](
+ QAbstractOAuth::Status status) {
+ if (status == QAbstractOAuth::Status::Granted)
+ emit authenticated();
+ });
+ oauth2.setModifyParametersFunction([&](QAbstractOAuth::Stage stage, QVariantMap *parameters) {
+ if (stage == QAbstractOAuth::Stage::RequestingAuthorization && isPermanent())
+ parameters->insert("duration", "permanent");
+ });
+ connect(&oauth2, &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser,
+ &QDesktopServices::openUrl);
+}
+
+RedditWrapper::RedditWrapper(const QString &clientIdentifier, QObject *parent) :
+ RedditWrapper(parent)
+{
+ oauth2.setClientIdentifier(clientIdentifier);
+}
+
+QNetworkReply *RedditWrapper::requestHotThreads()
+{
+ qDebug() << "Getting hot threads...";
+ return oauth2.get(hotUrl);
+}
+
+bool RedditWrapper::isPermanent() const
+{
+ return permanent;
+}
+
+void RedditWrapper::setPermanent(bool value)
+{
+ permanent = value;
+}
+
+void RedditWrapper::grant()
+{
+ oauth2.grant();
+}
+
+void RedditWrapper::subscribeToLiveUpdates()
+{
+ qDebug() << "Susbscribing...";
+ QNetworkReply *reply = oauth2.get(liveThreadsUrl);
+ connect(reply, &QNetworkReply::finished, [=]() {
+ reply->deleteLater();
+ if (reply->error() != QNetworkReply::NoError) {
+ qCritical() << "Reddit error:" << reply->errorString();
+ return;
+ }
+
+ const auto json = reply->readAll();
+
+ const auto document = QJsonDocument::fromJson(json);
+ Q_ASSERT(document.isObject());
+ const auto rootObject = document.object();
+ const auto dataValue = rootObject.value("data");
+ Q_ASSERT(dataValue.isObject());
+ const auto dataObject = dataValue.toObject();
+ const auto websocketUrlValue = dataObject.value("websocket_url");
+ Q_ASSERT(websocketUrlValue.isString() && websocketUrlValue.toString().size());
+ const QUrl websocketUrl(websocketUrlValue.toString());
+ emit subscribed(websocketUrl);
+ });
+}
diff --git a/ci/redditclient_qt5/redditwrapper.h b/ci/redditclient_qt5/redditwrapper.h
new file mode 100644
index 00000000..4b86ba97
--- /dev/null
+++ b/ci/redditclient_qt5/redditwrapper.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Network Auth module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, 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 The Qt Company Ltd 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 REDDITWRAPPER_H
+#define REDDITWRAPPER_H
+
+#include
+#include
+
+#include
+
+class RedditWrapper : public QObject
+{
+ Q_OBJECT
+
+public:
+ RedditWrapper(QObject *parent = nullptr);
+ RedditWrapper(const QString &clientIdentifier, QObject *parent = nullptr);
+
+ QNetworkReply *requestHotThreads();
+
+ bool isPermanent() const;
+ void setPermanent(bool value);
+
+public slots:
+ void grant();
+ void subscribeToLiveUpdates();
+
+signals:
+ void authenticated();
+ void subscribed(const QUrl &url);
+
+private:
+ QOAuth2AuthorizationCodeFlow oauth2;
+ bool permanent = false;
+};
+
+#endif // REDDITWRAPPER_H
diff --git a/ci/steps.yml b/ci/steps.yml
index 5ed24b33..bccfdcf9 100644
--- a/ci/steps.yml
+++ b/ci/steps.yml
@@ -174,10 +174,8 @@ steps:
unzip android-ndk-r21e-darwin-x86_64.zip
fi
export ANDROID_NDK_ROOT=$(Build.SourcesDirectory)/android-ndk-r21e
- mkdir $(Build.BinariesDirectory)/tests
- (cd $(Build.BinariesDirectory)/tests; 7zr x $(Build.SourcesDirectory)/ci/accelbubble.7z)
export PATH=$(QT_BINDIR):$PATH
- qmake $(Build.BinariesDirectory)/tests/accelbubble
+ qmake $(Build.SourcesDirectory)/ci/accelbubble
make
condition: |
and(
@@ -195,10 +193,8 @@ steps:
# for iOS target
- bash: |
set -ex
- mkdir $(Build.BinariesDirectory)/tests
- (cd $(Build.BinariesDirectory)/tests; 7zr x $(Build.SourcesDirectory)/ci/accelbubble.7z)
export PATH=$(QT_BINDIR):$PATH
- qmake $(Build.BinariesDirectory)/tests/accelbubble
+ qmake $(Build.SourcesDirectory)/ci/accelbubble
make
condition: |
and(eq(variables['TARGET'], 'ios'),
@@ -248,7 +244,9 @@ steps:
Write-Host '##vso[task.setvariable variable=VSVER]2022'
}
cd $(WIN_QT_BINDIR)
- unzip $(Build.SourcesDirectory)\ci\jom_1_1_3.zip
+ Invoke-WebRequest -Uri https://download.qt.io/official_releases/jom/jom.zip -OutFile jom.zip
+ md5sum -c md5sum.txt
+ unzip jom.zip
condition: |
and(eq(variables['Agent.OS'], 'Windows_NT'),
eq(variables['SUBCOMMAND'], 'install-qt'))
@@ -257,10 +255,8 @@ steps:
# When no modules
- script: |
set -ex
- mkdir $(Build.BinariesDirectory)/tests
- (cd $(Build.BinariesDirectory)/tests; 7zr x $(Build.SourcesDirectory)/ci/helloworld.7z)
export PATH=$(QT_BINDIR):$PATH
- qmake $(Build.BinariesDirectory)/tests/helloworld
+ qmake $(Build.SourcesDirectory)/ci/helloworld
make
condition: |
and(
@@ -285,11 +281,7 @@ steps:
Import-VisualStudioVars -VisualStudioVersion $(VSVER) -Architecture $(ARCHITECTURE)
$env:Path += ";$(WIN_QT_BINDIR)"
- mkdir $(Build.BinariesDirectory)\tests
- cd $(Build.BinariesDirectory)\tests
- 7z x $(Build.SourcesDirectory)\ci\helloworld.7z
- cd ..
- qmake $(Build.BinariesDirectory)\tests\helloworld
+ qmake $(Build.SourcesDirectory)/ci/helloworld
jom
} elseif ( $env:TOOLCHAIN -eq 'MINGW' ) {
python -m aqt install-tool $(if (($QT_BASE_MIRROR + "") -ne "") { "-b $QT_BASE_MIRROR" } else {""}) `
@@ -301,11 +293,7 @@ steps:
}
Set-Item -Path Env:Path -Value ("$(Build.BinariesDirectory)\Qt\Tools\$(MINGW_FOLDER)\bin;$(WIN_QT_BINDIR);" + $Env:Path)
Write-Host "Path == " + $env:Path
- mkdir $(Build.BinariesDirectory)\tests
- cd $(Build.BinariesDirectory)\tests
- 7z x $(Build.SourcesDirectory)\ci\helloworld.7z
- cd ..
- qmake $(Build.BinariesDirectory)\tests\helloworld
+ qmake $(Build.SourcesDirectory)\ci\helloworld
mingw32-make
}
condition: |
@@ -322,11 +310,8 @@ steps:
# When --archives non-empty
- script: |
set -ex
- rm -rf $(Build.BinariesDirectory)/tests
- mkdir $(Build.BinariesDirectory)/tests
- (cd $(Build.BinariesDirectory)/tests && 7zr x $(Build.SourcesDirectory)/ci/helloworld_qttools.7z)
export PATH=$(QT_BINDIR):$PATH
- qmake -d $(Build.BinariesDirectory)/tests/helloworld_qttools
+ qmake $(Build.SourcesDirectory)/ci/helloworld_qttools
make
condition: |
and(
@@ -350,11 +335,7 @@ steps:
Import-VisualStudioVars -VisualStudioVersion $(VSVER) -Architecture $(ARCHITECTURE)
$env:Path += ";$(WIN_QT_BINDIR)"
- try { rm -r -fo $(Build.BinariesDirectory)\tests } catch { $Error.Clear() }
- mkdir $(Build.BinariesDirectory)\tests
- cd $(Build.BinariesDirectory)\tests
- 7z x $(Build.SourcesDirectory)\ci\helloworld_qttools.7z
- qmake -d $(Build.BinariesDirectory)\tests\helloworld_qttools
+ qmake $(Build.SourcesDirectory)\ci\helloworld_qttools
nmake
} elseif ( $env:TOOLCHAIN -eq 'MINGW' ) {
Set-Item -Path Env:Path -Value ("$(Build.BinariesDirectory)\Qt\Tools\$(MINGW_FOLDER)\bin;$(WIN_QT_BINDIR);" + $Env:Path)
@@ -368,11 +349,7 @@ steps:
throw 'Failed to install tools_mingw'
}
}
- try { rm -r -fo $(Build.BinariesDirectory)\tests } catch { $Error.Clear() }
- mkdir $(Build.BinariesDirectory)\tests
- cd $(Build.BinariesDirectory)\tests
- 7z x $(Build.SourcesDirectory)\ci\helloworld_qttools.7z
- qmake -d $(Build.BinariesDirectory)\tests\helloworld_qttools
+ qmake $(Build.SourcesDirectory)\ci\helloworld_qttools
mingw32-make
}
condition: |
@@ -396,11 +373,7 @@ steps:
Import-VisualStudioVars -VisualStudioVersion $(VSVER) -Architecture $(ARCHITECTURE)
$env:Path += ";$(WIN_QT_BINDIR)"
echo Add Qt to PATH: $env:PATH
- mkdir $(Build.BinariesDirectory)/tests
- cd $(Build.BinariesDirectory)/tests
- 7z x $(Build.SourcesDirectory)/ci/redditclient.7z
- cd ..
- qmake $(Build.BinariesDirectory)\tests\redditclient
+ qmake $(Build.SourcesDirectory)/ci/redditclient
nmake
condition: |
and(
@@ -412,13 +385,12 @@ steps:
displayName: build test with qmake with MSVC with extra module
- bash: |
set -ex
- mkdir $(Build.BinariesDirectory)/tests
- (cd $(Build.BinariesDirectory)/tests; 7zr x $(Build.SourcesDirectory)/ci/redditclient.7z)
+ export PATH=$(QT_BINDIR):$PATH
if [[ "6" -eq "${QT_VERSION:0:1}" ]]; then
- (cd $(Build.BinariesDirectory)/tests/redditclient;patch -i redditclient_6.diff -p1)
+ qmake $(Build.SourcesDirectory)/ci/redditclient
+ else
+ qmake $(Build.SourcesDirectory)/ci/redditclient_qt5
fi
- export PATH=$(QT_BINDIR):$PATH
- qmake $(Build.BinariesDirectory)/tests/redditclient
make
condition: |
and(
@@ -441,15 +413,12 @@ steps:
./emsdk install $(EMSDK_VERSION)
./emsdk activate --embedded $(EMSDK_VERSION)
source $(Build.BinariesDirectory)/emsdk/emsdk_env.sh
- mkdir $(Build.BinariesDirectory)/tests
+ export PATH=$(QT_BINDIR):$PATH
if [[ $(QT_VERSION) = 6* ]]; then
- OPENGLWINDOW_7Z="openglwindow_qt6.7z"
+ qmake $(Build.SourcesDirectory)/ci/openglwindow
else
- OPENGLWINDOW_7Z="openglwindow.7z"
+ qmake $(Build.SourcesDirectory)/ci/openglwindow_qt5
fi
- (cd $(Build.BinariesDirectory)/tests; 7zr x $(Build.SourcesDirectory)/ci/$OPENGLWINDOW_7Z)
- export PATH=$(QT_BINDIR):$PATH
- qmake $(Build.BinariesDirectory)/tests/openglwindow
make
workingDirectory: $(Build.BinariesDirectory)
condition: |
@@ -475,13 +444,11 @@ steps:
echo "Add Qt/qmake to PATH at $(WIN_QT_BINDIR):"
echo "$env:Path"
if ('$(QT_VERSION)' -like '6*') {
- 7z x $(Build.SourcesDirectory)\ci\openglwindow_qt6.7z
echo "Inlined qmake.bat command is: $(WIN_AUTODESK_QT_BINDIR)\qmake -qtconf $(WIN_QT_BINDIR)\target_qt.conf $(Build.BinariesDirectory)\tests\openglwindow"
- $(WIN_AUTODESK_QT_BINDIR)\qmake.exe -qtconf "$(WIN_QT_BINDIR)\target_qt.conf" $(Build.BinariesDirectory)\tests\openglwindow
+ $(WIN_AUTODESK_QT_BINDIR)\qmake.exe -qtconf "$(WIN_QT_BINDIR)\target_qt.conf" $(Build.SourcesDirectory)\ci\openglwindow
} else {
- 7z x $(Build.SourcesDirectory)\ci\openglwindow.7z
echo "Qt5: run qmake.exe"
- qmake $(Build.BinariesDirectory)\tests\openglwindow
+ qmake $(Build.SourcesDirectory)\ci\openglwindow_qt5
}
if ($false -eq $?) {
Write-Error "qmake failed."