diff --git a/CMakeLists.txt b/CMakeLists.txt
index b43b4e1e3..0e74d8420 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -260,6 +260,10 @@ if (ENABLE_TESTS)
)
endif ()
+if (SquishQtBuiltinHook_ROOT)
+ find_package(SquishQtBuiltinHook)
+endif ()
+
# ########################################################################################
# GLOBAL SETUP
# ########################################################################################
@@ -364,6 +368,10 @@ if (ANDROID)
# Make sure the generator for android_deployment_settings.json can figure out the
# architecture
list(APPEND CMAKE_FIND_ROOT_PATH /)
+ # Make sure the generator for android_deployment_settings.json can find Squish libs
+ if (SquishQtBuiltinHook_ROOT)
+ list(APPEND CMAKE_FIND_ROOT_PATH ${SquishQtBuiltinHook_ROOT})
+ endif ()
endif ()
# ########################################################################################
diff --git a/INSTALL.md b/INSTALL.md
index 386ae2ca3..e848fa54f 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -635,6 +635,7 @@ Once the project is opened, build it from Xcode.
# 9. Auto Testing
+## Mergin API tests
You need to add cmake define `-DENABLE_TESTING=TRUE` on your cmake configure line.
Also, you need to open Passbolt and check for password for user `test_mobileapp` on `app.dev.merginmaps.com`,
or you need some user with unlimited projects limit. First workspace from list is taken.
@@ -650,3 +651,45 @@ TEST_API_PASSWORD=
Build binary, and you can run tests either with `ctest` or you can run individual tests by adding `--test`
e.g. ` ./MerginMaps --testMerginApi`
+
+## Squish tests
+### Prerequisites
+ - Squish for Qt for Android (ARMv8/ARMv7 depending on architecture you build for)
+ - Squish for Qt for iOS
+ - Squish for Qt (Windows/Mac/Linux), this should also include the Squish IDE
+
+### Android
+After you unpack both (Qt & Qt for Android) and install Squish IDE, add another cmake argument `-DSquishQtBuiltinHook_ROOT=/////`.
+This will build the apk with squish hook inside. You can verify that squish is working by finding these lines in log after startup:
+```shell
+I/Squish (26459): Setting SQUISH_PREFIX to '/data/data/uk.co.lutraconsulting'
+I/Squish (26459): libMerginMaps_arm64-v8a.so[26459]: Loading Qt Wrapper configuration from ":/squish/etc/qtwrapper.ini"
+I/Squish (26459): libMerginMaps_arm64-v8a.so[26459]: QObject lifetime tracking is disabled
+I/Squish (26459): libMerginMaps_arm64-v8a.so[26459]: Listening on port 7757 for incoming connections
+```
+
+### iOS
+After you unpack both (Qt & Qt for iOS) and install Squish IDE, add these cmake arguments
+```cmake
+-DSquishQtBuiltinHook_ROOT=/////
+-DCMAKE_FIND_ROOT_PATH=/////
+-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=BOTH
+```
+This will build the app with squish hook inside. You can verify that squish is working by finding these lines in log after startup:
+```shell
+MerginMaps[834]: Loading Qt Wrapper configuration from ":/squish/etc/qtwrapper.ini"
+MerginMaps[834]: QObject lifetime tracking is disabled
+MerginMaps[834]: Listening on port 7757 for incoming connections
+```
+
+### Squish
+In the squish IDE it's necessary to follow these steps to finish setting it up and start testing the application.
+1. In Squish IDE choose File, New Test Suite to create a new Test Suite and follow the wizard. When asked for the GUI Toolkit choose Qt. When asked for the Application Under Test choose \.
+2. [Register attachable AUT](https://doc.qt.io/squish/attaching-to-running-applications.html#register-the-attachable-aut)
+ 1. As _Name_ set `MerginMaps`, _Host_ is the IP address of your phone (has to be on the same Wifi) and set _Port_ to `7757`
+ 2. You can also use USB cable to connect both devices. However, there is some further setup to do, first you need to forward the device port to your PC with:
+ ```shell
+ $ adb forward tcp:portnumber tcp:portnumber
+ ```
+ After that the setup is the same as in point 1, just _Host_ will become `localhost`.
+3. The test script should start with `attachToApplication("MerginMaps")`
diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt
index e474aa9b2..d1d88e0b8 100644
--- a/app/CMakeLists.txt
+++ b/app/CMakeLists.txt
@@ -343,6 +343,20 @@ if (ANDROID)
${CMAKE_CURRENT_SOURCE_DIR}/android/build.gradle @ONLY
)
+ if (SquishQtBuiltinHook_FOUND)
+ list(
+ APPEND
+ SquishLibs
+ "${SquishQtBuiltinHook_ROOT}/lib/libsquishhook.so"
+ "${SquishQtBuiltinHook_ROOT}/lib/libsquishqtquickcommon.so"
+ "${SquishQtBuiltinHook_ROOT}/lib/libsquishqtwrapper.so"
+ "${SquishQtBuiltinHook_ROOT}/lib/extensions/qt/libsquishqgraphicsview.so"
+ "${SquishQtBuiltinHook_ROOT}/lib/extensions/qt/libsquishqtabwidget.so"
+ "${SquishQtBuiltinHook_ROOT}/lib/extensions/qt/libsquishqtquick.so"
+ "${SquishQtBuiltinHook_ROOT}/lib/extensions/qt/libsquishqtquicktypes.so"
+ )
+ endif ()
+
set_target_properties(
MerginMaps
PROPERTIES QT_ANDROID_PACKAGE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/android
@@ -350,6 +364,7 @@ if (ANDROID)
QT_ANDROID_MIN_SDK_VERSION ${MM_ANDROID_MIN_SDK_VERSION}
QT_ANDROID_VERSION_CODE ${MM_VERSION_CODE}
QT_ANDROID_VERSION_NAME ${MM_VERSION}
+ QT_ANDROID_EXTRA_LIBS "${SquishLibs}"
)
endif ()
@@ -558,8 +573,12 @@ if (IOS OR MACOS)
endif ()
if (ANDROID)
+ if (SquishQtBuiltinHook_FOUND)
+ squish_qt_add_builtin_hook(MerginMaps ATTACH_PORT 7757)
+ endif ()
+
set_property(
- TARGET MerginMaps PROPERTY QT_ANDROID_EXTRA_LIBS ${OpenSSL_SSL_LIBRARY}
+ TARGET MerginMaps APPEND PROPERTY QT_ANDROID_EXTRA_LIBS ${OpenSSL_SSL_LIBRARY}
${OpenSSL_CRYPTO_LIBRARY}
)
endif ()
@@ -577,6 +596,18 @@ if (IOS)
)
# TODO is this needed? this change requires cmake 3.28+
# qt_add_ios_ffmpeg_libraries(MerginMaps) # Qt Multimedia
+ if (SquishQtBuiltinHook_FOUND)
+ squish_qt_add_builtin_hook(
+ MerginMaps
+ ATTACH_PORT
+ 7757
+ EXTENSIONS
+ QGraphicsView
+ QTabWidget
+ QtQuickTypes
+ QtQuick
+ )
+ endif ()
endif ()
if (WIN)
diff --git a/app/qml/CMakeLists.txt b/app/qml/CMakeLists.txt
index 6eef31f76..c5daa443f 100644
--- a/app/qml/CMakeLists.txt
+++ b/app/qml/CMakeLists.txt
@@ -55,6 +55,7 @@ set(MM_QML
components/MMToolbar.qml
components/MMToolbarButton.qml
components/MMSingleClickMouseArea.qml
+ components/MMStackView.qml
components/private/MMBaseInput.qml
components/private/MMBaseSingleLineInput.qml
components/private/MMToolbarLongButton.qml
diff --git a/app/qml/components/MMStackView.qml b/app/qml/components/MMStackView.qml
new file mode 100644
index 000000000..b3eab081b
--- /dev/null
+++ b/app/qml/components/MMStackView.qml
@@ -0,0 +1,27 @@
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+import QtQuick
+import QtQuick.Controls
+
+// StackView wrapper, which improves Squish support. Should be used instead of pure QML StackView.
+
+StackView {
+ id: root
+
+ onEmptyChanged: function() {
+ visible = !empty
+ }
+
+ Component.onCompleted: {
+ if (empty) {
+ visible = false
+ }
+ }
+}
diff --git a/app/qml/form/MMFormStackController.qml b/app/qml/form/MMFormStackController.qml
index 9d8c4d1f3..a270a0009 100644
--- a/app/qml/form/MMFormStackController.qml
+++ b/app/qml/form/MMFormStackController.qml
@@ -10,6 +10,8 @@
import QtQuick
import QtQuick.Controls
+import MMInput
+
Item {
id: root
@@ -252,7 +254,7 @@ Item {
form.controllerToApply = null
}
- StackView {
+ MMStackView {
id: formsStack
property bool syncWhenFormCloses: false
diff --git a/app/qml/layers/MMLayersController.qml b/app/qml/layers/MMLayersController.qml
index 8b7d5487c..e9b46b1ac 100644
--- a/app/qml/layers/MMLayersController.qml
+++ b/app/qml/layers/MMLayersController.qml
@@ -11,6 +11,7 @@ import QtQuick
import QtQuick.Controls
import mm 1.0 as MM
+import MMInput
import "../components"
import "../inputs"
@@ -41,7 +42,7 @@ Item {
}
}
- StackView {
+ MMStackView {
id: pagesStackView
anchors.fill: parent
diff --git a/app/qml/main.qml b/app/qml/main.qml
index d417de897..492c6434b 100644
--- a/app/qml/main.qml
+++ b/app/qml/main.qml
@@ -423,7 +423,7 @@ ApplicationWindow {
onClosed: stateManager.state = "map"
}
- StackView {
+ MMStackView {
id: mapPanelsStackView
//
diff --git a/app/qml/project/MMProjectController.qml b/app/qml/project/MMProjectController.qml
index ab83449fe..b6360067e 100644
--- a/app/qml/project/MMProjectController.qml
+++ b/app/qml/project/MMProjectController.qml
@@ -14,6 +14,7 @@ import Qt5Compat.GraphicalEffects
import QtQuick.Dialogs
import mm 1.0 as MM
+import MMInput
import "../components"
import "../inputs"
@@ -88,7 +89,7 @@ Item {
stackView.focus = true
}
- StackView {
+ MMStackView {
id: stackView
initialItem: workspaceProjectsPanelComp
diff --git a/app/qml/settings/MMSettingsController.qml b/app/qml/settings/MMSettingsController.qml
index 938ca22e0..4b57758af 100644
--- a/app/qml/settings/MMSettingsController.qml
+++ b/app/qml/settings/MMSettingsController.qml
@@ -56,7 +56,7 @@ Item {
}
- StackView {
+ MMStackView {
id: stackview
width: ApplicationWindow.window?.width ?? 0
diff --git a/gallery/qml/pages/OnboardingPage.qml b/gallery/qml/pages/OnboardingPage.qml
index e3c09b76d..c61793128 100644
--- a/gallery/qml/pages/OnboardingPage.qml
+++ b/gallery/qml/pages/OnboardingPage.qml
@@ -11,13 +11,15 @@ import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
+import MMInput
+
import "../../app/qml/components"
import "../../app/qml/account"
Page {
id: root
- StackView {
+ MMStackView {
id: stackview
anchors.fill: parent
diff --git a/gallery/qml/pages/PagesPage.qml b/gallery/qml/pages/PagesPage.qml
index 0effaf990..3eff2cc27 100644
--- a/gallery/qml/pages/PagesPage.qml
+++ b/gallery/qml/pages/PagesPage.qml
@@ -11,6 +11,8 @@ import QtQuick
import QtQuick.Controls
import QtQuick.Controls.Basic
+import MMInput
+
import "../../app/qml/components"
import "../../app/qml"
import "../../app/qml/project"
@@ -21,7 +23,7 @@ import "../../app/qml/account"
Page {
id: root
- StackView {
+ MMStackView {
id: stackview
anchors.fill: parent